napari Plugin Engine

0.2.1 · active · verified Fri Apr 17

napari-plugin-engine is a Python library providing a generic plugin management system, forked from the widely used pluggy project. It enables applications like napari to discover, load, and execute plugins by defining clear hook specifications and allowing multiple plugin implementations. As of version 0.2.1, it provides a stable API for extending applications. Its release cadence is tied to its development within the napari ecosystem.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define hook specifications, implement plugins with hook implementations, register them with a PluginManager, and then call the hooks. It showcases a 'firstresult' hook and a multi-result hook.

from napari_plugin_engine import PluginManager, HookspecMarker, HookimplMarker

# 1. Define unique markers for your project
project_name = "my_app_plugins"
hookspec = HookspecMarker(project_name)
hookimpl = HookimplMarker(project_name)

# 2. Define your hook specifications
class MyAppHooks:
    @hookspec(firstresult=True)
    def get_data_source(self, name: str) -> str:
        """Get data from a named source."""
        pass

    @hookspec
    def process_data(self, data: str) -> str:
        """Process input data and return modified data."""
        pass

# 3. Implement a plugin
class MyFileSystemPlugin:
    @hookimpl
    def get_data_source(self, name: str) -> str:
        if name == "filesystem":
            return "Data from filesystem"
        return None # Crucial for firstresult hooks to allow other plugins

    @hookimpl
    def process_data(self, data: str) -> str:
        return f"Processed: {data.upper()}"

class MyNetworkPlugin:
    @hookimpl
    def get_data_source(self, name: str) -> str:
        if name == "network":
            return "Data from network"
        return None

# 4. Initialize the PluginManager
pm = PluginManager(project_name)
# Add hook specifications. Optional prefix can differentiate similar hook names.
pm.add_hookspecs(MyAppHooks, specname_prefix=f'{project_name}_')

# 5. Register plugins
pm.register(MyFileSystemPlugin())
pm.register(MyNetworkPlugin())

# 6. Call hooks
print(f"--- Hook Calls ---")

data_fs = pm.hook.get_data_source(name="filesystem")
print(f"get_data_source('filesystem'): {data_fs}")

data_net = pm.hook.get_data_source(name="network")
print(f"get_data_source('network'): {data_net}")

processed_data_fs = pm.hook.process_data(data=data_fs)
print(f"process_data(data_fs): {processed_data_fs}")

processed_data_net = pm.hook.process_data(data=data_net)
print(f"process_data(data_net): {processed_data_net}")

view raw JSON →