""" Base classes for Sideline plugins. Provides Plugin base class and PluginMetadata for plugin registration. """ from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import ClassVar, Set @dataclass class PluginMetadata: """Plugin metadata with security and compatibility information.""" name: str version: str author: str description: str sideline_version: str # Compatible Sideline version (semver constraint) permissions: Set[str] = field(default_factory=set) # Required security permissions capabilities: Set[str] = field(default_factory=set) # Provided capabilities def validate(self) -> None: """Validate metadata fields.""" if not self.name: raise ValueError("Plugin name cannot be empty") if not self.version: raise ValueError("Plugin version cannot be empty") if not self.author: raise ValueError("Plugin author cannot be empty") if not self.sideline_version: raise ValueError("Plugin sideline_version cannot be empty") class StagePlugin(ABC): """Base class for Sideline stage plugins (distributable pipeline components). A StagePlugin represents a distributable unit that can contain one or more pipeline stages. Plugins provide metadata for security, compatibility, and versioning. Subclasses must implement: - validate_security(granted_permissions) -> bool """ metadata: ClassVar[PluginMetadata] @abstractmethod def validate_security(self, granted_permissions: Set[str]) -> bool: """Check if plugin has required permissions. Args: granted_permissions: Set of granted security permissions Returns: True if plugin has all required permissions """ pass @classmethod def get_metadata(cls) -> PluginMetadata: """Get plugin metadata.""" return cls.metadata @classmethod def get_required_permissions(cls) -> Set[str]: """Get required security permissions.""" return cls.metadata.permissions @classmethod def get_provided_capabilities(cls) -> Set[str]: """Get provided capabilities.""" return cls.metadata.capabilities # Backward compatibility alias Plugin = StagePlugin