{ "info": { "author": "Michal Charemza", "author_email": "michal@charemza.name", "bugtrack_url": null, "classifiers": [ "Framework :: AsyncIO", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# aiomemoizeconcurrent [![CircleCI](https://circleci.com/gh/michalc/aiomemoizeconcurrent.svg?style=svg)](https://circleci.com/gh/michalc/aiomemoizeconcurrent) [![Test Coverage](https://api.codeclimate.com/v1/badges/5e70552f9dd435a18326/test_coverage)](https://codeclimate.com/github/michalc/aiomemoizeconcurrent/test_coverage)\n\nMemoize concurrent asyncio Python coroutine calls. This offers short-lived memoization: for any given set of arguments, the cache lasts only for the length of a single call.\n\n\n## Installation\n\n```base\npip install aiomemoizeconcurrent\n```\n\n## Usage\n\nFor a coroutine whose arguments are hashable, you can create a _memoized_ version by passing it to `memoize_concurrent`. Any concurrent calls to this version that have the same arguments will result in only a _single_ run of original coroutine. \n\nFor example, creating 3 concurrent invocations of a coroutine where 2 of them have identical arguments\n\n```python\nimport asyncio\nfrom aiomemoizeconcurrent import memoize_concurrent\n\nasync def main():\n memoized_coro = memoize_concurrent(coro)\n\n results = await asyncio.gather(*[\n memoized_coro('a'),\n memoized_coro('a'),\n memoized_coro('b'),\n ])\n print(results)\n\n await memoized_coro('a')\n\nasync def coro(value):\n print('Inside coro', value)\n await asyncio.sleep(1)\n return value\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(main())\nloop.close()\n```\n\nwill only run `coro` twice, as shown by the output\n\n```\nInside coro a\nInside coro b\n['a', 'a', 'b']\n```\n\n\n## Use cases\n\nThis can be used to memoize a function making calls to an API, and especially if\n\n- you expect many concurrent calls;\n- identical concurrent calls are idempotent;\n- there are enough such calls that are identical to justify such a caching layer.\n\nIt can also be used to avoid concurrency edge cases/race conditions with multiple tasks accessing shared resources. For example, multiple tasks may need to dynamically create shared UDP sockets. To ensure that this dynamic generation isn't called by multiple tasks at the same time for the same address, it can be wrapped with `memoize_concurrent`.\n\nThe function `memoize_concurrent` works with both coroutines, and functions that return a future.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/michalc/aiomemoizeconcurrent", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "aiomemoizeconcurrent", "package_url": "https://pypi.org/project/aiomemoizeconcurrent/", "platform": "", "project_url": "https://pypi.org/project/aiomemoizeconcurrent/", "project_urls": { "Homepage": "https://github.com/michalc/aiomemoizeconcurrent" }, "release_url": "https://pypi.org/project/aiomemoizeconcurrent/0.0.8/", "requires_dist": null, "requires_python": "~=3.5", "summary": "Memoize concurrent asyncio Python function calls", "version": "0.0.8" }, "last_serial": 5105612, "releases": { "0.0.6": [ { "comment_text": "", "digests": { "md5": "e8df8c57536e3352f2537d04544795b3", "sha256": "a1cc633730043baa9efaf12843dc325bf2697d5042f7d36f4075de29273035cb" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "e8df8c57536e3352f2537d04544795b3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 3514, "upload_time": "2019-03-31T09:54:11", "url": "https://files.pythonhosted.org/packages/6c/3e/0f271590b0cf199f9d88a16d45c979a2375bf609b3f913ab842224784d25/aiomemoizeconcurrent-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "32c6b8ce7669cae5a6a5dcf25b10a362", "sha256": "514207c446724f84d36867446f04b819edeee99e23ea152954d4e0a857de3be2" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.6.tar.gz", "has_sig": false, "md5_digest": "32c6b8ce7669cae5a6a5dcf25b10a362", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.5", "size": 2385, "upload_time": "2019-03-31T09:54:13", "url": "https://files.pythonhosted.org/packages/52/39/5221f730bf030c22926d6690ad0f460b043fe0e1b306f76e38fc90bdfd6c/aiomemoizeconcurrent-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "be78f70189e16e650026a5cd3d10f8dd", "sha256": "441bf78280079eb3063350dff40cb72edfca6552b07363c261099691cbe7ae73" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "be78f70189e16e650026a5cd3d10f8dd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 3514, "upload_time": "2019-03-31T10:43:21", "url": "https://files.pythonhosted.org/packages/bd/e7/aebe46576cb784d5f69b05ca83640004d92101ae79b6aae6fd73ff21c6c3/aiomemoizeconcurrent-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "14b7030e624680ff98c45b250c7f2afa", "sha256": "0ffd0ee0f483f7663a15d6fb2e839e6b858c12e2ce404221b9e1d8542eca9dc0" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.7.tar.gz", "has_sig": false, "md5_digest": "14b7030e624680ff98c45b250c7f2afa", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.5", "size": 2388, "upload_time": "2019-03-31T10:43:23", "url": "https://files.pythonhosted.org/packages/da/75/bbe2ecb87765480b17b770c7d10716f501528a484818386263d770b76add/aiomemoizeconcurrent-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "10cbddecceaf2d4290db77fe79891c19", "sha256": "dfc05e9a95724dae9c95f612929905dcccebc9011da7343b01d33c74855e7a43" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "10cbddecceaf2d4290db77fe79891c19", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 3510, "upload_time": "2019-04-05T20:48:29", "url": "https://files.pythonhosted.org/packages/92/a9/b4f81f3b6a963e2b5722776ff403a579a51e3dc7fad476e2d1a04e8d92b2/aiomemoizeconcurrent-0.0.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cba76ece3a2fbb452ac8f28052747f24", "sha256": "ecc64b22e5d4afad0e4ddc66575d08352c4ac4bdf177b89c7939c20440120d5b" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.8.tar.gz", "has_sig": false, "md5_digest": "cba76ece3a2fbb452ac8f28052747f24", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.5", "size": 2390, "upload_time": "2019-04-05T20:48:31", "url": "https://files.pythonhosted.org/packages/df/5a/0fa0e1c8bfd96d49787929f0d72e3f981239ef539c91c4fb733aa15f5cdd/aiomemoizeconcurrent-0.0.8.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "10cbddecceaf2d4290db77fe79891c19", "sha256": "dfc05e9a95724dae9c95f612929905dcccebc9011da7343b01d33c74855e7a43" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "10cbddecceaf2d4290db77fe79891c19", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.5", "size": 3510, "upload_time": "2019-04-05T20:48:29", "url": "https://files.pythonhosted.org/packages/92/a9/b4f81f3b6a963e2b5722776ff403a579a51e3dc7fad476e2d1a04e8d92b2/aiomemoizeconcurrent-0.0.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cba76ece3a2fbb452ac8f28052747f24", "sha256": "ecc64b22e5d4afad0e4ddc66575d08352c4ac4bdf177b89c7939c20440120d5b" }, "downloads": -1, "filename": "aiomemoizeconcurrent-0.0.8.tar.gz", "has_sig": false, "md5_digest": "cba76ece3a2fbb452ac8f28052747f24", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.5", "size": 2390, "upload_time": "2019-04-05T20:48:31", "url": "https://files.pythonhosted.org/packages/df/5a/0fa0e1c8bfd96d49787929f0d72e3f981239ef539c91c4fb733aa15f5cdd/aiomemoizeconcurrent-0.0.8.tar.gz" } ] }