Files
family_home_lab/portal/config.py

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()