aioresult


Nameaioresult JSON
Version 0.9 PyPI version JSON
download
home_page
SummaryCapture the result of a Trio or anyio task
upload_time2023-01-02 20:15:14
maintainer
docs_urlNone
authorArthur Tacca
requires_python>=3.7
licenseBoost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords async anyio trio result future nursery taskgroup
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            aioresult: Capture the result of a Trio or anyio task
=====================================================

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
<https://trio.readthedocs.io/en/stable/reference-core.html#nurseries-and-spawning>`__ and `anyio
task groups <https://anyio.readthedocs.io/en/stable/tasks.html>`__. It is not needed for Python 3.11
`asyncio task groups <https://docs.python.org/3/library/asyncio-task.html#task-groups>`__ because
those already return an object representing the task, allowing the result to be retrieved.

The code is hosted on github: https://github.com/arthur-tacca/aioresult

Documentation is on ReadTheDocs: https://aioresult.readthedocs.io/en/stable/docs.html


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 list, the effect is very similar to the `asyncio gather() function
<https://docs.python.org/3/library/asyncio-task.html#asyncio.gather>`__::

    async with trio.open_nursery() as n:
        results = [aioresult.ResultCapture.start_soon(n, foo, i) for i in range(10)]
    print("results:", *[r.result() for r in results])


.. note:: A key design decision about the ``ResultCapture`` class is that **exceptions are allowed
  to propagate out of the task into their enclosing nursery**. This is unlike some similar
  libraries, which consume the exception in its original context and rethrow it later. In practice,
  aioresult's behaviour is simpler and less error prone.

There is also a derived class ``StartableResultCapture``, meant for async functions that satisfy
`the Trio task start protocol
<https://trio.readthedocs.io/en/stable/reference-core.html#trio.Nursery.start>`__.

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``.


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())


Running the Tests
-----------------

The automated tests are currently not run through any automated pipeline. To run them yourself,
start by installing the dependencies::

    pip install pytest coverage anyio trio

To just run the tests, 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

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 <https://nuitka.net/>`__.  (Bundlers like `pyinstaller <https://pyinstaller.org/>`__
and `py2exe <https://www.py2exe.org/>`__ don't count for this because they still include the source
code internally.)

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "aioresult",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "async,anyio,trio,result,future,nursery,taskgroup",
    "author": "Arthur Tacca",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/0e/fe/c7fad0cabfc2593927acf7d818244c607afa236f35f14cb126d44c59dff0/aioresult-0.9.tar.gz",
    "platform": null,
    "description": "aioresult: Capture the result of a Trio or anyio task\r\n=====================================================\r\n\r\nWelcome to aioresult! This is a very small library to capture the result of an asynchronous\r\noperation, either an async function (with the ``ResultCapture`` class) or more generally (with the\r\n``Future`` class). It works with `Trio nurseries\r\n<https://trio.readthedocs.io/en/stable/reference-core.html#nurseries-and-spawning>`__ and `anyio\r\ntask groups <https://anyio.readthedocs.io/en/stable/tasks.html>`__. It is not needed for Python 3.11\r\n`asyncio task groups <https://docs.python.org/3/library/asyncio-task.html#task-groups>`__ because\r\nthose already return an object representing the task, allowing the result to be retrieved.\r\n\r\nThe code is hosted on github: https://github.com/arthur-tacca/aioresult\r\n\r\nDocumentation is on ReadTheDocs: https://aioresult.readthedocs.io/en/stable/docs.html\r\n\r\n\r\nQuick Overview\r\n--------------\r\n\r\nThe ``ResultCapture`` class runs an async function in a nursery and stores its return value (or\r\nraised exception) for later::\r\n\r\n    async with trio.open_nursery() as n:\r\n        result1 = ResultCapture.start_soon(n, foo, 1)\r\n        result2 = ResultCapture.start_soon(n, foo, 2)\r\n    # At this point the tasks have completed, and results are stashed in ResultCapture objects\r\n    print(\"results\", result1.result(), result2.result())\r\n\r\nWhen stored in list, the effect is very similar to the `asyncio gather() function\r\n<https://docs.python.org/3/library/asyncio-task.html#asyncio.gather>`__::\r\n\r\n    async with trio.open_nursery() as n:\r\n        results = [aioresult.ResultCapture.start_soon(n, foo, i) for i in range(10)]\r\n    print(\"results:\", *[r.result() for r in results])\r\n\r\n\r\n.. note:: A key design decision about the ``ResultCapture`` class is that **exceptions are allowed\r\n  to propagate out of the task into their enclosing nursery**. This is unlike some similar\r\n  libraries, which consume the exception in its original context and rethrow it later. In practice,\r\n  aioresult's behaviour is simpler and less error prone.\r\n\r\nThere is also a derived class ``StartableResultCapture``, meant for async functions that satisfy\r\n`the Trio task start protocol\r\n<https://trio.readthedocs.io/en/stable/reference-core.html#trio.Nursery.start>`__.\r\n\r\nThere is also a simple ``Future`` class that shares a lot of its code with ``ResultCapture``. The\r\nresult is retrieved the same way, but it is set explicitly rather than captured from a task. It is\r\nmost often used when an API wants to return a value that will be demultiplexed from a shared\r\nconnection::\r\n\r\n    # When making a request, create a future, store it for later and return to caller\r\n    f = aioresult.Future()\r\n\r\n    # The result is set, usually inside a networking API\r\n    f.set_result(result)\r\n\r\n    # The calling code can wait for the result then retrieve it\r\n    await f.wait_done()\r\n    print(\"result:\", f.result())\r\n\r\nThe interface in ``Future`` and ``ResultCapture`` to wait for a result and retrieve it is shared in\r\na base class ``ResultBase``.\r\n\r\n\r\nInstallation and Usage\r\n----------------------\r\n\r\nInstall into a suitable virtual environment with ``pip``::\r\n\r\n    pip install aioresult\r\n\r\naioresult can be used with Trio nurseries::\r\n\r\n    import trio\r\n    from aioresult import ResultCapture\r\n\r\n    async def wait_and_return(i):\r\n        await trio.sleep(i)\r\n        return i\r\n\r\n    async def use_aioresult():\r\n        async with trio.open_nursery() as n:\r\n            results = [ResultCapture.start_soon(n, wait_and_return, i) for i in range(5)]\r\n        print(\"results:\", *[r.result() for r in results])\r\n\r\n    if __name__ == \"__main__\":\r\n        trio.run(use_aioresult)\r\n\r\nIt can also be used with anyio task groups::\r\n\r\n    import asyncio\r\n    import anyio\r\n    from aioresult import ResultCapture\r\n\r\n    async def wait_and_return(i):\r\n        await anyio.sleep(i)\r\n        return i\r\n\r\n    async def use_aioresult():\r\n         async with anyio.create_task_group() as tg:\r\n             results = [ResultCapture.start_soon(tg, wait_and_return, i) for i in range(5)]\r\n         print(\"results:\", *[r.result() for r in results])\r\n\r\n    if __name__ == \"__main__\":\r\n        asyncio.run(use_aioresult())\r\n\r\n\r\nRunning the Tests\r\n-----------------\r\n\r\nThe automated tests are currently not run through any automated pipeline. To run them yourself,\r\nstart by installing the dependencies::\r\n\r\n    pip install pytest coverage anyio trio\r\n\r\nTo just run the tests, run ``pytest`` in the root of the repository::\r\n\r\n    python -m pytest\r\n\r\nTo also get coverage information, run it with the ``coverage`` command::\r\n\r\n    coverage run -m pytest\r\n\r\nYou can then use ``coverage html`` to get a nice HTML output of exactly what code has been tested\r\nand what has been missed.\r\n\r\n\r\nLicense\r\n-------\r\n\r\nCopyright Arthur Tacca 2022\r\n\r\nDistributed under the Boost Software License, Version 1.0.\r\nSee accompanying file LICENSE or the copy at https://www.boost.org/LICENSE_1_0.txt\r\n\r\nThis is similar to other liberal licenses like MIT and BSD: you can use this library without the\r\nneed to share your program's source code, so long as you provide attribution of aioresult.\r\n\r\nThe Boost license has the additional provision that you do not even need to provide attribution if\r\nyou are distributing your software in binary form only, e.g. if you have compiled to an executable\r\nwith `Nuitka <https://nuitka.net/>`__.  (Bundlers like `pyinstaller <https://pyinstaller.org/>`__\r\nand `py2exe <https://www.py2exe.org/>`__ don't count for this because they still include the source\r\ncode internally.)\r\n",
    "bugtrack_url": null,
    "license": "Boost Software License - Version 1.0 - August 17th, 2003  Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the \"Software\") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:  The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Capture the result of a Trio or anyio task",
    "version": "0.9",
    "split_keywords": [
        "async",
        "anyio",
        "trio",
        "result",
        "future",
        "nursery",
        "taskgroup"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ed890ae63ef64b23b4793cebc32f3eb604b0bb2422dc3e46a21e6c6bb7e925df",
                "md5": "2b0094efb9c8226aeb957d51d24a4a4f",
                "sha256": "98ee813e4bc8045542d0cbe75ac895eeacf826c2695c3836d84b7efb4d024ec4"
            },
            "downloads": -1,
            "filename": "aioresult-0.9-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2b0094efb9c8226aeb957d51d24a4a4f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 10166,
            "upload_time": "2023-01-02T20:15:12",
            "upload_time_iso_8601": "2023-01-02T20:15:12.237804Z",
            "url": "https://files.pythonhosted.org/packages/ed/89/0ae63ef64b23b4793cebc32f3eb604b0bb2422dc3e46a21e6c6bb7e925df/aioresult-0.9-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0efec7fad0cabfc2593927acf7d818244c607afa236f35f14cb126d44c59dff0",
                "md5": "df0876657b2bbd626c058e466290d230",
                "sha256": "59a5f8672c496e66f5ec2b60968cff999abaa4c1e04e7506434b24ed1bf546b4"
            },
            "downloads": -1,
            "filename": "aioresult-0.9.tar.gz",
            "has_sig": false,
            "md5_digest": "df0876657b2bbd626c058e466290d230",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 11798,
            "upload_time": "2023-01-02T20:15:14",
            "upload_time_iso_8601": "2023-01-02T20:15:14.071798Z",
            "url": "https://files.pythonhosted.org/packages/0e/fe/c7fad0cabfc2593927acf7d818244c607afa236f35f14cb126d44c59dff0/aioresult-0.9.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-02 20:15:14",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "aioresult"
}
        
Elapsed time: 0.02450s