forked from orbit-oss/flask
update docs about contexts
This commit is contained in:
parent
82c2e0366c
commit
e0dad45481
9 changed files with 74 additions and 124 deletions
56
docs/api.rst
56
docs/api.rst
|
|
@ -311,56 +311,28 @@ Useful Internals
|
||||||
.. autoclass:: flask.ctx.RequestContext
|
.. autoclass:: flask.ctx.RequestContext
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. data:: _request_ctx_stack
|
.. data:: flask.globals.request_ctx
|
||||||
|
|
||||||
The internal :class:`~werkzeug.local.LocalStack` that holds
|
The current :class:`~flask.ctx.RequestContext`. If a request context
|
||||||
:class:`~flask.ctx.RequestContext` instances. Typically, the
|
is not active, accessing attributes on this proxy will raise a
|
||||||
:data:`request` and :data:`session` proxies should be accessed
|
``RuntimeError``.
|
||||||
instead of the stack. It may be useful to access the stack in
|
|
||||||
extension code.
|
|
||||||
|
|
||||||
The following attributes are always present on each layer of the
|
This is an internal object that is essential to how Flask handles
|
||||||
stack:
|
requests. Accessing this should not be needed in most cases. Most
|
||||||
|
likely you want :data:`request` and :data:`session` instead.
|
||||||
`app`
|
|
||||||
the active Flask application.
|
|
||||||
|
|
||||||
`url_adapter`
|
|
||||||
the URL adapter that was used to match the request.
|
|
||||||
|
|
||||||
`request`
|
|
||||||
the current request object.
|
|
||||||
|
|
||||||
`session`
|
|
||||||
the active session object.
|
|
||||||
|
|
||||||
`g`
|
|
||||||
an object with all the attributes of the :data:`flask.g` object.
|
|
||||||
|
|
||||||
`flashes`
|
|
||||||
an internal cache for the flashed messages.
|
|
||||||
|
|
||||||
Example usage::
|
|
||||||
|
|
||||||
from flask import _request_ctx_stack
|
|
||||||
|
|
||||||
def get_session():
|
|
||||||
ctx = _request_ctx_stack.top
|
|
||||||
if ctx is not None:
|
|
||||||
return ctx.session
|
|
||||||
|
|
||||||
.. autoclass:: flask.ctx.AppContext
|
.. autoclass:: flask.ctx.AppContext
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. data:: _app_ctx_stack
|
.. data:: flask.globals.app_ctx
|
||||||
|
|
||||||
The internal :class:`~werkzeug.local.LocalStack` that holds
|
The current :class:`~flask.ctx.AppContext`. If an app context is not
|
||||||
:class:`~flask.ctx.AppContext` instances. Typically, the
|
active, accessing attributes on this proxy will raise a
|
||||||
:data:`current_app` and :data:`g` proxies should be accessed instead
|
``RuntimeError``.
|
||||||
of the stack. Extensions can access the contexts on the stack as a
|
|
||||||
namespace to store data.
|
|
||||||
|
|
||||||
.. versionadded:: 0.9
|
This is an internal object that is essential to how Flask handles
|
||||||
|
requests. Accessing this should not be needed in most cases. Most
|
||||||
|
likely you want :data:`current_app` and :data:`g` instead.
|
||||||
|
|
||||||
.. autoclass:: flask.blueprints.BlueprintSetupState
|
.. autoclass:: flask.blueprints.BlueprintSetupState
|
||||||
:members:
|
:members:
|
||||||
|
|
|
||||||
|
|
@ -136,14 +136,6 @@ local from ``get_db()``::
|
||||||
Accessing ``db`` will call ``get_db`` internally, in the same way that
|
Accessing ``db`` will call ``get_db`` internally, in the same way that
|
||||||
:data:`current_app` works.
|
:data:`current_app` works.
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
If you're writing an extension, :data:`g` should be reserved for user
|
|
||||||
code. You may store internal data on the context itself, but be sure to
|
|
||||||
use a sufficiently unique name. The current context is accessed with
|
|
||||||
:data:`_app_ctx_stack.top <_app_ctx_stack>`. For more information see
|
|
||||||
:doc:`/extensiondev`.
|
|
||||||
|
|
||||||
|
|
||||||
Events and Signals
|
Events and Signals
|
||||||
------------------
|
------------------
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,6 @@ when the application context ends. If it should only be valid during a
|
||||||
request, or would not be used in the CLI outside a reqeust, use
|
request, or would not be used in the CLI outside a reqeust, use
|
||||||
:meth:`~flask.Flask.teardown_request`.
|
:meth:`~flask.Flask.teardown_request`.
|
||||||
|
|
||||||
An older technique for storing context data was to store it on
|
|
||||||
``_app_ctx_stack.top`` or ``_request_ctx_stack.top``. However, this just
|
|
||||||
moves the same namespace collision problem elsewhere (although less
|
|
||||||
likely) and modifies objects that are very internal to Flask's
|
|
||||||
operations. Prefer storing data under a unique name in ``g``.
|
|
||||||
|
|
||||||
|
|
||||||
Views and Models
|
Views and Models
|
||||||
----------------
|
----------------
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,6 @@ or create an application context itself. At that point the ``get_db``
|
||||||
function can be used to get the current database connection. Whenever the
|
function can be used to get the current database connection. Whenever the
|
||||||
context is destroyed the database connection will be terminated.
|
context is destroyed the database connection will be terminated.
|
||||||
|
|
||||||
Note: if you use Flask 0.9 or older you need to use
|
|
||||||
``flask._app_ctx_stack.top`` instead of ``g`` as the :data:`flask.g`
|
|
||||||
object was bound to the request and not application context.
|
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,14 @@ context, which also pushes an :doc:`app context </appcontext>`. When the
|
||||||
request ends it pops the request context then the application context.
|
request ends it pops the request context then the application context.
|
||||||
|
|
||||||
The context is unique to each thread (or other worker type).
|
The context is unique to each thread (or other worker type).
|
||||||
:data:`request` cannot be passed to another thread, the other thread
|
:data:`request` cannot be passed to another thread, the other thread has
|
||||||
will have a different context stack and will not know about the request
|
a different context space and will not know about the request the parent
|
||||||
the parent thread was pointing to.
|
thread was pointing to.
|
||||||
|
|
||||||
Context locals are implemented in Werkzeug. See :doc:`werkzeug:local`
|
Context locals are implemented using Python's :mod:`contextvars` and
|
||||||
for more information on how this works internally.
|
Werkzeug's :class:`~werkzeug.local.LocalProxy`. Python manages the
|
||||||
|
lifetime of context vars automatically, and local proxy wraps that
|
||||||
|
low-level interface to make the data easier to work with.
|
||||||
|
|
||||||
|
|
||||||
Manually Push a Context
|
Manually Push a Context
|
||||||
|
|
@ -87,10 +89,9 @@ How the Context Works
|
||||||
|
|
||||||
The :meth:`Flask.wsgi_app` method is called to handle each request. It
|
The :meth:`Flask.wsgi_app` method is called to handle each request. It
|
||||||
manages the contexts during the request. Internally, the request and
|
manages the contexts during the request. Internally, the request and
|
||||||
application contexts work as stacks, :data:`_request_ctx_stack` and
|
application contexts work like stacks. When contexts are pushed, the
|
||||||
:data:`_app_ctx_stack`. When contexts are pushed onto the stack, the
|
|
||||||
proxies that depend on them are available and point at information from
|
proxies that depend on them are available and point at information from
|
||||||
the top context on the stack.
|
the top item.
|
||||||
|
|
||||||
When the request starts, a :class:`~ctx.RequestContext` is created and
|
When the request starts, a :class:`~ctx.RequestContext` is created and
|
||||||
pushed, which creates and pushes an :class:`~ctx.AppContext` first if
|
pushed, which creates and pushes an :class:`~ctx.AppContext` first if
|
||||||
|
|
@ -99,10 +100,10 @@ these contexts are pushed, the :data:`current_app`, :data:`g`,
|
||||||
:data:`request`, and :data:`session` proxies are available to the
|
:data:`request`, and :data:`session` proxies are available to the
|
||||||
original thread handling the request.
|
original thread handling the request.
|
||||||
|
|
||||||
Because the contexts are stacks, other contexts may be pushed to change
|
Other contexts may be pushed to change the proxies during a request.
|
||||||
the proxies during a request. While this is not a common pattern, it
|
While this is not a common pattern, it can be used in advanced
|
||||||
can be used in advanced applications to, for example, do internal
|
applications to, for example, do internal redirects or chain different
|
||||||
redirects or chain different applications together.
|
applications together.
|
||||||
|
|
||||||
After the request is dispatched and a response is generated and sent,
|
After the request is dispatched and a response is generated and sent,
|
||||||
the request context is popped, which then pops the application context.
|
the request context is popped, which then pops the application context.
|
||||||
|
|
|
||||||
|
|
@ -1284,29 +1284,30 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def teardown_appcontext(self, f: T_teardown) -> T_teardown:
|
def teardown_appcontext(self, f: T_teardown) -> T_teardown:
|
||||||
"""Registers a function to be called when the application context
|
"""Registers a function to be called when the application
|
||||||
ends. These functions are typically also called when the request
|
context is popped. The application context is typically popped
|
||||||
context is popped.
|
after the request context for each request, at the end of CLI
|
||||||
|
commands, or after a manually pushed context ends.
|
||||||
|
|
||||||
Example::
|
.. code-block:: python
|
||||||
|
|
||||||
ctx = app.app_context()
|
with app.app_context():
|
||||||
ctx.push()
|
...
|
||||||
...
|
|
||||||
ctx.pop()
|
|
||||||
|
|
||||||
When ``ctx.pop()`` is executed in the above example, the teardown
|
When the ``with`` block exits (or ``ctx.pop()`` is called), the
|
||||||
functions are called just before the app context moves from the
|
teardown functions are called just before the app context is
|
||||||
stack of active contexts. This becomes relevant if you are using
|
made inactive. Since a request context typically also manages an
|
||||||
such constructs in tests.
|
application context it would also be called when you pop a
|
||||||
|
request context.
|
||||||
|
|
||||||
Since a request context typically also manages an application
|
When a teardown function was called because of an unhandled
|
||||||
context it would also be called when you pop a request context.
|
exception it will be passed an error object. If an
|
||||||
|
:meth:`errorhandler` is registered, it will handle the exception
|
||||||
|
and the teardown will not receive it.
|
||||||
|
|
||||||
When a teardown function was called because of an unhandled exception
|
Teardown functions must avoid raising exceptions. If they
|
||||||
it will be passed an error object. If an :meth:`errorhandler` is
|
execute code that might fail they must surround that code with a
|
||||||
registered, it will handle the exception and the teardown will not
|
``try``/``except`` block and log any errors.
|
||||||
receive it.
|
|
||||||
|
|
||||||
The return values of teardown functions are ignored.
|
The return values of teardown functions are ignored.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,12 +227,10 @@ def has_app_context() -> bool:
|
||||||
|
|
||||||
|
|
||||||
class AppContext:
|
class AppContext:
|
||||||
"""The application context binds an application object implicitly
|
"""The app context contains application-specific information. An app
|
||||||
to the current thread or greenlet, similar to how the
|
context is created and pushed at the beginning of each request if
|
||||||
:class:`RequestContext` binds request information. The application
|
one is not already active. An app context is also pushed when
|
||||||
context is also implicitly created if a request context is created
|
running CLI commands.
|
||||||
but the application is not on top of the individual application
|
|
||||||
context.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app: "Flask") -> None:
|
def __init__(self, app: "Flask") -> None:
|
||||||
|
|
@ -278,10 +276,10 @@ class AppContext:
|
||||||
|
|
||||||
|
|
||||||
class RequestContext:
|
class RequestContext:
|
||||||
"""The request context contains all request relevant information. It is
|
"""The request context contains per-request information. The Flask
|
||||||
created at the beginning of the request and pushed to the
|
app creates and pushes it at the beginning of the request, then pops
|
||||||
`_request_ctx_stack` and removed at the end of it. It will create the
|
it at the end of the request. It will create the URL adapter and
|
||||||
URL adapter and request object for the WSGI environment provided.
|
request object for the WSGI environment provided.
|
||||||
|
|
||||||
Do not attempt to use this class directly, instead use
|
Do not attempt to use this class directly, instead use
|
||||||
:meth:`~flask.Flask.test_request_context` and
|
:meth:`~flask.Flask.test_request_context` and
|
||||||
|
|
|
||||||
|
|
@ -574,30 +574,27 @@ class Scaffold:
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def teardown_request(self, f: T_teardown) -> T_teardown:
|
def teardown_request(self, f: T_teardown) -> T_teardown:
|
||||||
"""Register a function to be run at the end of each request,
|
"""Register a function to be called when the request context is
|
||||||
regardless of whether there was an exception or not. These functions
|
popped. Typically this happens at the end of each request, but
|
||||||
are executed when the request context is popped, even if not an
|
contexts may be pushed manually as well during testing.
|
||||||
actual request was performed.
|
|
||||||
|
|
||||||
Example::
|
.. code-block:: python
|
||||||
|
|
||||||
ctx = app.test_request_context()
|
with app.test_request_context():
|
||||||
ctx.push()
|
...
|
||||||
...
|
|
||||||
ctx.pop()
|
|
||||||
|
|
||||||
When ``ctx.pop()`` is executed in the above example, the teardown
|
When the ``with`` block exits (or ``ctx.pop()`` is called), the
|
||||||
functions are called just before the request context moves from the
|
teardown functions are called just before the request context is
|
||||||
stack of active contexts. This becomes relevant if you are using
|
made inactive.
|
||||||
such constructs in tests.
|
|
||||||
|
|
||||||
Teardown functions must avoid raising exceptions. If
|
When a teardown function was called because of an unhandled
|
||||||
they execute code that might fail they
|
exception it will be passed an error object. If an
|
||||||
will have to surround the execution of that code with try/except
|
:meth:`errorhandler` is registered, it will handle the exception
|
||||||
statements and log any errors.
|
and the teardown will not receive it.
|
||||||
|
|
||||||
When a teardown function was called because of an exception it will
|
Teardown functions must avoid raising exceptions. If they
|
||||||
be passed an error object.
|
execute code that might fail they must surround that code with a
|
||||||
|
``try``/``except`` block and log any errors.
|
||||||
|
|
||||||
The return values of teardown functions are ignored.
|
The return values of teardown functions are ignored.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,10 @@ class EnvironBuilder(werkzeug.test.EnvironBuilder):
|
||||||
|
|
||||||
|
|
||||||
class FlaskClient(Client):
|
class FlaskClient(Client):
|
||||||
"""Works like a regular Werkzeug test client but has some knowledge about
|
"""Works like a regular Werkzeug test client but has knowledge about
|
||||||
how Flask works to defer the cleanup of the request context stack to the
|
Flask's contexts to defer the cleanup of the request context until
|
||||||
end of a ``with`` body when used in a ``with`` statement. For general
|
the end of a ``with`` block. For general information about how to
|
||||||
information about how to use this class refer to
|
use this class refer to :class:`werkzeug.test.Client`.
|
||||||
:class:`werkzeug.test.Client`.
|
|
||||||
|
|
||||||
.. versionchanged:: 0.12
|
.. versionchanged:: 0.12
|
||||||
`app.test_client()` includes preset default environment, which can be
|
`app.test_client()` includes preset default environment, which can be
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue