New in version 0.9.
One of the design ideas behind Flask is that there are two different “states” in which code is executed. The application setup state in which the application implicitly is on the module level. It starts when the
Flask object is instantiated, and it implicitly ends when the first request comes in. While the application is in this state a few assumptions are true:
In contrast, during request handling, a couple of other rules exist:
flask.requestand others) point to the current request.
There is a third state which is sitting in between a little bit. Sometimes you are dealing with an application in a way that is similar to how you interact with applications during request handling; just that there is no request active. Consider, for instance, that you’re sitting in an interactive Python shell and interacting with the application, or a command line application.
The application context is what powers the
current_app context local.
The main reason for the application’s context existence is that in the past a bunch of functionality was attached to the request context for lack of a better solution. Since one of the pillars of Flask’s design is that you can have more than one application in the same Python process.
So how does the code find the “right” application? In the past we recommended passing applications around explicitly, but that caused issues with libraries that were not designed with that in mind.
A common workaround for that problem was to use the
current_app proxy later on, which was bound to the current request’s application reference. Since creating such a request context is an unnecessarily expensive operation in case there is no request around, the application context was introduced.
There are two ways to make an application context. The first one is implicit: whenever a request context is pushed, an application context will be created alongside if this is necessary. As a result, you can ignore the existence of the application context unless you need it.
The second way is the explicit way using the
from flask import Flask, current_app app = Flask(__name__) with app.app_context(): # within this block, current_app points to app. print current_app.name
The application context is also used by the
url_for() function in case a
SERVER_NAME was configured. This allows you to generate URLs even in the absence of a request.
If no request context has been pushed and an application context has not been explicitly set, a
RuntimeError will be raised.
RuntimeError: Working outside of application context.
The application context is created and destroyed as necessary. It never moves between threads and it will not be shared between requests. As such it is the perfect place to store database connection information and other things. The internal stack object is called
flask._app_ctx_stack. Extensions are free to store additional information on the topmost level, assuming they pick a sufficiently unique name and should put their information there, instead of on the
flask.g object which is reserved for user code.
For more information about that, see Flask Extension Development.
The context is typically used to cache resources that need to be created on a per-request or usage case. For instance, database connections are destined to go there. When storing things on the application context unique names should be chosen as this is a place that is shared between Flask applications and extensions.
The most common usage is to split resource management into two parts:
Generally there would be a
get_X() function that creates resource
X if it does not exist yet and otherwise returns the same resource, and a
teardown_X() function that is registered as teardown handler.
This is an example that connects to a database:
import sqlite3 from flask import g def get_db(): db = getattr(g, '_database', None) if db is None: db = g._database = connect_to_database() return db @app.teardown_appcontext def teardown_db(exception): db = getattr(g, '_database', None) if db is not None: db.close()
The first time
get_db() is called the connection will be established. To make this implicit a
LocalProxy can be used:
from werkzeug.local import LocalProxy db = LocalProxy(get_db)
That way a user can directly access
db which internally calls
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.