Skip to main content

Zero-dependency async and concurrency utilities for Python.

Project description

pyasynckit

A zero-dependency toolkit for reliable asynchronous Python programs.

pyasynckit provides small, composable building blocks for common asyncio problems: retrying transient failures, applying backoff, limiting concurrency, and coordinating groups of tasks. It is designed for crawlers, API clients, bots, data pipelines, and services that need predictable async behaviour.

Project status: early development. Retry is the first public utility; queue, rate-limit, timeout, task, and parallel helpers are planned. The project does not claim that unimplemented APIs are available yet.

Why pyasynckit?

  • Zero runtime dependencies. The installed library uses only Python's standard library.
  • Python 3.8+. The public package supports CPython 3.8 and newer.
  • Async-first. APIs use async/await naturally and preserve task cancellation instead of accidentally swallowing it.
  • Predictable failure handling. Retry policies validate configuration early, preserve the final original exception, and support bounded delays.
  • Readable defaults. A policy should be obvious in a code review without requiring a large configuration framework.

Compared to existing libraries

The Python ecosystem already has mature alternatives for most of these problems. Reach for the existing library when you want its full feature surface; reach for pyasynckit when you want a small, zero-dep, single import.

Need Established library pyasynckit
Retry with backoff tenacity, backoff Retry — small, async-only, deterministic via injectable sleep / random_fn
Async stream / queue / parallel aiostream Planned Queue + parallel (M2)
Rate limiting asyncio-throttle, aiolimiter Planned Throttler (M1)
Async memoize / cache async-lru, cachetools Planned memoize (M3)
Timeout / deadline async-timeout Planned timeout / deadline (M1)

The differentiator is composability (every primitive shares the same async-context-manager shape and injectable clock) and deterministic testability (no time, randomness, or scheduling is hidden behind asyncio internals).

Installation

Install the published package once it is available on PyPI:

python -m pip install pyasynckit

For development from a clone:

git clone https://github.com/Goldhobbang/pyasynckit.git
cd pyasynckit
python -m pip install -e ".[dev]"

Quick start

Retry executes an asynchronous callable again after retryable failures. The times option means the total number of attempts, including the first one.

import asyncio

from pyasynckit import Retry


async def fetch_profile(user_id: str) -> dict:
    # Replace this with an async HTTP client call.
    return {"id": user_id}


async def main() -> None:
    async with Retry(times=3, delay=0.5, backoff="exponential") as retry:
        profile = await retry(fetch_profile, "42")
    print(profile)


asyncio.run(main())

The example attempts the operation at most three times. After failures, it waits 0.5 seconds and then 1.0 second before the next attempt.

Retry guide

Basic policy

retry = Retry(times=4, delay=0.25, backoff="linear")
result = await retry(operation, arg1, keyword="value")

The callable receives all positional and keyword arguments supplied to retry(...). It must return an awaitable, normally by being declared with async def.

Backoff strategies

backoff Delays for delay=1 after failed attempts
"constant" 1, 1, 1, ...
"linear" 1, 2, 3, ...
"exponential" (default) 1, 2, 4, ...

Use max_delay to prevent an exponential policy from growing without bound:

retry = Retry(
    times=5,
    delay=1.0,
    backoff="exponential",
    max_delay=10.0,
)

Jitter

When many workers retry the same dependency, identical delays can cause a retry spike. Enable jitter to distribute retries over time:

# Full jitter: a random value from 0 to the calculated delay.
retry = Retry(times=3, delay=1.0, jitter=True)

# Proportional jitter: vary the calculated delay by at most +/-20%.
retry = Retry(times=3, delay=1.0, jitter=0.2)

Retry only expected failures

The default retries subclasses of Exception. Narrow this for operations where only specific transient errors are safe to retry:

retry = Retry(
    times=3,
    delay=0.2,
    exceptions=(ConnectionError, TimeoutError),
)
result = await retry(call_remote_service)

The final retryable exception is raised unchanged. Exceptions outside the configured tuple are raised immediately.

Cancellation is never retried

asyncio.CancelledError always propagates immediately, even if a broad exception tuple is supplied. This keeps task cancellation, graceful shutdown, and timeout ownership under the caller's control.

API reference

Retry

Retry(
    *,
    times: int = 3,
    delay: float = 0.0,
    backoff: str = "exponential",
    max_delay: Optional[float] = None,
    jitter: Union[bool, float] = False,
    exceptions: Tuple[Type[BaseException], ...] = (Exception,),
)
Parameter Meaning
times Maximum total attempts; must be at least 1.
delay Initial delay in seconds; must be non-negative.
backoff "constant", "linear", or "exponential".
max_delay Optional upper bound for a calculated delay.
jitter True for full jitter, or a float from 0.0 to 1.0 for proportional jitter.
exceptions Non-empty tuple of exception classes eligible for retries.

For deterministic tests or custom event-loop integration, advanced callers may also inject sleep and random_fn. See the full docstring in pyasynckit.retry.

Development

Run the test suite

python -m pip install -e ".[dev]"
python -m pytest --cov

The project requires 100% line and branch coverage. New public behaviour must include normal, failure, cancellation, and boundary-case tests where relevant.

Project layout

src/pyasynckit/   # Library source code
tests/            # pytest and pytest-asyncio test suite
docs/             # Sphinx documentation source
.github/workflows/# CI and release automation

Contributing

  1. Create a focused branch from main.
  2. Add type hints and user-facing docstrings for public APIs.
  3. Add tests that keep the coverage gate at 100%.
  4. Run the test command above before opening a pull request.

Please keep runtime code limited to the standard library. Development-only tools belong in the dev optional dependency group in pyproject.toml.

Releases

Releases are created by pushing a version tag such as v0.1.0. The GitHub workflow verifies that the tag matches [project].version, builds both an sdist and wheel, and publishes them to PyPI using the repository's PYPI_API_TOKEN. See the release workflow for the exact process.

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

pyasynckit-0.1.1.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

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

pyasynckit-0.1.1-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file pyasynckit-0.1.1.tar.gz.

File metadata

  • Download URL: pyasynckit-0.1.1.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyasynckit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ad99b96207e6f9e2f57bdd29a77e0769bdb1e041732016177f5cafedc731dc64
MD5 7632d50dba17a4d0eaa66aeb13e2db0b
BLAKE2b-256 85626fe1784d80931ffb471c518b55e6ad0f1535cdf388bc8b9bbc926519e439

See more details on using hashes here.

File details

Details for the file pyasynckit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pyasynckit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyasynckit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ce0b5775383567e14b6b2af167b837d3f9e49b4e90666105ee2087ff437bbcc6
MD5 ab924f8b7f2a3c0a98ee0981a04a576b
BLAKE2b-256 867e211e759b69c00c47ede4018f2059aec91b6ed484f0b7cc4ed4d514dcf965

See more details on using hashes here.

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