All settings are managed by AppSettings (Pydantic Settings) and can be provided via environment variables or a .env file.
| Variable | Default | Description |
|---|---|---|
APP_ENV |
local |
Runtime environment: local / test / production |
APP_DEBUG |
false |
Include exception messages in 500 responses when true |
APP_NAME |
nene2-python |
Application name |
| Variable | Default | Description |
|---|---|---|
SECURITY_HEADERS_ENABLED |
true |
Add security headers to every response |
MAX_BODY_SIZE |
1048576 |
Maximum request body size in bytes (default 1 MiB) |
Security headers added when enabled:
| Header | Value |
|---|---|
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
Referrer-Policy |
strict-origin-when-cross-origin |
Content-Security-Policy |
default-src 'self' |
Permissions-Policy |
geolocation=(), microphone=() |
| Variable | Default | Description |
|---|---|---|
THROTTLE_ENABLED |
true |
Enable rate limiting |
THROTTLE_LIMIT |
60 |
Maximum requests per window |
THROTTLE_WINDOW |
60 |
Window size in seconds |
Uses a fixed-window algorithm keyed on client IP. Exceeding the limit returns 429 Too Many Requests with a Retry-After header.
| Variable | Default | Description |
|---|---|---|
CORS_ENABLED |
false |
Enable CORS middleware |
CORS_ORIGINS |
[] |
Allowed origins (comma-separated) |
CORS_ALLOW_CREDENTIALS |
false |
Allow credentials |
CORS_ALLOW_METHODS |
GET,POST,PUT,DELETE,OPTIONS |
Allowed methods |
CORS_ALLOW_HEADERS |
* |
Allowed headers |
CORS_ORIGINS=*is prohibited. Always specify explicit origins.
| Variable | Default | Description |
|---|---|---|
BEARER_TOKEN_ENABLED |
false |
Enable Bearer Token auth |
BEARER_TOKENS |
[] |
Valid tokens — JSON array format: ["tok-1","tok-2"] |
API_KEY_ENABLED |
false |
Enable API Key auth |
API_KEYS |
[] |
Valid API keys — JSON array format: ["key-1","key-2"] |
List fields require JSON array syntax in
.env. WritingBEARER_TOKENS=token-1(plain string) causes aJSONDecodeErrorat startup. Always useBEARER_TOKENS=["token-1","token-2"]. The same applies toAPI_KEYSandCORS_ORIGINS.
| Variable | Default | Description |
|---|---|---|
DB_ADAPTER |
sqlite |
sqlite / mysql / pgsql |
DB_NAME |
:memory: |
SQLite file path or DB name |
DB_HOST |
localhost |
Database host (ignored for SQLite) |
DB_PORT |
3306 |
Database port (ignored for SQLite) |
DB_USER |
"" |
Database user (ignored for SQLite) |
DB_PASSWORD |
"" |
Database password — stored as SecretStr, never logged |
AppSettings.db_url is a computed property built from the variables above.
The table below shows what URL is generated for each adapter + common DB_NAME values:
DB_ADAPTER |
DB_NAME |
Generated db_url |
|---|---|---|
sqlite |
:memory: |
sqlite:///:memory: |
sqlite |
./data/app.db |
sqlite:///./data/app.db |
sqlite |
/var/lib/app.db |
sqlite:////var/lib/app.db |
mysql |
mydb |
mysql+pymysql://user:pass@localhost:3306/mydb |
pgsql |
mydb |
postgresql+psycopg2://user:pass@localhost:5432/mydb |
For SQLite in-memory databases (
DB_NAME=:memory:), passpoolclass=StaticPooltocreate_engine()so all connections share the same in-process database. See the SQLAlchemy repository how-to for details.
APP_ENV=production
APP_DEBUG=false
THROTTLE_ENABLED=true
THROTTLE_LIMIT=100
THROTTLE_WINDOW=60
CORS_ENABLED=true
CORS_ORIGINS=["https://example.com","https://app.example.com"]
BEARER_TOKEN_ENABLED=true
BEARER_TOKENS=["secret-token-1","secret-token-2"]
DB_ADAPTER=mysql
DB_HOST=db.example.com
DB_PORT=3306
DB_NAME=myapp
DB_USER=myuser
DB_PASSWORD=supersecretCommit
.env.examplewith empty values. Keep the real.envin.gitignore.