Registry / serialization / napari-plugin-engine

napari-plugin-engine

JSON →
library0.2.1pypypi✓ verified 85d ago

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.

pip install napari-plugin-engine
INSTALL
IMPORT
SIG · NAPARI-PLUGIN-ENGI
N
napari-plugin-engine
serializationpythonv0.2.1
Install
1.5s avg
Import
122ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
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
musl
py 3.103.910 runs
installs and imports cleanly · install 0.0s · import 0.128s · 18MB
glibc
py 3.103.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}")
Debug
Known issues
gotchaEach PluginManager instance requires a unique `project_name` string during initialization and for its `HookspecMarker` and `HookimplMarker`. Reusing project names across different logical plugin systems or in different parts of an application can lead to unexpected plugin interactions or discovery issues.
fix
Ensure `PluginManager('myproject')`, `HookspecMarker('myproject')`, and `HookimplMarker('myproject')` use a globally unique string for 'myproject' within your application context.
affects: All versions
gotchaHook specification (hookspec) and hook implementation (hookimpl) signatures must match, or the hookimpl must be compatible (e.g., accepting `**kwargs` for extra arguments). Mismatches will result in `TypeError` when the hook is called, or the hookimpl might not be recognized.
fix
Always ensure the arguments of a `@hookimpl` function precisely match (or are a compatible superset of) its corresponding `@hookspec` function. Pay close attention to default values and `*args`/`**kwargs`.
affects: All versions
gotchaWhen using `firstresult=True` on a hookspec, only the first hook implementation that returns a non-`None` value will have its result used. If all registered hookimpls return `None`, the hook call itself will return `None` (or the default set in the hookspec).
fix
Plugin implementations for `firstresult` hooks should explicitly return `None` if they cannot handle the specific request, allowing other plugins a chance. Otherwise, return the actual result.
affects: All versions
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.
fix
Ensure 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.
fix
Review 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.
fix
Install 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.

Agent activity
16 hits · last 30 days
node
12
Amazon
1
OpenAI (training)
1
Resources
napari-plugin-engine — pip install napari-plugin-engine · libregistry