I have a python script that renders a jinja2 template. Something like this:
basic.py
#!/usr/bin/env python3
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
loader=PackageLoader('basic'),
autoescape=select_autoescape()
)
print(env.get_template('basic_template.md').render({'version': 'version123', 'date': 'some-date'}))
My directory structure looks like this:
.
|__ templates/
| |
| |__ basic_template.md
|
|__ basic.py
I'm running this in a CI pipeline. The job runs this command: python /path/to/basic.py
.
Whenever it runs, the whole script runs twice. This is being caused by the env
variable--specifically PackageLoader('basic')
. I'm pretty sure when this is loaded it's running the basic.py
script (again)--from within basic.py
.
If I create an empty dummy script and use that in PackageLoader
, my script works fine (only renders the template once):
.
|__ templates/
| |
| |__ basic_template.md
|
|__ basic.py
|
|__ other_script.py
#!/usr/bin/env python3
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
loader=PackageLoader('other_script'),
autoescape=select_autoescape()
)
print(env.get_template('basic_template.md').render({'version': 'version123', 'date': 'some-date'}))
If I pass a non-existent file to PackageLoader
or if I omit loader=PackageLoader()
all together, it throws an error.
So what's the right way to accomplish this? I don't want to have a random empty file lying around if I don't need it. How do I render the template without PackageLoader
running my script a second time?
The reason for this is indeed the fact that the PackageLoader
object is meant to import Python packages, so it will try to invoke either a file or a folder called as your package that are in the same folder as the current script.
So, there is two ways you can solve this:
PackageLoader
object and create yourself a basic
package, your file structure becomes
.
├── basic
│ ├── __init__.py
│ └── templates
│ └── basic_template.md
└── basic.py
The __init__.py
file is mandatory, but could be just an empty file.FileSystemLoader
instead of the PackageLoader
.basic.py
that changes:
#!/usr/bin/env python3
from jinja2 import Environment, FileSystemLoader, select_autoescape
env = Environment(
loader=FileSystemLoader('templates'),
autoescape=select_autoescape()
)
print(env.get_template('basic_template.md').render(
{'version': 'version123', 'date': 'some-date'}
))
Related issues in their issue tracker: