如何在Python中使用pip安装的jinja2过滤器

如何在Python中使用pip安装的jinja2过滤器,python,jinja2,Python,Jinja2,在我的Ansible项目中,我使用pip安装了库,允许我使用额外的jinja2过滤器 其中,我安装了netaddr库,允许我使用ipaddr过滤器,如下所示:{{interface.IP | ipaddr('netmask')}(这在我的Ansible playbook中起作用) 当我试图通过创建一个快速Python脚本来测试我的模板而不必运行Ansible playbook时,问题就来了。例如: from jinja2 import Template print Template('{{ ip

在我的Ansible项目中,我使用
pip
安装了库,允许我使用额外的jinja2过滤器

其中,我安装了
netaddr
库,允许我使用
ipaddr
过滤器,如下所示:
{{interface.IP | ipaddr('netmask')}
(这在我的Ansible playbook中起作用)

当我试图通过创建一个快速Python脚本来测试我的模板而不必运行Ansible playbook时,问题就来了。例如:

from jinja2 import Template
print Template('{{ ip | ipaddr("netmask") }}').render(ip='10.10.10.0/24')
向我抛出以下异常:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 945, in __new__
  return env.from_string(source, template_class=cls)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 880, in from_string
  return cls.from_code(self, self.compile(source), globals, None)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 591, in compile
  self.handle_exception(exc_info, source_hint=source_hint)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "<unknown>", line 1, in template
jinja2.exceptions.TemplateAssertionError: no filter named 'ipaddr'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/local/lib/python2.7/dist-packages/jinja2/environment.py”,第945行,新__
从字符串返回环境(源,模板类=cls)
文件“/usr/local/lib/python2.7/dist packages/jinja2/environment.py”,第880行,from_字符串
从_代码返回cls.from(self,self.compile(源代码),globals,None)
文件“/usr/local/lib/python2.7/dist-packages/jinja2/environment.py”,第591行,编译
self.handle\u异常(exc\u info,source\u hint=source\u hint)
文件“/usr/local/lib/python2.7/dist-packages/jinja2/environment.py”,第780行,在handle\u异常中
重放(exc_类型、exc_值、tb)
模板中第1行的文件“”
jinja2.exceptions.TemplateAssertionError:没有名为“ipaddr”的筛选器
我可以在最后一行看到,jinja2找不到“ipaddr”过滤器,它是
安装在
/usr/lib/python2.7/dist软件包中,但我在Python脚本中找不到如何直接使用通过pip安装的软件包。

我花了大半个小时的时间试图让它正常工作,这简直是一场噩梦。我最终不得不放弃。虽然这仍然是可能的,但我无法在任何地方获得很多信息,甚至创建了
Environment()
,并尝试加载扩展等等

我最后做的是使用这里提到的一种解决方案:

(该解决方案还提到了一些在线Jinja2解析器,但这些解析器似乎遇到了与交互式Python方法完全相同的问题。)

我最终采用的是Ansible_3Ansible_4解决方案的组合-

我创建了一个名为
nametest.yml
的测试文件,如下所示:

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template: src=name.j2 dest=output.conf
然后我将我的测试Jinja2内容放入
name.j2
文件中

我进行了如下测试:

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template: src=name.j2 dest=output.conf
ansible playbook nametest.yml--check--diff--connection=local-e role=api-e level=prod-e'{“item”:{“private_ip”:“1.2.3.4”}'-e debug_instance=false

这些
-e
选项分别设置单个变量的值。大多数情况下,我只使用了简单的
name=value
构造,但对于更复杂的嵌套对象,我使用了JSON版本


然后,为了使用不同的变量值运行,我只需旋转不同的命令行参数来测试我设置的所有不同的代码分支。

是的,您可以这样做。Ansible需要位于python路径中

import jinja2
from ansible.plugins.filter import ipaddr

template_dir = 'path/to/templates'
fname = 'template.txt'

# get the filters from ansible/plugins/filter/ipaddr
f = ipaddr.FilterModule()

# for a template in your filesystem, set the loader
loader = jinja2.FileSystemLoader(template_dir)

# create the environment
env = jinja2.Environment(loader=loader)

# *** Add the ipaddr filters to the environment ***
env.filters.update(f.filters())

# Set your template
template = env.get_template(fname)

print(template.render(ip='10.10.10.0/24'))
这将使您的模板文件(包含
{ip|ipaddr(“netmask”)}}
)输出