Asyncio utilities
Project description
Asyncio utilities for python >= 3.6
A small package of utilities that mimics some builtin methods, but in an asynchronous fashion.
Free software: MIT license
Features
Asyncio utilities
Install
To install:
pip install asyncio-utils
Usage
Almost everything is used with the await keyword before unless marked otherwise. However most of the method inputs can be awaitable (but not actually awaited yet) and they will still work, unless marked otherwise.
To run any of the examples:
import asyncio loop = asyncio.get_event_loop()
aiter
Example:
>>> async def main(): # wraps a normal type that is iterable. iterator = await aiter(range(1, 5)) async for n in iterator: print(n) >>> loop.run_until_complete(main()) 1 2 3 4 >>> async def main(): # returns the same input if the input is already an # AsyncIterator aiterator = await arange(1, 5) _aiter = await aiter(aiterator) print(_aiter == aiterator) >>> loop.run_until_complete(main()) True >>> async def main(): # will await on an object if needed, to see if it returns # an AsyncIterator async for n in aiter(arange(1)): # arange not awaited print(n) >>> loop.run_until_complete(main()) 0
aiter
Wraps/ensures an AsyncIterator.
If the input is Awaitable, then we will await the result, and check if it returns and AsyncIterator.
If the input is an async generator that was not called, then we will call it and yield it’s values.
Else if the input is an iterator we iterate it and yield the values.
Examples:
>>> async def main(): async for v in aiter2(range(1, 5)): # normal iterator print(v) >>> loop.run_until_complete(main()) 1 2 3 4 >>> async def main(): async for v in aiter2(arange(1, 5)): # not awaited print(v) >>> loop.run_until_complete(main()) 1 2 3 4 >>> async def main(): async for v in aiter2(await arange(1, 5)): # awaited works print(v) >>> loop.run_until_complete(main()) 1 2 3 4 >>> async def agen(): yield 1 yield 2 yield 3 yield 4 >>> async def main(): async for v in aiter2(agen): # oops forgot to call it print(v) >>> loop.run_until_complete(main()) 1 2 3 4
anext
Mimics the builtin next method. This method will not accept an awaitable. The input must be an AsyncIterator or you will get a TypeError.
Example:
>>> async def main(): myrange = await arange(1, 5) for n in range(1, 5): print(n, n == await anext(myrange)) try: n = await anext(myrange) print("This should not be shown") except StopAsyncIteration: print('Sorry no more values!') >>> loop.run_until_complete(main()) 1 True 2 True 3 True 4 True Sorry no more values!
Example of using a default value if a StopAsyncIteration has occured:
>>> async def main(): myrange = await arange(1) print(await anext(myrange)) print(await anext(myrange, 'Sorry no more values!')) # or as kwarg print(await anext(myrange, default='Still no more values!')) >>> loop.run_until_complete(main()) 1 Sorry no more values! Still no more values!
Example failure because a non AsyncIterator passed in:
>>> async def main(): val = await anext(arange(1, 5)) print(val) # never get here >>> loop.run_until_complete(main()) Traceback (most recent call last): ... TypeError: Not an AsyncIterator: <coroutine object arange at 0x1068170f8>
arange
Mimics the builtin range method. Returning an AsyncIterator.
Example:
>>> async def main(): myrange = await arange(1, 5) async for n in myrange: print(n) >>> loop.run_until_complete(main()) 1 2 3 4
alist
Transform an AsyncIterator to a list. This would be equivalent to:
[v async for v in async_iterator]
However we ensure that the async_iterator is actually an AsyncIterator.
Example:
>>> async def main(): print(await alist(arange(1, 5))) # or print(await alist(await arange(1, 5))) >>> loop.run_until_complete(main()) [1, 2, 3, 4] [1, 2, 3, 4]
atuple
Transform an AsyncIterator to a tuple. This would be equivalent to:
tuple([v async for v in async_iterator])
However we ensure that the async_iterator is actually an AsyncIterator.
Example:
>>> async def main(): print(await atuple(arange(1, 5))) # or print(await atuple(await arange(1, 5))) >>> loop.run_until_complete(main()) (1, 2, 3, 4) (1, 2, 3, 4)
aset
Transform an AsyncIterator to a set. This would be equivalent to:
{v async for v in async_iterator}
However we ensure that the async_iterator is actually an AsyncIterator.
Example:
>>> async def main(): print(await aset(arange(1, 5))) # or print(await aset(await arange(1, 5))) >>> loop.run_until_complete(main()) {1, 2, 3, 4} {1, 2, 3, 4}
adict
Transform an AsyncIterator to a dict. This would be equivalent to:
{k: v async for (k, v) in async_iterator}
However we ensure that the async_iterator is actually an AsyncIterator.
Example:
>>> async def k_v_gen(): async for n in await arange(1, 5): yield (n, n * 2) >>> async def main(): print(await adict(k_v_gen())) >>> loop.run_until_complete(main()) {1: 2, 2: 4, 3: 6, 4: 8}
amap
AsyncGenerator that mimics the builtin map method.
Example:
>>> async def main(): async for val in amap('${}'.format, arange(1, 5)): print(val) >>> loop.run_until_complete(main()) $1 $2 $3 $4
This also works if the function passed in is a coroutine:
>>> async def formatter(val): return f'${val}' >>> async def main(): async for val in amap(formatter, arange(1, 5)): print(val) >>> loop.run_until_complete(main()) $1 $2 $3 $4
transform_factory
This can be used to transform an AsyncIterator into any callable. This is the base for alist, aset, atuple, and adict. While not tested, in theory, you should be able to transform it into the output of any callable that takes a standard iterator.
Example of how the alist method is declared in the code:
>>> import functools >>> alist = functools.partial(transform_factory, _type=list) >>> alist.__doc__ = """Async list documentation."""
make_aiter
Non-async method that Wraps an iterator in an AsyncIterator. If the input has not been awaited on (is a coroutine) or is already and AsyncIterator, then we do nothing and return the input.
(non async version of aiter)
This can be useful if you want a class (for context) and need to ensure an AsyncIterator inside the __init__ method or any other non-async method.
Example:
>>> async def main(): aiterator = make_aiter(range(1, 5)) # make_aiter can not be awaited async for n in aiterator: print(n) >>> loop.run_until_complete(main()) 1 2 3 4
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.