from loguru import logger from pydantic import EmailStr, Field, MongoDsn, NonNegativeFloat, NonNegativeInt, PositiveInt, SecretStr from pydantic_settings import BaseSettings, SettingsConfigDict from types import MappingProxyType from typing import Literal, Mapping, Optional, Self class Settings(BaseSettings): """ Application settings loaded from environment variables. """ model_config = SettingsConfigDict( case_sensitive=False, env_file=".env", env_file_encoding="utf-8", extra="allow", frozen=True ) # Logging Configuration ― not actually used to configure Loguru, but defined to prevent warnings about “unknown” environment variables log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = Field(default_factory=lambda data: "DEBUG" if data.get("DEBUG", False) else "INFO") log_format: Literal["text", "json"] = "json" # HTTP Server Configuration http_host: str = "0.0.0.0" http_port: PositiveInt = 8080 # APScheduler Configuration scheduler_timezone: Optional[str] = "UTC" # Slack Configuration slack_bot_token: SecretStr slack_app_token: SecretStr # Vectorization Configuration embedding_model: str vector_dimension: PositiveInt chunk_size: PositiveInt chunk_overlap: NonNegativeInt top_k_matches: PositiveInt # MongoDB Configuration mongodb_uri: SecretStr # TODO: Contemplate switching to MongoDsn type for the main URL, and separate out the credentials to SecretStr variables. mongodb_name: str vectorized_chunks_collection_name: str = "vectorized_chunks" vectorized_chunks_search_index_name: Optional[str] = None score_threshold: NonNegativeFloat # Hugging Face Configuration hf_api_token: Optional[SecretStr] = None # TODO: Currently, this is unused. # OpenAI Configuration openai_api_key: SecretStr chat_model: str max_tokens: PositiveInt temperature: NonNegativeFloat system_prompt: str # Google Drive Configuration google_drive_root_id: str google_project_id: str google_private_key_id: SecretStr google_private_key: SecretStr google_client_id: str google_client_email: EmailStr google_token_uri: str = "https://oauth2.googleapis.com/token" # File Monitoring Configuration file_monitor_root_path: str = "" def __init__(self: Self, **data) -> None: super().__init__(**data) logger.debug("Created {}", self.__class__.__name__) if self.__pydantic_extra__: logger.warning("Extra unrecognized environment variables were provided: {}", ", ".join(self.__pydantic_extra__)) def get_extra_environment_variables(self: Self) -> Mapping[str, str]: return MappingProxyType(self.__pydantic_extra__)