import os import json from pathlib import Path from dotenv import load_dotenv # Load environment variables load_dotenv() def get_anthropic_api_key() -> str: """Get the Anthropic API key from environment""" api_key = os.getenv("ANTHROPIC_API_KEY") if not api_key: raise ValueError("ANTHROPIC_API_KEY not found in environment variables") return api_key # Default configurations DEFAULT_CONFIG = { "app": { "name": "EduAI Platform", "version": "1.0.0", "description": "AI-powered educational platform", "debug": False }, "ui": { "theme": "light", "page_title": "EduAI Platform", "page_icon": "🎓", "layout": "wide", "initial_sidebar_state": "expanded" }, "ai": { "model": { "name": "claude-3-opus-20240229", "max_tokens": 1024, "temperature": 0.7 }, "voice": { "enabled": True, "rate": 150, "volume": 0.9, "prefer_female_voice": True }, "speech_recognition": { "energy_threshold": 4000, "timeout": 5 } }, "learning": { "max_modules": 8, "achievement_levels": [1, 5, 10, 25], "difficulty_levels": ["beginner", "intermediate", "advanced"], "learning_styles": ["interactive", "visual", "theoretical", "practical"], "mastery_thresholds": { "not_started": 0.0, "in_progress": 0.5, "mastered": 0.8 } }, "features": { "voice_interaction": True, "code_playground": True, "achievements": True, "learning_paths": True, "progress_tracking": True } } class Config: _instance = None _config = None def __new__(cls): if cls._instance is None: cls._instance = super(Config, cls).__new__(cls) cls._instance._load_config() return cls._instance def _load_config(self): """Load configuration from file or use defaults""" config_path = Path("config.json") if config_path.exists(): try: with open(config_path) as f: self._config = {**DEFAULT_CONFIG, **json.load(f)} except Exception as e: print(f"Error loading config file: {e}") self._config = DEFAULT_CONFIG else: self._config = DEFAULT_CONFIG def get(self, key_path: str, default=None): """ Get configuration value using dot notation Example: config.get('ai.model.name') """ value = self._config for key in key_path.split('.'): try: value = value[key] except (KeyError, TypeError): return default return value def get_all(self): """Get complete configuration dictionary""" return self._config.copy() def save(self): """Save current configuration to file""" try: with open("config.json", "w") as f: json.dump(self._config, f, indent=2) except Exception as e: print(f"Error saving config file: {e}") # Helper functions for common config operations def get_model_name() -> str: """Get AI model name from config""" return Config().get('ai.model.name') def get_model_max_length() -> int: """Get model max token length from config""" return Config().get('ai.model.max_tokens') def get_voice_settings() -> dict: """Get voice settings from config""" return Config().get('ai.voice') def get_app_settings() -> dict: """Get application settings from config""" return Config().get('app') def get_ui_settings() -> dict: """Get UI settings from config""" return Config().get('ui') def get_learning_settings() -> dict: """Get learning-related settings from config""" return Config().get('learning') def is_feature_enabled(feature_name: str) -> bool: """Check if a feature is enabled""" return Config().get(f'features.{feature_name}', False) def get_mastery_thresholds() -> dict: """Get mastery level thresholds""" return Config().get('learning.mastery_thresholds') def save_config(): """Save current configuration""" Config().save() # Initialize configuration on module import config = Config()