Protocols and Contracts
Relevant source files
The following files were used as context for generating this wiki page:
Protocols and contracts in the FLEXT Plugin system establish a unified, type-safe interface for plugin management, lifecycle control, and execution. By leveraging Python's typing.Protocol and runtime checkable classes, the system ensures that all components—ranging from loaders and registries to the platform facade itself—adhere to a strict structural contract.
This architecture promotes Dependency Inversion (DIP) and Interface Segregation (ISP), allowing the platform to interact with plugin implementations through abstract definitions rather than concrete classes. This decoupling is essential for supporting diverse plugin types like Singer Taps, Services, and Utilities while maintaining a consistent operational flow.
Sources: src/flext_plugin/protocols.py:1-41, AGENTS.md:73-77
Architecture Overview
The protocol system is organized into a hierarchical structure under the FlextPluginProtocols class (aliased as p). This class extends the foundation protocols from flext_cli and adds a dedicated Plugin namespace for domain-specific operations.
Protocol Hierarchy
The following diagram illustrates the relationship between the base protocol facade and the specific plugin domains.
The hierarchy ensures that all plugin-related operations are logically grouped and accessible via the p.Plugin path.
Sources: src/flext_plugin/protocols.py:27-41, src/flext_plugin/protocols.py:44-50
Core Platform Contracts
The PlatformService protocol represents the public facade of the plugin platform. It defines the primary methods used by applications to interact with the plugin ecosystem.
PlatformService Operations
| Method | Purpose | Returns |
|---|---|---|
discover_plugins(paths) | Scans filesystem for available plugins | p.Result[Sequence[Plugin]] |
register_plugin(plugin) | Adds a plugin instance to the platform registry | p.Result[bool] |
execute_plugin(name, context) | Runs a specific plugin with provided data | p.Result[PluginExecution] |
start_hot_reload(paths) | Begins monitoring paths for live code changes | p.Result[bool] |
list_plugins() | Retrieves all registered plugins | Sequence[Plugin] |
Sources: src/flext_plugin/protocols.py:53-112
Lifecycle and Registry Contracts
Plugins follow a strict lifecycle managed through the PluginLifecycle protocol and stored via the PluginRegistry.
Plugin Lifecycle Flow
The lifecycle transition involves initialization, activation, execution, and eventual cleanup.
Key Lifecycle Methods:
initialize_plugin: Prepares resources and validates settings.activate_plugin: Transitions a plugin to a state where it can accept execution requests.deactivate_plugin: Safely halts operations.destroy_plugin: Final resource cleanup.
Sources: src/flext_plugin/protocols.py:284-315, examples/basic-plugin.md:93-134
Registry Operations
The PluginRegistry manages the persistence and lookup of plugin entities. It supports fetching by name, checking registration status, and listing all known plugins.
Sources: src/flext_plugin/protocols.py:155-197
Execution and Processing Contracts
Execution is handled by the PluginExecution protocol, which defines how data is passed to and from a plugin.
Data Flow Sequence
This diagram shows the interaction between the Platform, Registry, and the Plugin during an execution call.
Infrastructure Protocols
To support the core services, several infrastructure-level protocols are defined for discovery, configuration, and security.
Discovery and Configuration
PluginDiscovery: Defines strategies for finding plugins on disk and validating theirm.Plugin.DiscoveryData.PluginConfiguration: Manages the loading, saving, and validation of plugin settings against schemas.PluginHotReload: Provides the interface for watching file changes and reloading plugins without restarting the host process.
Sources: src/flext_plugin/protocols.py:133-153, src/flext_plugin/protocols.py:231-252, src/flext_plugin/protocols.py:258-282
Security and Validation
The PluginSecurity protocol ensures that plugins adhere to safety constraints before they are permitted to run.
| Feature | Protocol Method | Description |
|---|---|---|
| Permission Check | check_permissions | Validates if a plugin can access specific system resources. |
| Vulnerability Scan | scan_plugin_security | Performs a static or dynamic scan of the plugin package. |
| Compliance | validate_plugin_security | Ensures the plugin entity matches the security policy. |
Sources: src/flext_plugin/protocols.py:231-256
Domain Entity Contracts
Contracts extend to the domain entities themselves, which must record metrics and enforce business rules.
record_execution(time, success): Entities track their own performance metrics, including total execution time and success/failure counts.record_error(message): Maintains a log of the last error encountered by the entity.validate_business_rules(): A self-validation hook to ensure the entity state is consistent with domain requirements.
Sources: tests/unit/test_domain_entities.py:59-95
Conclusion
The "Protocols and Contracts" system provides the structural integrity required for the FLEXT Plugin platform. By enforcing clear boundaries between discovery, registry, and execution, the system ensures that any implementation—whether it be a simple utility or a complex Docker-integrated service—is interoperable and maintainable. This design fulfills the Single Responsibility Principle (SRP) and allows for robust testing through the use of shared protocol namespaces in both production and test suites.
Sources: src/flext_plugin/protocols.py:382-384, tests/protocols.py:18-32