@@ -20,7 +20,7 @@ data and to then invoke that function and pass it to a response object::
20
20
def generate():
21
21
for row in iter_all_rows():
22
22
yield f"{','.join(row)}\n"
23
- return app.response_class( generate(), mimetype=' text/csv' )
23
+ return generate(), {"Content-Type": " text/csv" )
24
24
25
25
Each ``yield `` expression is directly sent to the browser. Note though
26
26
that some WSGI middlewares might break streaming, so be careful there in
@@ -29,52 +29,57 @@ debug environments with profilers and other things you might have enabled.
29
29
Streaming from Templates
30
30
------------------------
31
31
32
- The Jinja2 template engine also supports rendering templates piece by
33
- piece. This functionality is not directly exposed by Flask because it is
34
- quite uncommon, but you can easily do it yourself::
35
-
36
- def stream_template(template_name, **context):
37
- app.update_template_context(context)
38
- t = app.jinja_env.get_template(template_name)
39
- rv = t.stream(context)
40
- rv.enable_buffering(5)
41
- return rv
42
-
43
- @app.route('/my-large-page.html')
44
- def render_large_template():
45
- rows = iter_all_rows()
46
- return app.response_class(stream_template('the_template.html', rows=rows))
47
-
48
- The trick here is to get the template object from the Jinja2 environment
49
- on the application and to call :meth: `~jinja2.Template.stream ` instead of
50
- :meth: `~jinja2.Template.render ` which returns a stream object instead of a
51
- string. Since we're bypassing the Flask template render functions and
52
- using the template object itself we have to make sure to update the render
53
- context ourselves by calling :meth: `~flask.Flask.update_template_context `.
54
- The template is then evaluated as the stream is iterated over. Since each
55
- time you do a yield the server will flush the content to the client you
56
- might want to buffer up a few items in the template which you can do with
57
- ``rv.enable_buffering(size) ``. ``5 `` is a sane default.
32
+ The Jinja2 template engine supports rendering a template piece by
33
+ piece, returning an iterator of strings. Flask provides the
34
+ :func: `~flask.stream_template ` and :func: `~flask.stream_template_string `
35
+ functions to make this easier to use.
36
+
37
+ .. code-block :: python
38
+
39
+ from flask import stream_template
40
+
41
+ @app.get (" /timeline" )
42
+ def timeline ():
43
+ return stream_template(" timeline.html" )
44
+
45
+ The parts yielded by the render stream tend to match statement blocks in
46
+ the template.
47
+
58
48
59
49
Streaming with Context
60
50
----------------------
61
51
62
- .. versionadded :: 0.9
52
+ The :data: `~flask.request ` will not be active while the generator is
53
+ running, because the view has already returned at that point. If you try
54
+ to access ``request ``, you'll get a ``RuntimeError ``.
63
55
64
- Note that when you stream data, the request context is already gone the
65
- moment the function executes. Flask 0.9 provides you with a helper that
66
- can keep the request context around during the execution of the
67
- generator::
56
+ If your generator function relies on data in ``request ``, use the
57
+ :func: `~flask.stream_with_context ` wrapper. This will keep the request
58
+ context active during the generator.
59
+
60
+ .. code-block :: python
68
61
69
62
from flask import stream_with_context, request
63
+ from markupsafe import escape
70
64
71
65
@app.route (' /stream' )
72
66
def streamed_response ():
73
67
def generate ():
74
- yield 'Hello '
75
- yield request.args['name']
76
- yield '!'
77
- return app.response_class(stream_with_context(generate()))
68
+ yield ' <p>Hello '
69
+ yield escape(request.args[' name' ])
70
+ yield ' !</p>'
71
+ return stream_with_context(generate())
72
+
73
+ It can also be used as a decorator.
74
+
75
+ .. code-block :: python
76
+
77
+ @stream_with_context
78
+ def generate ():
79
+ ...
80
+
81
+ return generate()
78
82
79
- Without the :func: `~flask.stream_with_context ` function you would get a
80
- :class: `RuntimeError ` at that point.
83
+ The :func: `~flask.stream_template ` and
84
+ :func: `~flask.stream_template_string ` functions automatically
85
+ use :func: `~flask.stream_with_context ` if a request is active.
0 commit comments