Storing Data During a Context with g
When you need to store data that should be accessible across different functions during a single request or CLI command, Flask provides the g object. This object is a temporary namespace tied to the active application context, ensuring that data is isolated to the current unit of work and automatically cleared when the context ends.
Managing Database Connections
A common use for g is to manage resources like database connections, ensuring they are created only once per request and properly closed afterward. In examples/tutorial/flaskr/db.py, Flask uses g to cache a SQLite connection.
from flask import g, current_app
import sqlite3
def get_db():
if "db" not in g:
g.db = sqlite3.connect(
current_app.config["DATABASE"],
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
return g.db
@app.teardown_appcontext
def close_db(e=None):
db = g.pop("db", None)
if db is not None:
db.close()
In this pattern:
get_dbchecks ifdbis already ing.- If not, it creates the connection and stores it as
g.db. - The
close_dbfunction, registered with@app.teardown_appcontext, usesg.popto retrieve and remove the connection so it can be closed when the request finishes.
Caching Authenticated Users
You can use g to store the results of expensive operations, such as fetching a user from a database, so that subsequent view functions or decorators can access the data without re-querying. The Flask tutorial in examples/tutorial/flaskr/auth.py demonstrates this with a before_app_request hook.
@bp.before_app_request
def load_logged_in_user():
user_id = session.get("user_id")
if user_id is None:
g.user = None
else:
g.user = (
get_db().execute("SELECT * FROM user WHERE id = ?", (user_id,)).fetchone()
)
Once g.user is set, any view function processing the same request can access the user object directly via g.user.
Advanced Data Access Methods
The g object is an instance of _AppCtxGlobals (accessed via the _AppCtxGlobalsProxy). It supports dictionary-like methods for safer data handling, as shown in tests/test_appctx.py.
get(name, default=None): Retrieve an attribute without raising anAttributeErrorif it is missing.setdefault(name, default): Get the value of an attribute if it exists; otherwise, set it to the default and return it.pop(name, default): Retrieve and remove an attribute in one step.inoperator: Check if a key is present in the namespace.
from flask import g
# Check for existence
if "user" in g:
print(g.user)
# Use setdefault for lazy initialization
db = g.setdefault("db", create_new_connection())
# Use pop for cleanup
resource = g.pop("temporary_resource", None)
Customizing the g Object
If you need specific behavior or type hinting for the g object, you can override the class Flask uses to instantiate it. By default, Flask uses _AppCtxGlobals from flask.ctx. You can provide your own class by setting app_ctx_globals_class on your application instance.
from flask import Flask, ctx
class MyGlobals(ctx._AppCtxGlobals):
def custom_method(self):
return "Hello from g"
app = Flask(__name__)
app.app_ctx_globals_class = MyGlobals
Important Considerations
- Lifecycle: Data stored in
gis unique to the application context. It is created when the context is pushed and destroyed when the context is popped (usually at the end of a request). - Persistence:
gis not for storing data across multiple requests. For persistent data like user sessions, use thesessionobject instead. - Context Requirement: Accessing
goutside of an active application context will raise aRuntimeError. If you are working in a script or shell, ensure you wrap your code in awith app.app_context():block. - Thread Safety: In standard Flask usage, each request runs in its own thread or task with its own context, making
gsafe to use for request-local storage.