Application Configuration
The configuration system in this codebase is centered around the Config class, which extends the standard Python dict to provide specialized loading mechanisms. It is designed to handle everything from hardcoded defaults to environment-specific overrides and external configuration files.
The Config Object
The Config class (found in src/flask/config.py) is the primary container for application settings. While it behaves like a dictionary, it enforces a convention where only uppercase keys are processed when loading from external sources. This allows developers to use lowercase variables for temporary logic within configuration files without them being accidentally added to the application state.
When a Flask application is initialized, it creates an instance of this class and assigns it to app.config.
Loading Configuration Defaults
The most common pattern for setting initial values is using from_mapping. This is typically done during application factory setup to ensure required keys exist.
from flask import Flask
import os
def create_app():
app = Flask(__name__, instance_relative_config=True)
# Setting defaults via mapping
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE=os.path.join(app.instance_path, "flaskr.sqlite"),
)
return app
Loading from External Sources
This codebase provides several methods to populate the Config object from external files and objects.
Object-based Configuration
The from_object method allows loading configuration from a Python module or class. It iterates through the object's attributes and adds those with uppercase names to the config.
class DefaultConfig:
DEBUG = True
SECRET_KEY = 'development-key'
app.config.from_object(DefaultConfig)
# Or via import string
app.config.from_object('yourapplication.default_config')
File-based Configuration
For external files, from_pyfile and from_file are used:
from_pyfile(filename): Executes a Python file and loads its uppercase variables. This is ideal for complex configuration that requires logic.from_file(filename, load): Loads data using a custom loader (e.g.,json.loadortomllib.load).
import json
# Load from a JSON file
app.config.from_file("config.json", load=json.load)
# Load from a Python config file, often in the instance folder
app.config.from_pyfile("config.py", silent=True)
Environment Variable Integration
Managing configuration via environment variables is a core feature, supporting both direct file pointers and prefixed variable loading.
Prefixed Environment Variables
The from_prefixed_env method is a modern way to load variables starting with a specific prefix (defaulting to FLASK_). It supports automatic JSON-style type conversion and nested dictionaries using double underscores (__).
# If environment has:
# FLASK_DATABASE__HOST=localhost
# FLASK_DEBUG=true
app.config.from_prefixed_env()
# Resulting config:
# app.config['DATABASE'] == {'HOST': 'localhost'}
# app.config['DEBUG'] == True
Environment File Pointers
The from_envvar method looks for an environment variable that contains a path to a configuration file, then loads that file using from_pyfile.
# export YOURAPP_SETTINGS='/path/to/real_config.py'
app.config.from_envvar('YOURAPP_SETTINGS')
Attribute-based Access with ConfigAttribute
The ConfigAttribute class in src/flask/config.py is a descriptor that maps class attributes directly to keys in the config dictionary. This is how the application object exposes common settings like testing or secret_key as direct attributes.
In src/flask/sansio/app.py, you can see this pattern in action:
class App(Scaffold):
testing = ConfigAttribute[bool]("TESTING")
secret_key = ConfigAttribute[str | bytes | None]("SECRET_KEY")
permanent_session_lifetime = ConfigAttribute[timedelta](
"PERMANENT_SESSION_LIFETIME",
get_converter=_make_timedelta,
)
When you access app.testing, the descriptor retrieves app.config["TESTING"]. It also supports a get_converter to transform the raw config value (e.g., converting an integer to a timedelta).
Modular Configuration with Namespaces
When an application uses multiple extensions or components, configuration keys often share a prefix. The get_namespace method extracts these into a separate dictionary, optionally stripping the prefix and lowercasing the keys.
app.config['IMAGE_STORE_TYPE'] = 'fs'
app.config['IMAGE_STORE_PATH'] = '/var/app/images'
# Extracting the namespace
image_store_config = app.config.get_namespace('IMAGE_STORE_')
# Result: {'type': 'fs', 'path': '/var/app/images'}
This is particularly useful for passing a subset of configuration directly into a component's constructor or a third-party library.