{ "info": { "author": "Ivan Sagalaev", "author_email": "maniac@softwaremaniacs.org", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "License :: OSI Approved :: BSD License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Programming Language :: Python", "Topic :: Internet", "Topic :: Software Development :: Libraries" ], "description": "Adisp is a library that allows structuring code with asynchronous calls and\r\ncallbacks without defining callbacks as separate functions. The code then\r\nbecomes sequential and easy to read. The library is not a framework by itself\r\nand can be used in other environments that provides asynchronous working model\r\n(see an example with Tornado server in proxy_example.py).\r\n\r\nUsage:\r\n\r\n## Organizing calling code\r\n\r\nAll the magic is done with Python 2.5 decorators that allow for control flow to\r\nleave a function, do sometihing else for some time and then return into the\r\ncalling function with a result. So the function that makes asynchronous calls\r\nshould look like this:\r\n\r\n @process\r\n def my_handler():\r\n response = yield some_async_func()\r\n data = parse_response(response)\r\n result = yield some_other_async_func(data)\r\n store_result(result)\r\n\r\nEach `yield` is where the function returns and lets the framework around it to\r\ndo its job. And the code after `yield` is what usually goes in a callback.\r\n\r\nThe @process decorator is needed around such a function. It makes it callable\r\nas an ordinary function and takes care of dispatching callback calls back into\r\nit.\r\n\r\n## Writing asynchronous function\r\n\r\nIn the example above functions \"some_async_func\" and \"some_other_async_func\"\r\nare those that actually run an asynchronous process. They should follow two\r\nconditions:\r\n\r\n- accept a \"callback\" parameter with a callback function that they should call\r\n after an asynchronous process is finished\r\n- a callback should be called with one parameter -- the result\r\n- be wrapped in the @async decorator\r\n\r\nThe @async decorator makes a function call lazy allowing the @process that\r\ncalls it to provide a callback to call.\r\n\r\nUsing async with @-syntax is most convenient when you write your own\r\nasynchronous function (and can make your callback parameter to be named\r\n\"callback\"). But when you want to call some library function you can wrap it in\r\nasync in place.\r\n\r\n # call http.fetch(url, callback=callback)\r\n result = yield async(http.fetch)\r\n\r\n # call http.fetch(url, cb=safewrap(callback))\r\n result = yield async(http.fetch, cbname='cb', cbwrapper=safewrap)(url)\r\n\r\nHere you can use two optional parameters for async:\r\n\r\n- `cbname`: a name of a parameter in which the function expects callbacks\r\n- `cbwrapper`: a wrapper for the callback iself that will be applied before\r\n calling it\r\n\r\n## Chain calls\r\n\r\n@async function can also be @process'es allowing to effectively chain\r\nasynchronous calls as it can be done with normal functions. In this case the\r\n@async decorator shuold be the outer one:\r\n\r\n @async\r\n @process\r\n def async_calling_other_asyncs(arg, callback):\r\n # ....\r\n\r\n## Multiple asynchronous calls\r\n\r\nThe library also allows to call multiple asynchronous functions in parallel and\r\nget all their result for processing at once:\r\n\r\n @async\r\n def async_http_get(url, callback):\r\n # get url asynchronously\r\n # call callback(response) at the end\r\n\r\n @process\r\n def get_stat():\r\n urls = ['http://.../', 'http://.../', ... ]\r\n responses = yield map(async_http_get, urls)\r\n\r\nAfter *all* the asynchronous calls will complete `responses` will be a list of\r\nresponses corresponding to given urls.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://code.launchpad.net/~isagalaev/adisp/trunk", "keywords": "", "license": "UNKNOWN", "maintainer": "", "maintainer_email": "", "name": "adisp", "package_url": "https://pypi.org/project/adisp/", "platform": "Linux,Mac", "project_url": "https://pypi.org/project/adisp/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://code.launchpad.net/~isagalaev/adisp/trunk" }, "release_url": "https://pypi.org/project/adisp/0.0.3/", "requires_dist": null, "requires_python": null, "summary": "Callback-less python async calls dispatcher", "version": "0.0.3" }, "last_serial": 786130, "releases": { "0.0.3": [ { "comment_text": "", "digests": { "md5": "8a26d447ad203fd9010c1e821550fa2c", "sha256": "572b198f5182aecd31dd419221ad27b7b1aab09ee4428ba0a017d7b804e5aa77" }, "downloads": -1, "filename": "adisp-0.0.3.tar.gz", "has_sig": false, "md5_digest": "8a26d447ad203fd9010c1e821550fa2c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3766, "upload_time": "2012-12-11T08:14:25", "url": "https://files.pythonhosted.org/packages/af/e6/9eca89300c504541316f7a6cd3ea2ad8897473e84ef98580c4a5b57e8aed/adisp-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8a26d447ad203fd9010c1e821550fa2c", "sha256": "572b198f5182aecd31dd419221ad27b7b1aab09ee4428ba0a017d7b804e5aa77" }, "downloads": -1, "filename": "adisp-0.0.3.tar.gz", "has_sig": false, "md5_digest": "8a26d447ad203fd9010c1e821550fa2c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3766, "upload_time": "2012-12-11T08:14:25", "url": "https://files.pythonhosted.org/packages/af/e6/9eca89300c504541316f7a6cd3ea2ad8897473e84ef98580c4a5b57e8aed/adisp-0.0.3.tar.gz" } ] }