Skip to main content

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:

  1. get_db checks if db is already in g.
  2. If not, it creates the connection and stores it as g.db.
  3. The close_db function, registered with @app.teardown_appcontext, uses g.pop to 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 an AttributeError if 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.
  • in operator: 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 g is 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: g is not for storing data across multiple requests. For persistent data like user sessions, use the session object instead.
  • Context Requirement: Accessing g outside of an active application context will raise a RuntimeError. If you are working in a script or shell, ensure you wrap your code in a with app.app_context(): block.
  • Thread Safety: In standard Flask usage, each request runs in its own thread or task with its own context, making g safe to use for request-local storage.