{ "info": { "author": "Ryan Northey", "author_email": "ryan@3ca.org.uk", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Detailed documentation\n**********************\n\naio.app\n=======\n\nApplication runner for the aio_ asyncio framework\n\n.. _aio: https://github.com/phlax/aio\n\n\nBuild status\n------------\n\n.. image:: https://travis-ci.org/phlax/aio.app.svg?branch=master\n\t :target: https://travis-ci.org/phlax/aio.app\n\n\nInstallation\n------------\n\nRequires python >= 3.4\n\nInstall with:\n\n.. code:: bash\n\n\t pip install aio.app\n\n\nQuick start - hello world scheduler\n-----------------------------------\n\nSave the following into a file \"hello.conf\"\n\n.. code:: ini\n\t \n\t [schedule/EXAMPLE]\n\t every = 2\n\t func = my_example.schedule_handler\n\nAnd save the following into a file named \"my_example.py\"\t \n\t \n.. code:: python\n\n\t import asyncio\n\t \n\t def schedule_handler(event):\n\t yield from asyncio.sleep(1)\n\t print (\"Received scheduled: %s\" % event.name)\n\nRun with the aio run command\n\n.. code:: bash\n\n\t aio run -c hello.conf\n\t \n\n\nThe *aio config* command\n------------------------\n\nWhen saving or reading configuration options, configuration files are searched for in order from the following locations\n\n- aio.conf\n- etc/aio.conf\n- /etc/aio/aio.conf\n\nTo dump the system configuration you can run\n\n.. code:: bash\n\n\t aio config\n\nTo dump a configuration section you can use -g or --get with the section name\n\n.. code:: bash\n\n\t aio config -g aio\n\n\t aio config --get aio/commands\n\nTo get a configuration option, you can use -g with the section name and option\n\n.. code:: bash\n\n\t aio config -g aio:log_level\n\n\t aio config --get listen/example:example-signal\n\nYou can set a configuration option with -s or --set\n\nOptions containing interpolation should be enclosed in single quotes\n\nMulti-line options should be enclosed in \" and separated with \"\\\\n\"\n\n.. code:: bash\n\n\t aio config --set aio:log_level DEBUG\n\n\t aio config -s aio/otherapp:log_level '${aio:log_level}'\n\t \n\t aio config -s listen/example:example-signal \"my.listener\\nmy.listener2\"\n\nIf no configuration files are present in the standard locations, aio will attempt to save in \"aio.conf\" in the current working directory\n\nTo get or set an option in a particular file you can use the -f flag\n\n.. code:: bash\n\n\t aio config -g aio:modules -f custom.conf\n\n\t aio config -s aio:log_level DEBUG -f custom.conf\n\nWhen getting config values with the -f flag, ExtendedInterpolation_ is not used, and you therefore see the raw values\n\n\n\nthe *aio run* command\n---------------------\n\nYou can run an aio app as follows:\n\n.. code:: bash\n\n\t aio run\n\nOr with a custom configuration file\n\t \n.. code:: bash\n\n\t aio -c custom.conf run\n\n\nOn startup aio run sets up the following\n\n- Configuration - system-wide configuration\n- Modules - initialization and configuration of modules\n- Logging - system logging policies \n- Schedulers - functions called at set times\n- Servers - listening on tcp/udp or other type of socket\n- Signals - functions called in response to events\n\n\nConfiguration\n~~~~~~~~~~~~~\n\nConfiguration is in ini syntax\n\n.. code:: ini\n\n\t [aio]\n\t foo = eggs\n\t spam\n\nWhile the app is running the system configuration is importable from aio.app\n\n.. code:: python\n\n\t from aio.app import config\n\nConfiguration is parsed using ExtendedInterpolation_ as follows\n\n- aio.app defaults read\n- user configuration read to initialize modules\n- \"aio.conf\" read from initialized modules where present\n- user configuration read again\n\n\nLogging\n~~~~~~~\n\nLogging policies can be placed in the configuration file, following pythons fileConfig_ format\n\n.. _fileConfig: https://docs.python.org/3/library/logging.config.html#logging-config-fileformat\n\nAs the configuration is parsed with ExtendedInterpolation_ you can use options from other sections\n\n.. code:: ini\n\n\t [logger_root]\n\t level=${aio:log_level}\n\t handlers=consoleHandler\n\t qualname=aio\n\nThe default aio:log_level is INFO\n\nAny sections that begin with handler, logger, or formatter will automattically be added to the relevant logging section\n\nSo by adding a section such as\n\n.. code:: ini\n\n\t [logger_custom]\n\t level=${aio:log_level}\n\t handlers=consoleHandler\n\t qualname=custom\n\n\"logger_custom\" will automatically be added to the logger keys:\n\n.. code:: ini\n\n\t [loggers]\n\t keys=root,custom\n\n\nModules\n~~~~~~~\n\nYou can list any modules that should be imported at runtime in the configuration\n\n.. code:: ini\n\n\t [aio]\n\t modules = aio.web.server\n\t aio.manhole.server\n\nConfiguration for each module is read from a file named \"aio.conf\" in the module's path, if it exists.\n\nThe initialized modules can be accessed from aio.app\n\n.. code:: python\n\n\t from aio.app import modules\n\n\nSchedulers\n~~~~~~~~~~\n\nSchedule definition sections are in the following format\n\n.. code:: ini\n\n\t [schedule/SCHEDULE_NAME]\n\n\nSpecify the frequency and the function to call. The function will be wrapped in a coroutine if it isnt one already\n\n.. code:: ini\n\n\t [schedule/example]\n\t every = 2\n\t func = my.scheduler.example_scheduler\n\nThe scheduler function receives a ScheduledEvent object\n\n.. code:: python\n\n\t def example_scheduler(event):\n yield from asyncio.sleep(2)\n\t # do something\n\t print(event.name)\n\t pass\n\nServers\n~~~~~~~\n\nServer definition sections are in the following format\n\n.. code:: ini\n\n\t [server/SERVER_NAME]\n\nThe server requires either a factory or a protocol to start\n\nProtocol configuration example:\n\n.. code:: ini\n\n\t [server/example]\n\t protocol = my.example.MyServerProtocol\n\t port = 8888\n\nProtocol example code:\n\n.. code:: python\n\n\t class MyServerProtocol(asyncio.Protocol):\n\n\t def connection_made(self, transport):\n\t self.transport = transport\n\n\t def data_received(self, data):\n\t # do stuff\n\t self.transport.close()\n\nFor the protocol option you can either specify a subclass of asyncio.Protocol or you can use a function decorated with aio.app.server.protocol\n\n.. code:: ini\n\n\t [server/example]\n\t protocol = my.example.protocol\n\t port = 8888\n\nExample code for a server protocol function\n\n.. code:: python\n\n\t import asyncio\n\t import aio.app\n\t \n\t @aio.app.server.protocol\n\t def server_protocol():\n\t yield from asyncio.sleep(1)\n\t # do something\n\t \n\t return MyServerProtocol\n\t \n\nIf you need further control over how the protocol is attached you can specify a factory method\n\nFactory configuration example:\n\n.. code:: ini\n\n\t [server/example]\n\t factory = my.example.server_factory\n\t port = 8080\n\nThe factory method must be wrapped in aio.app.server.factory, and is called in a coroutine\n\n.. code:: python\n\n\t @aio.app.server.factory\n\t def server_factory(name, protocol, address, port):\n\t yield from asyncio.sleep(1)\n\t # do something\n\t \n\t loop = asyncio.get_event_loop()\n\t return (\n\t yield from loop.create_server(\n\t\t MyServerProtocol, address, port))\n\n\nSignals\n~~~~~~~\n\nSignal definition sections are in the following format\n\n.. code:: ini\n\n\t [signal/SIGNAL_NAME]\n\nAn example listen configuration section\n\n.. code:: ini\n\n\t [listen/example]\n\t example-signal = my.example.listener\n\nAnd an example listener function. The listener function will be called as a coroutine\n\n.. code:: python\n\n\t def listener(signal):\n\t yield from asyncio.sleep(2)\n\t print(signal.data)\n\nSignals are emitted in a coroutine\n\n.. code:: python\n\n\t yield from app.signals.emit(\n 'example-signal', \"BOOM!\")\n\nYou can add multiple subscriptions within each configuration section\n\nYou can also subscribe multiple functions to a signal, and you can have multiple \"listen/\" sections\n\n.. code:: ini\n\n\t [listen/example]\n\t example-signal = my.example.listener\n\t example-signal-2 = my.example.listener2\n\t my.example.listener\n\n\t [listen/example-2]\n\t example-signal-3 = my.example.listener2\t\t\t \n\n \nThe *aio test* command\n----------------------\n\nYou can test the modules set in the aio:modules configuration option\n\n.. code:: ini\n\n\t [aio]\n\t modules = aio.config\n aio.core\n\t aio.signals\n\nBy default the aio test command will test all of your test modules\n\t\t \n.. code:: bash\n\n\t aio test\n\nYou can also specify a module, or modules\n\n.. code:: bash\n\n\t aio test aio.app\n\n\t aio test aio.app aio.core\n\nIf you want to specify a set of modules for testing other than your app modules, you can list them in aio/testing:modules\n\n.. code:: ini\n\n\t [aio/testing]\n\t modules = aio.config\n aio.core\n\nThese can include the app modules\n\n.. code:: ini\n\n\t [aio/testing]\n\t modules = ${aio:modules}\n\t aio.web.page\n\t\t aio.web.server\n\t\t \n\nDependencies\n------------\n\naio.app depends on the following packages\n\n- aio.core_\n- aio.signals_\n- aio.config_\n\n\nRelated software\n----------------\n\n- aio.testing_\n- aio.http.server_\n- aio.web.server_\n- aio.manhole.server_\n\n.. _aio.testing: https://github.com/phlax/aio.testing\n.. _aio.core: https://github.com/phlax/aio.core\n.. _aio.signals: https://github.com/phlax/aio.signals\n.. _aio.config: https://github.com/phlax/aio.config\n\n.. _aio.http.server: https://github.com/phlax/aio.http.server\n.. _aio.web.server: https://github.com/phlax/aio.web.server\n.. _aio.manhole.server: https://github.com/phlax/aio.manhole.server\n\n.. _ExtendedInterpolation: https://docs.python.org/3/library/configparser.html#interpolation-of-values\n\n\n\n\n\naio.app usage\n-------------\n\nThe aio command can be run with any commands listed in the [aio/commands] section of its configuration\n\nThere are also 3 builtin commands - run, config and test\n\nInitially aio.app does not have any config, signals, modules or servers\n\n>>> import aio.app\n\n>>> print(aio.app.signals, aio.app.config, aio.app.modules, aio.app.servers)\nNone None () {}\n\n\nLets start the app runner in a test loop with the default configuration and print out the signals and config objects\n\n>>> import aio.testing\n>>> from aio.app.runner import runner\n\n>>> @aio.testing.run_until_complete\n... def run_app():\n... runner(['run'])\n... \n... print(aio.app.signals)\n... print(aio.app.config)\n... print(aio.app.modules)\n... print(aio.app.servers)\n\n>>> run_app()\n\n\n(,)\n{}\n\n\nClear the app\n-------------\n\nWe can clear the app vars.\n\nThis will also close any socket servers that are currently running\n\n>>> aio.app.clear()\n\n>>> print(aio.app.signals, aio.app.config, aio.app.modules, aio.app.servers)\nNone None () {}\n\n\nAdding a signal listener\n------------------------\n\nWe can add a signal listener in the app config\n\n>>> config = \"\"\"\n... [listen/testlistener]\n... test-signal = aio.app.tests._example_listener\n... \"\"\"\n\nLets create a test listener and make it importable\n\nThe listener needs to be wrapped with aio.app.signal.listener and is called in a coroutine\n\n>>> import asyncio\n\n>>> @aio.app.signal.listener\n... def listener(signal):\n... yield from asyncio.sleep(1)\n... print(\"Listener received: %s\" % signal.data)\n\n>>> aio.app.tests._example_listener = listener\n\nRunning the test...\n\n>>> @aio.testing.run_until_complete \n... def run_app(message):\n... runner(['run'], config_string=config)\n... yield from aio.app.signals.emit('test-signal', message)\n... aio.app.clear()\n\n>>> run_app('BOOM!')\nListener received: BOOM!\n\n\nWe can also add listeners programatically\n\n>>> @aio.testing.run_until_complete \n... def run_app(message):\n... runner(['run'])\n... \n... aio.app.signals.listen('test-signal-2', aio.app.signal.listener(listener))\n... yield from aio.app.signals.emit('test-signal-2', message)\n... aio.app.clear() \n\n>>> run_app('BOOM AGAIN!')\nListener received: BOOM AGAIN!\n \n\nAdding app modules\n------------------\n\nWhen you run the app with the default configuration, the only module listed is aio.app\n\n>>> @aio.testing.run_until_complete\n... def run_app(config_string=None):\n... runner(['run'], config_string=config_string)\n... print(aio.app.modules)\n... aio.app.clear()\n\n>>> run_app()\n(,)\n\nWe can make the app runner aware of any modules that we want to include, these are imported at runtime\n\n>>> config = \"\"\"\n... [aio]\n... modules = aio.app\n... aio.core\n... \"\"\"\n\n>>> run_app(config_string=config)\n(, )\n\n\nRunning a scheduler\n-------------------\n\nA basic configuration for a scheduler\n\n>>> config = \"\"\"\n... [schedule/test-scheduler]\n... every: 2\n... func: aio.app.tests._example_scheduler\n... \"\"\"\n\nLets create a scheduler function and make it importable.\n\nThe scheduler function is wrapped in a coroutine\n\n>>> def scheduler(event):\n... print('HIT: %s' % event.name)\n\n>>> aio.app.tests._example_scheduler = scheduler\n\nWe need to use a aio.testing.run_forever to wait for the scheduled events to occur\n\n>>> @aio.testing.run_forever(timeout=5)\n... def run_app():\n... runner(['run'], config_string=config)\n... \n... return aio.app.clear\n \nRunning the test for 5 seconds we get 3 hits\n\n>>> run_app()\nHIT: test-scheduler\nHIT: test-scheduler\nHIT: test-scheduler\n\n\nRunning a server\n----------------\n\nLets set up and run an addition server\n\nAt a minimum we should provide a protocol and a port to listen on\n\n>>> config_server_protocol = \"\"\"\n... [server/additiontest]\n... protocol: aio.app.tests._example_AdditionServerProtocol\n... port: 8888\n... \"\"\"\n\nLets create the server protocol and make it importable\n\n>>> class AdditionServerProtocol(asyncio.Protocol):\n... \n... def connection_made(self, transport):\n... self.transport = transport\n... \n... def data_received(self, data):\n... nums = [\n... int(x.strip())\n... for x in\n... data.decode(\"utf-8\").split(\"+\")] \n... self.transport.write(str(sum(nums)).encode())\n... self.transport.close()\n\n>>> aio.app.tests._example_AdditionServerProtocol = AdditionServerProtocol\n\nAfter the server is set up, let's call it with a simple addition\n\n\n>>> @aio.testing.run_forever\n... def run_addition_server(config_string, addition):\n... runner(['run'], config_string=config_string)\n... \n... def call_addition_server():\n... reader, writer = yield from asyncio.open_connection(\n... '127.0.0.1', 8888)\n... writer.write(addition.encode())\n... yield from writer.drain()\n... result = yield from reader.read()\n... aio.app.clear()\n... \n... print(int(result))\n... \n... return call_addition_server\n\n>>> run_addition_server(\n... config_server_protocol,\n... '2 + 2 + 3')\n7\n\nIf you need more control over how the server protocol is created you can specify a factory instead\n\n>>> config_server_factory = \"\"\"\n... [server/additiontest]\n... factory = aio.app.tests._example_addition_server_factory\n... port: 8888\n... \"\"\"\n\nThe factory method must be decorated with aio.app.server.factory\n\n>>> @aio.app.server.factory\n... def addition_server_factory(name, protocol, address, port):\n... loop = asyncio.get_event_loop()\n... return (\n... yield from loop.create_server(\n... AdditionServerProtocol,\n... address, port))\n\n>>> aio.app.tests._example_addition_server_factory = addition_server_factory\n\n>>> run_addition_server(\n... config_server_protocol,\n... '17 + 5 + 1')\n23", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/phlax/aio.app", "keywords": "", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "aio.app", "package_url": "https://pypi.org/project/aio.app/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/aio.app/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/phlax/aio.app" }, "release_url": "https://pypi.org/project/aio.app/0.1.8/", "requires_dist": null, "requires_python": null, "summary": "Aio application runner", "version": "0.1.8" }, "last_serial": 1563890, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "53ef53ac5ab4aee399e90c3e45b3cb96", "sha256": "a61fd5461d058bafeb4e052d8f50e94a9459f81b4ba602b4fec32fb498efbb17" }, "downloads": -1, "filename": "aio.app-0.0.1.tar.gz", "has_sig": false, "md5_digest": "53ef53ac5ab4aee399e90c3e45b3cb96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7145, "upload_time": "2015-05-17T21:52:14", "url": "https://files.pythonhosted.org/packages/db/55/01dfde75c84b26585facb8115a71a8a6a8888f5096fd44ab913f4ddcfd6d/aio.app-0.0.1.tar.gz" } ], "0.0.10": [ { "comment_text": "", "digests": { "md5": "34b3d456b6bebfa1f074e1f5362c0f94", "sha256": "ca81023166f4c8d8fc29a45bb6a948273222a889e403211c875b937a063735af" }, "downloads": -1, "filename": "aio.app-0.0.10.tar.gz", "has_sig": false, "md5_digest": "34b3d456b6bebfa1f074e1f5362c0f94", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10692, "upload_time": "2015-05-19T14:59:18", "url": "https://files.pythonhosted.org/packages/41/3d/8f39cc531ed7c9f1d75ff641cc9b2847985bf64c92e34df2a01208de7adf/aio.app-0.0.10.tar.gz" } ], "0.0.11": [ { "comment_text": "", "digests": { "md5": "62234081a96864f111bcabf8326e3d14", "sha256": "8ad4fc5d2861aa7e2e7fcef8455a157921084f1fc06887452bb25e7436d2964a" }, "downloads": -1, "filename": "aio.app-0.0.11.tar.gz", "has_sig": false, "md5_digest": "62234081a96864f111bcabf8326e3d14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10885, "upload_time": "2015-05-19T15:04:08", "url": "https://files.pythonhosted.org/packages/04/97/73205ea54f9facd828f8c12285d26f90cceb54d2b5b52eadb1d2f936ee90/aio.app-0.0.11.tar.gz" } ], "0.0.12": [ { "comment_text": "", "digests": { "md5": "805c8da24942826313ab2f11808ea586", "sha256": "1efc661737d99938adce7a9e8f2220213bea66f5cf890808f24f1a6107a58eb0" }, "downloads": -1, "filename": "aio.app-0.0.12.tar.gz", "has_sig": false, "md5_digest": "805c8da24942826313ab2f11808ea586", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10980, "upload_time": "2015-05-19T16:37:14", "url": "https://files.pythonhosted.org/packages/94/c8/0797d422905f1bcf8e8e206363093c930c4ebe219955b37d2c0210a3f9b2/aio.app-0.0.12.tar.gz" } ], "0.0.13": [ { "comment_text": "", "digests": { "md5": "728117da645e0b14006c401af4ded21a", "sha256": "a402a0d6d81d371a0abc17160c1d0c5a62040c7931df4600ca13672b870c8839" }, "downloads": -1, "filename": "aio.app-0.0.13.tar.gz", "has_sig": false, "md5_digest": "728117da645e0b14006c401af4ded21a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10976, "upload_time": "2015-05-19T16:56:29", "url": "https://files.pythonhosted.org/packages/de/17/6056421e294429e4910f8512dd55993774befd8affdd6ab2b877d8569eef/aio.app-0.0.13.tar.gz" } ], "0.0.14": [ { "comment_text": "", "digests": { "md5": "6e69a6d0eaa7fac23e644d23443acf3a", "sha256": "865a2e676df7c5f0712422df1a43d9fd6918f6488cdaf32d2c55c00fa7b13916" }, "downloads": -1, "filename": "aio.app-0.0.14.tar.gz", "has_sig": false, "md5_digest": "6e69a6d0eaa7fac23e644d23443acf3a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11223, "upload_time": "2015-05-19T19:29:31", "url": "https://files.pythonhosted.org/packages/d9/f2/3a45a0b61fc3507590909c4a339d10079bcb272955eb3faa7143bc8eeec5/aio.app-0.0.14.tar.gz" } ], "0.0.15": [ { "comment_text": "", "digests": { "md5": "e41242eb3ee9614626946ea01964a110", "sha256": "d068f20af381e57e24d45ffca432a57e60fd82ae0760c4f6d1d7b88d5dcd0887" }, "downloads": -1, "filename": "aio.app-0.0.15.tar.gz", "has_sig": false, "md5_digest": "e41242eb3ee9614626946ea01964a110", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11131, "upload_time": "2015-05-19T19:32:18", "url": "https://files.pythonhosted.org/packages/fc/7e/09184c34bab74d45d25aed381bf1d94b02878b9cad4b7ce33e802aaa83e8/aio.app-0.0.15.tar.gz" } ], "0.0.16": [ { "comment_text": "", "digests": { "md5": "fdff270b174f61b269dbc22eca13d30f", "sha256": "b1841edd6018372137e1ef1bea6321956029d151b3c10c5df57c75c6b0e84952" }, "downloads": -1, "filename": "aio.app-0.0.16.tar.gz", "has_sig": false, "md5_digest": "fdff270b174f61b269dbc22eca13d30f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11195, "upload_time": "2015-05-19T20:10:09", "url": "https://files.pythonhosted.org/packages/67/a2/953642560546551d461f3d2e3f3f423a40cc2439a3e869cb4a69890c3977/aio.app-0.0.16.tar.gz" } ], "0.0.17": [ { "comment_text": "", "digests": { "md5": "1d82f25cc0cb9d3cb0b8c8bd5e92f895", "sha256": "1879deeaa27ed227780debec2f5276c6694bed4dbb631aa9ef86c4b2bfad2642" }, "downloads": -1, "filename": "aio.app-0.0.17.tar.gz", "has_sig": false, "md5_digest": "1d82f25cc0cb9d3cb0b8c8bd5e92f895", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11159, "upload_time": "2015-05-19T22:47:36", "url": "https://files.pythonhosted.org/packages/3f/4f/670e31405e0b94980f72a20b31a27c31a1c87ed9b3524d84b88a9661faa3/aio.app-0.0.17.tar.gz" } ], "0.0.18": [ { "comment_text": "", "digests": { "md5": "ae92057119ca7a9138bfb9639590f9cc", "sha256": "bd5b4fdd89bba264b9fecdfe934d10d2354d18000fe0730e2247258986b2c4a8" }, "downloads": -1, "filename": "aio.app-0.0.18.tar.gz", "has_sig": false, "md5_digest": "ae92057119ca7a9138bfb9639590f9cc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12018, "upload_time": "2015-05-20T11:59:16", "url": "https://files.pythonhosted.org/packages/35/fd/b0b97660efbe40c52015b63dbe973ce7dbb58d4ca8d34cab37897b4c8c35/aio.app-0.0.18.tar.gz" } ], "0.0.19": [ { "comment_text": "", "digests": { "md5": "6464f9a7d958fbc3602d95b5804aca8c", "sha256": "8d52486b374aa6680b5595e0071e9b8d887b0601c068a0b66788598001d963e1" }, "downloads": -1, "filename": "aio.app-0.0.19.tar.gz", "has_sig": false, "md5_digest": "6464f9a7d958fbc3602d95b5804aca8c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13313, "upload_time": "2015-05-20T20:06:01", "url": "https://files.pythonhosted.org/packages/7e/27/fa7811108d36b72584ea07fc8e2c12721ec44cc8c62268d77cb47fa8717b/aio.app-0.0.19.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "5cb95876a8b6ddcbaf4ae8f31fb014fd", "sha256": "32784dd27c56bc54294bff1937b610d63ba7c2d43b8725beea2d5d89e3d24a5d" }, "downloads": -1, "filename": "aio.app-0.0.2.tar.gz", "has_sig": false, "md5_digest": "5cb95876a8b6ddcbaf4ae8f31fb014fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7141, "upload_time": "2015-05-17T21:57:11", "url": "https://files.pythonhosted.org/packages/85/44/b3c1caf34f641e85f0f6afb8a38ab8fe7d9a229ffeed120cf6b911aecda9/aio.app-0.0.2.tar.gz" } ], "0.0.20": [ { "comment_text": "", "digests": { "md5": "694e390ed3df127566c5dae89037ec9b", "sha256": "bbb90642782b87602cee50ce114c2dbb55f819f5ff2227c293a27bd473aeaa4a" }, "downloads": -1, "filename": "aio.app-0.0.20.tar.gz", "has_sig": false, "md5_digest": "694e390ed3df127566c5dae89037ec9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13316, "upload_time": "2015-05-20T20:11:32", "url": "https://files.pythonhosted.org/packages/87/93/e712783505f28443f8f98b7945a488b7518360d39a975e88ed5cfc563d2a/aio.app-0.0.20.tar.gz" } ], "0.0.21": [ { "comment_text": "", "digests": { "md5": "0677da3607583e983393f005ef2d2700", "sha256": "6fe2ad989367be3e71b71ba301fa47df42b8ab7e031bffbdb358211638e52db6" }, "downloads": -1, "filename": "aio.app-0.0.21.tar.gz", "has_sig": false, "md5_digest": "0677da3607583e983393f005ef2d2700", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13312, "upload_time": "2015-05-20T20:16:52", "url": "https://files.pythonhosted.org/packages/05/73/3d1718b171dd4e4af14732cb456c904311317e8a8dadea5144173f56e5e4/aio.app-0.0.21.tar.gz" } ], "0.0.22": [ { "comment_text": "", "digests": { "md5": "d40be675198bffec29b6da59158e0a4c", "sha256": "b6bae3320c2ae2b13c335ea471c379ff4afe81013e3ee3420bfed1883878e4de" }, "downloads": -1, "filename": "aio.app-0.0.22.tar.gz", "has_sig": false, "md5_digest": "d40be675198bffec29b6da59158e0a4c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13333, "upload_time": "2015-05-20T20:21:46", "url": "https://files.pythonhosted.org/packages/99/de/c85e0b27dea73348f8831fc7c0e0c5268891a631563a40ff484ae5ea952d/aio.app-0.0.22.tar.gz" } ], "0.0.23": [ { "comment_text": "", "digests": { "md5": "d1e6f8aa2ce545bcd5b7f9a331e62dc6", "sha256": "4b1aac952f8ecf3af4ff54aa4f6f5c83884a51ab49b7e5f35fa00680ca50fdb0" }, "downloads": -1, "filename": "aio.app-0.0.23.tar.gz", "has_sig": false, "md5_digest": "d1e6f8aa2ce545bcd5b7f9a331e62dc6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13546, "upload_time": "2015-05-22T18:19:12", "url": "https://files.pythonhosted.org/packages/3e/22/f184bdd3560b39419d43228b8dfa07191180ed02340c1abeda7f2a82e1ba/aio.app-0.0.23.tar.gz" } ], "0.0.24": [ { "comment_text": "", "digests": { "md5": "8c95ab2c7b14ab9cab926ffc6db1f7c6", "sha256": "1fa3f4f60a254d6448401882ea93fea80e7a8022b73139c8bda3caf9425e1fe4" }, "downloads": -1, "filename": "aio.app-0.0.24.tar.gz", "has_sig": false, "md5_digest": "8c95ab2c7b14ab9cab926ffc6db1f7c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13705, "upload_time": "2015-05-23T15:01:33", "url": "https://files.pythonhosted.org/packages/ff/31/a1558351e530020f5c82c6801fb84a401cb5741cd9915e3b0c861f4e8c72/aio.app-0.0.24.tar.gz" } ], "0.0.25": [ { "comment_text": "", "digests": { "md5": "7e4107ec3079edcf9a484e1353efd6fb", "sha256": "fd43fe1e20b470afb866f7220abcffa0cf8d50c6a8591103253b85df473a00cd" }, "downloads": -1, "filename": "aio.app-0.0.25.tar.gz", "has_sig": false, "md5_digest": "7e4107ec3079edcf9a484e1353efd6fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13718, "upload_time": "2015-05-23T15:06:52", "url": "https://files.pythonhosted.org/packages/e0/33/449441a1e0f78bffcb8011f4a1ae9e81320580222527329ffa21518f0ff5/aio.app-0.0.25.tar.gz" } ], "0.0.26": [ { "comment_text": "", "digests": { "md5": "87f22b45d4b6eee1cfd1dd7b0e89045b", "sha256": "9815547be673b7a053717ead4fc827f4d9f293e6847dc5c9324c30912137bd0f" }, "downloads": -1, "filename": "aio.app-0.0.26.tar.gz", "has_sig": false, "md5_digest": "87f22b45d4b6eee1cfd1dd7b0e89045b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13769, "upload_time": "2015-05-23T21:02:25", "url": "https://files.pythonhosted.org/packages/a5/e0/a818b41e80a072a0d0bc0a016488f891d14be7e0027f3f033e7241630314/aio.app-0.0.26.tar.gz" } ], "0.0.27": [ { "comment_text": "", "digests": { "md5": "1cabd666b490d820c8b93dfe6c8e01f7", "sha256": "093c11eb78f01012efd0b12ccad8b05b1a97438fcd1d31d806e124de9be60b13" }, "downloads": -1, "filename": "aio.app-0.0.27.tar.gz", "has_sig": false, "md5_digest": "1cabd666b490d820c8b93dfe6c8e01f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13741, "upload_time": "2015-05-23T22:38:42", "url": "https://files.pythonhosted.org/packages/9a/4e/546600826f4cd15849a35bdff766a92dacd89dafc0ed1476632851c94aa7/aio.app-0.0.27.tar.gz" } ], "0.0.28": [ { "comment_text": "", "digests": { "md5": "d768a80f8dfd95551b9615ec0a09bdd2", "sha256": "7d087b1151d56c4fe49a8460e6182612b5e2d14e3a1cffaf910a86f268b0862a" }, "downloads": -1, "filename": "aio.app-0.0.28.tar.gz", "has_sig": false, "md5_digest": "d768a80f8dfd95551b9615ec0a09bdd2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13947, "upload_time": "2015-05-24T02:59:03", "url": "https://files.pythonhosted.org/packages/7b/18/d72f3ab29562feb5fbc1bac57edcfa919b612aa2c9ea1331ec940bedb6e0/aio.app-0.0.28.tar.gz" } ], "0.0.29": [ { "comment_text": "", "digests": { "md5": "576d0403d5c001218eaa2fda74aece4a", "sha256": "dcb0581694eff5b3943ae8dfdf4df07a2bd3cd744ad164e318d23664ab5fed33" }, "downloads": -1, "filename": "aio.app-0.0.29.tar.gz", "has_sig": false, "md5_digest": "576d0403d5c001218eaa2fda74aece4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13943, "upload_time": "2015-05-24T03:02:59", "url": "https://files.pythonhosted.org/packages/38/01/ce2fa4be2bdd8e607e7edb2e83d13c114f9f688ffdf88d30a07b55921d5d/aio.app-0.0.29.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "c471b7e6d59b24ce2658c30ba9aae088", "sha256": "a35646a500effb32503577088642bf8135afb59c20df0f062a9f7461c91ac92f" }, "downloads": -1, "filename": "aio.app-0.0.3.tar.gz", "has_sig": false, "md5_digest": "c471b7e6d59b24ce2658c30ba9aae088", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7165, "upload_time": "2015-05-17T22:00:34", "url": "https://files.pythonhosted.org/packages/c3/2e/cb352110acd3694d8e983c372467734dca67f08a0248eea6b9286bf1937b/aio.app-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "13a868424627e82a4ab8ebc7f655d64d", "sha256": "748023e056ac9752b52995f9696ea79ca0d7129d682dc214716b86be61c27d27" }, "downloads": -1, "filename": "aio.app-0.0.4.tar.gz", "has_sig": false, "md5_digest": "13a868424627e82a4ab8ebc7f655d64d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7705, "upload_time": "2015-05-18T13:06:28", "url": "https://files.pythonhosted.org/packages/ae/c4/b90d71612ed46eeae515acab88756a5276471144502fffa0e46ebc909c7b/aio.app-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "93d4d0185d6cdaf646b5e6210dc6c0dc", "sha256": "bf960f5b850b495a540fdd5996f4f0505094f8e066ac39f3c47a98c89ac7dda1" }, "downloads": -1, "filename": "aio.app-0.0.5.tar.gz", "has_sig": false, "md5_digest": "93d4d0185d6cdaf646b5e6210dc6c0dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9052, "upload_time": "2015-05-18T14:24:32", "url": "https://files.pythonhosted.org/packages/e9/e7/21a9e8226ce5885ed4e6c42677cbc154f388b6c9aaa68250558a688b96cc/aio.app-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "40238eb28a8042c800a535d8f9ce18f8", "sha256": "87483a520043870018216d207b7643fe72685507a4024ee498c8ea8458634e2e" }, "downloads": -1, "filename": "aio.app-0.0.6.tar.gz", "has_sig": false, "md5_digest": "40238eb28a8042c800a535d8f9ce18f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9129, "upload_time": "2015-05-18T19:25:18", "url": "https://files.pythonhosted.org/packages/54/80/afcf291f2d3161a57ad411b56ab8b3c19fb83ed25a5012c18ac5fe27f919/aio.app-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "94e17e99d6e76dabd9b4eff6d0e79f82", "sha256": "89698e1f61f68091c7cca230c1e898d72d4d44bac5b1066f2f1b7fdc3b01ff74" }, "downloads": -1, "filename": "aio.app-0.0.7.tar.gz", "has_sig": false, "md5_digest": "94e17e99d6e76dabd9b4eff6d0e79f82", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9168, "upload_time": "2015-05-18T19:38:13", "url": "https://files.pythonhosted.org/packages/f7/78/0df4f0a6b65cb5bd15e4608bae17950e7f84503ba55dddd1bba95d3600ae/aio.app-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "ab62021dcd291e05a17505f5f4e30d75", "sha256": "060a2a9ba5dd2acac4e7941829aa98f8f7984db0d871f562d8838dcf839515df" }, "downloads": -1, "filename": "aio.app-0.0.8.tar.gz", "has_sig": false, "md5_digest": "ab62021dcd291e05a17505f5f4e30d75", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9170, "upload_time": "2015-05-19T08:22:41", "url": "https://files.pythonhosted.org/packages/5e/08/05473fc0bf97b5d591b99cd87275c5a1875bc3937a329117d7446e532498/aio.app-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "e211542e0f8512b1a261190f343840ac", "sha256": "288ae90447454d8e38e796842b2851ce31e290b7206dc9be7f827d6feadede6c" }, "downloads": -1, "filename": "aio.app-0.0.9.tar.gz", "has_sig": false, "md5_digest": "e211542e0f8512b1a261190f343840ac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10322, "upload_time": "2015-05-19T08:58:26", "url": "https://files.pythonhosted.org/packages/d1/23/27c610e9a9bb74236c8710d6679ff730892b26381b8f0e4e54412a121e22/aio.app-0.0.9.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "6576b6e3aa496dd0afb14ce362d8a12b", "sha256": "bfb1c5a3de3c97574f5e79fa173582484b0d03262c64acaecafff5eafd186fd6" }, "downloads": -1, "filename": "aio.app-0.1.0.tar.gz", "has_sig": false, "md5_digest": "6576b6e3aa496dd0afb14ce362d8a12b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14368, "upload_time": "2015-05-24T21:40:36", "url": "https://files.pythonhosted.org/packages/4f/ca/d71de87234684e77e0b997a0f5801bea89a8dd65e3a1eb860ad00834ee67/aio.app-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "2d4645b1643abf9e41a5f167a117dfc5", "sha256": "84e852e5a3514b605d57b945236d432139a6819a2d8afd49c237f3d1369bc91f" }, "downloads": -1, "filename": "aio.app-0.1.1.tar.gz", "has_sig": false, "md5_digest": "2d4645b1643abf9e41a5f167a117dfc5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14365, "upload_time": "2015-05-24T21:46:19", "url": "https://files.pythonhosted.org/packages/e7/61/a842ea2ad52ac2c6173ff506cb0af6bcbacea03b6b65d4a770e9fd1842e9/aio.app-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "ed9e211ecc63cc386998c702b67317db", "sha256": "6eaead21852f63b4fb97f40f4d9bf3d1e8ddfa63d7de84309498a34500eea1bf" }, "downloads": -1, "filename": "aio.app-0.1.2.tar.gz", "has_sig": false, "md5_digest": "ed9e211ecc63cc386998c702b67317db", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15123, "upload_time": "2015-05-25T17:45:24", "url": "https://files.pythonhosted.org/packages/f7/35/c595bab796f53cb87896d9cda2a0de1c3c472ade636ecb0f968a2c6523df/aio.app-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "0a966900e9758cae67062f8afa946461", "sha256": "3eff125274003c35364f50c0fb11122842f2cfd2afba17c65776480a4f5c0aba" }, "downloads": -1, "filename": "aio.app-0.1.3.tar.gz", "has_sig": false, "md5_digest": "0a966900e9758cae67062f8afa946461", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15210, "upload_time": "2015-05-25T19:01:23", "url": "https://files.pythonhosted.org/packages/f2/13/d4d975bc64f1b72cae2db23ec2f02f3cc5cae3568ed68f72ddce1d8c726f/aio.app-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "42c0dfd036983414fbf33d9157eb6657", "sha256": "761aacab19f60511943478dca7f6459330585bcd49e8567be0779014e6abea24" }, "downloads": -1, "filename": "aio.app-0.1.4.tar.gz", "has_sig": false, "md5_digest": "42c0dfd036983414fbf33d9157eb6657", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15722, "upload_time": "2015-05-25T19:53:05", "url": "https://files.pythonhosted.org/packages/b8/bf/d25db2549f5e209b1c27b663f7771df8923fc3a271f1c86b574503fe6026/aio.app-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "2ad857da6958963eb390703d316930a5", "sha256": "0f44432137b4616ffc4c31b2f730337d1a7bb186e9659bf02bdf07a4de60ab4e" }, "downloads": -1, "filename": "aio.app-0.1.5.tar.gz", "has_sig": false, "md5_digest": "2ad857da6958963eb390703d316930a5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16066, "upload_time": "2015-05-26T22:14:33", "url": "https://files.pythonhosted.org/packages/e5/c2/667d88d7940e15e7337ea0426ef962c6b5ca7f31d75da01faf6bbe5a4186/aio.app-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "b3f55ab97fb7db867db300c44c68187b", "sha256": "2170e46f299616b00b7702e3e0ed05f251778245f6f06fecbd46bc25859ddd80" }, "downloads": -1, "filename": "aio.app-0.1.6.tar.gz", "has_sig": false, "md5_digest": "b3f55ab97fb7db867db300c44c68187b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16086, "upload_time": "2015-05-26T22:17:13", "url": "https://files.pythonhosted.org/packages/c1/5c/99b20edb3a0ae73d0d27dd917e73488f74dbee6bada63f49e2c10b3ff43d/aio.app-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "810c0b3b86c6ad5652a9c4d05df6e9ed", "sha256": "b90cca4c98c5d699dde073540b56be93680391b1fbd53605e3871d009725fcc8" }, "downloads": -1, "filename": "aio.app-0.1.7.tar.gz", "has_sig": false, "md5_digest": "810c0b3b86c6ad5652a9c4d05df6e9ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16086, "upload_time": "2015-05-26T22:41:45", "url": "https://files.pythonhosted.org/packages/5f/96/881108ccdacccae53c7fcee90b00805253ddffdd46e0d734649e6316c9c0/aio.app-0.1.7.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "53fb2543aaa8ee60e05e809936097bec", "sha256": "41c1860e904fd01b09315c8143d577b5ea92726f3cb5b4092a62e7b8dd40ebfa" }, "downloads": -1, "filename": "aio.app-0.1.8.tar.gz", "has_sig": false, "md5_digest": "53fb2543aaa8ee60e05e809936097bec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16076, "upload_time": "2015-05-26T23:13:50", "url": "https://files.pythonhosted.org/packages/c1/64/f11c23560bd621781f634ce47eacd3e1296af9c5e70565e41126a56b5c2f/aio.app-0.1.8.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "53fb2543aaa8ee60e05e809936097bec", "sha256": "41c1860e904fd01b09315c8143d577b5ea92726f3cb5b4092a62e7b8dd40ebfa" }, "downloads": -1, "filename": "aio.app-0.1.8.tar.gz", "has_sig": false, "md5_digest": "53fb2543aaa8ee60e05e809936097bec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16076, "upload_time": "2015-05-26T23:13:50", "url": "https://files.pythonhosted.org/packages/c1/64/f11c23560bd621781f634ce47eacd3e1296af9c5e70565e41126a56b5c2f/aio.app-0.1.8.tar.gz" } ] }