Manually Managing Contexts
When you need to access Flask globals like current_app, g, request, or session outside of a standard request cycle—such as in a standalone script, a CLI command, or a unit test—you must manually manage an AppContext.
Using the Context Manager
The most reliable way to manage a context is using the with statement. This ensures that the context is automatically pushed when entering the block and popped when exiting, even if an exception occurs.
from flask import Flask, current_app
app = Flask(__name__)
with app.app_context():
# current_app and g are now available
print(current_app.name)
For scenarios requiring request-specific data like request.args or session, use test_request_context instead:
from flask import Flask, request
app = Flask(__name__)
with app.test_request_context("/?name=Flask"):
# request and session are now available
assert request.args["name"] == "Flask"
Manual Push and Pop
In some cases, such as complex test setups where the context lifecycle spans multiple function calls, you may need to call push() and pop() manually on the AppContext instance.
def test_manual_context_binding(app):
@app.route("/")
def index():
return f"Hello {flask.request.args['name']}!"
# Create the context object
ctx = app.test_request_context("/?name=World")
# Manually activate it
ctx.push()
try:
assert index() == "Hello World!"
finally:
# Always pop in a finally block to ensure teardown runs
ctx.pop()
Handling Teardown and Exceptions
When you manually call pop(), Flask executes all registered teardown functions (e.g., functions decorated with @app.teardown_appcontext or @app.teardown_request). If an unhandled exception occurred while the context was active, you should pass it to pop() so that teardown functions can handle it correctly.
ctx = app.app_context()
ctx.push()
try:
# Do work that might raise an exception
...
except Exception as e:
ctx.pop(e)
raise
else:
ctx.pop()
Managing Nested Contexts
Flask's AppContext uses a "push count" mechanism. If the same context object is pushed multiple times, it remains active until it has been popped an equal number of times. Teardown functions and signals like appcontext_popped only trigger when the push count reaches zero.
ctx = app.app_context()
ctx.push() # push_count = 1
ctx.push() # push_count = 2
ctx.pop() # push_count = 1, no teardown yet
ctx.pop() # push_count = 0, teardown functions run
Choosing the Right Context
Flask provides three methods on the Flask class to create an AppContext, depending on your needs:
app.app_context(): Creates a context with only application-level data (current_app,g). Accessingrequestorsessioninside this context will raise aRuntimeError.app.test_request_context(*args, **kwargs): Creates a context that includes request and session data. It accepts the same arguments as Werkzeug'sEnvironBuilderto simulate a specific request.app.request_context(environ): Creates a context from an existing WSGI environment. This is used internally by Flask and is rarely needed in application code.
[!IMPORTANT] As of Flask 3.2,
RequestContexthas been merged intoAppContext. While theRequestContextalias still exists for backward compatibility, you should useAppContextfor all manual context management.