Files
SlabUploader/backend/app/config.py
T
grokbot_ty e5514fe3bf feat(#27): Gate B [07/10]: FastAPI health endpoint + app factory (H-1)
- App factory pattern (FUND-8): create_app() produces fresh app per test
- Logging config (structured, no secrets)
- Config validation: SLAB_AES_KEY required, WOO_BASE_URL HTTPS-only
- GET /api/health returns 200 {status: ok, version, woo_reachable: false}
- SQLite + alembic skeleton: full DATA-MODEL schema, initial migration
- API contract tests via httpx TestClient: 5 cases all green
  - test_returns_200, test_returns_ok_status, test_woo_reachable_false
  - test_response_shape, test_with_test_client_lifespan (FUND-9/10)
2026-09-07 07:53:36 +00:00

47 lines
1.7 KiB
Python

"""Application settings loaded from environment."""
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""FastAPI application settings.
WOO_BASE_URL is the deploy-time SoT for the WooCommerce store.
It must be HTTPS. FastAPI refuses startup when missing or HTTP.
SLAB_AES_KEY is the AES-GCM master key (32-byte base64). Required.
Missing key refuses startup.
All Woo credentials and inference secrets are stored AES-GCM encrypted
in the settings table at runtime, not passed as env vars.
"""
model_config = SettingsConfigDict(env_prefix="SLAB_", env_file=".env", env_file_encoding="utf-8")
aes_key: str | None = None
woo_base_url: str | None = None
app_hostname: str | None = None
# Image output constants (from TECH-SPEC)
aspect_ratio: str = "3:4"
output_px: int = 1600
output_px_min: int = 1600
fill_target: float = 0.80
def validate(self) -> None:
"""Refuse startup on invalid config."""
if self.aes_key is None:
raise ValueError("SLAB_AES_KEY environment variable is required")
if len(self.aes_key) < 32:
raise ValueError("SLAB_AES_KEY must be at least 32 bytes base64")
if self.woo_base_url is None:
raise ValueError("WOO_BASE_URL environment variable is required")
if not self.woo_base_url.startswith("https://"):
raise ValueError("WOO_BASE_URL must be HTTPS")
@property
def woo_credentials_configured(self) -> bool:
"""Whether Woo application password has been stored (checked via DB at runtime)."""
return False # Always false from config alone; checked via settings table at runtime