Configuring via Environment Variables
To configure your Flask application using environment variables, use the Config.from_prefixed_env method. This allows you to inject configuration values directly from the environment, supporting automatic type conversion and nested dictionary structures.
from flask import Flask
app = Flask(__name__)
# Load environment variables starting with FLASK_
# e.g., FLASK_DEBUG=true -> app.config["DEBUG"] = True
app.config.from_prefixed_env()
Loading Values with Automatic Type Conversion
The from_prefixed_env method uses json.loads by default to attempt to convert environment variable strings into Python types. If the value is not valid JSON, it remains a string.
As demonstrated in tests/test_config.py, the following environment variables are converted automatically:
# Environment Variables:
# FLASK_STRING="value" -> app.config["STRING"] == "value"
# FLASK_BOOL=true -> app.config["BOOL"] is True
# FLASK_INT=1 -> app.config["INT"] == 1
# FLASK_FLOAT=1.2 -> app.config["FLOAT"] == 1.2
# FLASK_LIST=[1, 2] -> app.config["LIST"] == [1, 2]
# FLASK_DICT={"k": "v"} -> app.config["DICT"] == {"k": "v"}
app.config.from_prefixed_env()
Configuring Nested Dictionaries
You can set values in nested dictionaries by separating keys with double underscores (__). If an intermediate key does not exist, Config will initialize it as an empty dictionary.
This pattern is useful for overriding specific keys in complex configurations, such as those used in the Celery example in examples/celery/src/task_app/__init__.py:
app.config.from_mapping(
CELERY=dict(
broker_url="redis://localhost",
result_backend="redis://localhost",
task_ignore_result=True,
),
)
# To override the broker_url via environment:
# export FLASK_CELERY__broker_url="redis://production-redis:6379/0"
app.config.from_prefixed_env()
In tests/test_config.py, this behavior is verified for deeply nested structures:
# Environment: FLASK_EXIST__inner__ik="2"
# If app.config["EXIST"] = {"inner": {"ik": 1}}
app.config.from_prefixed_env()
# Result: app.config["EXIST"]["inner"]["ik"] == 2
Using Custom Prefixes
While FLASK_ is the default, you can specify a custom prefix to isolate application-specific settings.
# Environment: MYAPP_DATABASE_URI="sqlite:///test.db"
app.config.from_prefixed_env(prefix="MYAPP")
# Result: app.config["DATABASE_URI"] == "sqlite:///test.db"
Loading Configuration Files via Environment Variables
If you prefer to keep configuration in a separate Python file but want to specify the file path dynamically, use from_envvar. This is a shortcut for from_pyfile that reads the path from an environment variable.
# Environment: export SETTINGS_PATH='/path/to/config.cfg'
app.config.from_envvar('SETTINGS_PATH')
The implementation in src/flask/config.py ensures that if the variable is missing, a RuntimeError is raised unless silent=True is passed:
def from_envvar(self, variable_name: str, silent: bool = False) -> bool:
rv = os.environ.get(variable_name)
if not rv:
if silent:
return False
raise RuntimeError(f"The environment variable {variable_name!r} is not set...")
return self.from_pyfile(rv, silent=silent)
Troubleshooting and Gotchas
JSON Parsing Fallbacks
The from_prefixed_env method attempts to parse every value with json.loads. If the value is a simple string that isn't valid JSON (like a database URI without quotes), the try...except block in src/flask/config.py catches the error and treats the value as a raw string:
try:
value = loads(value)
except Exception:
# Keep the value as a string if loading failed.
pass
Windows Case-Insensitivity
On Windows, environment variable keys are always stored as uppercase. If your application relies on lowercase keys in a nested dictionary (e.g., app.config["database"]["host"]), using from_prefixed_env on Windows will result in uppercase keys (e.g., app.config["DATABASE"]["HOST"]), which may cause mismatches if the rest of your code expects lowercase.
Deterministic Loading Order
Environment variables are loaded in sorted() order. This ensures that if multiple variables affect the same nested dictionary, the outcome is consistent across different environments.