Skip to main content

Getting Started with Configuration

The Config object in Flask is a specialized dictionary subclass that manages your application's settings. It provides several methods to load values from files, environment variables, and Python objects, while enforcing a strict "uppercase only" rule for keys loaded through these helper methods.

In this tutorial, you will build a configuration system for a Flask application that handles default values, external file overrides, and environment variables.

Prerequisites

To follow this tutorial, you need the flask package installed. You should also have a basic understanding of Python dictionaries.

Step 1: Initialize the Application and Set Defaults

First, create your Flask application instance. You will use from_mapping to define default values. This is useful for settings that should always exist but might be overridden later.

import os
from flask import Flask

def create_app():
# instance_relative_config=True allows loading config files
# relative to the instance folder
app = Flask(__name__, instance_relative_config=True)

# Set default configuration
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE=os.path.join(app.instance_path, "app.sqlite"),
DEBUG=True
)

return app

app = create_app()
print(f"Default Secret Key: {app.config['SECRET_KEY']}")

The from_mapping method works like a standard dictionary update but only accepts uppercase keys. If you passed secret_key="dev", it would be ignored by this method.

Step 2: Load Overrides from a Python File

In production or different environments, you often want to keep secrets and specific settings in a separate file. Use from_pyfile to load values from a .py file.

Create a file named config.py in your application's instance folder:

# instance/config.py
SECRET_KEY = "production-secret-key"
DEBUG = False

Now, update your application factory to load this file if it exists:

def create_app():
app = Flask(__name__, instance_relative_config=True)

# 1. Set defaults
app.config.from_mapping(SECRET_KEY="dev", DEBUG=True)

# 2. Override with values from instance/config.py
# silent=True prevents an error if the file doesn't exist
app.config.from_pyfile("config.py", silent=True)

return app

When from_pyfile runs, it executes the Python file and adds all top-level uppercase variables to the app.config dictionary.

Step 3: Load Configuration from Environment Variables

Modern applications often use environment variables for configuration, especially in containerized environments. The from_prefixed_env method automatically loads environment variables that start with a specific prefix (defaulting to FLASK_).

If you set the following environment variables in your terminal:

export FLASK_DATABASE_URI="postgresql://localhost/mydb"
export FLASK_POOL_SIZE=10

You can load them into your app like this:

app = create_app()

# Loads all variables starting with FLASK_
# FLASK_DATABASE_URI becomes app.config['DATABASE_URI']
app.config.from_prefixed_env()

print(app.config["DATABASE_URI"]) # Output: postgresql://localhost/mydb
print(app.config["POOL_SIZE"]) # Output: 10 (automatically parsed as int)

The from_prefixed_env method is powerful because it attempts to parse values as JSON. This means FLASK_POOL_SIZE=10 becomes an integer 10, and FLASK_DEBUG=true becomes a boolean True.

Step 4: Use Class-Based Configuration

For complex projects, you might want to organize configurations into classes. The from_object method allows you to import configuration from a class or module.

class ProductionConfig:
DATABASE_URI = "mysql://user@localhost/foo"
SECRET_KEY = "very-secret"

class DevelopmentConfig:
DEBUG = True
DATABASE_URI = "sqlite:///dev.db"

# Load from the class directly
app.config.from_object(DevelopmentConfig)

Like other methods, from_object only picks up attributes that are defined in all uppercase.

Complete Working Example

Combining these techniques allows for a flexible configuration hierarchy: defaults -> file overrides -> environment variables.

import os
from flask import Flask

def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)

# 1. Hardcoded defaults
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE="sqlite:///default.db",
)

if test_config is None:
# 2. Load from instance/config.py if it exists
app.config.from_pyfile("config.py", silent=True)
else:
# 3. Load test-specific config if passed
app.config.from_mapping(test_config)

# 4. Final overrides from environment variables (FLASK_*)
app.config.from_prefixed_env()

return app

if __name__ == "__main__":
app = create_app()
print(f"Final Database: {app.config['DATABASE']}")

Next Steps

  • Explore Instance Folders to learn where from_pyfile looks for files by default.
  • Use app.config.get_namespace() to extract a subset of settings (e.g., all keys starting with DATABASE_) into a separate dictionary for third-party libraries.