Repository navigation
Configuration
File: app/config/settings.py
Pydantic BaseSettings β reads from environment variables (.env auto-loaded by python-dotenv).
| Variable | Required | Default | Description |
|---|---|---|---|
BOT_TOKEN |
β | β | Telegram bot token from BotFather |
DATABASE_URL |
β | β | PostgreSQL DSN (postgresql://user:pass@host:port/db) |
REDIS_URL |
β | redis://localhost:6379 |
Redis DSN; Redis is optional |
BOT_MODE |
β | polling |
polling or webhook
|
GENIUS_TOKEN |
β | β | Genius API token for lyrics |
SPOTIFY_ENABLED |
β | false |
Enable Spotify enrichment |
SPOTIFY_CLIENT_ID |
β | β | Spotify app client ID |
SPOTIFY_CLIENT_SECRET |
β | β | Spotify app client secret |
WEBHOOK_PUBLIC_URL |
webhook only | β | Public URL Telegram posts updates to |
WEBHOOK_SECRET_PATH |
webhook only | β | URL path component (random string) |
WEBHOOK_SECRET_TOKEN |
webhook only | β | Header token Telegram sends with each update |
WEBHOOK_CERT_PATH |
webhook only | β | Path to self-signed cert inside container |
WEBHOOK_KEY_PATH |
webhook only | β | Path to private key inside container |
ADMIN_ID |
β | β | Legacy single admin Telegram ID (prefer admins.json) |
EXTERNAL_SERVICE_COOLDOWN_SECONDS |
β | 60 |
Circuit breaker cooldown after API failures |
FAVORITES_LIMIT |
β | 50 |
Caps the /favorites keyboard; Telegram rejects an over-large reply_markup |
LOG_LEVEL |
β | INFO |
Python log level |
LOG_FORMAT |
β | text |
text or json (structured logging) |
LOG_SAMPLE_RATE |
β | 1.0 |
Fraction of DEBUG/INFO records kept (0.0β1.0). WARNING and above, and any record with exception info, are never sampled. Lower only if log volume is an observed problem β sampled-out lines leave no trace. |
Full list with defaults: see .env.example at project root.
| Context | DSN |
|---|---|
| Host machine (local dev, scripts) | postgresql://user:pass@localhost:5432/db |
| Inside Docker container | postgresql://user:pass@postgres:5432/db |
docker-compose.yml sets DATABASE_URL for the container using the service name postgres. Local dev and scripts use localhost.
File: config/admins.json (never committed β in .gitignore)
{ "admin_ids": [123456789, 987654321] }Legacy alternative: ADMIN_ID=123456789 in .env (single ID only).
load_admin_ids() in app/config/admins.py tries admins.json first, falls back to ADMIN_ID. Result is LRU-cached β clear_admin_ids_cache() forces reload.
Template: config/admins.example.json
scripts/check_env_example.py β CI check that every os.getenv() call in the codebase has a corresponding entry in .env.example. Prevents undocumented environment variables.
Never commit or push:
.env
config/admins.json
certs/
data/
logs/
If .env was ever uploaded to GitHub, regenerate all tokens (Telegram, Genius, Spotify).