Skip to main content

asyncio-contextmanager-pool

A library providing a pool-like object for holding AsyncContextManager instances.

Why?

Some objects, like MongoDB connections to a Replica Set, are expensive to create, time-wise. As a result, they are usually created once and then used across the entire application. This mitigates, or eliminates, the costs associated with creating and setting up such objects.

However, there are situations where one may need to dynamically create such objects. One such example would be a multi-tenant API that can talk to multiple instances.

One could use cachetools to hold the references, perhaps in a TTLCache, so that not "too many" instances are kept (especially when not used), but then they must also make sure that instances are cleaned up properly, sometimes with some leniency (TTL).

Features

  • Async Context Manager (async with) support to manage objects
  • Memoizes instances based on the arguments used to create them, which prevents duplicates and saves init time
  • Provides TTL support, so that objects are kept for a set period of time after not being used, which again helps preventing duplication

Usage

import asyncio
from asyncio_contextmanager_pool import Pool


class Example:
    """
    A dummy implementation of an AsyncContextManager
    that "knows" when it was used.
    """
    def __init__(self, message: str) -> None:
        self.message = message

        self.enter_called = 0
        self.exit_called = 0

    async def __aenter__(self):
        self.enter_called += 1
        return self

    async def __aexit__(self, *args, **kwargs):
        self.exit_called += 1


async with Pool(Example, ttl=5) as p:
    # Get an instance of Example
    async with p.get("hello, world") as inst_1:
        # Use it
        assert inst_1.message == "hello, world"

    # Here, under normal circumstances, `inst_1` is still alive
    assert inst_1.exit_called == 0

    # So, if I `get` it again...
    async with p.get("hello, world") as inst_2:
        # And use it...
        assert inst_2.message == "hello, world"
    
    # I will get the exact same object
    assert inst_1 is inst_2

    # Now, let's assume some time passes...
    await asyncio.sleep(10)

    # Here, inst_1 already expired, so inst_3
    # will be a new object...
    async with p.get("hello, world") as inst_3:
        assert inst_3.message == "hello, world"

    assert inst_1 is not inst_3
    assert inst_1.exit_called == 1

# And after the `async with` block, everything is cleaned:
assert inst_3.exit_called == 1

Notes

Pickle support

If a Pool instance is copied via Pickle (e.g., through multiprocessing.Process or a concurrent.futures.ProcessPoolExecutor), the instances are not copied.

This is by design, because:

  • Some objects should not be copied between processes (e.g., pymongo.MongoClient)
  • Object expiration uses asyncio's Timer functions, which are attached to the Event Loop. Event Loops cannot be shared between processes.

Metadata

Release files for asyncio-contextmanager-pool 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asyncio-contextmanager-pool 0.1.2
File Size Uploaded
asyncio-contextmanager-pool-0.1.2.tar.gz 5.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asyncio-contextmanager-pool 0.1.2
File Interpreter ABI Platform
asyncio_contextmanager_pool-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 10.6 kB

Release files / asyncio-contextmanager-pool-0.1.2.tar.gz

Download URL asyncio-contextmanager-pool-0.1.2.tar.gz
Size 5.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f09cee7f89f2d580ead75e0643fc991042834dcd3d8abd5e8804c63f927e6f64
BLAKE2b-256 checksum
How to use checksums
50f965d7e9f9d03475f9cefe4cb643d2d97d2e5b5501e157f58b2b8b89ab470c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.8 CPython/3.10.0 Linux/5.14.18-300.fc35.x86_64

Release files / asyncio_contextmanager_pool-0.1.2-py3-none-any.whl

Download URL asyncio_contextmanager_pool-0.1.2-py3-none-any.whl
Size 5.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
49011add476484fc7f78174e1c4e9067ed634c6b03ce65198ce226b615320408
BLAKE2b-256 checksum
How to use checksums
124d410e08e7fbc2791a233744593f6f052521d8dccc7f1ac6f27860a4b629c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.8 CPython/3.10.0 Linux/5.14.18-300.fc35.x86_64

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page