Flask Config Management
Configuration management controls how your Flask app behaves in different environments — development, testing, and production. Flask provides multiple ways to load configuration values so you can change database URLs, debug settings, and secret keys without modifying code.
Why Configuration Management Matters
Development: DEBUG=True, SQLite database, verbose logs Testing: In-memory database, TESTING=True, no emails sent Production: DEBUG=False, PostgreSQL, real secrets from environment
Hardcoding these values in your source code causes two problems: you must change the file every time you switch environments, and sensitive values like passwords end up in version control where anyone can read them.
Method 1: Direct Config Assignment
app = Flask(__name__)
app.config['SECRET_KEY'] = 'my-secret'
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dev.db'Simple but not scalable. Suitable only for very small scripts.
Method 2: Config from a Python Object
class Config:
SECRET_KEY = 'change-this-in-production'
DEBUG = False
TESTING = False
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = 'postgresql://user:pass@host/db'
app.config.from_object(DevelopmentConfig)Method 3: Environment Variables
Sensitive values like database passwords and secret keys must not be in source code. Store them in environment variables and read them at runtime:
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'fallback-dev-key'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///dev.db'
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')The .env File
During development, set environment variables in a .env file in your project root:
SECRET_KEY=my-super-secret-key-32-chars-long
DATABASE_URL=postgresql://alice:password@localhost/myapp
MAIL_PASSWORD=my-email-password
FLASK_ENV=developmentLoad the .env file automatically using python-dotenv:
pip install python-dotenv# At the top of run.py or app.py
from dotenv import load_dotenv
load_dotenv() # reads .env file into environment variablesAdd .env to your .gitignore immediately — never commit it to version control.
Method 4: Config from a File
app.config.from_pyfile('instance/config.py', silent=True)Flask reads key-value pairs from a Python file. silent=True ignores missing files instead of raising an error. This is ideal for machine-specific overrides in the instance/ folder.
Built-In Flask Config Variables
| Variable | Default | Purpose |
|---|---|---|
SECRET_KEY | None | Signs sessions and cookies |
DEBUG | False | Enables debugger and reloader |
TESTING | False | Enables testing mode |
MAX_CONTENT_LENGTH | None | Max request body size in bytes |
SERVER_NAME | None | Hostname for URL generation |
Accessing Config in Your App
Read config values inside view functions and anywhere the app context is active:
from flask import current_app
@app.route('/debug-info')
def debug_info():
debug_mode = current_app.config['DEBUG']
return f'Debug mode is: {debug_mode}'Complete Config Setup Pattern
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev')
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///dev.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
MAIL_SERVER = os.environ.get('MAIL_SERVER', 'smtp.gmail.com')
MAIL_PORT = int(os.environ.get('MAIL_PORT', 587))
class ProductionConfig(Config):
DEBUG = False
TESTING = False
class DevelopmentConfig(Config):
DEBUG = TrueSummary
Never hardcode secrets in your source code. Load environment-specific values from environment variables using os.environ.get(). Use a .env file locally with python-dotenv. Use config classes to organize settings per environment. In production, set environment variables on the server or in a secrets manager. Add .env to .gitignore and commit only the config class structure, never the actual secrets.
