Internal Structure
Every plugin must implement the sct.plugins.protocols.InputProductPluginProtocol.
A minimal implementation looks like the following:
from sct.io.extended_protocols import (
ALECorrectionFunctionType,
SCTInputProduct
)
from sct.plugins.protocols import InputProductPluginProtocol
from sct_<product_name>_reader import __version__ # (1)!
class <ProductName>Plugin(InputProductPluginProtocol): # (2)!
version = __version__
@classmethod
def get_manager(cls) -> type[SCTInputProduct]:
"""Return the class of the input product manager."""
@classmethod
def get_detector(cls) -> Callable[[str | Path], bool]:
"""Return a function that returns True if the given product
can be read by this plugin."""
@classmethod
def get_ale_corrector(cls) -> ALECorrectionFunctionType:
"""Return the function that corrects the ALE errors in
the product, if any."""
- Substitue
<product_name>with
the name of the product. - Substitute
<ProductName>with
the name of the product.
The plugin is responsible for:
- Determining whether a product belongs to the supported format
- Creating a reader object capable of exposing the required data
- Adapting the native product structure to the format expected by SCT analyses
The version attribute should contain the version of the plugin package. This is typically imported from the package init.
Keeping track of the plugin version helps SCT:
- ensure compatibility between plugins and the core framework
- improve reproducibility of analysis results
- assist debugging and reporting
Input Product Manager
The class method sct.plugins.protocols.InputProductPluginProtocol.get_manager must return a class that must be compliant to
the sct.io.extended_protocols.SCTInputProduct protocol.
The returned class is the input product manager, which is responsible for:
- opening the product files
- parsing the native product structure
- exposing the product data through the standard SCT data model
The manager therefore acts as an adapter layer between the product format and the analysis modules.
Conceptually:
flowchart TD
A["Native Product Format"]
B["Input Product Manager (SCTInputProduct)"]
C["SCT Analyses"]
A -->|plugin reader| B
B -->|standardized interface| C
Internal Data Model
All analyses in SCT expect their inputs to follow a common internal data model. This model is defined through the
class sct.io.extended_protocols.SCTInputProduct protocol and related protocol definitions.
The manager returned by class method sct.plugins.protocols.InputProductPluginProtocol.get_manager must therefore implement
all the attributes and methods required by these protocols.
This ensures that:
- analyses can run independently of the original product format
- different satellite products can be processed using the same analysis code
- new product formats can be supported simply by providing a compatible manager
In practice, the input product manager translates the native product data into the structures required by SCT analyses.
Registering the Plugin
To allow SCT to discover the plugin automatically, the plugin class must be registered through a Python entry point.
In your pyproject.toml file:
[project.entry-points."sct.input_products"]
myproduct = "sct_<product_name>_reader.interface:<ProductName>Plugin"
Where:
sct.input_productsis the entry point namespace used by SCT.<product_name>is the plugin identifier.sct_<product_name>_reader.interface:<ProductName>Pluginis the import path to the plugin class.
When SCT starts, the plugin loader will scan this namespace using stevedore and automatically import all available
plugins.
Example
💡 This registers the class EOS04ProductPlugin as a plugin for SCT.
Plugin Discovery
At runtime, SCT uses OpenStack's stevedore to discover and load plugins:
from stevedore import ExtensionManager
manager = ExtensionManager(
namespace="sct.input_products",
invoke_on_load=True,
on_load_failure_callback=_on_load_failure
)
- Namespace must match the entry point group defined in each plugin’s
pyproject.toml. - invoke_on_load=True imports the plugin immediately.
- Any plugin that fails to load triggers the failure callback.
All installed packages exposing entry points in the sct.input_products namespace are loaded automatically.
No manual registration is required. After installation, SCT will automatically detect the plugin during startup.
Best Practices
When developing a plugin:
- Keep product-specific logic isolated inside the plugin package.
- Avoid introducing dependencies into the core SCT package.
- Provide unit tests using representative product samples.
- Clearly document the supported product version and sensor.
Distribution
Plugins can be distributed independently from SCT via PyPI or internal/local package repositories.
This allows users to install only the plugins required for the specific products they want to analyze.