Metadata-Version: 2.4
Name: py-asyncutils
Version: 0.8.11
Summary: A library containing versatile and adaptable tools to well complement the asyncio framework. Not as performant as C extensions, but startup speed is great considering the features it provides.
Author-email: Jonathan Dung <jonathandung@yahoo.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/jonathandung/asyncutils
Project-URL: Repository, https://github.com/jonathandung/asyncutils.git
Keywords: asynchronous,convenient,fast,light,feature-rich
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Dynamic: license-file

# asyncutils (unfortunately py-asyncutils on pip)

A python library abstracting all the common patterns the creator can think of that somehow always pop up in async code.

Includes a wide range of submodules tailored for specific usages, though concrete implementations are lacking.

Prides in being as fast as can be in terms of import time, with detailed type checking provided via stub files included in the distribution.

Also has a well-equipped command line interface taking many flags and options.

## Setup

Essentially no setup required! Just install py-asyncutils from pip. We are working hard towards packaging for anaconda.

Refer to [SUPPORT.md](SUPPORT.md) for steps to checking the installation.

## Usage

A typical program that uses this module would look like this:

`# demo.py`

    import asyncutils as autils
    with autils.event_loop() as loop: # this wraps the asyncio event loop implementation with proper cleanup
        rdv = autils.Rendezvous[int](loop=loop) # some types support subscripting
        print(*(loop.run_until_complete(asyncio.gather(*map(rdv.put, range(10, 20)), rdv.exchange(20),\
        *map(rdv.exchange, range(1, 10)), *(rdv.get() for _ in range(10)))))[20:]) # simulate some work with values passed between tasks
        # Here Rendezvous is a class implementing get and put methods that complete only after there is a corresponding putter or getter

which prints `1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20` in 175 ms including the import time of both modules! For reference, asyncio loads in around 160-165 ms. That is, the only reason this module starts slow is due to asyncio loading all its submodules on import, which is frankly suboptimal. Command used:

    python -m timeit -n 1 -r 1 "import demo"

The above demo may be considered bad practice in that the shortened names (`autils.event_loop`, `autils.Rendezvous`) are used instead of the fully qualified names (`asyncutils.base.event_loop`, `asyncutils.channels.Rendezvous`), though considering how many submodules we provide (30 and ever-increasing!), it is acceptable. In fact, the submodules are only loaded on demand by a sophisticated name exposure system, unless the -p/--load-all switch is passed.

## Remarks

It is strongly recommended that you read the [asyncio docs](https://docs.python.org/3/library/asyncio.html) thoroughly if using event loop related features.

Other resources if you're new to the world of async: [asyncio HOWTO](https://docs.python.org/3/howto/a-conceptual-overview-of-asyncio.html#a-conceptual-overview-of-asyncio), [Real Python's Async IO Tutorial](https://realpython.com/async-io-python/), [Python Async Basics Video Guide](https://www.youtube.com/watch?v=t5Bo1Je9EmE)

## Contributing

If you have suggestions for how asyncutils could be improved, or want to report a bug, do open an issue! All contributions are welcome.

For more, check out the [Contributing Guide](CONTRIBUTING.md).

## License

[MIT](LICENSE) © 2026 Jonathan Dung

Have fun!

![GitHub release](https://img.shields.io/github/v/release/jonathandung/asyncutils)
![GitHub release date](https://img.shields.io/github/release-date/jonathandung/asyncutils)
![GitHub last commit](https://img.shields.io/github/last-commit/jonathandung/asyncutils)
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/jonathandung/asyncutils)
![GitHub issues](https://img.shields.io/github/issues/jonathandung/asyncutils)
![GitHub pull requests](https://img.shields.io/github/issues-pr/jonathandung/asyncutils)
![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)
![License](https://img.shields.io/badge/License-MIT-yellow.svg)
![GitHub stars](https://img.shields.io/github/stars/jonathandung/asyncutils?style=social)
![GitHub forks](https://img.shields.io/github/forks/jonathandung/asyncutils?style=social)
![GitHub watchers](https://img.shields.io/github/watchers/jonathandung/asyncutils?style=social)
![GitHub contributors](https://img.shields.io/github/contributors/jonathandung/asyncutils)
![GitHub](https://img.shields.io/github/followers/jonathandung?style=social)
![PyPI version](https://badge.fury.io/py/py-asyncutils.svg)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/py-asyncutils)
![PyPI - Downloads](https://img.shields.io/pypi/dm/py-asyncutils)
![PyPI - License](https://img.shields.io/pypi/l/py-asyncutils)
![PyPI - Wheel](https://img.shields.io/pypi/wheel/py-asyncutils)
![PyPI - Format](https://img.shields.io/pypi/format/py-asyncutils)
![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
