""" Application configuration using Pydantic Settings. Following best practices: modular settings, environment-based config. """ from functools import lru_cache from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Application settings loaded from environment variables.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # API Configuration library_api_key: str = Field(..., description="API key for authentication") # Neo4j Configuration neo4j_uri: str = Field(default="bolt://neo4j:7687", description="Neo4j Bolt URI") neo4j_user: str = Field(default="neo4j", description="Neo4j username") neo4j_password: str = Field(..., description="Neo4j password") # Qdrant Configuration qdrant_host: str = Field(default="qdrant", description="Qdrant host") qdrant_port: int = Field(default=6333, description="Qdrant port") # Wiki.js Configuration wikijs_url: str = Field(default="http://wiki:3000", description="Wiki.js URL") wikijs_username: str = Field(..., description="Wiki.js username") wikijs_password: str = Field(..., description="Wiki.js password") # SearXNG Configuration searxng_url: str = Field(default="http://searxng:8080", description="SearXNG URL") # Ollama Configuration (for embeddings) ollama_url: str = Field(default="http://ollama:11434", description="Ollama URL") ollama_model: str = Field(default="nomic-embed-text", description="Ollama embedding model") # HybridRAG Configuration reranker_model: str = Field(default="mistral-nemo", description="Model for LLM re-ranking") reranker_enabled: bool = Field(default=True, description="Enable LLM re-ranking") hybrid_rag_vector_limit: int = Field(default=10, ge=1, le=50, description="Vector search limit") hybrid_rag_graph_limit: int = Field(default=10, ge=1, le=50, description="Graph search limit") hybrid_rag_web_limit: int = Field(default=5, ge=1, le=20, description="Web search limit") # Redis Configuration (for job tracking - separate DB from wiki) redis_host: str = Field(default="redis-shared", description="Redis host") redis_port: int = Field(default=6379, description="Redis port") redis_db: int = Field(default=4, description="Redis database number (4 for library-desk jobs)") # Application app_name: str = Field(default="Library Desk", description="Application name") app_version: str = Field(default="1.0.0", description="Application version") debug: bool = Field(default=False, description="Debug mode") @property def qdrant_url(self) -> str: """Computed Qdrant URL.""" return f"http://{self.qdrant_host}:{self.qdrant_port}" @property def redis_url(self) -> str: """Computed Redis URL.""" return f"redis://{self.redis_host}:{self.redis_port}/{self.redis_db}" @lru_cache def get_settings() -> Settings: """ Get cached settings instance. Uses lru_cache to ensure single instance across app. """ return Settings()