# Configuration Management API Documentation ## Overview The Configuration Management system provides centralized, type-safe configuration handling for all Trixy components across different deployment modes (server, client, standalone). **Location**: `./trixy_core/config/` ## Core Components ### ConfigManager Main configuration management class with hot-reloading and validation. ### Configuration Classes - `ServerConfig`: Server-specific configuration - `ClientConfig`: Client/satellite configuration - `StandaloneConfig`: Standalone mode configuration ### ConfigValidator Validates configuration values and dependencies. ## API Reference ### ConfigManager Class #### Initialization ```python from trixy_core.config import ConfigManager, DeploymentMode config_manager = ConfigManager( mode=DeploymentMode.SERVER, config_file="config/server_config.json", debug_mode=False ) ``` #### Core Methods ##### `load_config()` Loads and validates configuration from file. ```python config = config_manager.load_config() print(f"Command port: {config.network.command_port}") ``` ##### `get_config()` Returns current loaded configuration. ```python current_config = config_manager.get_config() ``` ##### `save_config(config=None)` Saves configuration to file with backup. ```python # Modify and save config = config_manager.get_config() config.network.command_port = 2105 config_manager.save_config(config) ``` ##### `reload_config()` Reloads configuration from file. ```python config_manager.reload_config() ``` ##### `override_config(overrides: Dict)` Apply runtime configuration overrides. ```python config_manager.override_config({ "network": {"command_port": 2105}, "max_satellites": 100, "debug": {"enable_verbose_logging": True} }) ``` ##### `enable_hot_reload(interval: float = 1.0)` Enables automatic configuration reloading. ```python # Check for config changes every 2 seconds config_manager.enable_hot_reload(interval=2.0) # Register callback for config changes def on_config_changed(old_config, new_config): print("Configuration updated!") config_manager.enable_hot_reload(callback=on_config_changed) ``` ##### `disable_hot_reload()` Disables automatic configuration reloading. ```python config_manager.disable_hot_reload() ``` ##### `validate_config(config=None)` Validates configuration against schema. ```python is_valid, errors = config_manager.validate_config() if not is_valid: for error in errors: print(f"Config error: {error}") ``` ##### `backup_config()` Creates manual backup of current configuration. ```python backup_path = config_manager.backup_config() print(f"Config backed up to: {backup_path}") ``` ##### `restore_backup(backup_file: str)` Restores configuration from backup. ```python config_manager.restore_backup("config/backups/server_config_20241201_120000.json") ``` ### Configuration Classes #### ServerConfig ```python @dataclass class ServerConfig: # Network configuration network: NetworkConfig # Satellite management max_satellites: int = 50 registration_timeout: int = 60 # Plugin settings plugins: PluginConfig # Audio processing audio: AudioConfig # ML models models: ModelConfig # Logging logging: LoggingConfig # Security security: SecurityConfig ``` #### ClientConfig ```python @dataclass class ClientConfig: # Network configuration network: ClientNetworkConfig # Server connection server: ServerConnectionConfig # Audio capture audio: ClientAudioConfig # ML models (wakeword, voice recognition) models: ClientModelConfig # Hardware settings hardware: HardwareConfig # Logging logging: LoggingConfig ``` #### StandaloneConfig ```python @dataclass class StandaloneConfig: # Combines server and client features network: NetworkConfig audio: AudioConfig models: ModelConfig plugins: PluginConfig logging: LoggingConfig # Standalone-specific sync: SyncConfig # Server synchronization settings ``` ### Configuration Sections #### NetworkConfig ```python @dataclass class NetworkConfig: command_port: int = 2101 audio_input_port: int = 2102 audio_output_port: int = 2103 music_output_port: int = 2104 bind_address: str = "0.0.0.0" max_connections: int = 100 connection_timeout: int = 30 keepalive_interval: int = 60 ``` #### AudioConfig ```python @dataclass class AudioConfig: sample_rate: int = 16000 channels: int = 1 bit_depth: int = 16 chunk_size: int = 1024 input_device: Optional[str] = None output_device: Optional[str] = None noise_reduction: bool = True auto_gain_control: bool = True ``` #### ModelConfig ```python @dataclass class ModelConfig: wakeword_model: str = "models/wakeword/default.pth" voice_recognition_model: str = "models/voice_recognition/default.pth" model_password: str = "" use_gpu: bool = False model_cache_size: int = 2 inference_threads: int = 1 ``` ## Environment Variables The configuration system supports environment variable overrides with the `TRIXY_` prefix: ```bash # Network settings export TRIXY_NETWORK_COMMAND_PORT=2201 export TRIXY_NETWORK_BIND_ADDRESS="127.0.0.1" # Model settings export TRIXY_MODELS_USE_GPU=true export TRIXY_MODELS_MODEL_PASSWORD="secret123" # Debug settings export TRIXY_DEBUG_ENABLE_VERBOSE_LOGGING=true ``` ## Configuration File Management ### Default Configuration Files #### server_config.json ```json { "network": { "command_port": 2101, "audio_input_port": 2102, "audio_output_port": 2103, "music_output_port": 2104, "bind_address": "0.0.0.0", "max_connections": 50 }, "max_satellites": 50, "registration_timeout": 60, "plugins": { "directory": "plugins", "auto_load": true, "hot_reload": true }, "audio": { "sample_rate": 16000, "channels": 1, "bit_depth": 16 }, "models": { "wakeword_model": "models/wakeword/default.pth", "voice_recognition_model": "models/voice_recognition/default.pth" } } ``` #### client_config.json ```json { "network": { "local_ports": { "audio_input": 3102, "audio_output": 3103, "music_output": 3104 } }, "server": { "host": "localhost", "port": 2101, "reconnect_interval": 5, "max_reconnect_attempts": -1 }, "audio": { "sample_rate": 16000, "channels": 1, "input_device": null, "noise_reduction": true }, "models": { "wakeword_model": "models/wakeword/client.pth", "voice_recognition_model": "models/voice_recognition/client.pth", "use_gpu": false } } ``` ## Advanced Usage ### Configuration Override Priority 1. **Runtime overrides** (highest priority) 2. **Environment variables** 3. **Command line arguments** 4. **Configuration files** (lowest priority) ### Hot-Reload with Callbacks ```python class ConfigurableComponent: def __init__(self, config_manager): self.config_manager = config_manager self.config_manager.enable_hot_reload(callback=self.on_config_changed) def on_config_changed(self, old_config, new_config): # Handle configuration changes if old_config.network.command_port != new_config.network.command_port: self.restart_network_listener(new_config.network.command_port) ``` ### Configuration Validation ```python from trixy_core.config import ConfigValidator validator = ConfigValidator() # Add custom validation rules @validator.add_rule("network.command_port") def validate_port(value): if not (1024 <= value <= 65535): return False, "Port must be between 1024 and 65535" return True, None # Validate configuration is_valid, errors = validator.validate(config) ``` ### Configuration Migration ```python def migrate_config_v1_to_v2(config_dict): """Migrate configuration from version 1 to 2""" if config_dict.get("version", 1) == 1: # Rename old settings if "server_port" in config_dict: config_dict["network"] = {"command_port": config_dict.pop("server_port")} config_dict["version"] = 2 return config_dict config_manager.add_migration(migrate_config_v1_to_v2) ``` ## Integration Examples ### Plugin Configuration Access ```python from trixy_core.plugins import TrixyPlugin class MyPlugin(TrixyPlugin): def initialize(self): # Access global config config = self.application.get_config_manager().get_config() # Use configuration values if config.debug.enable_plugin_debugging: self.enable_debug_mode() # Watch for config changes self.application.get_config_manager().enable_hot_reload( callback=self.on_config_changed ) def on_config_changed(self, old_config, new_config): # React to configuration changes if old_config.audio.sample_rate != new_config.audio.sample_rate: self.restart_audio_processing() ``` ### Component Configuration ```python class NetworkManager: def __init__(self, application): self.application = application self.config_manager = application.get_config_manager() self.current_config = self.config_manager.get_config() # Enable hot-reload for network settings self.config_manager.enable_hot_reload( callback=self.on_network_config_changed ) def on_network_config_changed(self, old_config, new_config): # Check if network settings changed if old_config.network != new_config.network: self.restart_network_services(new_config.network) ``` ## Error Handling ### Configuration Errors ```python from trixy_core.config import ( ConfigurationError, ConfigurationValidationError, ConfigurationLoadError, ConfigurationSaveError ) try: config = config_manager.load_config() except ConfigurationLoadError as e: print(f"Failed to load config: {e}") # Use default configuration config = config_manager.get_default_config() except ConfigurationValidationError as e: print(f"Invalid configuration: {e}") # Show validation errors to user for error in e.validation_errors: print(f" - {error}") ``` ### File System Errors ```python try: config_manager.save_config() except ConfigurationSaveError as e: print(f"Failed to save config: {e}") # Try saving to alternate location backup_path = config_manager.backup_config() print(f"Configuration saved to backup: {backup_path}") ``` ## Best Practices ### 1. Configuration Structure ```python # Good: Logical grouping { "network": {"command_port": 2101, "bind_address": "0.0.0.0"}, "audio": {"sample_rate": 16000, "channels": 1}, "models": {"wakeword_model": "path/to/model.pth"} } # Avoid: Flat structure { "command_port": 2101, "bind_address": "0.0.0.0", "sample_rate": 16000 } ``` ### 2. Environment Variable Usage ```python # Use environment variables for sensitive data { "api_keys": { "openai_key": "${TRIXY_OPENAI_API_KEY}", "google_key": "${TRIXY_GOOGLE_API_KEY}" } } ``` ### 3. Configuration Validation ```python class MyComponent: def __init__(self, config_manager): self.config = config_manager.get_config() # Validate required configuration if not self.config.network.command_port: raise ConfigurationError("Command port not configured") if not (1024 <= self.config.network.command_port <= 65535): raise ConfigurationError("Invalid command port range") ``` ### 4. Hot-Reload Handling ```python def on_config_changed(self, old_config, new_config): # Only react to relevant changes if old_config.audio != new_config.audio: self.restart_audio_system() # Avoid unnecessary restarts if old_config.logging != new_config.logging: self.update_log_level(new_config.logging.level) # Don't restart entire component ``` ## Performance Considerations - **File Watching**: Hot-reload uses efficient file system watching - **Validation**: Validation is cached and only run when config changes - **Memory Usage**: Configurations are loaded once and cached - **Thread Safety**: All operations are thread-safe ## Security Considerations - **Sensitive Data**: Use environment variables for passwords/keys - **File Permissions**: Configuration files should have restricted permissions - **Backup Security**: Backups inherit security settings from original files - **Validation**: Always validate configuration before use