In Flask, there are two types of context:
- AppContext, it’s a Flask object
app = Flask(__name__)
- RequestContext, it’s a Request object
- Flask core object is stored in AppContext
- Request object is stored in RequestContext
Why is context needed?
It’s a type of system design. For certain objects, some info belongs to the external environment not the objects themselves.
But if we want to use this info with e.g. the core Flask object, we can put both Flask and external info into a new object,
called AppContext.
To clarify:
Flask: core object. It contains the core features in Flask e.g. routes, config
AppContext: an encapsulation of Flask with additional external parameters
Request: core object. It contains the request info, url parameters etc.
RequestContext: an encapsulation of Request, similar to AppContext
We need to access Flask and Request via AppContext and RequestContext, however in the code we rarely use AppContext or RequestContext explicitly.
Because LocalProxy has the ability to operate on context objects indirectly.
{% asset_img "localproxy.PNG" %}How is context operated?
- Start with a request
- Flask will first check the top of
_app_ctx_stack
, if it’s None or not the same as thecurrent_app
,
an AppContext will be pushed into_app_ctx_stack
; then push RequestContext to_request_ctx_stack
- Once the request is ended, RequestContext is popped
for example:
from flask import Flask, current_app
app = Flask(__name__)
ctx = app.app_context()
ctx.push()
a = current_app
d = current_app.config["DEBUG"]
ctx.pop()
- We can apply
with
to the context objects, aka objects with__enter__
and__exit__
methods
- The above can be re-written as below
from flask import Flask, current_app
app = Flask(__name__)
with app.app_context():
b = current_app
c = current_app.config["DEBUG"]
AppContext or RequestContext are essentially context managers
with app.app_context()
is the context expression, which need to return a context managerwith
is an efficient way to manage resources