Jinja 2.9+ has async support built right in, so now you can handle templates without needing any specially made packages.
Here is a simple way to use jinja2 in a Sanic app.
First, I built a couple utility functions that can be reused throughout the handlers: util/templating.py
async def _build_env():
project_path = '/path/to/project'
templates_dir = 'templates'
package_loader = PackageLoader(project_path, templates_dir, encoding='utf-8')
environment = Environment(loader=package_loader, enable_async=True)
environment.filters["usd"] = lambda x: "${:,.2f} USD".format(x)
environment.filters["datefmt"] = lambda x: x.strftime('%Y-%m-%d')
return environment
async def render_template(request, file_name, **kwargs):
environment = await _build_environment()
template = environment.get_template(file_name)
context = {
'web_wrapper': 'web_wrapper.html',
'request': request,
'session': request.ctx.session
}
rendered_template = await template.render_async(context, **kwargs)
return rendered_template
There are a few (very small) things to do to take Jinja2 asynchronous:
- When instantiating Environment, specify
enable_async=True
- When rendering a loaded template, use
template.render_async()
- and of course, use
async def
andawait
appropriately
That’s all there is to it. For completeness, here’s how to use it from within a handler:
blueprint = Blueprint('public')
@blueprint.route("/")
async def index(request):
template = await render_template("/index.html", request, my_test_arg="This is a test!")
return HTTPResponse(template, content_type='text/html')
web_wrapper.html
<html>
<head><title>{{ page_title }}</title></head>
<body>{% block content %}{% endblock %}</body>
</html>
index.html
{% extends web_wrapper %}
{% set page_title = "Async Jinja2 w/ Sanic Example" %}
{% block content %}
This is the index! {{ my_test_arg }}</body></html>
{% endblock %}
(I provide this code w/o any guarantees that it will work on your project. I tried to make it as simple as possible so it can be modified to fit your needs.)
(Also, please feel free to copy this example and use it on any blogs or w/e else. I created this because it seemed like there was a shortage of information on Jinja2’s async capability, so PLEASE share this around if you’re inclined to do so.)