在Python中测试Ansible to_nice_json过滤器时遇“无此过滤器”报错的解决
问题描述
想要用Python脚本测试Ansible Jinja2模板,编写了如下代码,但运行时出现to_nice_json过滤器未找到的错误:
#!/usr/bin/env bash # python3 -m pip install ansible python3 <<EOF import ansible import jinja2 print(ansible.__version__) print(jinja2.__version__) output = jinja2.Template("Hello {{ var | to_nice_json }}!").render(var=f"{{ 'a': 1, 'b': 2 }}") print(output) EOF
运行返回错误:
2.15.6 3.1.2 Traceback (most recent call last): File "<stdin>", line 7, in <module> File "/Users/werner/.pyenv/versions/3.11.6/lib/python3.11/site-packages/jinja2/environment.py", line 1208, in __new__ return env.from_string(source, template_class=cls) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/werner/.pyenv/versions/3.11.6/lib/python3.11/site-packages/jinja2/environment.py", line 1105, in from_string return cls.from_code(self, self.compile(source), gs, None) ^^^^^^^^^^^^^^^^^^^^ File "/Users/werner/.pyenv/versions/3.11.6/lib/python3.11/site-packages/jinja2/environment.py", line 768, in compile self.handle_exception(source=source_hint) File "/Users/werner/.pyenv/versions/3.11.6/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "<unknown>", line 1, in template jinja2.exceptions.TemplateAssertionError: No filter named 'to_nice_json'.
原因是直接使用原生Jinja2模板环境不会自动加载Ansible的自定义过滤器,to_nice_json是Ansible扩展的过滤器,并非Jinja2原生自带。
解决方法
方法一:使用Ansible官方模板渲染机制(推荐)
直接调用Ansible内置的模板处理类,它会自动初始化包含所有Ansible过滤器的Jinja2环境:
修改后的代码如下:
#!/usr/bin/env bash # python3 -m pip install ansible python3 <<EOF import ansible from ansible.template import Template print(ansible.__version__) # 使用Ansible的Template类渲染 template_content = "Hello {{ var | to_nice_json }}!" output = Template(template_content).render(var={'a': 1, 'b': 2}) print(output) EOF
运行后会输出:
2.15.6 Hello { "a": 1, "b": 2 }!
方法二:手动向Jinja2环境添加单个过滤器
如果只需要特定过滤器,可以手动导入对应函数并注册到Jinja2环境中:
#!/usr/bin/env bash # python3 -m pip install ansible python3 <<EOF import ansible import jinja2 from ansible.plugins.filter.core import to_nice_json print(ansible.__version__) print(jinja2.__version__) # 创建Jinja2环境并注册过滤器 env = jinja2.Environment() env.filters['to_nice_json'] = to_nice_json template = env.from_string("Hello {{ var | to_nice_json }}!") output = template.render(var={'a': 1, 'b': 2}) print(output) EOF
这种方式适合只需要少量特定过滤器的场景,避免加载整个Ansible模板环境。
内容的提问来源于stack exchange,提问作者slhck
相关产品推荐
相关产品推荐

