Context Functions
Flask provides several functions to work with application and request contexts.
has_request_context()
Test if an app context is active and if it has request information.
has_request_context() -> bool
Returns True if a request context is active, otherwise False.
Example
from flask import has_request_context, request
if has_request_context():
remote_addr = request.remote_addr
has_app_context()
Test if an app context is active.
has_app_context() -> bool
Returns True if an app context is active, otherwise False. Unlike has_request_context(), this can be true outside a request, such as in a CLI command.
Example
from flask import has_app_context, g
if has_app_context():
g.cached_data = load_data()
after_this_request()
Decorate a function to run after the current request.
@after_this_request
def callback(response: Response) -> Response:
return response
The response object that will be sent to the client.
The behavior is the same as @app.after_request, except it only applies to the current request, rather than every request. Must be used within a request context.
Returns the modified response object.
Example
from flask import after_this_request
@app.route('/')
def index():
@after_this_request
def add_header(response):
response.headers['X-Foo'] = 'Parachute'
return response
return 'Hello, World!'
copy_current_request_context()
Decorate a function to run inside the current request context.
@copy_current_request_context
def callback(*args, **kwargs):
# Can access flask.request, flask.session, etc.
pass
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.
Due to caveats with context copying, it is often safer to pass the data you need when starting the task, rather than using this and relying on the context objects.
Caveats
- In order to avoid execution switching partially through reading data, either read the request body (access
form, json, data, etc.) before starting the task, or use a lock.
- 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.
Example
import gevent
from flask import copy_current_request_context
@app.route('/')
def index():
@copy_current_request_context
def do_some_work():
# Can access flask.request or flask.session
user = session.get('user')
# Do work...
gevent.spawn(do_some_work)
return 'Regular response'
AppContext
An app context contains information about an app, and about the request when handling a request. A context is pushed at the beginning of each request and CLI command, and popped at the end.
Do not use this class directly. Use Flask.app_context() to create an app context if needed during setup, and Flask.test_request_context() to create a request context if needed during tests.
Constructor
AppContext(
app: Flask,
*,
request: Request | None = None,
session: SessionMixin | None = None
)
The application this context represents.
request
Request | None
default:"None"
The request data this context represents.
session
SessionMixin | None
default:"None"
The session data this context represents. If not given, loaded from the request on first access.
Properties
app
The application represented by this context. Accessed through current_app.
The global data for this context. Accessed through the g proxy.
request
The request object associated with this context. Accessed through the request proxy. Only available in request contexts.
Raises RuntimeError if there is no request in this context.
session
The session object associated with this context. Accessed through the session proxy. Only available in request contexts.
ctx.session -> SessionMixin
Raises RuntimeError if there is no request in this context.
has_request
True if this context was created with request data.
Methods
push()
Push this context so that it is the active context.
Typically, this is not used directly. Instead, use a with block to manage the context.
pop()
Pop this context so that it is no longer the active context. Then call teardown functions and signals.
ctx.pop(exc: BaseException | None = None) -> None
exc
BaseException | None
default:"None"
An unhandled exception that was raised while the context was active. Passed to teardown functions.
Typically, this is not used directly. Instead, use a with block to manage the context.
copy()
Create a new context with the same data objects as this context.
Returns a new AppContext instance.
Usage with Context Manager
with app.app_context():
# Code here has access to current_app and g
db.create_all()
with app.test_request_context('/', method='POST'):
# Code here has access to request, session, and g
assert request.method == 'POST'
Context Locals
Flask uses context-local objects to make certain objects globally accessible in a way that’s safe for concurrent requests.
A namespace object that can store data during an application context. This is a good place to store things like database connections or the current user object.
from flask import g
@app.before_request
def load_user():
g.user = get_current_user()
@app.route('/')
def index():
return f'Hello, {g.user.name}!'
request
The current request object. Contains all the information about the incoming HTTP request.
from flask import request
@app.route('/search')
def search():
query = request.args.get('q')
return f'Searching for: {query}'
session
The current session object. A dictionary-like object that persists across requests using cookies.
from flask import session
@app.route('/login', methods=['POST'])
def login():
session['user_id'] = user.id
return redirect(url_for('index'))
@app.route('/logout')
def logout():
session.pop('user_id', None)
return redirect(url_for('index'))
current_app
The current Flask application instance. Useful when you need to access the app from places where you don’t have direct access to the app object.
from flask import current_app
@app.route('/config')
def show_config():
debug_mode = current_app.config['DEBUG']
return f'Debug mode: {debug_mode}'
Complete Example
from flask import Flask, g, request, session, has_request_context, after_this_request
import sqlite3
app = Flask(__name__)
app.secret_key = 'secret'
def get_db():
if 'db' not in g:
g.db = sqlite3.connect('database.db')
return g.db
@app.teardown_appcontext
def close_db(exception):
db = g.pop('db', None)
if db is not None:
db.close()
@app.before_request
def log_request():
if has_request_context():
app.logger.info(f'{request.method} {request.path}')
@app.route('/')
def index():
@after_this_request
def add_custom_header(response):
response.headers['X-Request-ID'] = request.environ.get('REQUEST_ID')
return response
visits = session.get('visits', 0)
session['visits'] = visits + 1
return f'You have visited this page {visits + 1} times'
if __name__ == '__main__':
app.run(debug=True)
CLI Context
When running Flask CLI commands, an app context is automatically created:
import click
from flask import current_app
@app.cli.command()
def init_db():
"""Initialize the database."""
with current_app.app_context():
db.create_all()
click.echo('Initialized the database.')