tornado
tornado copied to clipboard
gen.coroutine support in Templates
[Edited to fix failing tests in python3--apologies for the spam.]
We're building a semi-lazy-loading asynchronous ORM and have found the gen.coroutine
decorator to be a great resource. Our objects come out looking something like the below:
Model.attribute = value
Model.reference = Future
Model.collection_name = [Future, Future]
So it's very efficient for us to start generating content from our templates and only wait for references and collections if we need to. Hence, our templates look like the below:
<html>
<head>
<title>{{ Model.some_value }} </title>
<body>
<h1>{{ yield Model.some_reference }}</h1>
</body>
We love working with the most recent version of Tornado, and aren't willing to break off from the main fork. With that in mind, we're currently using a modified version of the template.py
, represented in the pull. If this is something that you aren't interested in incorporating into the main repo, we'll happily subclass as necessary to accomplish it without conflict.
Obviously, it's easier for us to modify the code in place, and I'm happy to help incorporate these changes more thoroughly if you think the feature could be useful in, e.g. the UIModules. Those changes could be non-trivial, however, as I believe ultimately everything that uses a coroutine=True argument will need to be decorated with gen.coroutine
. Please correct me if I'm wrong. If so, separate methods for .render() and .render_string() are probably necessary.
For future reference, you can just push new commits to an existing branch instead of closing the PR and opening a new one.
There is another implementation of this feature in #553 and discussion in https://groups.google.com/forum/?fromgroups#!searchin/python-tornado/template$20asynchronous%7Csort:date/python-tornado/Eoyb2wphJ-o/fj9EAb166PIJ. I've been skeptical of the idea but @ajdavis has convinced me to give it another shot.
It occurs to me that this could perhaps be simpler with undecorated coroutines (#1305) - we wouldn't need to declare a template as a coroutine or not, we'd just need an async-aware version of render that could handle the returned generator if it contained any yields. ({% apply %}
is as usual the trickiest part)
I think this is outdated
It is outdated (at a minimum it should support async def
and not just @coroutine
), but I'm leaving the PR open because updating it may be easier than starting from scratch whenever someone takes another look at it.