from abc import ABC, abstractmethod from typing import List, Dict, Any, Optional class Plugin(ABC): @property @abstractmethod def name(self) -> str: pass @property @abstractmethod def version(self) -> str: pass @property @abstractmethod def description(self) -> str: pass @abstractmethod def load_rules(self) -> List[Dict[str, Any]]: pass def get_metadata(self) -> Dict[str, Any]: return { 'name': self.name, 'version': self.version, 'description': self.description, } class PluginRegistry: def __init__(self): self._plugins: Dict[str, Plugin] = {} self._rules_cache: List[Dict[str, Any]] = [] def register(self, plugin: Plugin) -> None: self._plugins[plugin.name] = plugin def unregister(self, name: str) -> None: if name in self._plugins: del self._plugins[name] self._rules_cache = [] def get_plugin(self, name: str) -> Optional[Plugin]: return self._plugins.get(name) def list_plugins(self) -> List[Dict[str, Any]]: return [p.get_metadata() for p in self._plugins.values()] def get_all_rules(self) -> List[Dict[str, Any]]: if not self._rules_cache: for plugin in self._plugins.values(): try: rules = plugin.load_rules() self._rules_cache.extend(rules) except Exception as e: print(f"Warning: Failed to load rules from plugin {plugin.name}: {e}") return self._rules_cache def clear(self) -> None: self._plugins.clear() self._rules_cache.clear()