File size: 3,810 Bytes
5628f48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Configuration management for the AI Web Visualization Generator.

This module handles all application settings using Pydantic for validation
and type safety. Settings are loaded from environment variables and .env files.
"""

from pathlib import Path
from typing import List

from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class AppSettings(BaseSettings):
    """
    Manages application settings using Pydantic for validation.
    
    All settings can be configured via environment variables or a .env file.
    Settings are validated at startup to ensure proper configuration.
    
    Attributes:
        primary_model_name: Name of the primary AI model (default: Gemini Flash)
        gemini_api_keys: Comma-separated list of Gemini API keys
        fallback_model_name: Name of the fallback AI model (default: Gemini Pro)
        requesty_api_key: API key for Requesty service (required)
        requesty_site_url: URL of the site using Requesty
        requesty_site_name: Name of the site for Requesty headers
        cors_allow_origins: Comma-separated list of allowed CORS origins
        static_dir: Directory containing static frontend files
    """
    
    model_config = SettingsConfigDict(
        env_file='.env',
        env_file_encoding='utf-8',
        extra='ignore'
    )
    
    # AI Model Configuration
    primary_model_name: str = Field(
        default="gemini-1.5-flash-latest",
        alias="PRIMARY_AI_MODEL_NAME",
        description="Primary AI model to use for generation"
    )
    
    gemini_api_keys: str = Field(
        default="",
        alias="GEMINI_API_KEYS",
        description="Comma-separated list of Gemini API keys"
    )
    
    fallback_model_name: str = Field(
        default="gemini-1.5-pro-latest",
        alias="AI_MODEL_NAME",
        description="Fallback AI model name"
    )
    
    # Requesty Configuration
    requesty_api_key: str = Field(
        ...,
        alias="REQUESTY_API_KEY",
        description="API key for Requesty service (required)"
    )
    
    requesty_site_url: str = Field(
        default="",
        alias="REQUESTY_SITE_URL",
        description="Site URL for Requesty headers"
    )
    
    requesty_site_name: str = Field(
        default="AI Visualization Generator",
        alias="REQUESTY_SITE_NAME",
        description="Site name for Requesty headers"
    )
    
    # Server Configuration
    cors_allow_origins: str = Field(
        default="*",
        alias="CORS_ALLOW_ORIGINS",
        description="Comma-separated list of allowed CORS origins"
    )
    
    static_dir: Path = Field(
        default=Path("static"),
        alias="STATIC_DIR",
        description="Directory containing static frontend files"
    )
    
    @property
    def index_file(self) -> Path:
        """Path to the main index.html file."""
        return self.static_dir / "index.html"
    
    @property
    def gemini_api_keys_list(self) -> List[str]:
        """
        Parse comma-separated Gemini API keys into a list.
        
        Returns:
            List of API keys, empty list if none provided
        """
        if isinstance(self.gemini_api_keys, str):
            return [key.strip() for key in self.gemini_api_keys.split(',') if key.strip()]
        return []


def load_settings() -> AppSettings:
    """
    Load and validate application settings.
    
    Returns:
        AppSettings: Validated application settings
        
    Raises:
        RuntimeError: If configuration is invalid or missing required values
    """
    try:
        return AppSettings()
    except Exception as e:
        raise RuntimeError(
            f"FATAL: Configuration error. Is your .env file set up correctly? "
            f"Details: {e}"
        )