from typing import List import os from pathlib import Path class Settings: """Configuration principale avec variables d'environnement obligatoires""" # Environnement - OBLIGATOIRE ENVIRONMENT: str = os.getenv("ENVIRONMENT") if not ENVIRONMENT: raise ValueError("ENVIRONMENT variable is required. Use development or production") # Debug et reload DEBUG: bool = os.getenv("DEBUG", "false").lower() == "true" RELOAD: bool = os.getenv("RELOAD", "false").lower() == "true" # Database - OBLIGATOIRE DATABASE_URL: str = os.getenv("DATABASE_URL") if not DATABASE_URL: raise ValueError("DATABASE_URL variable is required") # JWT - OBLIGATOIRE JWT_SECRET_KEY: str = os.getenv("JWT_SECRET_KEY") if not JWT_SECRET_KEY: raise ValueError("JWT_SECRET_KEY variable is required") JWT_ALGORITHM: str = os.getenv("JWT_ALGORITHM", "HS256") JWT_EXPIRATION_MINUTES: int = int(os.getenv("JWT_EXPIRATION_MINUTES", "10080")) # Upload UPLOAD_PATH: str = os.getenv("UPLOAD_PATH", "./uploads") MAX_UPLOAD_SIZE: int = int(os.getenv("MAX_UPLOAD_SIZE", "104857600")) ALLOWED_IMAGE_TYPES: List[str] = os.getenv("ALLOWED_IMAGE_TYPES", "image/jpeg,image/png,image/gif,image/webp").split(",") ALLOWED_VIDEO_TYPES: List[str] = os.getenv("ALLOWED_VIDEO_TYPES", "video/mp4,video/mpeg,video/quicktime,video/webm").split(",") # CORS - OBLIGATOIRE CORS_ORIGINS: str = os.getenv("CORS_ORIGINS") if not CORS_ORIGINS: raise ValueError("CORS_ORIGINS variable is required") CORS_ORIGINS_LIST: List[str] = CORS_ORIGINS.split(",") # Email SMTP_HOST: str = os.getenv("SMTP_HOST", "smtp.gmail.com") SMTP_PORT: int = int(os.getenv("SMTP_PORT", "587")) SMTP_USER: str = os.getenv("SMTP_USER", "") SMTP_PASSWORD: str = os.getenv("SMTP_PASSWORD", "") SMTP_FROM: str = os.getenv("SMTP_FROM", "noreply@lediscord.com") # Admin - OBLIGATOIRE ADMIN_EMAIL: str = os.getenv("ADMIN_EMAIL") if not ADMIN_EMAIL: raise ValueError("ADMIN_EMAIL variable is required") ADMIN_PASSWORD: str = os.getenv("ADMIN_PASSWORD") if not ADMIN_PASSWORD: raise ValueError("ADMIN_PASSWORD variable is required") # Notifications Push (VAPID) VAPID_PRIVATE_KEY: str = os.getenv("VAPID_PRIVATE_KEY", "") VAPID_PUBLIC_KEY: str = os.getenv("VAPID_PUBLIC_KEY", "") VAPID_CLAIMS_EMAIL: str = os.getenv("VAPID_CLAIMS_EMAIL", "mailto:admin@lediscord.com") # App APP_NAME: str = os.getenv("APP_NAME", "LeDiscord") APP_URL: str = os.getenv("APP_URL", "http://localhost:5173") # Logging LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO" if ENVIRONMENT == "production" else "DEBUG") # Performance WORKERS: int = int(os.getenv("WORKERS", "1" if ENVIRONMENT in ["local", "development"] else "4")) # Sécurité (production uniquement) SECURE_COOKIES: bool = os.getenv("SECURE_COOKIES", "false").lower() == "true" SECURE_HEADERS: bool = os.getenv("SECURE_HEADERS", "false").lower() == "true" def __str__(self) -> str: """Représentation lisible de la configuration""" return f""" 🔧 Configuration LeDiscord - Environnement: {self.ENVIRONMENT.upper()} 📊 Debug: {self.DEBUG} 🔄 Reload: {self.RELOAD} 🌐 CORS Origins: {', '.join(self.CORS_ORIGINS_LIST)} 🗄️ Database: {self.DATABASE_URL.split('@')[1] if '@' in self.DATABASE_URL else 'Unknown'} 📁 Upload Path: {self.UPLOAD_PATH} 📝 Log Level: {self.LOG_LEVEL} 🚀 Workers: {self.WORKERS} """ def validate(self) -> bool: """Valide la configuration""" required_vars = [ "ENVIRONMENT", "DATABASE_URL", "JWT_SECRET_KEY", "CORS_ORIGINS", "ADMIN_EMAIL", "ADMIN_PASSWORD" ] for var in required_vars: if not getattr(self, var): print(f"❌ Configuration invalide: {var} est manquant") return False print("✅ Configuration validée avec succès") return True # Instance globale try: settings = Settings() except ValueError as e: print(f"❌ Erreur de configuration: {e}") raise # Validation automatique au démarrage if __name__ == "__main__": print(settings) settings.validate()