Spaces:
Sleeping
Sleeping
| """Configuration management using Pydantic settings.""" | |
| import os | |
| from typing import List, Literal | |
| from pydantic import Field, field_validator | |
| from pydantic_settings import BaseSettings, SettingsConfigDict | |
| class Settings(BaseSettings): | |
| """ | |
| Application settings with environment variable support. | |
| Settings are loaded from (in order of precedence): | |
| 1. Environment variables | |
| 2. .env file (if present) | |
| 3. Default values | |
| Works without .env file for HuggingFace Spaces and containerized deployments. | |
| """ | |
| model_config = SettingsConfigDict( | |
| env_file=".env", | |
| env_file_encoding="utf-8", | |
| case_sensitive=False, | |
| extra="ignore", | |
| # Don't error if .env file is missing (for HF Spaces, Docker, etc.) | |
| env_ignore_empty=True, | |
| ) | |
| # Application Settings | |
| app_name: str = Field(default="AI Writing Studio", description="Application name") | |
| app_version: str = Field(default="1.0.0", description="Application version") | |
| environment: Literal["development", "staging", "production"] = Field( | |
| default="development", description="Runtime environment" | |
| ) | |
| debug: bool = Field(default=False, description="Enable debug mode") | |
| # Server Configuration | |
| host: str = Field(default="0.0.0.0", description="Server host") | |
| port: int = Field(default=7860, ge=1, le=65535, description="Server port") | |
| server_workers: int = Field(default=4, ge=1, description="Number of worker processes") | |
| # Model Configuration | |
| default_model: str = Field( | |
| default="google/flan-t5-base", | |
| description="Default HuggingFace model (instruction-tuned for revision)" | |
| ) | |
| max_model_length: int = Field(default=512, ge=1, description="Maximum model input length") | |
| default_max_length: int = Field(default=512, ge=1, description="Default generation length") | |
| default_num_sequences: int = Field(default=1, ge=1, description="Number of sequences") | |
| # Security | |
| allowed_origins: str = Field( | |
| default="http://localhost:7860,http://127.0.0.1:7860", | |
| description="Comma-separated CORS origins", | |
| ) | |
| rate_limit_per_minute: int = Field(default=10, ge=1, description="Rate limit per minute") | |
| max_text_length: int = Field( | |
| default=10000, ge=1, description="Maximum input text length" | |
| ) | |
| enable_auth: bool = Field(default=False, description="Enable authentication") | |
| secret_key: str = Field(default="", description="Secret key for sessions") | |
| # Logging | |
| log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = Field( | |
| default="INFO", description="Logging level" | |
| ) | |
| log_format: Literal["json", "text"] = Field(default="json", description="Log format") | |
| log_file_path: str = Field(default="./logs/app.log", description="Log file path") | |
| log_max_bytes: int = Field(default=10485760, ge=1, description="Max log file size") | |
| log_backup_count: int = Field(default=5, ge=0, description="Number of log backups") | |
| # Monitoring | |
| enable_metrics: bool = Field(default=True, description="Enable Prometheus metrics") | |
| metrics_port: int = Field(default=8000, ge=1, le=65535, description="Metrics port") | |
| # Cache Configuration | |
| enable_cache: bool = Field(default=True, description="Enable caching") | |
| cache_ttl: int = Field(default=3600, ge=1, description="Cache TTL in seconds") | |
| cache_max_size: int = Field(default=100, ge=1, description="Maximum cache entries") | |
| # Feature Flags | |
| enable_diff_highlighting: bool = Field(default=True, description="Enable diff view") | |
| enable_rubric_scoring: bool = Field(default=True, description="Enable rubric scoring") | |
| enable_prompt_packs: bool = Field(default=True, description="Enable prompt packs") | |
| def parse_origins(cls, v: str) -> List[str]: | |
| """Parse comma-separated origins into a list.""" | |
| if isinstance(v, str): | |
| return [origin.strip() for origin in v.split(",") if origin.strip()] | |
| return v | |
| def ensure_directory_exists(cls, v: str) -> str: | |
| """Ensure directory exists for file paths.""" | |
| directory = os.path.dirname(v) if os.path.splitext(v)[1] else v | |
| if directory and not os.path.exists(directory): | |
| os.makedirs(directory, exist_ok=True) | |
| return v | |
| def is_production(self) -> bool: | |
| """Check if running in production.""" | |
| return self.environment == "production" | |
| def is_development(self) -> bool: | |
| """Check if running in development.""" | |
| return self.environment == "development" | |
| # Global settings instance | |
| settings = Settings() | |