Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to write Jinja loaders that use async/await #1304

Open
simonw opened this issue Oct 30, 2020 · 4 comments
Open

Ability to write Jinja loaders that use async/await #1304

simonw opened this issue Oct 30, 2020 · 4 comments

Comments

@simonw
Copy link
Contributor

simonw commented Oct 30, 2020

I'm writing code within an async framework, using Jinja's excellent async mode.

I want to write a custom template loader that can load templates asynchronously from my database - but as far as I can tell the Jinja loader mechanisms only work with synchronous functions.

Borrowing an example from here I'd love to be able to do something like this:

async def load_template(name):
    row = await db.execute("select body from templates where name = ?", name)
    return row[0]

loader = FunctionLoader(load_template)

I initially implemented a workaround for this by loading templates asynchronously in my own code and compiling them for Jinja with jinja_env.from_string(plugin_template_source) - but then I realized that this doesn't work for templates loaded internally by Jinja due to {% extends ... %} and {% include ... %} blocks.

I'd be happy to help implement this if it's a feature that Jinja maintainers agree should be part of the library.

@davidism
Copy link
Member

I'd be fine adding it in, but I have no idea what the API/implementation would look like. Did you have something in mind?

@simonw
Copy link
Contributor Author

simonw commented Nov 1, 2020

My ideal implementation as a user would be the one listed above - where the FunctionLoader loader can take an async function and magically call it in the right way, by internally using the auto_await() function (assuming Jinja is running in async mode, otherwise it would throw an error):

async def auto_await(value):
if inspect.isawaitable(value):
return await value
return value

The implementation looks tricky though, since I imagine getting {% include %} and {% extends %} working against an async loader would require some changes to the code that the Jinja compiler generates, which I'm not at all familiar with.

It may be more Jinja-like to have a new Loader class called AsyncLoader rather than reusing the existing FunctionLoader though.

@grondman
Copy link

I'm using Tortoise ORM all over the place and being able to asynchronously load templates from a DB is something I'd definitely use 🙂

@ssjunior
Copy link

ssjunior commented Dec 11, 2023

I am using a custom loader from database in a Django async application... Is there a way to make the loader async? Otherwise I can't load templates from database.. :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants