Configuration and Sessions
Managing application settings and persistent user state is handled through the Config and Session systems. The Config object allows you to load settings from various sources, while the Session system provides a way to store data across multiple requests using signed cookies.
Configuring the Application
The Flask.config object is a dictionary subclass that provides methods for loading configuration from files, objects, and environment variables.
Loading Configuration Defaults
Use from_mapping to set default values during application initialization. This is commonly used in application factories.
import os
from flask import Flask
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
# Set default configuration
app.config.from_mapping(
SECRET_KEY="dev",
DATABASE=os.path.join(app.instance_path, "flaskr.sqlite"),
)
if test_config is None:
# Load the instance config, if it exists, when not testing
app.config.from_pyfile("config.py", silent=True)
else:
# Load the test config if passed in
app.config.update(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:
# export FLASK_SECRET_KEY="production-key"
# export FLASK_DATABASE_URL="sqlite:///prod.db"
app = Flask(__name__)
app.config.from_prefixed_env()
# app.config["SECRET_KEY"] is now "production-key"
# app.config["DATABASE_URL"] is now "sqlite:///prod.db"
The from_prefixed_env method automatically attempts to parse values as JSON, allowing you to pass booleans, integers, or even dictionaries.
# export FLASK_DEBUG=true
# export FLASK_PORT=5000
# export FLASK_SETTINGS__THEME="dark"
app.config.from_prefixed_env()
# app.config["DEBUG"] is True (bool)
# app.config["PORT"] is 5000 (int)
# app.config["SETTINGS"] is {"THEME": "dark"} (dict)
The Uppercase Rule
When using from_object, from_pyfile, or from_mapping, only keys that are fully uppercase are added to the configuration. This allows you to use lowercase variables for internal logic within configuration files without polluting the application config.
# config.py
DEBUG = True
secret_key = "this will be ignored"
Managing User Sessions
Sessions allow you to store information specific to a user across requests. Flask's default implementation, SecureCookieSessionInterface, uses itsdangerous to sign cookies cryptographically.
Setting Up Sessions
To use sessions, you must set a SECRET_KEY. If this is missing, Flask will raise a RuntimeError when you attempt to modify the session.
app = Flask(__name__)
app.config["SECRET_KEY"] = "a-very-secret-string"
Using the Session Proxy
The session object behaves like a dictionary. You can store and retrieve data within your view functions.
from flask import Blueprint, session, redirect, url_for, request
bp = Blueprint("auth", __name__)
@bp.route("/login", methods=("POST",))
def login():
# ... validate user ...
if user_is_valid:
session.clear()
session["user_id"] = user["id"]
return redirect(url_for("index"))
@bp.route("/logout")
def logout():
session.clear()
return redirect(url_for("index"))
Permanent Sessions
By default, sessions last until the browser is closed. To make a session persist across browser restarts, set session.permanent = True. The lifetime is controlled by the PERMANENT_SESSION_LIFETIME configuration (default is 31 days).
from datetime import timedelta
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(days=7)
@app.route("/login", methods=("POST",))
def login():
session.permanent = True
session["user_id"] = user_id
return redirect(url_for("index"))
Advanced Session Configuration
The behavior of the session cookie can be customized using several configuration keys:
| Key | Default | Description |
|---|---|---|
SESSION_COOKIE_NAME | 'session' | The name of the cookie. |
SESSION_COOKIE_HTTPONLY | True | Prevents JavaScript from accessing the cookie. |
SESSION_COOKIE_SECURE | False | Only sends the cookie over HTTPS. |
SESSION_COOKIE_SAMESITE | 'Lax' | Controls CSRF protection for the cookie. |
To implement a custom session backend, you can create a subclass of SessionInterface and assign it to app.session_interface.
from flask.sessions import SessionInterface
class MySessionInterface(SessionInterface):
def open_session(self, app, request):
# Custom logic to load session
pass
def save_session(self, app, session, response):
# Custom logic to save session
pass
app = Flask(__name__)
app.session_interface = MySessionInterface()
Troubleshooting
Session Not Saving
If you modify a mutable object (like a list or dictionary) stored inside the session, Flask might not detect the change. You must manually set session.modified = True.
@app.route("/add-item")
def add_item():
if "cart" not in session:
session["cart"] = []
session["cart"].append("new-item")
# Explicitly mark as modified because we changed a nested list
session.modified = True
return "Item added"
Missing Secret Key
If you see RuntimeError: The session is unavailable because no secret key was set, ensure that app.config["SECRET_KEY"] is populated before the first request that uses the session. In production, this should be a random string loaded from an environment variable or an instance-relative config file.