Skip to main content

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:

KeyDefaultDescription
SESSION_COOKIE_NAME'session'The name of the cookie.
SESSION_COOKIE_HTTPONLYTruePrevents JavaScript from accessing the cookie.
SESSION_COOKIE_SECUREFalseOnly 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.