Skip to main content

A small, dependency-free plugin framework: hook specs, entry-point discovery, and sync/async dispatch

Project description

pluginkit

A small, dependency-free plugin framework for Python: declare hook specifications, let plugins implement them, and discover plugins via entry points. Supports sync and async dispatch, hook ordering, wrappers, pipeline (fold) dispatch, and historic hooks - in a few readable files.

The library is three files under src/pluginkit/ (markers.py, manager.py, exceptions.py), has zero runtime dependencies (standard library only), and ships a py.typed marker.

from pluginkit import HookspecMarker, HookimplMarker, PluginManager

hookspec = HookspecMarker("greeter")
hookimpl = HookimplMarker("greeter")


class Specs:
    @staticmethod
    @hookspec
    def greeting(name: str) -> str:
        """Return a greeting for the given name."""


class Casual:
    @hookimpl
    def greeting(self, name: str) -> str:
        return f"hey {name}!"


pm = PluginManager("greeter")
pm.add_hookspecs(Specs)
pm.register(Casual(), name="casual")
print(pm.hook.greeting(name="Ada"))   # ['hey Ada!']

What it supports

  • collecting, firstresult, and pipeline (fold/middleware) hooks;
  • call ordering with tryfirst / trylast, plus optionalhook and specname;
  • generator wrappers that decorate results and observe exceptions safely;
  • historic hooks replayed to plugins registered later;
  • async dispatch via AsyncPluginManager (awaits coroutine impls);
  • plugin lifecycle: register, unregister (by name or object), set_blocked, lookup, call_extra;
  • registration-time validation and call-time argument checking (failures are loud);
  • external plugin discovery via the stdlib importlib.metadata (no setuptools);
  • thread-safe registry mutation.

Layout

src/pluginkit/          the library (pure - no demo code)
tour/                   pluginkit-tour: a guided CLI walkthrough, one step per mechanism
examples/               standalone single-file recipes, run directly
plugins/smoothie-extra/ an external plugin distribution (its own uv project)
docs/                   mkdocs + Material documentation
tests/                  library, tour, and example tests

The tour and examples are two complementary ways to learn it: the tour is a guided walkthrough on one host (pluginkit-tour run all), while the examples are independent, real-world recipes you run on their own.

Use it

make install              # uv sync (library + tour + external plugin)
make test                 # pytest (framework, tour, examples)
make lint                 # ruff + mypy + pyright
make docs-serve           # serve the docs at http://127.0.0.1:8000
make docs-build           # build the docs (strict)

Two ways to learn it

The tour (tour/) walks through one mechanism at a time on a single host:

make run                  # run every step
make run DEMO=wrapper      # run one
uv run pluginkit-tour list

The examples apply the library to different realistic domains - see examples/:

uv run python examples/report_builder.py
uv run python examples/notification_router.py
uv run python examples/validation_rules.py
uv run python examples/app_lifecycle.py

Documentation

Full docs (concepts, one page per mechanism, production/hardening notes, and a generated API reference) live under docs/. Serve them with make docs-serve.

Is it production ready?

It is solid - exception-safe wrappers, fail-fast validation, lifecycle management, resilient discovery, thread-safe mutation, strict typing, and a test suite. But for anything you ship, prefer pluggy itself: it is maintained and battle tested by pytest, tox, and datasette. See docs/production/vs-pluggy.md for the honest inventory of what differs.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pluginkit-0.1.0.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pluginkit-0.1.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file pluginkit-0.1.0.tar.gz.

File metadata

  • Download URL: pluginkit-0.1.0.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pluginkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 76db3dd0b345dd4114ba7ac5440a8c1f668f4d78156e22b60973cceddf87812d
MD5 9cbbc82cec24f0676f68c4e9ca5d2cd3
BLAKE2b-256 d8d634b5bf554a9276cf398ebd2fb134b1e66fa4a8294a8d8a3d0b8944610188

See more details on using hashes here.

Provenance

The following attestation bundles were made for pluginkit-0.1.0.tar.gz:

Publisher: release.yml on winterop-com/pluginkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pluginkit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pluginkit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pluginkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 88a2a70957082c3584d3b0dd3eb5b24d8cf5e4436da55a96f85f12ec987ea534
MD5 32c93bdd927f2bff38718be06cbd55d5
BLAKE2b-256 cc1e47acc5f8fd2b6dede2e3999052c3756ae8c8a6a19e393fc361047123e1fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pluginkit-0.1.0-py3-none-any.whl:

Publisher: release.yml on winterop-com/pluginkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page