Streaming内容¶
有时,您希望向客户机发送大量的数据,这比您希望在内存中保存的数据要多得多。但是,当您在运行中生成数据时,如何在没有文件系统往返的情况下将数据发送回客户机?
答案是使用生成器和直接响应。
基本用法¶
这是一个基本的视图函数,可以动态生成大量的csv数据。诀窍是拥有一个内部函数,该函数使用生成器生成数据,然后调用该函数并将其传递给响应对象:
@app.route('/large.csv')
def generate_large_csv():
def generate():
for row in iter_all_rows():
yield f"{','.join(row)}\n"
return generate(), {"Content-Type": "text/csv"}
各 yield
表达式直接发送到浏览器。请注意,虽然一些WSGi中间软件可能会中断流,但是在使用配置文件和其他您可能启用的东西的调试环境中要小心。
从模板流式传输¶
JJIA2模板引擎支持逐段呈现模板,返回字符串迭代器。烧瓶提供了 stream_template()
和 stream_template_string()
函数以使其更易于使用。
from flask import stream_template
@app.get("/timeline")
def timeline():
return stream_template("timeline.html")
呈现流生成的部分往往与模板中的语句块匹配。
与上下文流式处理¶
这个 request
在生成器运行时不会处于活动状态,因为此时视图已返回。如果您尝试访问 request
,你会得到一个 RuntimeError
。
如果您的生成器函数依赖 request
,请使用 stream_with_context()
包装纸。这将使请求上下文在生成器期间保持活动状态。
from flask import stream_with_context, request
from markupsafe import escape
@app.route('/stream')
def streamed_response():
def generate():
yield '<p>Hello '
yield escape(request.args['name'])
yield '!</p>'
return stream_with_context(generate())
它也可以用作装饰品。
@stream_with_context
def generate():
...
return generate()
这个 stream_template()
和 stream_template_string()
函数自动使用 stream_with_context()
如果请求处于活动状态。