Skip to main content

A wrapper of "pluggy" to support asyncio and context managers

Project description

apluggy

PyPI - Version PyPI - Python Version Test Status Test Status codecov

A wrapper of pluggy to support asyncio and context managers.

This package provides a subclass of pluggy.PluginManager that

  • allows async functions, context managers, and async context managers to be hooks
  • and accepts plugin factories in addition to plugin instances for registration.

The package also provides asynccontextmanager decorator, which is a wrapper of contextlib.asynccontextmanager to preserve the signature of the decorated function. This decorator is implemented in the same way as contextmanager from the decorator package is implemented.


Table of Contents

Installation

pip install apluggy

How to use

Import packages

>>> import asyncio
>>> import apluggy as pluggy
>>> from apluggy import asynccontextmanager, contextmanager

(contextmanager is imported from the decorator package.)

Create hook specification and implementation decorators

>>> hookspec = pluggy.HookspecMarker('project')
>>> hookimpl = pluggy.HookimplMarker('project')

(These makers are imported from the pluggy package.)

Define hook specifications

In this example, we define three hooks: async function, context manager, and async context manager.

>>> class Spec:
...     """A hook specification namespace."""
...
...     @hookspec
...     async def afunc(self, arg1, arg2):
...         pass
...
...     @hookspec
...     @contextmanager
...     def context(self, arg1, arg2):
...         pass
...
...     @hookspec
...     @asynccontextmanager
...     async def acontext(self, arg1, arg2):
...         pass

Define plugins

We define two plugins as classes. Each plugin implements the three hooks defined above.

>>> class Plugin_1:
...     """A hook implementation namespace."""
...
...     @hookimpl
...     async def afunc(self, arg1, arg2):
...         print('inside Plugin_1.afunc()')
...         return arg1 + arg2
...
...     @hookimpl
...     @contextmanager
...     def context(self, arg1, arg2):
...         print('inside Plugin_1.context()')
...         yield arg1 + arg2
...
...     @hookimpl
...     @asynccontextmanager
...     async def acontext(self, arg1, arg2):
...         print('inside Plugin_1.acontext()')
...         yield arg1 + arg2

>>> class Plugin_2:
...     """A 2nd hook implementation namespace."""
...
...     @hookimpl
...     async def afunc(self, arg1, arg2):
...         print('inside Plugin_2.afunc()')
...         return arg1 - arg2
...
...     @hookimpl
...     @contextmanager
...     def context(self, arg1, arg2):
...         print('inside Plugin_2.context()')
...         yield arg1 - arg2
...
...     @hookimpl
...     @asynccontextmanager
...     async def acontext(self, arg1, arg2):
...         print('inside Plugin_2.acontext()')
...         yield arg1 - arg2

Create a plugin manager and register plugins

Plugins can be registered as instances or factories. In the following example, we register two plugins: Plugin_1 as an instance, and Plugin_2 as a factory.

>>> pm = pluggy.PluginManager('project')
>>> pm.add_hookspecs(Spec)
>>> _ = pm.register(Plugin_1())  # instantiation is optional.
>>> _ = pm.register(Plugin_2)  # callable is considered a plugin factory.

Call hooks

The following example shows how to call hooks.

>>> async def call_afunc():
...     results = await pm.ahook.afunc(arg1=1, arg2=2)  # ahook instead of hook
...     print(results)

>>> asyncio.run(call_afunc())
inside Plugin_2.afunc()
inside Plugin_1.afunc()
[-1, 3]
>>> with pm.with_.context(arg1=1, arg2=2) as y:  # with_ instead of hook
...     print(y)
inside Plugin_2.context()
inside Plugin_1.context()
[-1, 3]
>>> async def call_acontext():
...     async with pm.awith.acontext(arg1=1, arg2=2) as y:  # awith instead of hook
...         print(y)

>>> asyncio.run(call_acontext())
inside Plugin_2.acontext()
inside Plugin_1.acontext()
[-1, 3]

Links

License

  • apluggy is licensed under the MIT license.

Contact

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

apluggy-0.9.0.tar.gz (8.1 kB view details)

Uploaded Source

Built Distribution

apluggy-0.9.0-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file apluggy-0.9.0.tar.gz.

File metadata

  • Download URL: apluggy-0.9.0.tar.gz
  • Upload date:
  • Size: 8.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.2

File hashes

Hashes for apluggy-0.9.0.tar.gz
Algorithm Hash digest
SHA256 25786ce16c3754216e5b811071238656b0e9e478093729cfca3a7390bf7129ec
MD5 7646e49b36acda8bf7662a75b725188c
BLAKE2b-256 d787d0e159f4594f1eb6890a71600e6bb74ae17fa56ab8d885bfa9b1b432c5c2

See more details on using hashes here.

File details

Details for the file apluggy-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: apluggy-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.2

File hashes

Hashes for apluggy-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7c1f88b31a666b7d628da982d555fafd30fb510adcc9653079225cde3140ec79
MD5 f6dcf5164bfa2dc0b009b7b27966d0a4
BLAKE2b-256 759e3c7d54a2f3f1170244853cf3954861903f028e2f44f9c86950eb48850410

See more details on using hashes here.

Supported by

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