Configuration¶
Every application needs different settings for different environments — debug mode in development, real secrets in production, different database URLs for testing. This guide covers how to manage configuration cleanly.
Environment Variables¶
The simplest and most universal approach. Environment variables work everywhere — locally, in Docker, on cloud platforms — and keep secrets out of your source code:
import os
import responder
api = responder.API(
debug=os.getenv("DEBUG", "false").lower() == "true",
secret_key=os.environ["SECRET_KEY"],
cors=os.getenv("CORS_ENABLED", "false").lower() == "true",
)
Some variables Responder handles automatically:
PORT— when set, the server binds to0.0.0.0on this port
Set variables in your shell:
$ export SECRET_KEY="your-secret-here"
$ export DEBUG=true
$ python app.py
Or in a .env file (don’t commit this to git):
SECRET_KEY=your-secret-here
DEBUG=true
Using .env Files¶
For local development, a .env file is convenient. Install
python-dotenv and load it at the top of your app:
$ uv pip install python-dotenv
from dotenv import load_dotenv
load_dotenv()
import os
import responder
api = responder.API(
secret_key=os.environ["SECRET_KEY"],
)
Add .env to your .gitignore — never commit secrets.
Configuration Class Pattern¶
For larger applications, a configuration class keeps things organized:
import os
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-secret")
DEBUG = os.environ.get("DEBUG", "false").lower() == "true"
DATABASE_URL = os.environ.get("DATABASE_URL", "sqlite:///dev.db")
CORS_ORIGINS = os.environ.get("CORS_ORIGINS", "").split(",")
config = Config()
api = responder.API(
debug=config.DEBUG,
secret_key=config.SECRET_KEY,
cors=bool(config.CORS_ORIGINS[0]),
cors_params={"allow_origins": config.CORS_ORIGINS},
)
This makes it easy to see all your settings in one place.
Secret Key¶
The secret_key is used to sign session cookies. If someone knows your
secret key, they can forge session data and impersonate any user.
Rules:
Never use the default in production
Generate a random key:
python -c "import secrets; print(secrets.token_hex(32))"Store it in an environment variable, not in code
Rotate it if it’s ever compromised (this invalidates all sessions)
api = responder.API(secret_key=os.environ["SECRET_KEY"])
Debug Mode¶
Debug mode controls error page behavior:
On (
debug=True): detailed error pages with tracebacks. Never use this in production — it exposes your source code.Off (
debug=False): generic error pages. This is the default.
api = responder.API(debug=True) # development only
A common pattern is to read it from the environment:
api = responder.API(debug=os.getenv("DEBUG") == "true")
Allowed Hosts¶
In production, always set allowed_hosts to prevent Host header
attacks. This should match the domain names your application serves:
api = responder.API(
allowed_hosts=["example.com", "www.example.com"],
)
In development, you can use ["*"] (the default) or specific local
addresses:
api = responder.API(allowed_hosts=["localhost", "127.0.0.1"])
Putting It All Together¶
A production-ready configuration setup:
import os
from dotenv import load_dotenv
load_dotenv()
import responder
api = responder.API(
debug=os.getenv("DEBUG", "false") == "true",
secret_key=os.environ["SECRET_KEY"],
allowed_hosts=os.getenv("ALLOWED_HOSTS", "*").split(","),
cors=bool(os.getenv("CORS_ORIGINS")),
cors_params={
"allow_origins": os.getenv("CORS_ORIGINS", "").split(","),
"allow_methods": ["GET", "POST", "PUT", "DELETE"],
},
)
With a .env file for local development:
SECRET_KEY=dev-secret-do-not-use-in-prod
DEBUG=true
ALLOWED_HOSTS=localhost,127.0.0.1
CORS_ORIGINS=http://localhost:3000
And environment variables set properly in production (via your cloud platform’s dashboard, Docker secrets, or a secrets manager).