File size: 2,976 Bytes
0231daa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90528a8
0231daa
 
 
 
90528a8
0231daa
 
90528a8
 
 
0231daa
 
 
1c7e30d
0231daa
 
 
 
 
 
1c7e30d
0231daa
 
 
 
 
 
90528a8
0231daa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""
Application settings and configuration.

This module uses Pydantic Settings for environment variable management
and configuration validation.
"""

from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """
    Application settings loaded from environment variables.

    All settings can be overridden via environment variables with the
    same name. Example: APP_NAME="My API" in .env file.
    """

    # Application Info
    APP_NAME: str = "Unified Embedding API - Dense & Sparse Embedding"
    VERSION: str = "3.5.0"
    DEBUG: bool = False
    ENVIRONMENT: str = "development"  # development, staging, production

    # Server Configuration
    HOST: str = "0.0.0.0"
    PORT: int = 7860
    WORKERS: int = 1
    RELOAD: bool = False

    # Model Configuration
    MODEL_CONFIG_PATH: str = "src/config/models.yaml"
    MODEL_CACHE_DIR: str = "./model_cache"
    PRELOAD_MODELS: bool = True

    # Request Limits
    MAX_TEXT_LENGTH: int = 32000
    MAX_BATCH_SIZE: int = 100
    REQUEST_TIMEOUT: int = 30

    # Logging
    LOG_LEVEL: str = "INFO"  # DEBUG, INFO, WARNING, ERROR, CRITICAL
    LOG_FILE: bool = True  # Write logs to file
    LOG_DIR: str = "logs"

    CORS_ENABLED: bool = False
    CORS_ORIGINS: list[str] = ["*"]

    # Model Settings
    DEVICE: str = "cpu"  # "cpu" or "cuda
    TRUST_REMOTE_CODE: bool = True  # For models requiring remote code

    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        case_sensitive=True,
        extra="ignore",
    )

    @property
    def model_config_file(self) -> Path:
        """Get Path object for model configuration file."""
        return Path(self.MODEL_CONFIG_PATH)

    @property
    def is_production(self) -> bool:
        """Check if running in production environment."""
        return self.ENVIRONMENT.lower() == "production"

    @property
    def is_development(self) -> bool:
        """Check if running in development environment."""
        return self.ENVIRONMENT.lower() == "development"

    def validate_paths(self) -> None:
        """
        Validate that required paths exist.

        Raises:
            FileNotFoundError: If model config file is not found
        """
        if not self.model_config_file.exists():
            raise FileNotFoundError(
                f"Model configuration file not found: {self.MODEL_CONFIG_PATH}"
            )

        Path(self.MODEL_CACHE_DIR).mkdir(parents=True, exist_ok=True)

        if self.LOG_FILE:
            Path(self.LOG_DIR).mkdir(parents=True, exist_ok=True)


@lru_cache()
def get_settings() -> Settings:
    """
    Get cached settings instance.

    Uses lru_cache to ensure settings are loaded only once
    and reused across the application.

    Returns:
        Settings instance
    """
    settings = Settings()
    settings.validate_paths()
    return settings