mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 14:50:19 +00:00
a3b49ab9fd
New documentation pages: - Authentication: API keys, JWT tokens, session auth, custom exceptions - WebSocket Tutorial: echo server, chat room, HTML client, data formats - Writing Middleware: hooks vs middleware, Starlette integration, ordering - Configuration: env vars, .env files, secret keys, debug mode, production setup Also: - Complete working example at end of quickstart with cross-references - Three new example files: rest_api.py, websocket_chat.py, sse_stream.py - Changelog updated for v3.2.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
173 lines
4.3 KiB
ReStructuredText
173 lines
4.3 KiB
ReStructuredText
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 to ``0.0.0.0`` on 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).
|