Configuration and SECRET_KEY
Introduction
Flask stores settings in app.config—a dict-like object for debug flags, database URLs, and secrets. This chapter uses config classes, .env files with python-dotenv, the instance/ folder, and explains why SECRET_KEY must be random and private in production.
Prerequisites
- Your First Flask Application
python-dotenvinstalled
app.config Basics
from flask import Flask
app = Flask(__name__)
app.config["DEBUG"] = True
app.config["SECRET_KEY"] = "dev-only-change-me"
app.config["ITEMS_PER_PAGE"] = 20Access in views:
@app.route("/")
def index():
limit = app.config["ITEMS_PER_PAGE"]
return f"Showing {limit} items"Common keys:
| Key | Purpose |
|---|---|
DEBUG | Dev traceback and reload |
SECRET_KEY | Signs sessions and CSRF tokens |
TESTING | Test mode behavior |
SQLALCHEMY_DATABASE_URI | DB URL (Flask-SQLAlchemy, later) |
Config Classes
Apply when creating app:
from flask import Flask
def create_app(config_name="development"):
app = Flask(__name__)
config_map = {
"development": DevelopmentConfig,
"production": ProductionConfig,
"testing": TestingConfig,
}
app.config.from_object(config_map[config_name])
return appCode explanation:
from_objectloads uppercase attributes from the class ontoapp.config
Load From .env
Create .env (gitignored):
FLASK_DEBUG=1
SECRET_KEY=your-long-random-string-here
DATABASE_URL=mysql+pymysql://user:pass@localhost/mydbLoad in app.py or factory:
import os
from dotenv import load_dotenv
from flask import Flask
load_dotenv()
app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ["SECRET_KEY"]
app.config["DEBUG"] = os.getenv("FLASK_DEBUG", "0") == "1"Code explanation:
load_dotenv()reads.envintoos.environbefore you read variables
Warning
Do Not Commit .env
Use .env.example with placeholder keys for teammates:
SECRET_KEY=replace-me
DATABASE_URL=mysql+pymysql://user:pass@localhost/dbnameinstance/ Folder
Flask supports instance/ for local-only config files:
app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile("config.py", silent=True)Place instance/config.py (gitignored):
SECRET_KEY = "machine-specific-secret"Code explanation:
instance_relative_config=Truekeeps secrets outside the importable package
SECRET_KEY in Production
Generate a strong key:
python -c "import secrets; print(secrets.token_hex(32))"Set on server environment—never hardcode in source:
export SECRET_KEY="paste-generated-value"If SECRET_KEY leaks, attackers can forge session cookies.
Environment-Based Factory
FAQ
SECRET_KEY missing error?
Flask extensions (sessions, WTF) require it—set in config or env.
DEBUG=True in production?
Never—exposes stack traces and enables debugger risks.
.env not loading?
Call load_dotenv() before reading os.environ; check file path.
Config vs environment variables?
Twelve-factor style: store secrets in env; use config classes for defaults.
Multiple .env files?
.env.production with load_dotenv(".env.production")—load one per deploy target.
SQLAlchemy URI format?
mysql+pymysql://user:password@host:3306/dbname—see MySQL configuration and clients.