render_template hangs when using microdot_asyncio
Odud opened this issue · 5 comments
Describe the bug
render_template hangs when using microdot_asyncio but works fine with microdot. If I remove the render template call and just return some text then this works fine as expected.
To Reproduce
from microdot_asyncio import Microdot, Response
from microdot_utemplate import render_template
app = Microdot()
Response.default_content_type = 'text/html'
@app.route('/')
def index(req):
return render_template(
"test.html",
Test="This Test",
)
app.run(debug=True)
Expected behavior
Browser should return the web page, but instead it hangs, there is no debug output from the server other than Starting async server on 0.0.0.0:5000...
Additional context
MicroPython v1.20.0 on 2023-04-26; Raspberry Pi Pico W with RP2040
If I replace from microdot_asyncio...
by from microdot...
then everything works fine, the template displays in the browser and I see debug output Starting sync server on 0.0.0.0:5000... GET / 200.
The template is as follows:
{% args Test %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>{{ Test }} </p>
</body>
</html>
BTW I'm relatively new to asyncio but have used microdot successfully before
Apologies, it isn't render_template that is hanging it is the return of the template. I put some print statements around the render_template and it is working fine. I needed to make the function after the @route an async.
@app.route('/')
async def index(req):
I don't really uderstand why, but suspect this is my lack of understanding of async. Happy to close if my thought is correct
@Odud: Ah, okay, I do see what the problem is now. In MicroPython async functions are really generators. The render_template()
function returns a generator as well. Microdot is confused because a non-async function is returning something that looks like what an async function would return. I need to find a way to distinguish the return value of calling an async function from a generator returned by a non-async function, which actually look the same.
In the meantime your solution is fine, just make sure any functions that use render_template()
are defined as async functions. I'll investigate to see if I can figure out how to make non-async functions work as well.
Microdot 2 has been redesigned to work asynchronously, and the template extensions can also be used asynchronously, which should address this problem.