Plugin Discovery System
Relevant source files
The following files were used as context for generating this wiki page:
The Plugin Discovery System is a core component of the FLEXT Plugin framework designed to locate, identify, and validate plugin modules across different environments. It employs a strategy-based architecture to scan file systems and Python entry points, transforming raw file or package information into standardized Pydantic domain models for use by the plugin platform.
The system ensures that only valid, safe, and compatible plugins are loaded into the platform. By utilizing a common discovery protocol, it provides a unified interface for the Plugin Platform to scan directories or query installed packages, facilitating seamless extensibility for the FLEXT ecosystem.
Sources: src/flext_plugin/_utilities/discovery.py:12-20, src/flext_plugin/models.py:192-205
Architecture and Discovery Strategies
The discovery system is built around the FlextPluginDiscovery class, which implements a strategy pattern. It coordinates multiple specialized strategies to search for plugins in diverse locations.
Discovery Flow
The following diagram illustrates how the discovery system iterates through configured strategies to find and aggregate plugin data.
The system prioritizes unique plugin names; if multiple strategies find a plugin with the same name, the first one discovered is retained.
Sources: src/flext_plugin/_utilities/discovery.py:27-31, src/flext_plugin/_utilities/discovery.py:102-118
Components and Key Classes
| Component | Class/Function | Description |
|---|---|---|
| Discovery Manager | FlextPluginDiscovery | The central orchestrator that manages strategies and provides the public discovery API. |
| File Strategy | FileSystemStrategy | Scans local directories and files, looking for .py, .yaml, .json, or .yml files. |
| Entry Point Strategy | EntryPointStrategy | Queries Python distributions for the flext.plugins entry point group. |
| Utility Helper | discover_python_plugins_in_directory | A recursive utility for deep scanning directories for Python modules. |
| Validation | validate_plugin_file | Checks file size and scans for dangerous code patterns (e.g., exec, eval). |
Sources: src/flext_plugin/_utilities/discovery.py:22-25, src/flext_plugin/utilities.py:65-71, src/flext_plugin/utilities.py:164-180
Discovery Data Models
Data discovered by the system is encapsulated in immutable Pydantic value objects. This ensures type safety and semantic version validation before a plugin even reaches the loading phase.
DiscoveryData Model
The m.Plugin.DiscoveryData model represents the initial "found" state of a plugin.
| Field | Type | Description |
|---|---|---|
name | str | Unique identifier (must follow ^[a-zA-Z][a-zA-Z0-9_-]*$). |
version | str | Semantic version (X.Y.Z). Defaults to 1.0.0. |
path | Path | Physical location on the file system. |
discovery_type | Literal | file, directory, or entry_point. |
discovery_method | Literal | file_system or entry_points. |
metadata | JsonMapping | Extensible dictionary for additional context. |
Sources: src/flext_plugin/models.py:192-230, src/flext_plugin/utilities.py:63
File System Scanning Logic
The FileSystemStrategy handles the complexity of traversing directories while respecting safety constraints.
- Recursive Traversal: Uses
rglob("*")or recursive calls todiscover_python_plugins_in_directoryto find potential modules. - Extension Filtering: Only considers files with allowed extensions:
.py,.yaml,.yml, and.json. - Safety Checks: Before a file is marked as a discovered plugin, it is passed through
validate_plugin_file.- Size Limit: Files exceeding 100MB are rejected.
- Code Analysis: Python files are scanned for dangerous keywords:
exec(,eval(,__import__,subprocess, andos.system.
# Validation logic example from utilities.py
dangerous_patterns = ["exec(", "eval(", "__import__", "subprocess", "os.system"]
for pattern in dangerous_patterns:
if pattern in content:
return r[None].fail(f"Plugin contains potentially dangerous code: {pattern}")
Sources: src/flext_plugin/utilities.py:157-195, src/flext_plugin/_utilities/discovery.py:145-165
Entry Point Discovery
The EntryPointStrategy allows plugins to be distributed as standard Python packages (e.g., via PyPI or internal wheels). It uses importlib.metadata to select entry points registered under the flext.plugins group.
Integration with Plugin Platform
The FlextPluginPlatform service invokes the discovery system through its discover_plugins method. This method follows a railway-oriented flow to transition from raw discovery data to registered plugin entities.
- Requirement: Checks if a discovery protocol is configured.
- Execution: Calls
discovery.discover_plugins(paths). - Validation: Maps discovered data to
FlextPluginPlatform.Pluginentities and validates business rules (e.g., name non-empty, valid semantic version). - Registration: Persists the validated plugins into the internal registry.
Sources: src/flext_plugin/_utilities/plugin_platform.py:270-298, src/flext_plugin/models.py:148-183
Summary
The Plugin Discovery System provides a robust and secure mechanism for identifying FLEXT plugins. By abstracting discovery into strategies and enforcing strict validation via Pydantic models and security scanners, it ensures the platform remains extensible without compromising stability or safety. The system's ability to handle both local file development and packaged entry points supports both rapid prototyping and production-grade deployments.