Skip to main content

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.load or tomllib.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.