Skip to content

asyncio Context Manager with Explicit Interface

License

Notifications You must be signed in to change notification settings

Bibo-Joshi/aiorem

Repository files navigation

aiorem

PyPi Package Version Supported Python versions Documentation Status MIT License Github Actions workflow https://codecov.io/gh/Bibo-Joshi/aiorem/graph/badge.svg?token=H1HUA2FDR3 pre-commit.ci status Code Style: Black

A simple asyncio context manager with explicit interface.

Introduction

This library provides a simple context manager for managing resources in an asyncio environment. It's designed to have an explicit interface, which makes it easy to use both as context manager and as a regular object for custom use cases.

Installing

You can install or upgrade aiorem via

$ pip install aiorem --upgrade

Motivation

When working with asyncio Python libraries, async context managers are a common pattern for managing resources and snippets like

async with some_lib.Client() as client:
    ...

are often seen in the quickstart. However, there are two use cases, where this pattern is hard to use and an explicit interface for acquiring and releasing resources is desirable.

  1. Nested context managers: When writing a class that manages several resources, acquiring and releasing these resources should each usually be bundled in a single method.
  2. Low level event loop usage: In some advanced cases, it can be desirable to use things like loop.run_until_complete than await-ing a coroutine.

For both cases, one can then either explicitly call Client.__aenter__ and Client.__aexit__ or duplicate whatever logic is used within these methods. Unfortunately, the behavior of Client.__aenter__ and Client.__aexit__ is not always well documented. Moreover, using magic/dunder might be viewed as bad practice, as they are mostly intended to be used by the Python interpreter.

This shortcoming is what aiorem aims to improve. As the Quick Start below shows, subclasses of aiorem.AbstractResourceManager can be used in different ways according to the needs of the use case while the behavior is well documented and explicit. For the case of nested context managers, aiorem provides the AbstractResourceManagerCollection class as a natural extension of AbstractResourceManager.

Quick Start

Here is a simple example of how to use aiorem:

import asyncio
from aiorem import AbstractResourceManager


class ResourceManager(AbstractResourceManager):
    async def acquire_resources(self):
        print("Resource acquired")

    async def release_resources(self):
        print("Resource released")


async def context_manager():
    async with ResourceManager():
        print("Context manager block")


@ResourceManager()
async def decorator():
    print("Decorator block")


async def explicit_interface():
    rm = ResourceManager()
    await rm.acquire_resources()
    print("Explicit interface block")
    await rm.release_resources()


async def main():
    await context_manager()
    await decorator()
    await explicit_interface()


if __name__ == "__main__":
    asyncio.run(main())

For more information on how to use aiorem, please refer to the documentation.

About

asyncio Context Manager with Explicit Interface

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages