Files

70 lines
2.1 KiB
Python

"""Application configuration from environment variables (spec section 7)."""
from __future__ import annotations
from functools import lru_cache
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
app_env: str = "development"
# Database
database_url: str = Field(
default="postgresql+psycopg://mqttadmin:changeme@localhost:5432/mqttadmin",
)
# Management admin bootstrap (spec 7.1) — only consumed when the
# users table has no administrator.
admin_initial_username: str = "admin"
admin_initial_password: str = ""
# Session signing
session_secret: str = ""
session_ttl_seconds: int = 60 * 60 * 8
# Private-key encryption at rest (spec section 43) — AES-256-GCM
# master key. Never stored in PostgreSQL.
secret_encryption_key: str = ""
# Mosquitto management channel
mosquitto_host: str = "mosquitto"
mosquitto_mgmt_port: int = 1883
mosquitto_dynsec_username: str = "admin"
mosquitto_dynsec_password: str = ""
# Control sidecar
control_base_url: str = "http://mosquitto-control:8090"
control_api_token: str = ""
# TLS defaults (used by Release 2 config generation)
default_tls_min_version: str = "tlsv1.2"
default_cert_validity_days: int = 365
default_ca_validity_days: int = 3650
# Broker container ports published to the host by compose.yaml —
# listeners on other ports are only reachable INSIDE the Docker
# network (the platform generates any port; compose gates access).
# Comma-separated container ports; see compose.yaml `ports:`.
published_ports: str = "1883,8883"
@property
def published_port_set(self) -> set[int]:
return {
int(p.strip())
for p in self.published_ports.split(",")
if p.strip().isdigit()
}
@property
def is_production(self) -> bool:
return self.app_env == "production"
@lru_cache
def get_settings() -> Settings:
return Settings()