Skip to main content

Core Application & Configuration

The central component of this codebase is the Flask class, which serves as the primary interface for defining application behavior, managing configuration, and handling the request/response lifecycle.

The Flask Application Object​

The Flask class (found in src/flask/app.py) inherits from App and Scaffold. It acts as a central registry for view functions, URL rules, and template configuration. When initializing a Flask instance, the import_name is the most critical parameter as it determines how the application locates resources like templates and static files.

Application Factory Pattern​

The recommended way to initialize the application is through the Application Factory pattern. This involves defining a function that creates and configures the Flask instance. This pattern is exemplified in the tutorial's create_app function:

# examples/tutorial/flaskr/__init__.py

def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE=os.path.join(app.instance_path, "flaskr.sqlite"),
)

if test_config is None:
# load the instance config, if it exists, when not testing
app.config.from_pyfile("config.py", silent=True)
else:
# load the test config if passed in
app.config.update(test_config)

# ... setup blueprints and routes ...
return app

Configuration Management​

Configuration is managed by the Config class (defined in src/flask/config.py), which is a specialized dictionary. A strict rule in this system is that only uppercase keys are recognized as configuration variables.

Loading Configuration​

The Config object provides several methods for populating settings from different sources:

  • from_mapping: Loads values from a dictionary or keyword arguments.
  • from_pyfile: Executes a Python file and loads its uppercase variables.
  • from_object: Loads uppercase attributes from a module or class.
  • from_prefixed_env: Automatically loads environment variables starting with a specific prefix (defaulting to FLASK_).

Example of loading from environment variables:

# tests/test_config.py

def test_from_prefixed_env(monkeypatch):
monkeypatch.setenv("FLASK_STRING", "value")
monkeypatch.setenv("FLASK_INT", "1")

app = flask.Flask(__name__)
app.config.from_prefixed_env()

assert app.config["STRING"] == "value"
assert app.config["INT"] == 1

Application Context and State​

The AppContext class (in src/flask/ctx.py) manages the state of the application during a request or a CLI command.

Context Merger (Flask 3.2+)​

In version 3.2, RequestContext was merged into AppContext. This means a single context object now tracks both application-level state and request-specific data (if available). The AppContext tracks:

  • The current application instance (self.app).
  • The request object (self._request), accessible via the request proxy.
  • The session object (self._session), accessible via the session proxy.
  • The g object (self.g), a namespace for temporary data.

The g Object​

The _AppCtxGlobals class (aliased as g) provides a thread-safe namespace for storing data during a context's lifetime. It is reset every time a context is popped.

# src/flask/ctx.py

class _AppCtxGlobals:
def __getattr__(self, name: str) -> t.Any:
try:
return self.__dict__[name]
except KeyError:
raise AttributeError(name) from None

def __setattr__(self, name: str, value: t.Any) -> None:
self.__dict__[name] = value

Lifecycle and Setup Restrictions​

The application lifecycle is divided into a setup phase and a handling phase. To ensure consistency, certain methods are decorated with @setupmethod (defined in src/flask/sansio/scaffold.py).

Methods like register_blueprint, add_url_rule, and before_request cannot be called once the application has started handling its first request. Attempting to do so will trigger a RuntimeError via the _check_setup_finished check.

Teardown Functions​

Resources can be cleaned up using teardown functions. teardown_request functions run after every request, while teardown_appcontext functions run when the AppContext is popped, regardless of whether a request was handled. These are registered using the respective decorators on the Flask or Blueprint objects.