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.1.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

apluggy-0.9.1-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: apluggy-0.9.1.tar.gz
  • Upload date:
  • Size: 11.8 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.1.tar.gz
Algorithm Hash digest
SHA256 c7a887cf3483a2a8fc8f40600aa3d02c0ef261506435064968b0769b742da722
MD5 7c6b5552b5a4e4a4fec09649afc6f437
BLAKE2b-256 dfac0d41f5bbb72ae9725e8b4fb79f20bc0182056a55a14cc1eb8e7129e4043d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: apluggy-0.9.1-py3-none-any.whl
  • Upload date:
  • Size: 7.2 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 445b1372ebc35f83d1bfb8199d80abada777d345e0e4e0a13ee960a39d7c1e77
MD5 f33f1e7291568405ed1e6d9a31d96dea
BLAKE2b-256 a3c3351bccf0dc81bcc41561826d07a512c3778c527a205ce86e2f0f07c82ce5

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