- FastAPI + APScheduler + SQLite, single container - Daily generation at 06:00 Europe/Copenhagen + cold-start generation - Retry with backoff (3 attempts/15 min), stale fallback with banner - OpenAI-compatible endpoint via env (OPENAI_BASE_URL/MODEL/API_KEY) - docker-compose with named volume for joke persistence
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
import os
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class Settings:
|
|
openai_base_url: str = field(
|
|
default_factory=lambda: os.environ.get(
|
|
"OPENAI_BASE_URL", "https://api.openai.com/v1"
|
|
).rstrip("/")
|
|
)
|
|
openai_model: str = field(
|
|
default_factory=lambda: os.environ.get("OPENAI_MODEL", "gpt-4o-mini")
|
|
)
|
|
openai_api_key: str = field(
|
|
default_factory=lambda: os.environ.get("OPENAI_API_KEY", "")
|
|
)
|
|
db_path: str = field(
|
|
default_factory=lambda: os.environ.get("DB_PATH", "/data/jokes.db")
|
|
)
|
|
timezone: str = field(
|
|
default_factory=lambda: os.environ.get("TZ", "Europe/Copenhagen")
|
|
)
|
|
generate_hour: int = field(
|
|
default_factory=lambda: int(os.environ.get("GENERATE_HOUR", "6"))
|
|
)
|
|
generate_minute: int = field(
|
|
default_factory=lambda: int(os.environ.get("GENERATE_MINUTE", "0"))
|
|
)
|
|
max_attempts: int = field(
|
|
default_factory=lambda: int(os.environ.get("MAX_ATTEMPTS", "3"))
|
|
)
|
|
retry_minutes: int = field(
|
|
default_factory=lambda: int(os.environ.get("RETRY_MINUTES", "15"))
|
|
)
|
|
wikipedia_lang: str = field(
|
|
default_factory=lambda: os.environ.get("WIKIPEDIA_LANG", "en")
|
|
)
|
|
|
|
|
|
settings = Settings()
|