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.
Essentially no setup required! Just install py-asyncutils from pip. We are working hard towards packaging for anaconda.
Refer to SUPPORT.md for steps to checking the installation.
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.
This is asyncutils v0.8.13.
This library is currently in alpha stage, meaning the public API is subject to change even between patch versions, and changes made may be backward-incompatible. Of course, this isn't a significant issue, seeing as though nobody currently uses the process.
Besides using command line arguments to change console settings, the behaviour of this module as a library can be customized as well, including aspects such as where to output logging, customizing the underlying executor type used, and setting a seed for random number generation using the AUTILSCFGPATH environment variable (all uppercase due to Windows limitations), which should point to an absolute path to a configuration json/jsonl.
See format.jsonc for details.
It is strongly recommended that you read the asyncio docs thoroughly if using event loop related features.
Other resources if you're new to the world of async: asyncio HOWTO, Real Python's Async IO Tutorial, Python Async Basics Video Guide
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.
MIT © 2026 Jonathan Dung
Have fun!