import asyncio import logging import os import yaml logger = logging.getLogger(__name__) CONFIG_PATH = os.environ.get("CONFIG_PATH", os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.yaml")) _config = {} _mtime = 0.0 _callbacks = [] def _load(): global _config, _mtime with open(CONFIG_PATH, "r") as f: _config = yaml.safe_load(f) _mtime = os.path.getmtime(CONFIG_PATH) logger.info("Config loaded from %s", CONFIG_PATH) def _reload_if_changed(): global _mtime try: current_mtime = os.path.getmtime(CONFIG_PATH) if current_mtime != _mtime: old_config = _config.copy() _load() logger.info("Config reloaded (changed)") for cb in _callbacks: try: cb(old_config, _config) except Exception: logger.exception("Error in config reload callback") except Exception: logger.exception("Error checking config file") def on_reload(callback): _callbacks.append(callback) async def watch(interval: float = 2.0): while True: await asyncio.sleep(interval) _reload_if_changed() def get(key: str, default=None): keys = key.split(".") val = _config for k in keys: if isinstance(val, dict): val = val.get(k) else: return default if val is None: return default return val # Load on import _load()