forked from orbit-oss/flask
document that headers must be set before streaming
This commit is contained in:
parent
f00ad424ee
commit
a29f88ce6f
4 changed files with 55 additions and 8 deletions
|
|
@ -8,6 +8,21 @@ roundtrip to the filesystem?
|
|||
|
||||
The answer is by using generators and direct responses.
|
||||
|
||||
HTTP Response Behavior
|
||||
----------------------
|
||||
|
||||
**Headers cannot be changed after the streaming response starts.**
|
||||
|
||||
When using streaming, it's important to be aware of the order than an HTTP
|
||||
response is sent. All headers must be sent first, then the body. More headers
|
||||
cannot be sent after the body has begun. Therefore, you must make sure all
|
||||
headers are set before starting the response, outside the generator.
|
||||
|
||||
In particular, if the generator will access ``session``, be sure to do so in the
|
||||
view as well so that the ``Vary: cookie`` header will be set. Do not modify the
|
||||
session in the generator, as the ``Set-Cookie`` header will already be sent.
|
||||
|
||||
|
||||
Basic Usage
|
||||
-----------
|
||||
|
||||
|
|
|
|||
|
|
@ -225,5 +225,11 @@ functions to make this easier to use.
|
|||
return stream_template("timeline.html")
|
||||
|
||||
These functions automatically apply the
|
||||
:func:`~flask.stream_with_context` wrapper if a request is active, so
|
||||
that it remains available in the template.
|
||||
:func:`~flask.stream_with_context` wrapper if a request is active, so that
|
||||
:data:`.request`, :data:`.session`, and :data:`.g` remain available in the
|
||||
template.
|
||||
|
||||
More headers cannot be sent after the body has begun. Therefore, you must
|
||||
make sure all headers are set before starting the response. In particular,
|
||||
if the template will access ``session``, be sure to do so in the view as
|
||||
well so that the ``Vary: cookie`` header will be set.
|
||||
|
|
|
|||
|
|
@ -153,13 +153,27 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
|
|||
|
||||
|
||||
def copy_current_request_context(f: F) -> F:
|
||||
"""A helper function that decorates a function to retain the current
|
||||
request context. This is useful when working with greenlets. The moment
|
||||
the function is decorated a copy of the request context is created and
|
||||
then pushed when the function is called. The current session is also
|
||||
included in the copied request context.
|
||||
"""Decorate a function to run inside the current request context. This can
|
||||
be used when starting a background task, otherwise it will not see the app
|
||||
and request objects that were active in the parent.
|
||||
|
||||
Example::
|
||||
.. warning::
|
||||
|
||||
Due to the following caveats, it is often safer (and simpler) to pass
|
||||
the data you need when starting the task, rather than using this and
|
||||
relying on the context objects.
|
||||
|
||||
In order to avoid execution switching partially though reading data, either
|
||||
read the request body (access ``form``, ``json``, ``data``, etc) before
|
||||
starting the task, or use a lock. This can be an issue when using threading,
|
||||
but shouldn't be an issue when using greenlet/gevent or asyncio.
|
||||
|
||||
If the task will access ``session``, be sure to do so in the parent as well
|
||||
so that the ``Vary: cookie`` header will be set. Modifying ``session`` in
|
||||
the task should be avoided, as it may execute after the response cookie has
|
||||
already been written.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import gevent
|
||||
from flask import copy_current_request_context
|
||||
|
|
|
|||
|
|
@ -68,6 +68,18 @@ def stream_with_context(
|
|||
available, even though at the point the generator runs the request context
|
||||
will typically have ended.
|
||||
|
||||
.. warning::
|
||||
|
||||
Due to the following caveat, it is often safer to pass the data you
|
||||
need as arguments to the generator, rather than relying on the context
|
||||
objects.
|
||||
|
||||
More headers cannot be sent after the body has begun. Therefore, you must
|
||||
make sure all headers are set before starting the response. In particular,
|
||||
if the generator will access ``session``, be sure to do so in the view as
|
||||
well so that the ``Vary: cookie`` header will be set. Do not modify the
|
||||
session in the generator, as the ``Set-Cookie`` header will already be sent.
|
||||
|
||||
Use it as a decorator on a generator function:
|
||||
|
||||
.. code-block:: python
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue