Install & Compatibility
Where this runs
tested against v0.2.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.128s · 18MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 1.5s · import 0.115s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
PluginManager
✓ from napari_plugin_engine import PluginManager
HookspecMarker
✓ from napari_plugin_engine import HookspecMarker
HookimplMarker
✓ from napari_plugin_engine import HookimplMarker
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}")
Errors
Common errors & fixes
AttributeError: 'HookRelay' object has no attribute 'my_hook'
The PluginManager's hook relay cannot find the specified hook. This usually means the hook specification (with `@hookspec`) was not added to the PluginManager, or the `specname_prefix` did not match.
fixEnsure you have called `pm.add_hookspecs(MyHooksClass)` with the class containing your `@hookspec` definitions. Also, check that the `specname_prefix` used when adding hookspecs matches any prefix you might be expecting for the hook name.
TypeError: my_hook() missing 1 required positional argument: 'arg1'
A hook implementation's signature does not match the hook specification or the arguments provided during the hook call.
fixReview both the `@hookspec` definition and the `@hookimpl` definition for `my_hook`. Ensure that the `hookimpl` accepts all arguments defined in the `hookspec` and that all required arguments are passed when calling `pm.hook.my_hook(...)`.
ModuleNotFoundError: No module named 'napari_plugin_engine'
The `napari-plugin-engine` package is not installed in your current Python environment.
fixInstall the package using pip: `pip install napari-plugin-engine`.
Upgrade
Version history
0.2.1latest on PyPI · released Feb 10, 2026
Audit
Dependencies
No dependency data recorded yet.