# VIPR Plugins VIPR uses a modular plugin architecture to extend functionality. Plugins can add new handlers, hooks, filters, and complete workflows. ## Built-in Plugins These plugins are included with vipr-core and provide core functionality: - **[Inference Plugin](built-in/inference.md)** - 5-step ML inference workflow system - Domain-agnostic design for ML/AI inference - Handler system for pluggable components - Hook and filter system for extensibility - Configuration-driven pipeline - **[Normalizers Plugin](built-in/normalizers.md)** - Data normalization methods - MinMax, Z-Score, and Log normalization - Filter-based architecture for Step 3 of inference workflow - DataSet-aware transformations with error propagation support - **[API Plugin](built-in/api/)** - FastAPI endpoint generation and data collection - @api decorator for automatic endpoint generation from CLI controllers - DataCollector for structured UI data (tables, diagrams, images, logs) - UUID-based result storage with automatic file extraction - **[HuggingFace Plugin](built-in/huggingface.md)** - HuggingFace model management - Automatic model download from HuggingFace repositories - Support for multiple repositories and models - Configurable storage paths for weights and configs - CLI commands for manual model downloads - **[Discovery Plugin](built-in/discovery.md)** - Component registry and introspection - Decorator-based discovery for handlers, hooks, and filters - CLI/API endpoints for component listing and filtering - **[Performance Plugin](built-in/performance.md)** - Inference execution time tracking - Automatic timing metrics for workflow and steps - Persisted performance metadata in result output ## Domain-Specific Plugins Plugins that extend VIPR for specific scientific domains: - **[Reflectometry Plugin](external/reflectometry/index.md)** - Reflectometry analysis - Reflectorch model integration - RefNx physics-based refinement - Specialized data loaders and visualizations - **[GID Plugin](external/gid/index.md)** - GIWAXS/GID Bragg peak detection - TIFF and HDF5 loaders - ONNX inference via mlgidDETECT - Structured peak table + detection image outputs ## Plugin Management ### Installing Plugins External plugins can be installed via pip: ```bash # Example: Install the reflectometry plugin pip install git+https://codebase.helmholtz.cloud/vipr/vipr-reflectorch-plugin.git ``` Plugins are automatically discovered through Python entry points defined in `pyproject.toml`. VIPR loads plugins in two stages: 1. **Internal plugins** - Built-in plugins from vipr-core (loaded via Cement's plugin system) 2. **External plugins** - Installed packages (loaded via `discover_and_load_external_plugins()` during app setup) This two-stage loading ensures proper initialization order and allows external plugins to extend core functionality. ### Listing Installed Plugins ```bash # List all installed plugins vipr plugins list # Show discovery registry summary vipr discovery plugins ``` ### Plugin Configuration Plugins can be controlled via YAML files (e.g., `vipr-plugins.yaml` in your working directory): ```yaml plugin.my_plugin: enabled: true # Plugin-specific configuration ``` **Note:** The key `plugin.my_plugin` matches the entry point name defined in the plugin's `pyproject.toml`, not the package name. ## Developing Plugins ### Quick Start For a working example, check out [example-plugin](../../../example-plugin). ### Naming Convention **Recommended package naming:** `vipr_{plugin_name}` While not technically required, this convention: - **Enables automatic discovery filtering**: Discovery commands can filter by plugin name - **Creates consistency**: Entry point name matches package structure - **Simplifies component discovery**: Pattern matching works automatically **Example:** ```toml # pyproject.toml [project] name = "vipr-reflectometry" # PyPI package name (with dash) [project.entry-points."vipr.plugins"] reflectometry = "vipr_reflectometry:load" # Plugin name → package:load_function ``` **Entry Point Format:** `plugin_name = "package_name:load_function"` - `reflectometry` - Plugin identifier - `vipr_reflectometry` - Python package to import - `:load` - Function to call for plugin initialization (receives `app` parameter) **Understanding Entry Points:** Entry points are Python's standard plugin discovery mechanism. When a package is installed (via pip), its entry points are registered in the Python environment. This allows applications to automatically discover installed plugins without knowing their names or import paths. **How VIPR uses entry points:** 1. **Automatic Plugin Discovery**: ```python # In vipr-core/vipr/main.py entry_points = importlib.metadata.entry_points(group="vipr.plugins") # Finds all packages with [project.entry-points."vipr.plugins"] ``` VIPR queries Python for all packages that registered under the `"vipr.plugins"` group. 2. **Load Function Resolution and Execution**: The entry point specifies both the package and the load function: ```python # Entry point: reflectometry = "vipr_reflectometry:load" from vipr_reflectometry import load # Import the load function load(app) # Call it with VIPR app instance ``` The `:load` part tells Python which function to call for plugin initialization. 3. **Plugin Identifier**: The entry point name (`reflectometry`) is used in logs, CLI output, and configuration **Why this matters:** - **No manual registration needed**: Installing a plugin via pip automatically makes it available to VIPR - **Clean separation**: Each plugin is an independent Python package - **Standard Python mechanism**: Uses Python's built-in plugin architecture **Important Distinction:** - Entry point name **"reflectometry"** = Plugin identifier for loading/config - Package name **"vipr_reflectometry"** = Module path used for component filtering ```bash # Plugin filtering uses the PACKAGE name, not entry point name vipr discovery hooks --plugin reflectometry # → Matches module paths starting with: vipr_reflectometry.* ``` **Package structure:** ``` vipr_reflectometry/ # Root package (matches entry point) ├── __init__.py ├── reflectorch/ │ ├── model_loader/ │ └── ... └── shared/ ├── data_loader/ └── ... ``` This naming allows filtering components by plugin: ```bash vipr discovery hooks --plugin reflectometry # Matches vipr_reflectometry.* ``` See [Discovery Plugin documentation](built-in/discovery.md#plugin-filtering) for technical details on how plugin filtering works. ### Full Plugin Development Guide See **[Developing Plugins](developing.md)** for a step-by-step guide on creating your own plugins. ## Plugin Architecture VIPR plugins can: - Register **handlers** for component interfaces (data loaders, model loaders, etc.) - Register **hooks** for event-driven callbacks - Register **filters** for data transformation - Define **CLI controllers** for command-line interface - Provide **configuration schemas** for validation