Spaces:
Running
Running
Download src/core/plugins/manager.py from Leon4gr45/brain: direct link, hf CLI and curl.
- Browser
- Download file 4.43 kB
-
https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/src/core/plugins/manager.py
- Command line
-
hf download hf://spaces/Leon4gr45/brain/src/core/plugins/manager.py
-
curl -L -o manager.py https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/src/core/plugins/manager.py
4.43 kB
| from __future__ import annotations | |
| import logging | |
| import shutil | |
| from pathlib import Path | |
| from typing import Optional | |
| from src.core.plugins.catalog import PluginManifestCatalog | |
| from src.core.plugins.manifest import MANIFEST_FILENAME, PluginManifest, parse_manifest | |
| from src.core.plugins.registry import PluginMeta, PluginRegistryClient | |
| logger = logging.getLogger("brainapi.plugins.manager") | |
| class PluginManager: | |
| def __init__( | |
| self, | |
| plugins_dir: Path, | |
| registry_url: Optional[str] = None, | |
| publisher_id: Optional[str] = None, | |
| publisher_api_key: Optional[str] = None, | |
| ): | |
| self.plugins_dir = plugins_dir | |
| self.registry_url = registry_url | |
| self._manifest_catalog = PluginManifestCatalog( | |
| plugins_dir=plugins_dir, | |
| logger_override=logger, | |
| ) | |
| self._registry: Optional[PluginRegistryClient] = None | |
| if registry_url: | |
| self._registry = PluginRegistryClient( | |
| registry_url=registry_url, | |
| publisher_id=publisher_id, | |
| api_key=publisher_api_key, | |
| ) | |
| def _ensure_registry(self) -> PluginRegistryClient: | |
| if self._registry is None: | |
| raise RuntimeError( | |
| "No plugin registry configured. " | |
| "Set PLUGIN_REGISTRY_URL environment variable or pass registry_url." | |
| ) | |
| return self._registry | |
| def install(self, name: str, version: str = "latest") -> PluginManifest: | |
| existing_dir = self.plugins_dir / name | |
| existing_manifest = existing_dir / MANIFEST_FILENAME | |
| if existing_manifest.exists(): | |
| try: | |
| current = parse_manifest(existing_manifest) | |
| if version == "latest" or current.version == version: | |
| logger.info("Plugin '%s' v%s already installed, skipping", name, current.version) | |
| return current | |
| except Exception: | |
| pass | |
| registry = self._ensure_registry() | |
| plugin_dir = registry.download(name, version=version, target_dir=self.plugins_dir) | |
| manifest_path = plugin_dir / MANIFEST_FILENAME | |
| if not manifest_path.exists(): | |
| raise FileNotFoundError( | |
| f"Downloaded plugin '{name}' does not contain a {MANIFEST_FILENAME}" | |
| ) | |
| manifest = parse_manifest(manifest_path) | |
| errors = manifest.validate() | |
| if errors: | |
| shutil.rmtree(plugin_dir, ignore_errors=True) | |
| raise ValueError( | |
| f"Plugin '{name}' manifest validation failed: {'; '.join(errors)}" | |
| ) | |
| logger.info("Installed plugin '%s' v%s to '%s'", manifest.name, manifest.version, plugin_dir) | |
| return manifest | |
| def uninstall(self, name: str) -> bool: | |
| plugin_dir = self.plugins_dir / name | |
| if not plugin_dir.exists(): | |
| logger.warning("Plugin '%s' not found in '%s'", name, self.plugins_dir) | |
| return False | |
| shutil.rmtree(plugin_dir) | |
| logger.info("Uninstalled plugin '%s'", name) | |
| return True | |
| def list_installed(self) -> list[PluginManifest]: | |
| return self._manifest_catalog.discover(validate=False) | |
| def list_available(self) -> list[PluginMeta]: | |
| registry = self._ensure_registry() | |
| return registry.list_plugins() | |
| def get_info(self, name: str) -> PluginMeta: | |
| registry = self._ensure_registry() | |
| return registry.get_plugin_info(name) | |
| def update(self, name: str) -> PluginManifest: | |
| return self.install(name, version="latest") | |
| def publish(self, archive_path: Path, name: Optional[str] = None, force: bool = False) -> dict: | |
| registry = self._ensure_registry() | |
| return registry.publish(archive_path, name=name, force=force) | |
| def delete_remote(self, name: str, version: Optional[str] = None) -> dict: | |
| registry = self._ensure_registry() | |
| return registry.delete(name, version=version) | |
| def register_publisher(self, publisher_id: Optional[str] = None) -> dict: | |
| if not self.registry_url: | |
| raise RuntimeError( | |
| "No plugin registry configured. " | |
| "Set PLUGIN_REGISTRY_URL environment variable or pass registry_url." | |
| ) | |
| client = PluginRegistryClient(registry_url=self.registry_url) | |
| return client.register_publisher(publisher_id=publisher_id) | |