Capture the result of a Trio or anyio task
Project description
Welcome to aioresult!
This is a very small library to capture the result of an asynchronous operation, either an async function (with the ResultCapture class) or more generally (with the Future class). It works with Trio nurseries and anyio task groups. It is not needed for Python 3.11 asyncio task groups because those already return an object representing the task, allowing the result to be retrieved.
Code is hosted on github: https://github.com/arthur-tacca/aioresult
Documentation is on ReadTheDocs:
Overview (this page): https://aioresult.readthedocs.io/en/v1.0/overview.html
Capturing a result: https://aioresult.readthedocs.io/en/v1.0/result_capture.html
Future objects: https://aioresult.readthedocs.io/en/v1.0/future.html
Utility functions for waiting: https://aioresult.readthedocs.io/en/v1.0/wait.html
The package is on PyPI: https://pypi.org/project/aioresult/
Quick Overview
The ResultCapture class runs an async function in a nursery and stores its return value (or raised exception) for later:
async with trio.open_nursery() as n: result1 = ResultCapture.start_soon(n, foo, 1) result2 = ResultCapture.start_soon(n, foo, 2) # At this point the tasks have completed, and results are stashed in ResultCapture objects print("results", result1.result(), result2.result())
When stored in a list, the effect is very similar to the asyncio gather() function:
async with trio.open_nursery() as n: results = [ResultCapture.start_soon(n, foo, i) for i in range(10)] print("results:", *[r.result() for r in results])
There is also a simple Future class that shares a lot of its code with ResultCapture. The result is retrieved the same way, but it is set explicitly rather than captured from a task. It is most often used when an API wants to return a value that will be demultiplexed from a shared connection:
# When making a request, create a future, store it for later and return to caller f = aioresult.Future() # The result is set, usually inside a networking API f.set_result(result) # The calling code can wait for the result then retrieve it await f.wait_done() print("result:", f.result())
The interface in Future and ResultCapture to wait for a result and retrieve it is shared in a base class ResultBase.
There are also a few simple utility functions to help waiting for results: wait_any() and wait_all() to wait for one or all of a collection of tasks to complete, and results_to_channel() to allow using the results as they become available.
Installation and Usage
Install into a suitable virtual environment with pip:
pip install aioresult
aioresult can be used with Trio nurseries:
import trio from aioresult import ResultCapture async def wait_and_return(i): await trio.sleep(i) return i async def use_aioresult(): async with trio.open_nursery() as n: results = [ResultCapture.start_soon(n, wait_and_return, i) for i in range(5)] print("results:", *[r.result() for r in results]) if __name__ == "__main__": trio.run(use_aioresult)
It can also be used with anyio task groups:
import asyncio import anyio from aioresult import ResultCapture async def wait_and_return(i): await anyio.sleep(i) return i async def use_aioresult(): async with anyio.create_task_group() as tg: results = [ResultCapture.start_soon(tg, wait_and_return, i) for i in range(5)] print("results:", *[r.result() for r in results]) if __name__ == "__main__": asyncio.run(use_aioresult())
Contributing
This library is deliberately small and limited in scope, so it is essentially “done”. An exception to this is that the typing annotations are not exhaustive and have not been tested with any type checker, so contributions to improve this would be welcome. I could perhaps also be persuaded to add support for optionally including a per-task cancel scope (see issue #2).
To test any changes, install the test requirements (see the pyproject.toml file) and run pytest in the root of the repository:
python -m pytest
To also get coverage information, run it with the coverage command:
coverage run -m pytest
You can then use coverage html to get a nice HTML output of exactly what code has been tested and what has been missed.
License
Copyright Arthur Tacca 2022 - 2024
Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE or the copy at https://www.boost.org/LICENSE_1_0.txt
This is similar to other liberal licenses like MIT and BSD: you can use this library without the need to share your program’s source code, so long as you provide attribution of aioresult.
The Boost license has the additional provision that you do not even need to provide attribution if you are distributing your software in binary form only, e.g. if you have compiled to an executable with Nuitka. (Bundlers like pyinstaller and py2exe don’t count for this because they still include the source code internally.)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file aioresult-1.0.tar.gz
.
File metadata
- Download URL: aioresult-1.0.tar.gz
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f91b64811b8fb9238f40bda951f36cd7bb15e4f57c7d464b507c30e1b00d37dd |
|
MD5 | ee5fd878a68edaa11c29425697bc8178 |
|
BLAKE2b-256 | d042e9dbc01938ff8152215c17cfdcd36eb5d2236dfa2e732722aaa6a6e76933 |
File details
Details for the file aioresult-1.0-py3-none-any.whl
.
File metadata
- Download URL: aioresult-1.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ab8c9a25761b1da71942cdac3488a09a0cf927b12e572ec239a6008337fdacb8 |
|
MD5 | 62f6ad152e441422915301ff996cb8e9 |
|
BLAKE2b-256 | 41122bdc3cddba3e46f30f14f35ea2be5b89d5223c64682ffc87706e77851c0e |