Step 08: Config Hot Reload
Edit without restart.
Prerequisites
Same as Step 06 - copy the config file and add your API key:
cp default_workspace/config.example.yaml default_workspace/config.user.yaml
# Edit config.user.yaml to add your API keysWhat We Will Build
Key Components
- ConfigReloader - Watches workspace for config file changes using watchdog
- Config Merging - Runtime config overrides user config via deep merge
class Config(BaseModel):
"""Configuration with hot reload support."""
@classmethod
def _load_merged_configs(cls, workspace_dir: Path) -> dict[str, Any]:
config_data: dict[str, Any] = {}
user_config = workspace_dir / "config.user.yaml"
runtime_config = workspace_dir / "config.runtime.yaml"
with open(user_config) as f:
config_data = cls._deep_merge(config_data, yaml.safe_load(f) or {})
with open(runtime_config) as f:
config_data = cls._deep_merge(config_data, yaml.safe_load(f) or {})
return config_data
def reload(self) -> bool:
config_data = self._load_merged_configs(self.workspace)
new_config = Config.model_validate(config_data)
for field_name in Config.model_fields:
setattr(self, field_name, getattr(new_config, field_name))
return True
class ConfigHandler(FileSystemEventHandler):
"""Handles config file modification events."""
def __init__(self, config: Config):
self._config = config
def on_modified(self, event):
"""Reload config when config.user.yaml changes."""
if not event.is_directory and event.src_path.endswith("config.user.yaml"):
self._config.reload()Try it out
Actually nothing should be different from previous step...
Impatient reader can skip to Step 09: Channels.
What's Next
Step 09: Channels - multi-platform support for CLI, Telegram, and other interfaces.