Configuring Application State
To manage application settings in this project, you use the config attribute of the App class. This object is a specialized dictionary that allows you to load configuration from Python objects, files, and environment variables.
Initializing Configuration in an Application Factory
The recommended way to configure your application is within an application factory. This allows you to set defaults and then override them with instance-specific files or environment variables.
import os
from flask import Flask
def create_app(test_config=None):
# instance_relative_config=True makes paths relative to the instance folder
app = Flask(__name__, instance_relative_config=True)
# 1. Set default configuration
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE=os.path.join(app.instance_path, "flaskr.sqlite"),
)
if test_config is None:
# 2. Load the instance config, if it exists, when not testing
# This file is looked up in the instance folder
app.config.from_pyfile("config.py", silent=True)
else:
# 3. Load the test config if passed in
app.config.from_mapping(test_config)
return app
Loading from Environment Variables
You can load configuration directly from environment variables using from_prefixed_env. By default, it looks for variables starting with FLASK_.
# If environment has:
# FLASK_SECRET_KEY="production-key"
# FLASK_DATABASE__HOST="localhost"
app.config.from_prefixed_env()
# Resulting config:
# app.config["SECRET_KEY"] == "production-key"
# app.config["DATABASE"] == {"HOST": "localhost"}
Key features of from_prefixed_env:
- Prefix: Defaults to
FLASK_. You can change this viaapp.config.from_prefixed_env(prefix="MYAPP"). - Type Conversion: It uses
json.loadsby default. Values liketrue,1, or{"a": 1}are converted to their Python equivalents. - Nested Keys: Use double underscores (
__) to create nested dictionaries in the configuration.
Loading from Files (JSON/TOML)
The from_file method allows you to load configuration from various formats by providing a loader function.
import json
import tomllib
# Load from a JSON file
app.config.from_file("config.json", load=json.load)
# Load from a TOML file (requires binary mode)
app.config.from_file("config.toml", load=tomllib.load, text=False)
Using Class-Based Configuration
For complex applications, you might want to organize settings into classes. Use from_object to load uppercase attributes from a class or module.
class Config:
DEBUG = False
TESTING = False
DATABASE_URI = "sqlite:///:memory:"
class ProductionConfig(Config):
DATABASE_URI = "mysql://user@localhost/foo"
app.config.from_object(ProductionConfig)
Accessing Configuration
You can access configuration values using standard dictionary syntax or through convenience attributes on the App instance.
# Dictionary access
db_uri = app.config["DATABASE_URI"]
# Proxy attributes (ConfigAttribute)
# These map directly to app.config["DEBUG"], app.config["SECRET_KEY"], etc.
app.debug = True
app.secret_key = "super-secret"
print(app.testing)
The App class provides several ConfigAttribute proxies:
debug: Maps toDEBUG.testing: Maps toTESTING.secret_key: Maps toSECRET_KEY.permanent_session_lifetime: Maps toPERMANENT_SESSION_LIFETIME.
Troubleshooting Configuration
Uppercase Requirement
The Config class only loads keys that are fully uppercase. Lowercase attributes in a Python file or keys in a mapping are ignored.
# This will be loaded
app.config.from_mapping(DEBUG=True)
# This will be ignored
app.config.from_mapping(debug=True)
Path Resolution
If instance_relative_config=True is set in the App constructor, relative paths passed to from_pyfile or from_file are resolved relative to the application's instance folder. Otherwise, they are relative to the application's root path.
Late Debug Setting
Setting app.debug after the application has started handling requests may not behave as expected, as some extensions and internal components (like the Jinja environment) check this value during initialization. Always perform configuration before calling app.run() or handling the first request.