79 lines
2.8 KiB
Python
79 lines
2.8 KiB
Python
"""Application configuration.
|
|
|
|
All values come from environment variables (populated by docker-compose or a
|
|
local .env). No secrets are committed to the repo.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|
|
|
|
|
def _bool(name: str, default: bool = False) -> bool:
|
|
raw = os.getenv(name)
|
|
if raw is None:
|
|
return default
|
|
return raw.strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
|
class Settings:
|
|
# --- General ---
|
|
APP_NAME: str = os.getenv("APP_NAME", "Family Home Lab")
|
|
DEBUG: bool = _bool("DEBUG", False)
|
|
SECRET_KEY: str = os.getenv(
|
|
"SESSION_SECRET", "change-me-in-prod-use-openssl-rand-hex"
|
|
)
|
|
SESSION_COOKIE: str = os.getenv("SESSION_COOKIE", "fhl_session")
|
|
# How long a session cookie stays valid (seconds). 7 days.
|
|
SESSION_TTL: int = int(os.getenv("SESSION_TTL", str(7 * 24 * 3600)))
|
|
|
|
# --- First-run admin bootstrap (breed: env only, never committed) ---
|
|
ADMIN_USERNAME: str = os.getenv("ADMIN_USERNAME", "sam")
|
|
ADMIN_PASSWORD: str = os.getenv("ADMIN_PASSWORD", "")
|
|
ADMIN_FULLNAME: str = os.getenv("ADMIN_FULLNAME", "Sam")
|
|
|
|
# --- Database (pgvector pg16) ---
|
|
DATABASE_URL: str = os.getenv(
|
|
"DATABASE_URL", "postgresql+asyncpg://fhl:fhl@postgres:5432/fhl"
|
|
)
|
|
|
|
# --- Task queue (Celery + RabbitMQ broker, Redis backend) ---
|
|
# Final decision (plan.md §8 #1): own RabbitMQ container in our stack.
|
|
REDIS_URL: str = os.getenv("REDIS_URL", "redis://redis:6379/0")
|
|
CELERY_BROKER_URL: str = os.getenv(
|
|
"CELERY_BROKER_URL", "amqp://guest:guest@rabbitmq:5672//"
|
|
)
|
|
|
|
# --- Object storage (Garage S3) ---
|
|
S3_ENDPOINT_URL: str = os.getenv("S3_ENDPOINT_URL", "http://garage:3900")
|
|
S3_REGION: str = os.getenv("S3_REGION", "garage")
|
|
S3_ACCESS_KEY: str = os.getenv("S3_ACCESS_KEY", "")
|
|
S3_SECRET_KEY: str = os.getenv("S3_SECRET_KEY", "")
|
|
|
|
# --- Tool catalogue endpoint for opening tools ---
|
|
SECTION_COLORS: dict[str, str] = {
|
|
"chat": "#62aef0", # accent-sky
|
|
"image": "#d6b6f6", # accent-purple
|
|
"video": "#ff64c8", # accent-pink
|
|
"audio": "#dd5b00", # accent-orange
|
|
"docs": "#2a9d99", # accent-teal
|
|
"ai": "#62aef0", # accent-sky (fallback for ai stack)
|
|
"media": "#5fbf7a", # media & entertainment
|
|
"data": "#c07af0", # data & links
|
|
"storage": "#e0a63c", # storage & backups
|
|
"home": "#41b6c6", # home & iot
|
|
"home-mgmt": "#3fbfa8", # home management
|
|
"dev": "#e07b39", # development
|
|
"portfolio": "#b089d6", # portfolio / resume
|
|
"infra": "#9aa4ad", # infrastructure
|
|
"network": "#7db2f0", # home network
|
|
}
|
|
|
|
@property
|
|
def is_secure(self) -> bool:
|
|
return not self.DEBUG
|
|
|
|
|
|
settings = Settings() |