"""Typed configuration for asf-core, loaded from env vars (or .env file).""" from __future__ import annotations from functools import lru_cache from typing import List from pydantic import Field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # -------- General -------- asf_env: str = "development" asf_log_level: str = "INFO" cors_origins: List[str] = Field(default_factory=lambda: ["http://localhost:3000"]) api_prefix: str = "/api/v1" @field_validator("cors_origins", mode="before") @classmethod def _split_csv(cls, v): # noqa: D401 - allow comma separated list if isinstance(v, str): return [item.strip() for item in v.split(",") if item.strip()] return v # -------- MongoDB -------- mongo_uri: str = "mongodb://172.19.40.102:27017,172.19.40.103:27017/asf?replicaSet=rs0" mongo_db: str = "asf" mongo_min_pool_size: int = 5 mongo_max_pool_size: int = 50 # -------- RabbitMQ -------- rabbitmq_uri: str = "amqp://azurian:StrongPassword123!@172.19.40.201:5672/asf" rabbitmq_events_exchange: str = "asf.events" rabbitmq_jobs_exchange: str = "asf.jobs" queues: dict = Field( default_factory=lambda: { "ai_interactive": "asf.ai.interactive", "ai_background": "asf.ai.background", "indexing": "asf.indexing", "code_analysis": "asf.code_analysis", "testing": "asf.testing", "devops": "asf.devops", "notifications": "asf.notifications", } ) # -------- Redis -------- redis_uri: str = "redis://:asfredis123@localhost:6379/0" # -------- MinIO -------- minio_host: str = "localhost:9000" minio_user: str = "asfadmin" minio_password: str = "asfadmin123" minio_bucket: str = "asf-artifacts" minio_secure: bool = False # -------- Security -------- jwt_secret: str = "change-me-in-production-please" # nosec - default only session_ttl_seconds: int = 86400 # -------- Auth (bootstrap mock) -------- # When true, accept a trusted `X-ASF-Tenant-Id` header for local dev. # MUST be false in production! dev_trust_tenant_header: bool = True dev_trust_user_header: bool = True @lru_cache(maxsize=1) def get_settings() -> Settings: return Settings()