{ "info": { "author": "Michael Housh", "author_email": "mhoush@houshhomeenergy.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 3.6" ], "description": "===============================\nasyncio-utils\n===============================\n\n\n.. image:: https://img.shields.io/pypi/v/asyncio_utils.svg\n :target: https://pypi.python.org/pypi/asyncio_utils\n\n.. image:: https://img.shields.io/travis/m-housh/asyncio-utils.svg\n :target: https://travis-ci.org/m-housh/asyncio-utils\n\n.. image:: https://coveralls.io/repos/github/m-housh/asyncio-utils/badge.svg?branch=master\n :target: https://coveralls.io/github/m-housh/asyncio-utils?branch=master\n\n\nAsyncio utilities for python >= 3.6\n\nA small package of utilities that mimics some builtin methods, but in an \nasynchronous fashion.\n\n\n* Free software: MIT license\n\n\nFeatures\n--------\n\n* Asyncio utilities\n\nInstall\n-------\n\nTo install::\n\n pip install asyncio-utils\n\nUsage\n------\n\nAlmost everything is used with the ``await`` keyword before unless marked\notherwise. However most of the method inputs can be ``awaitable`` (but not\nactually awaited yet) and they will still work, unless marked otherwise.\n\nTo run any of the examples::\n\n import asyncio\n loop = asyncio.get_event_loop()\n\n\naiter\n--------------\n\nWraps/ensures an ``AsyncIterator``. \n\nIf the input is ``Awaitable``, then we will ``await`` the result, and check\nif it returns and ``AsyncIterator``.\n\nIf the input is an ``async generator`` that was not called, then we will\ncall it and yield it's values.\n\nElse if the input is an ``iterator`` we iterate it and yield the values.\n\n\nExamples::\n\n >>> async def main():\n async for v in aiter2(range(1, 5)): # normal iterator\n print(v)\n\n >>> loop.run_until_complete(main())\n 1\n 2\n 3\n 4\n\n >>> async def main():\n async for v in aiter2(arange(1, 5)): # not awaited\n print(v)\n\n >>> loop.run_until_complete(main())\n 1\n 2\n 3\n 4\n\n >>> async def main():\n async for v in aiter2(await arange(1, 5)): # awaited works\n print(v)\n\n >>> loop.run_until_complete(main())\n 1\n 2\n 3\n 4\n\n >>> async def agen():\n yield 1\n yield 2\n yield 3\n yield 4\n\n >>> async def main():\n async for v in aiter2(agen): # oops forgot to call it\n print(v)\n\n >>> loop.run_until_complete(main())\n 1\n 2\n 3\n 4\n\n\n\nanext\n-----------------\n\nMimics the builtin ``next`` method. This method will not accept an \n``awaitable``. The input must be an ``AsyncIterator`` or you will get a \n``TypeError``.\n\nExample:: \n\n >>> async def main():\n myrange = await arange(1, 5)\n for n in range(1, 5):\n print(n, n == await anext(myrange))\n try:\n n = await anext(myrange)\n print(\"This should not be shown\")\n except StopAsyncIteration:\n print('Sorry no more values!')\n\n >>> loop.run_until_complete(main())\n 1 True\n 2 True\n 3 True\n 4 True\n Sorry no more values!\n\n\nExample of using a default value if a ``StopAsyncIteration`` has occured::\n\n >>> async def main():\n myrange = await arange(1)\n print(await anext(myrange))\n print(await anext(myrange, 'Sorry no more values!'))\n # or as kwarg\n print(await anext(myrange, default='Still no more values!'))\n\n >>> loop.run_until_complete(main())\n 1\n Sorry no more values!\n Still no more values!\n\n\nExample failure because a non ``AsyncIterator`` passed in:: \n\n >>> async def main():\n val = await anext(arange(1, 5))\n print(val) # never get here\n\n >>> loop.run_until_complete(main())\n Traceback (most recent call last):\n ...\n TypeError: Not an AsyncIterator: \n\n\namap\n--------------\n\n``AsyncGenerator`` that mimics the builtin ``map`` method.\n\n.. note::\n You do not use ``await`` on ``AsyncGenerator``'s\n\nExample:: \n\n >>> async def main():\n async for val in amap('${}'.format, arange(1, 5)):\n print(val)\n\n >>> loop.run_until_complete(main())\n $1\n $2\n $3\n $4\n\nThis also works if the function passed in is a coroutine::\n\n >>> async def formatter(val):\n return f'${val}'\n\n >>> async def main():\n async for val in amap(formatter, arange(1, 5)):\n print(val)\n\n >>> loop.run_until_complete(main())\n $1\n $2\n $3\n $4\n\nafilter\n---------------\n\nAn ``async generator`` that mimics the builtin ``filter`` method.\n\nExample::\n\n >>> async def main():\n myfilter = await afilter(lambda x: x == 2, arange(1, 5))\n print(await anext(myfilter, 'Oops no more twos'))\n print(await anext(myfilter, 'Oops no more twos'))\n\n >>> loop.run_until_complete(main())\n 2\n Oops no more twos\n\n\narange\n---------------------\n\nMimics the builtin ``range`` method. Returning an ``AsyncIterator``.\n\nExample:: \n\n >>> async def main():\n myrange = await arange(1, 5)\n async for n in myrange:\n print(n)\n\n >>> loop.run_until_complete(main())\n 1\n 2\n 3\n 4\n\n\nalist\n------------------\n\nTransform an ``AsyncIterator`` to a list. This would be equivalent to:: \n\n [v async for v in async_iterator]\n\nHowever we ensure that the ``async_iterator`` is actually an ``AsyncIterator``.\n\nExample:: \n\n >>> async def main():\n print(await alist(arange(1, 5)))\n # or\n print(await alist(await arange(1, 5)))\n\n >>> loop.run_until_complete(main())\n [1, 2, 3, 4]\n [1, 2, 3, 4]\n\n\natuple\n-----------------\n\nTransform an ``AsyncIterator`` to a ``tuple``. This would be equivalent to:: \n\n tuple([v async for v in async_iterator])\n\nHowever we ensure that the ``async_iterator`` is actually an ``AsyncIterator``.\n\nExample:: \n\n >>> async def main():\n print(await atuple(arange(1, 5)))\n # or\n print(await atuple(await arange(1, 5)))\n\n >>> loop.run_until_complete(main())\n (1, 2, 3, 4)\n (1, 2, 3, 4)\n\n\naset\n-------------\n\nTransform an ``AsyncIterator`` to a ``set``. This would be equivalent to:: \n\n {v async for v in async_iterator}\n\nHowever we ensure that the ``async_iterator`` is actually an ``AsyncIterator``.\n\nExample:: \n\n >>> async def main():\n print(await aset(arange(1, 5)))\n # or\n print(await aset(await arange(1, 5)))\n\n >>> loop.run_until_complete(main())\n {1, 2, 3, 4}\n {1, 2, 3, 4}\n\n\nadict\n-----------\n\nTransform an ``AsyncIterator`` to a ``dict``. This would be equivalent to:: \n\n {k: v async for (k, v) in async_iterator}\n\nHowever we ensure that the ``async_iterator`` is actually an ``AsyncIterator``.\n\nExample:: \n\n >>> async def k_v_gen():\n async for n in await arange(1, 5):\n yield (n, n * 2)\n\n >>> async def main():\n print(await adict(k_v_gen()))\n\n >>> loop.run_until_complete(main())\n {1: 2, 2: 4, 3: 6, 4: 8}\n\n\ntransform_factory\n-----------------\n\nThis can be used to transform an ``AsyncIterator`` into any callable. This is\nthe base for ``alist``, ``aset``, ``atuple``, and ``adict``. While not tested,\nin theory, you should be able to transform it into the output of any \n``callable`` that takes a standard iterator.\n\n\nExample of how the ``alist`` method is declared in the code:: \n\n >>> import functools\n >>> alist = functools.partial(transform_factory, _type=list)\n >>> alist.__doc__ = \"\"\"Async list documentation.\"\"\"\n\n >>> async def main():\n print(await alist(arange(1, 5)))\n\n >>> loop.run_until_complete(main())\n [1, 2, 3, 4]\n\n\nmake_async\n-----------------\n\nMake's any callable awaitable. Can be used as a decorator.\n\nExample::\n\n >>> class AClass(object):\n\n def __init__(self):\n self.a = 'a'\n\n >>> async_aclass = make(async_aclass)\n\n # or as a decorator\n >>> @make_async\n def sync_a():\n return 'a'\n\n >>> async def main():\n async_a = await async_aclass()\n print(async_a.a == 'a')\n\n print(await sync_a())\n \n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/m-housh/asyncio_utils", "keywords": "asyncio_utils", "license": "MIT license", "maintainer": "", "maintainer_email": "", "name": "asyncio_utils", "package_url": "https://pypi.org/project/asyncio_utils/", "platform": "", "project_url": "https://pypi.org/project/asyncio_utils/", "project_urls": { "Homepage": "https://github.com/m-housh/asyncio_utils" }, "release_url": "https://pypi.org/project/asyncio_utils/0.1.4/", "requires_dist": null, "requires_python": "", "summary": "Asyncio utilities", "version": "0.1.4" }, "last_serial": 2951013, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "4d2804df6659e3ac02859e9ff9b7bb54", "sha256": "ec6f036cb3699f67944872ae5bd0919b5c1fd8f9bd11c30e30b8757020c6f4f6" }, "downloads": -1, "filename": "asyncio_utils-0.1.0.tar.gz", "has_sig": false, "md5_digest": "4d2804df6659e3ac02859e9ff9b7bb54", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7068, "upload_time": "2017-06-14T01:04:18", "url": "https://files.pythonhosted.org/packages/59/34/c98cfed7c90d7d7f8b89dda1b4561fb2029602c41c8d4a7961c947d1a2f4/asyncio_utils-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "e6f78583e292a76fa2f0e2896fde9432", "sha256": "f1ab49ce1e797ff27d90e959d81f6827f2efb0b1d26d0c3cfdd6996350fc29c3" }, "downloads": -1, "filename": "asyncio_utils-0.1.1.tar.gz", "has_sig": false, "md5_digest": "e6f78583e292a76fa2f0e2896fde9432", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6934, "upload_time": "2017-06-14T01:16:00", "url": "https://files.pythonhosted.org/packages/27/bc/394a7806a0c9a5032114a2c2e8b692e4768977e0893c8e83ca4ba2959d10/asyncio_utils-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "39948778ba3ff30957763fd046284d30", "sha256": "6c2a2eb4d202db25b373614c0b73b09a60f98d95b2a9ed53e20ac9e267d8a36a" }, "downloads": -1, "filename": "asyncio_utils-0.1.2.tar.gz", "has_sig": false, "md5_digest": "39948778ba3ff30957763fd046284d30", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6941, "upload_time": "2017-06-14T01:33:44", "url": "https://files.pythonhosted.org/packages/64/d4/9cc1d25e1b3d131c0774ee81fc30b46b17b3b36516ed8b99dcf9667adec4/asyncio_utils-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "5c993602c6e18495d787bbb0dbaf8077", "sha256": "900eed3c2c71efa8e2aa6fbb05fa9f855f4935d2d0bc78ad7afad4a1ca954e33" }, "downloads": -1, "filename": "asyncio_utils-0.1.3.tar.gz", "has_sig": false, "md5_digest": "5c993602c6e18495d787bbb0dbaf8077", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7969, "upload_time": "2017-06-15T00:47:48", "url": "https://files.pythonhosted.org/packages/df/86/27c2479891037b4013e22ccee5b2a1c374f450c446ccad37d86607bdd657/asyncio_utils-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "30cf904729cf977a8d10a147c67f6a64", "sha256": "ec0bb2ee91201706a7bec7904577e01686b1090cc87b5d9a3021f56ec25cf64a" }, "downloads": -1, "filename": "asyncio_utils-0.1.4.tar.gz", "has_sig": false, "md5_digest": "30cf904729cf977a8d10a147c67f6a64", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7805, "upload_time": "2017-06-15T01:22:09", "url": "https://files.pythonhosted.org/packages/d5/92/a57d53d4e13921b110772d2f45e9313ed09c64d1171204479c3894b648ab/asyncio_utils-0.1.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "30cf904729cf977a8d10a147c67f6a64", "sha256": "ec0bb2ee91201706a7bec7904577e01686b1090cc87b5d9a3021f56ec25cf64a" }, "downloads": -1, "filename": "asyncio_utils-0.1.4.tar.gz", "has_sig": false, "md5_digest": "30cf904729cf977a8d10a147c67f6a64", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7805, "upload_time": "2017-06-15T01:22:09", "url": "https://files.pythonhosted.org/packages/d5/92/a57d53d4e13921b110772d2f45e9313ed09c64d1171204479c3894b648ab/asyncio_utils-0.1.4.tar.gz" } ] }