简体   繁体   中英

How to insert Sanic stream object to jinja asynchronous template

In Sanic (python async web framework) I can create stream object output to html with this:

from sanic.response import stream

@app.route("/")
async def test(request):
    async def sample_streaming_fn(response):
        await response.write('<b>foo</b>') 
        await response.write('<b>bar</b>')
    return stream(sample_streaming_fn, content_type='text/html')

Result:

foo bar

And with Jinja2 I can render asynchronously like so after turn on the async feature:

from sanic.response import html

@app.route('/')
async def test(request):
     rendered_template = await template.render_async(
         key='value')
     return html(rendered_template)

I tried with this to output stream object to Jinja2 template:

@app.route('/')
async def test(request):
    async def stream_template(response):
        rendered_template =  await template.render_async(
            key="<b>value</b>")
        await response.write(rendered_template)
    return stream(stream_template, content_type='text/html') # I need it to return stream

but all I got was the downloaded template (html file).

I there any way to rig Jinja2 template.render_async to accept Sanic's response.write and return it in stream?

After tweaking, here's what I came up with:

from sanic.response import stream

@app.route("/")
async def test(request):
    async def sample_streaming_fn(response):
        await response.write(await template.render_async(key='<b>foo</b>'))
        await asyncio.sleep(1) # just for checking if it's indeed streamed
        await response.write(await template.render_async(key='<b>bar</b>'))
    return stream(sample_streaming_fn, content_type='text/html')

And here's the Jinja2 template:

<p>{{ key|safe }}</p>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM