{ "info": { "author": "Caleb Hattingh", "author_email": "caleb.hattingh@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. contents:: Table of Contents\n\n\n.. image:: https://travis-ci.org/cjrh/aiorun.svg?branch=master\n :target: https://travis-ci.org/cjrh/aiorun\n\n.. image:: https://ci.appveyor.com/api/projects/status/fov7fixihcokvifl/branch/master?svg=true\n :target: https://ci.appveyor.com/project/cjrh/aiorun\n\n.. image:: https://coveralls.io/repos/github/cjrh/aiorun/badge.svg?branch=master\n :target: https://coveralls.io/github/cjrh/aiorun?branch=master\n\n.. image:: https://img.shields.io/pypi/pyversions/aiorun.svg\n :target: https://pypi.python.org/pypi/aiorun\n\n.. image:: https://img.shields.io/github/tag/cjrh/aiorun.svg\n :target: https://img.shields.io/github/tag/cjrh/aiorun.svg\n\n.. image:: https://img.shields.io/badge/install-pip%20install%20aiorun-ff69b4.svg\n :target: https://img.shields.io/badge/install-pip%20install%20aiorun-ff69b4.svg\n\n.. image:: https://img.shields.io/pypi/v/aiorun.svg\n :target: https://img.shields.io/pypi/v/aiorun.svg\n\n.. image:: https://img.shields.io/badge/calver-YYYY.MM.MINOR-22bfda.svg\n :target: http://calver.org/\n\n\n\ud83c\udfc3 aiorun\n======================\n\nHere's the big idea (how you use it):\n\n.. code-block:: python\n\n import asyncio\n from aiorun import run\n\n async def main():\n # Put your application code here\n await asyncio.sleep(1.0)\n\n if __name__ == '__main__':\n run(main())\n\nThis package provides a ``run()`` function as the starting point\nof your ``asyncio``-based application. The ``run()`` function will\nrun forever. If you want to shut down when ``main()`` completes, just\ncall ``loop.stop()`` inside it: that will initiate shutdown.\n\n\n\ud83e\udd14 Why?\n----------------\n\nThe ``run()`` function will handle **everything** that normally needs\nto be done during the shutdown sequence of the application. All you\nneed to do is write your coroutines and run them.\n\nSo what the heck does ``run()`` do exactly?? It does these standard,\nidiomatic actions for asyncio apps:\n\n- creates a ``Task`` for the given coroutine (schedules it on the\n event loop),\n- calls ``loop.run_forever()``,\n- adds default (and smart) signal handlers for both ``SIGINT``\n and ``SIGTERM`` that will stop the loop;\n- and *when* the loop stops (either by signal or called directly), then it will...\n- ...gather all outstanding tasks,\n- cancel them using ``task.cancel()``,\n- resume running the loop until all those tasks are done,\n- wait for the *executor* to complete shutdown, and\n- finally close the loop.\n\nAll of this stuff is boilerplate that you will never have to write\nagain. So, if you use ``aiorun`` this is what **you** need to remember:\n\n- Spawn all your work from a single, starting coroutine\n- When a shutdown signal is received, **all** currently-pending tasks\n will have ``CancelledError`` raised internally. It's up to you whether\n you want to handle this inside each coroutine with\n a ``try/except`` or not.\n- If you want to protect coros from cancellation, see `shutdown_waits_for()`\n further down.\n- Try to have executor jobs be shortish, since the shutdown process will wait\n for them to finish. If you need a long-running thread or process tasks, use\n a dedicated thread/subprocess and set ``daemon=True`` instead.\n\nThere's not much else to know for general use. `aiorun` has a few special\ntools that you might need in unusual circumstances. These are discussed\nnext.\n\n\ud83d\udda5\ufe0f What about TCP server startup?\n-----------------------------------\n\nYou will see in many examples online that for servers, startup happens in\nseveral ``run_until_complete()`` phases before the primary ``run_forever()``\nwhich is the \"main\" running part of the program. How do we handle that with\n*aiorun*?\n\nLet's recreate the `echo client & server `_\nexamples from the Standard Library documentation:\n\n**Client:**\n\n.. code-block:: python\n\n # echo_client.py\n import asyncio\n from aiorun import run\n\n async def tcp_echo_client(message):\n # Same as original!\n reader, writer = await asyncio.open_connection('127.0.0.1', 8888)\n print('Send: %r' % message)\n writer.write(message.encode())\n data = await reader.read(100)\n print('Received: %r' % data.decode())\n print('Close the socket')\n writer.close()\n asyncio.get_event_loop().stop() # Exit after one msg like original\n\n message = 'Hello World!'\n run(tcp_echo_client(message))\n\n**Server:**\n\n.. code-block:: python\n\n import asyncio\n from aiorun import run\n\n async def handle_echo(reader, writer):\n # Same as original!\n data = await reader.read(100)\n message = data.decode()\n addr = writer.get_extra_info('peername')\n print(\"Received %r from %r\" % (message, addr))\n print(\"Send: %r\" % message)\n writer.write(data)\n await writer.drain()\n print(\"Close the client socket\")\n writer.close()\n\n async def main():\n server = await asyncio.start_server(handle_echo, '127.0.0.1', 8888)\n print('Serving on {}'.format(server.sockets[0].getsockname()))\n try:\n # Wait for cancellation\n while True:\n await asyncio.sleep(10)\n except asyncio.CancelledError:\n server.close()\n await server.wait_closed()\n\n run(main())\n\nIt works the same as the original examples, except you see this\nwhen you hit ``CTRL-C`` on the server instance:\n\n.. code-block:: bash\n\n $ python echo_server.py\n Running forever.\n Serving on ('127.0.0.1', 8888)\n Received 'Hello World!' from ('127.0.0.1', 57198)\n Send: 'Hello World!'\n Close the client socket\n ^CStopping the loop\n Entering shutdown phase.\n Cancelling pending tasks.\n Cancelling task: \n Running pending tasks till complete\n Waiting for executor shutdown.\n Leaving. Bye!\n\nTask gathering, cancellation, and executor shutdown all happen\nautomatically.\n\n\ud83d\udca8 Do you like `uvloop `_?\n------------------------------------------------------------------\n\n.. code-block:: python\n\n import asyncio, aiorun\n\n async def main():\n \n\n if __name__ == '__main__':\n run(main(), use_uvloop=True)\n\nNote that you have to ``pip install uvloop`` yourself.\n\n\ud83d\udee1\ufe0f Smart shield for shutdown\n---------------------------------\n\nIt's unusual, but sometimes you're going to want a coroutine to not get\ninterrupted by cancellation *during the shutdown sequence*. You'll look in\nthe official docs and find ``asyncio.shield()``.\n\nUnfortunately, ``shield()`` doesn't work in shutdown scenarios because\nthe protection offered by ``shield()`` only applies if the specific coroutine\n*inside which* the ``shield()`` is used, gets cancelled directly.\n\nLet me explain: if you do a conventional shutdown sequence (like ``aiorun``\nis doing internally), this is the sequence of steps:\n\n- ``tasks = all_tasks()``, followed by\n- ``group = gather(*tasks)``, and then\n- ``group.cancel()``\n\nThe way ``shield()`` works internally is it creates a *secret, inner*\ntask\u2014which also gets included in the ``all_tasks()`` call above! Thus\nit also receives a cancellation signal just like everything else.\n\nTherefore, we have an alternative version of ``shield()`` that works better for\nus: ``shutdown_waits_for()``. If you've got a coroutine that must **not** be\ncancelled during the shutdown sequence, just wrap it in\n``shutdown_waits_for()``!\n\nHere's an example:\n\n.. code-block:: python\n\n import asyncio\n from aiorun import run, shutdown_waits_for\n\n async def corofn():\n await asyncio.sleep(60)\n print('done!')\n\n async def main():\n try:\n await shutdown_waits_for(corofn())\n except asyncio.CancelledError\n print('oh noes!')\n\n run(main())\n\nIf you hit ``CTRL-C`` *before* 60 seconds has passed, you will see\n``oh noes!`` printed immediately, and then after 60 seconds (since start),\n``done!`` is printed, and thereafter the program exits.\n\nBehind the scenes, ``all_tasks()`` would have been cancelled by ``CTRL-C``,\n*except* ones wrapped in ``shutdown_waits_for()`` calls. In this respect, it\nis loosely similar to ``asyncio.shield()``, but with special applicability\nto our shutdown scenario in ``aiorun()``.\n\nBe careful with this: the coroutine should still finish up at some point.\nThe main use case for this is short-lived tasks that you don't want to\nwrite explicit cancellation handling.\n\nOh, and you can use ``shutdown_waits_for()`` as if it were ``asyncio.shield()``\ntoo. For that use-case it works the same. If you're using ``aiorun``, there\nis no reason to use ``shield()``.\n\n\ud83d\ude4f Windows Support\n-------------------------\n\n``aiorun`` also supports Windows! Kinda. Sorta. The root problem with Windows,\nfor a thing like ``aiorun`` is that Windows doesn't support *signal handling*\nthe way Linux or Mac OS X does. Like, at all.\n\nFor Linux, ``aiorun`` does \"the right thing\" out of the box for the\n``SIGINT`` and ``SIGTERM`` signals; i.e., it will catch them and initiate\na safe shutdown process as described earlier. However, on *Windows*, these\nsignals don't work.\n\nThere are two signals that work on Windows: the ``CTRL-C`` signal (happens\nwhen you press, unsurprisingly, ``CTRL-C``, and the ``CTRL-BREAK`` signal\nwhich happens when you...well, you get the picture.\n\nThe good news is that, for ``aiorun``, both of these will work. Yay! The bad\nnews is that for them to work, you have to run your code in a Console\nwindow. Boo!\n\nFortunately, it turns out that you can run an asyncio-based process *not*\nattached to a Console window, e.g. as a service or a subprocess, *and* have\nit also receive a signal to safely shut down in a controlled way. It turns\nout that it is possible to *send a ``CTRL-BREAK`` signal* to another process,\nwith no console window involved, but only as long as that process was created\nin a particular way and---here is the drop---this targetted process is a\nchild process of the one sending the signal. Yeah, I know, it's a downer.\n\nThere is an example of how to do this in the tests:\n\n.. code-block:: python3\n\n import subprocess as sp\n\n proc = sp.Popen(\n ['python', 'app.py'],\n stdout=sp.PIPE,\n stderr=sp.STDOUT,\n creationflags=sp.CREATE_NEW_PROCESS_GROUP\n )\n print(proc.pid)\n\nNotice how we print out the process id (``pid``). Then you can send that\nprocess the signal from a completely different process, once you know\nthe ``pid``:\n\n.. code-block:: python3\n\n import os, signal\n\n os.kill(pid, signal.CTRL_BREAK_EVENT)\n\n(Remember, ``os.kill()`` doesn't actually kill, it only sends a signal)\n\n``aiorun`` supports this use-case above, although I'll be pretty surprised\nif anyone actually uses it to manage microservices (does anyone do this?)\n\nSo to summarize: ``aiorun`` will do a controlled shutdown if either\n``CTRL-C`` or ``CTRL-BREAK`` is entered via keyboard in a Console window\nwith a running instance, or if the ``CTRL-BREAK`` signal is sent to\na *subprocess* that was created with the ``CREATE_NEW_PROCESS_GROUP``\nflag set. `Here `_ is a much more\ndetailed explanation of these issues.\n\nFinally, ``uvloop`` is not yet supported on Windows so that won't work\neither.\n\nAt the very least, ``aiorun`` will, well, *run* on Windows \u00af\\_(\u30c4)_/\u00af\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cjrh/aiorun", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "aiorun", "package_url": "https://pypi.org/project/aiorun/", "platform": "", "project_url": "https://pypi.org/project/aiorun/", "project_urls": { "Homepage": "https://github.com/cjrh/aiorun" }, "release_url": "https://pypi.org/project/aiorun/2019.4.1/", "requires_dist": [ "typing; python_version < '3.5'", "pytest; extra == \"dev\"", "pytest-cov; extra == \"dev\"" ], "requires_python": ">=3.5", "summary": "Boilerplate for asyncio applications", "version": "2019.4.1" }, "last_serial": 5128294, "releases": { "2017.10.1": [ { "comment_text": "", "digests": { "md5": "f5190ad7182477256f38315a4d675be3", "sha256": "095894c711bf65e509f2da8de95843dade8e4f56e000c4df2dde0a6e263c5665" }, "downloads": -1, "filename": "aiorun-2017.10.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f5190ad7182477256f38315a4d675be3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15550, "upload_time": "2017-10-20T12:02:10", "url": "https://files.pythonhosted.org/packages/40/d5/75516116e00712c40931accbbaacc4455cb15a89b63fb31e731119b20b78/aiorun-2017.10.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6a9d0c3b4c6a370ea91c109ab6a24e51", "sha256": "baf61bdb8d3cc85641805bc4c9dc6a0f0e53ac253e4128ed1ed3288ee3258608" }, "downloads": -1, "filename": "aiorun-2017.10.1.tar.gz", "has_sig": false, "md5_digest": "6a9d0c3b4c6a370ea91c109ab6a24e51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7946, "upload_time": "2017-10-20T12:02:20", "url": "https://files.pythonhosted.org/packages/9a/2c/ea01f0cc5e1943738d3bc051b966adb2727c4e238b9130e44b63d40ccecd/aiorun-2017.10.1.tar.gz" } ], "2017.10.2": [ { "comment_text": "", "digests": { "md5": "e8f26108f11abcbee68fb83c580f18b3", "sha256": "c7e572d7064cd2c82a9e71b86922429b191058cced71ca0fde2248e1066a7fe1" }, "downloads": -1, "filename": "aiorun-2017.10.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e8f26108f11abcbee68fb83c580f18b3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15623, "upload_time": "2017-10-24T11:05:39", "url": "https://files.pythonhosted.org/packages/14/f2/af1e52afdc68b0abf7d36096a5a645ba8af7b57edb6d5de6a6024c9f19bb/aiorun-2017.10.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "513bbce8cc9de87f146193a345e6a2e2", "sha256": "7f7cb189aa9d279974b8501e78f84fb7281e12201f5e419269c7594039b0c8c1" }, "downloads": -1, "filename": "aiorun-2017.10.2.tar.gz", "has_sig": false, "md5_digest": "513bbce8cc9de87f146193a345e6a2e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7965, "upload_time": "2017-10-24T11:05:42", "url": "https://files.pythonhosted.org/packages/d3/7d/ef30df9a0d34e2b1639d83df1b08de2d74a5e7fb3131fffaf01c7c2ac1da/aiorun-2017.10.2.tar.gz" } ], "2017.10.3": [ { "comment_text": "", "digests": { "md5": "4a5ea418e1929f765c15d3988ddb78e1", "sha256": "fea610c9b9454f42ad30c06388d23ada58332edc6eb55e9016eba55685c58822" }, "downloads": -1, "filename": "aiorun-2017.10.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4a5ea418e1929f765c15d3988ddb78e1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15592, "upload_time": "2017-10-25T08:22:15", "url": "https://files.pythonhosted.org/packages/eb/d9/b7baa5f3fbf9c8f1cc52201d517fcd6d31ae766cad64a94080de998bcd04/aiorun-2017.10.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "543ea29512981b881344067bdc6d99e5", "sha256": "f1fd3ac3599b9c4ff94927ecf4aa1fe9aaa300bf1479a9f89560c51e289f76f7" }, "downloads": -1, "filename": "aiorun-2017.10.3.tar.gz", "has_sig": false, "md5_digest": "543ea29512981b881344067bdc6d99e5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8004, "upload_time": "2017-10-25T08:22:22", "url": "https://files.pythonhosted.org/packages/98/a0/f1b24f31067c335cf68d2685c74d6cc9b184b51b7c8179266395ba68c667/aiorun-2017.10.3.tar.gz" } ], "2017.10.4": [ { "comment_text": "", "digests": { "md5": "3490278e4c131e793382ee87d3c1f1e9", "sha256": "d5ccd244848ac0d10260c833db8c9a8f1dd2e77418f72b9d858318ce26a8d743" }, "downloads": -1, "filename": "aiorun-2017.10.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3490278e4c131e793382ee87d3c1f1e9", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21196, "upload_time": "2017-10-27T09:57:40", "url": "https://files.pythonhosted.org/packages/31/a2/e621a9676497bfc9f20419153eb1ed3c3d723e716157544077a4f863d562/aiorun-2017.10.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7ab56a7ccab0005eadffeabe538d392c", "sha256": "fecfb6f038770233fd1f0b1bac47c9bcc900473bb30ac92a99684409e75a37b9" }, "downloads": -1, "filename": "aiorun-2017.10.4.tar.gz", "has_sig": false, "md5_digest": "7ab56a7ccab0005eadffeabe538d392c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11513, "upload_time": "2017-10-27T09:57:44", "url": "https://files.pythonhosted.org/packages/80/50/ab7071b373d3c1c2da2de74b31d0dd0093b2e56413695f4a2d9c1dab9cbd/aiorun-2017.10.4.tar.gz" } ], "2017.10.5": [ { "comment_text": "", "digests": { "md5": "d595bae27d986aec4d37abf6a52c5932", "sha256": "7ca9a2d4661f568d16d2fb0828d491215b6ba39e57b595e0782373bc1e575ebc" }, "downloads": -1, "filename": "aiorun-2017.10.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d595bae27d986aec4d37abf6a52c5932", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21576, "upload_time": "2017-10-28T20:58:58", "url": "https://files.pythonhosted.org/packages/53/ca/cdd1ab460e74fe8d56e70e18c9a7ddd78da62e6fd5bf5d7d386d8f545456/aiorun-2017.10.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "473339dd34460eb5ca82bb2e6c956f1a", "sha256": "992c180466b72ab2414d590584ce002c1568647775e5a641b7cac63d506c6e3d" }, "downloads": -1, "filename": "aiorun-2017.10.5.tar.gz", "has_sig": false, "md5_digest": "473339dd34460eb5ca82bb2e6c956f1a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11651, "upload_time": "2017-10-28T20:59:02", "url": "https://files.pythonhosted.org/packages/9d/86/3bebab774ee1e6cb2ce65f514100e887bc01545a7cc19b232b5c989134f6/aiorun-2017.10.5.tar.gz" } ], "2017.11.1": [ { "comment_text": "", "digests": { "md5": "a42d8d52a8a6702bd4a2a1d64b4ef613", "sha256": "6be190a96fae6c3f9f6223b35c53b1eef0acfa94fb4d9bf5356fd6a49c06ad06" }, "downloads": -1, "filename": "aiorun-2017.11.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a42d8d52a8a6702bd4a2a1d64b4ef613", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21808, "upload_time": "2017-11-04T23:35:41", "url": "https://files.pythonhosted.org/packages/0a/1e/de347bc5b1c1840e1288326d0611cd814d2eadaa3997e56d5e7396331f9e/aiorun-2017.11.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6464c9eeda9120f3a4a466a2645f7804", "sha256": "44c78c4a647696b910d3806c482307471daf455bdef058e5cdaf8049b0fa543a" }, "downloads": -1, "filename": "aiorun-2017.11.1.tar.gz", "has_sig": false, "md5_digest": "6464c9eeda9120f3a4a466a2645f7804", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11779, "upload_time": "2017-11-04T23:35:45", "url": "https://files.pythonhosted.org/packages/05/28/c8488396940ecb9d395b47cf3e7d3509c9e0e7ab02b12a741b07d47a8872/aiorun-2017.11.1.tar.gz" } ], "2017.11.2": [ { "comment_text": "", "digests": { "md5": "3a92ca394096e1b8cc45ca30b22ae15a", "sha256": "108f46ef3e0f90bdcda1d8e659e2d777b7e161fb52c962d6813d2844c2b6ebd2" }, "downloads": -1, "filename": "aiorun-2017.11.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3a92ca394096e1b8cc45ca30b22ae15a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 22328, "upload_time": "2017-11-08T03:04:56", "url": "https://files.pythonhosted.org/packages/7c/0b/8d1279f6a0c2913baee82900228cf721ce9da5ae0bd1d55ab9db24cf97d5/aiorun-2017.11.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "20a2fd59a9cc5fed21c9f8ae6417988b", "sha256": "8ea3bfc7e9b7374773e8f8ffb502d5abacb4e57b30a28082ca31615296eb6270" }, "downloads": -1, "filename": "aiorun-2017.11.2.tar.gz", "has_sig": false, "md5_digest": "20a2fd59a9cc5fed21c9f8ae6417988b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12128, "upload_time": "2017-11-08T03:04:59", "url": "https://files.pythonhosted.org/packages/d9/eb/d8225a35f7cc56bcd23dc73bb7422fa66426a146cc4dd2cde161eda5a4ee/aiorun-2017.11.2.tar.gz" } ], "2017.11.4": [ { "comment_text": "", "digests": { "md5": "12c569270a10673c18d84ac1987b0db4", "sha256": "70839d66809fd9bd57b439302912713cc2e8adf049cbc0cf9771e21ce4e38076" }, "downloads": -1, "filename": "aiorun-2017.11.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "12c569270a10673c18d84ac1987b0db4", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24172, "upload_time": "2017-11-14T22:23:02", "url": "https://files.pythonhosted.org/packages/6e/c6/6b43ceb9802f86f1f453c8a636981363968e53f2a346dfa6df0fdf2c1df9/aiorun-2017.11.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fed9c4df0912e5aab72ef77cef4973a1", "sha256": "30b263202750210fcdd324597f67ac9c71af0291ce229fac254697040a827dca" }, "downloads": -1, "filename": "aiorun-2017.11.4.tar.gz", "has_sig": false, "md5_digest": "fed9c4df0912e5aab72ef77cef4973a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12776, "upload_time": "2017-11-14T22:23:05", "url": "https://files.pythonhosted.org/packages/d2/2d/15907a39f4d45341717efd94274d20202a2f06575ece1127e12377fa6401/aiorun-2017.11.4.tar.gz" } ], "2017.11.5": [ { "comment_text": "", "digests": { "md5": "fffcb5fb955538ad324a040212ff5de1", "sha256": "28ec96a9336109e7bb6cce88ffd7f5cdb94546ae613e0c8bc669cbd1c66981ff" }, "downloads": -1, "filename": "aiorun-2017.11.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fffcb5fb955538ad324a040212ff5de1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 25050, "upload_time": "2017-11-15T01:08:57", "url": "https://files.pythonhosted.org/packages/ca/8f/685d7484fee18a9761eeabd3f6e6352f7e2214730878e44afe8bcbeb7dcf/aiorun-2017.11.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b591489c1cd33f043e93b98116c1136b", "sha256": "3108894c0762c899510f40cfe45f797b02553eebf453b46f2de23a578518e0a8" }, "downloads": -1, "filename": "aiorun-2017.11.5.tar.gz", "has_sig": false, "md5_digest": "b591489c1cd33f043e93b98116c1136b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13799, "upload_time": "2017-11-15T01:09:00", "url": "https://files.pythonhosted.org/packages/e4/09/388d7cbdc3eed0ceb8a69c907ea37bdbdd1b270cdd408063dc1842947564/aiorun-2017.11.5.tar.gz" } ], "2017.11.6": [ { "comment_text": "", "digests": { "md5": "391cc271557b95603a91fd3e7b9cd55f", "sha256": "a7100573b83bdf31135f4dddefea0a2be42c6172887ba6b0adbcdc9b8aafdb56" }, "downloads": -1, "filename": "aiorun-2017.11.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "391cc271557b95603a91fd3e7b9cd55f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24774, "upload_time": "2017-11-28T22:35:47", "url": "https://files.pythonhosted.org/packages/de/71/6550f287ff10c27b77782f8b18123b99e1ff896b7e3daa68696fca9f7f98/aiorun-2017.11.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "245c458f544bfc65beb75a4c2793c6fd", "sha256": "373c3cbd3afe350174e8d971d9b8cd25839b915126575f22da9cd09dddc4b63b" }, "downloads": -1, "filename": "aiorun-2017.11.6.tar.gz", "has_sig": false, "md5_digest": "245c458f544bfc65beb75a4c2793c6fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14187, "upload_time": "2017-11-28T22:35:50", "url": "https://files.pythonhosted.org/packages/5d/5b/3fef8c22e9b399fac7520460216816db027d4ece8e7eb67085b64dc29a95/aiorun-2017.11.6.tar.gz" } ], "2018.3.1": [ { "comment_text": "", "digests": { "md5": "d6c8e98c441d2fc0557275fbd410f85a", "sha256": "429640979c450cb81c169f13147ba0cdf54074e791c423b6fc1be4c8724402bd" }, "downloads": -1, "filename": "aiorun-2018.3.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d6c8e98c441d2fc0557275fbd410f85a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24771, "upload_time": "2018-03-26T01:31:33", "url": "https://files.pythonhosted.org/packages/2c/cd/2d5b2a8ec5c61b61dfc351cd09f7e2d2256311a8e3634b9845281622cba9/aiorun-2018.3.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cb235a98799131321858e899da30a7a4", "sha256": "4e5622651de5e2bfe1ac167bc3d53ff41630e4af497d9639e88553558524bfb4" }, "downloads": -1, "filename": "aiorun-2018.3.1.tar.gz", "has_sig": false, "md5_digest": "cb235a98799131321858e899da30a7a4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14200, "upload_time": "2018-03-26T01:31:35", "url": "https://files.pythonhosted.org/packages/fe/5b/da518d9cd2a4c9062e71cf2aae47e37e0d5a302ce3ab349c7c0db718bfd6/aiorun-2018.3.1.tar.gz" } ], "2018.4.1": [ { "comment_text": "", "digests": { "md5": "5f457484594f8401d3505095d1e67fd6", "sha256": "3d5129248ce824e235a680b543eded32efc4603b491f4823242734e96230703d" }, "downloads": -1, "filename": "aiorun-2018.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5f457484594f8401d3505095d1e67fd6", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24994, "upload_time": "2018-04-20T06:11:55", "url": "https://files.pythonhosted.org/packages/03/e2/ad8cc44a3a7209f9472f2869bd47948b238696052cd301c1a81370d3b769/aiorun-2018.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8f22a2983967af66d6163fb862a7b5ee", "sha256": "4714329c02c59befabdf327c38a6e39509a69f2c1ab45f379d73d60a3f29e0f1" }, "downloads": -1, "filename": "aiorun-2018.4.1.tar.gz", "has_sig": false, "md5_digest": "8f22a2983967af66d6163fb862a7b5ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14433, "upload_time": "2018-04-20T06:12:00", "url": "https://files.pythonhosted.org/packages/c9/d2/d7c46c6c1841c170421f30d15e2e8841feb3874e87152a6bd414523ce809/aiorun-2018.4.1.tar.gz" } ], "2018.8.1": [ { "comment_text": "", "digests": { "md5": "f72ec6644677af43bb79ac8d3252f592", "sha256": "4a2c6755254671090c89b13cbb0824f33f79f61ee9fa49fe15718c5ee99118dd" }, "downloads": -1, "filename": "aiorun-2018.8.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f72ec6644677af43bb79ac8d3252f592", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24976, "upload_time": "2018-08-07T05:57:19", "url": "https://files.pythonhosted.org/packages/0e/1f/22968ffadfc5b209413899cd04a4dc72a72b95fcba400538263a10c4110d/aiorun-2018.8.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cffe24fd35e842e4c176399677db545c", "sha256": "cf92656b9a95d9a1c24bd2a28ce5e549fd6a850d2cbcb73fa4b9916d452f5525" }, "downloads": -1, "filename": "aiorun-2018.8.1.tar.gz", "has_sig": false, "md5_digest": "cffe24fd35e842e4c176399677db545c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14545, "upload_time": "2018-08-07T05:57:22", "url": "https://files.pythonhosted.org/packages/77/9a/4d3a3d264495f77fb08bb2156ec5d7fc89157405b7466424390ee30a7850/aiorun-2018.8.1.tar.gz" } ], "2018.9.1": [ { "comment_text": "", "digests": { "md5": "58d69adf1800e007eb2ea7094bb5c3f0", "sha256": "1e1180e09ab7753c51473eb1402a1bba73ff06e3f0421964af7dd90bdb0d08be" }, "downloads": -1, "filename": "aiorun-2018.9.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "58d69adf1800e007eb2ea7094bb5c3f0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24996, "upload_time": "2018-09-10T04:32:26", "url": "https://files.pythonhosted.org/packages/e7/5f/f00aa011452206e8a34caff15ce22de01adabaa667b874d80d355deb641d/aiorun-2018.9.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fd3234208ad8ce090050d4b336554695", "sha256": "535ab7d2864c7dfcf262a5bac5b8eef944eecc5f4ddd46168875863462c3f576" }, "downloads": -1, "filename": "aiorun-2018.9.1.tar.gz", "has_sig": false, "md5_digest": "fd3234208ad8ce090050d4b336554695", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14560, "upload_time": "2018-09-10T04:32:29", "url": "https://files.pythonhosted.org/packages/d7/38/2be882ef5438bb708281b08552b988027964651b49ab0fbce8ccdddf7661/aiorun-2018.9.1.tar.gz" } ], "2019.3.1": [ { "comment_text": "", "digests": { "md5": "3b40c481dfb4a443be2de85105bca8d3", "sha256": "cc08ece87a51268b0064e1330f06d7ed3e4dcf0a316d07cd4388560b02d90153" }, "downloads": -1, "filename": "aiorun-2019.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3b40c481dfb4a443be2de85105bca8d3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 25294, "upload_time": "2019-03-29T14:31:35", "url": "https://files.pythonhosted.org/packages/80/5f/8641d235e416d8588d6ab6ab0f75678af09d2a938a10719de8abeb7db1fa/aiorun-2019.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "57c920f3fe9985327efc755f455cc5f4", "sha256": "607c8bff92d35b688aca3e1d5c9267b48df5c87d3fec09f35c1b6401c4ec01f1" }, "downloads": -1, "filename": "aiorun-2019.3.1.tar.gz", "has_sig": false, "md5_digest": "57c920f3fe9985327efc755f455cc5f4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 14923, "upload_time": "2019-03-29T14:31:44", "url": "https://files.pythonhosted.org/packages/a1/b9/ac2a773d867662a25428137954e0f869b07e868d35c6fae2f412abeafb69/aiorun-2019.3.1.tar.gz" } ], "2019.4.1": [ { "comment_text": "", "digests": { "md5": "c4ee9dc4dd2e09199d9c405a4ca4be46", "sha256": "4b831cc6fcae3275fbe24fd9ae4647f87ceb12171dfcfe0d79c984814bbaedb1" }, "downloads": -1, "filename": "aiorun-2019.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "c4ee9dc4dd2e09199d9c405a4ca4be46", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 28210, "upload_time": "2019-04-11T10:35:42", "url": "https://files.pythonhosted.org/packages/c0/c1/ba5f1ce8d9bc3ac3a17969414ba5e0935ef4c440420705a368f3677b5892/aiorun-2019.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e9fb0cb3bc6fc43e719d5841be2bceb4", "sha256": "5da1ebc219b2c3c52bd92ffbe412f1debc936836a0ea048a62835b7be2f60436" }, "downloads": -1, "filename": "aiorun-2019.4.1.tar.gz", "has_sig": false, "md5_digest": "e9fb0cb3bc6fc43e719d5841be2bceb4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 17509, "upload_time": "2019-04-11T10:35:53", "url": "https://files.pythonhosted.org/packages/d7/d1/38d43147c81bf0f324d27d8821ee60045dbb57372b76b8e40129ee758f1d/aiorun-2019.4.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c4ee9dc4dd2e09199d9c405a4ca4be46", "sha256": "4b831cc6fcae3275fbe24fd9ae4647f87ceb12171dfcfe0d79c984814bbaedb1" }, "downloads": -1, "filename": "aiorun-2019.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "c4ee9dc4dd2e09199d9c405a4ca4be46", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 28210, "upload_time": "2019-04-11T10:35:42", "url": "https://files.pythonhosted.org/packages/c0/c1/ba5f1ce8d9bc3ac3a17969414ba5e0935ef4c440420705a368f3677b5892/aiorun-2019.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e9fb0cb3bc6fc43e719d5841be2bceb4", "sha256": "5da1ebc219b2c3c52bd92ffbe412f1debc936836a0ea048a62835b7be2f60436" }, "downloads": -1, "filename": "aiorun-2019.4.1.tar.gz", "has_sig": false, "md5_digest": "e9fb0cb3bc6fc43e719d5841be2bceb4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 17509, "upload_time": "2019-04-11T10:35:53", "url": "https://files.pythonhosted.org/packages/d7/d1/38d43147c81bf0f324d27d8821ee60045dbb57372b76b8e40129ee758f1d/aiorun-2019.4.1.tar.gz" } ] }