{ "info": { "author": "Sebastian Klaassen", "author_email": "rcsepp@hotmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Application Frameworks" ], "description": "*asyncframes* is a coroutine library for Python and a reference implementation of the *Frame Hierarchy Programming Model* (FHM). The goal of FHM is to help programmers design clean and scalable parallel programs.\nThe main features of *asyncframes* are:\n\n- Hierarchical code design\n- Inherent and scalable parallelism\n- Architecture independence\n- Extensibility through frame classes (a class whose lifetime is bound to the execution of a frame)\n\n\nIntroduction\n============\n\nIn the *Frame Hierarchy Programming Model* (FHM) a program is represented as a dynamic tree of *frames*. A frame is a suspendable function (a coroutine) with an object oriented context (the frame class) that only exists until the function returns. Frames can be used to represent both temporal processes (using the coroutine) and physical or conceptual objects (using the frame class).\n\nEach FHM program has exactly one root frame. The root frame can recursively spawn child frames. Each child frame runs in parallel unless it's awaiting another frame or an awaitable event. Frames of type ``Frame`` run on a single thread. They use cooperative multitasking to simulate parallelism. Frames of type ``PFrame`` run on any of the threads available in the event loop's thread pool. ``Frame`` and ``PFrame`` are frame classes. They can be sub-classed to create specialized frame classes with encapsulated data.\n\nInstallation\n============\n\n*asyncframes* can be installed via `pip`: ::\n\n pip install asyncframes\n\n*asyncframes* requires an event loop to suspend execution without blocking the operating system. The default event loop is ``asyncframes.asyncio_eventloop.EventLoop``. It doesn't depend on any Python packages besides the builtin *asyncio* package.\nSome frameworks, like Qt, use their own event loops. When using such frameworks, the framework's event loop should be reused for *asyncframes* by implementing the ``asyncframes.AbstractEventLoop`` interface.\n\n\nExamples\n========\n\nHere is a minimal example of using *asyncframes*: ::\n\n from asyncframes import Frame\n from asyncframes.asyncio_eventloop import EventLoop\n\n @Frame\n async def main_frame():\n print(\"Hello World!\")\n\n loop = EventLoop()\n loop.run(main_frame)\n\nHere is an example of suspending a frame: ::\n\n from asyncframes import Frame, sleep\n from asyncframes.asyncio_eventloop import EventLoop\n\n @Frame\n async def main_frame():\n for i in range(5):\n await sleep(1)\n print(i + 1)\n\n loop = EventLoop()\n loop.run(main_frame)\n\nHere is an example of running two frames in parallel: ::\n\n from asyncframes import Frame, sleep\n from asyncframes.asyncio_eventloop import EventLoop\n\n @Frame\n async def counter(c):\n for i in range(5):\n await sleep(1)\n print(c)\n\n @Frame\n async def main_frame():\n a = counter('a') # Start counter 'a'\n await sleep(0.5) # Wait 0.5 seconds\n b = counter('b') # Start counter 'b'\n await (a & b) # Wait until both counters finish\n\n loop = EventLoop()\n loop.run(main_frame)\n\nHere is an example of running two blocking operations in parallel using a parallel frame (``PFrame``): ::\n\n import time\n from asyncframes import Frame, PFrame, sleep\n from asyncframes.asyncio_eventloop import EventLoop\n\n @PFrame\n async def counter(c):\n for i in range(5):\n time.sleep(1)\n print(c)\n\n @Frame\n async def main_frame():\n a = counter('a') # Start counter 'a'\n await sleep(0.5) # Wait 0.5 seconds\n b = counter('b') # Start counter 'b'\n await (a & b) # Wait until both counters finish\n\n loop = EventLoop()\n loop.run(main_frame)\n\n\nChangelog\n=========\n\n2.2.0 (2019-02-18)\n------------------\n\n- Inline frames - Quickly create frame hierarchies using Python's \"with\" syntax.\n- Lifebound awaitables - Create awaitables that fire when they are removed by passing lifebound=True.\n- Destructors - Define a destructor for any Awaitable or Primitive by overloading _ondispose().\n\n2.1.0 (2019-01-07)\n------------------\n\n- GTK support - Create GTK widgets using the GLib eventloop.\n\n2.0.0 (2018-12-06)\n------------------\n\n- Multithreading - Run frames in parallel using PFrame's.\n- Delayed startup - By default creating a frame queues it's execution and returns immediately.\n- Frame exception handlers - Exceptions propagate along the frame hierarchy, instead of along awaiting frames.\n- Simplified events - EventSource's are now Event's. Awaited events emit only event arguments.\n- Cancelable free events - Cancel free events by setting event.cancel to True.\n- Frame factories - Instances of frame classes are of type [MyFrameClass].Factory.\n- Threadsafe post() - Use post() to queue events on any thread, instead of separate post & invoke functions.\n- \"singleshot\" - Event argument \"autoremove\" has been renamed to \"singleshot\"\n\n1.1.0 (2018-09-18)\n------------------\n\n- Threadsafe events - Wake up event sources across threads using invoke().\n- Free event - Frames emit the self.free event just before they are removed.\n- Hierarchy changes - any\\_ and all\\_ do not take over parenthood of their awaitables.\n\n\n1.0.0 (2018-09-05)\n------------------\n\n- Initial release\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/RcSepp/asyncframes", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "asyncframes", "package_url": "https://pypi.org/project/asyncframes/", "platform": "", "project_url": "https://pypi.org/project/asyncframes/", "project_urls": { "Homepage": "https://github.com/RcSepp/asyncframes" }, "release_url": "https://pypi.org/project/asyncframes/2.2.0/", "requires_dist": null, "requires_python": ">=3.5", "summary": "Parallel programming for software engineers", "version": "2.2.0" }, "last_serial": 4836358, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "155924fb1b9e10f640bb5cce2f6bb2af", "sha256": "17530ddd1d039f87111789e7248bba823b4134ac677a213cf33e9b146f7a2a10" }, "downloads": -1, "filename": "asyncframes-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "155924fb1b9e10f640bb5cce2f6bb2af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 8730, "upload_time": "2018-09-05T18:34:03", "url": "https://files.pythonhosted.org/packages/0c/a1/6a98cfde67c55fc11e8ced597b824cecfdbcabf27f1f8387c57157a42c22/asyncframes-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9f03a27f1434eaade1a8e6a19e76d3da", "sha256": "13c6c48e5ba5a3f9820c1322b5a6e990ad5664ee51fbbf904f4ea01c0654dbbe" }, "downloads": -1, "filename": "asyncframes-1.0.0.tar.gz", "has_sig": false, "md5_digest": "9f03a27f1434eaade1a8e6a19e76d3da", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11013, "upload_time": "2018-09-05T18:34:04", "url": "https://files.pythonhosted.org/packages/46/b2/edb9f86d2d2bd7117a689f92eddfe91cc04124d888714455487d55d75381/asyncframes-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "d982beabe17716df0ec531a2727ec37a", "sha256": "66d4062b46e4196aa9815ef378b2bd9e15fe25d93181b24b8a3140bd40a94a8d" }, "downloads": -1, "filename": "asyncframes-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "d982beabe17716df0ec531a2727ec37a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 8751, "upload_time": "2018-09-05T19:07:42", "url": "https://files.pythonhosted.org/packages/91/93/215d9480bca9cd56d51f2d8497f57d793f162b36178b25f673fa18adcbe0/asyncframes-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "82e7e9ec749b244d35dbaa7ba3e96e54", "sha256": "913cd1df56473f92572cb335f503eb9e00559351d0b768b7dab0426c98084bef" }, "downloads": -1, "filename": "asyncframes-1.0.1.tar.gz", "has_sig": false, "md5_digest": "82e7e9ec749b244d35dbaa7ba3e96e54", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11050, "upload_time": "2018-09-05T19:07:43", "url": "https://files.pythonhosted.org/packages/0c/4f/84975da9a42f30af80b0c68e280201f8c4e0c2bb97872cad294deb884b72/asyncframes-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "ca71e022662828a90c5d820be38699a9", "sha256": "abd6b5be1b60aef192bef228259c7fefb7d7b79e281a71b9f3b584d69bde432b" }, "downloads": -1, "filename": "asyncframes-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ca71e022662828a90c5d820be38699a9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 9365, "upload_time": "2018-09-18T13:55:48", "url": "https://files.pythonhosted.org/packages/f3/33/89928eb12d91901fc77d33d5a4e81a6d2ddc726a1a464f4ab4c7ddb50800/asyncframes-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "577ba63c1190f1661696c988a098c543", "sha256": "ec44c76e1c62aa0165236518e0b0bbd98309c83857eca2de2e9225b6fb851224" }, "downloads": -1, "filename": "asyncframes-1.1.0.tar.gz", "has_sig": false, "md5_digest": "577ba63c1190f1661696c988a098c543", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 13381, "upload_time": "2018-09-18T13:55:49", "url": "https://files.pythonhosted.org/packages/bb/e3/4ed93e8d644a99ca5ed114e614852ff0815212c314aeda5f2d51204f4ded/asyncframes-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "21314b4d3463c293202dfbaf7836fbe6", "sha256": "d27d846c5d7e490b2b454361371f3255ed00ba058c33011b0799e18770769bc0" }, "downloads": -1, "filename": "asyncframes-1.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "21314b4d3463c293202dfbaf7836fbe6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 12490, "upload_time": "2018-10-27T21:18:30", "url": "https://files.pythonhosted.org/packages/7b/1e/d7b9e9629ab198dbb5e26ff55169c91080c92ab14e129004f84217ba67fe/asyncframes-1.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3ae34d3e35d3d74217beaed892ce7806", "sha256": "d25ba0b7034777f0354a70eadabdb7b09e10958565e860e364414eab3a05e70c" }, "downloads": -1, "filename": "asyncframes-1.1.1.tar.gz", "has_sig": false, "md5_digest": "3ae34d3e35d3d74217beaed892ce7806", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 14352, "upload_time": "2018-10-27T21:18:32", "url": "https://files.pythonhosted.org/packages/97/f3/c163438a24587c1b5d4dadef87e080dc9cf635acf3215a3ac44b52846d30/asyncframes-1.1.1.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "1ee25462e74b21c7318c78e30da94b87", "sha256": "174d99e7f08fdaabf15e1bb66ea54ee4572bf4c099631b98030d14d9246e2f61" }, "downloads": -1, "filename": "asyncframes-2.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "1ee25462e74b21c7318c78e30da94b87", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 15223, "upload_time": "2018-12-06T22:57:22", "url": "https://files.pythonhosted.org/packages/68/2a/cd10e0db8b411fbf282b7b98e054b8f4d11facee26e1fdd213e8a02c52b2/asyncframes-2.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e9c4fa495fc9f8f83d2e06d499f4c2b2", "sha256": "46865fca7dba5477b23e25df175bdbfed14f45d2a5ecde24dfd8283fcdbeee2a" }, "downloads": -1, "filename": "asyncframes-2.0.0.tar.gz", "has_sig": false, "md5_digest": "e9c4fa495fc9f8f83d2e06d499f4c2b2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 22218, "upload_time": "2018-12-06T22:57:23", "url": "https://files.pythonhosted.org/packages/6a/2b/6e5646db3ee6e1936037ffaece7d0a83b574a10c69988a4022c895b996cb/asyncframes-2.0.0.tar.gz" } ], "2.1.0": [ { "comment_text": "", "digests": { "md5": "796b7475ec294b3fbc89fcef83d357c3", "sha256": "d27f86abe9c826ac2148205b80e54b3f3e06c57e7e2889f2feb1fca92b03d4cf" }, "downloads": -1, "filename": "asyncframes-2.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "796b7475ec294b3fbc89fcef83d357c3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18179, "upload_time": "2019-01-07T23:05:38", "url": "https://files.pythonhosted.org/packages/01/bf/5a80730099dc6c12ac23ccfc81c28daae12bc88894b1265a8cccd5670f9a/asyncframes-2.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1c4a901492b72e3e5eafed8ae23f5e95", "sha256": "02e1f312c76d90c151fa6a7d0aac83f35a157a2deff340bcfb11dcb281e07052" }, "downloads": -1, "filename": "asyncframes-2.1.0.tar.gz", "has_sig": false, "md5_digest": "1c4a901492b72e3e5eafed8ae23f5e95", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 23165, "upload_time": "2019-01-07T23:05:39", "url": "https://files.pythonhosted.org/packages/4b/80/dd7be7d7bad66aae8fa546fe533de3655bd69e87544aae4158e927f62863/asyncframes-2.1.0.tar.gz" } ], "2.1.1": [ { "comment_text": "", "digests": { "md5": "aa3849b386a512ec356db86f3f874c24", "sha256": "21e1af7027637b3cd923184522194a6fa08acf80641974aec00a5c0d7195d2f9" }, "downloads": -1, "filename": "asyncframes-2.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "aa3849b386a512ec356db86f3f874c24", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16549, "upload_time": "2019-01-14T20:40:12", "url": "https://files.pythonhosted.org/packages/19/47/2b41a447ca451b884aea302729c5f32b4f08896f0e96dfae2aacf5903ee8/asyncframes-2.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "29974d0fcd79b4874c4dfb598b397f1e", "sha256": "74b407977e976d055e7419ba11d90ff4aaaa7aa277e42a64c17472cd32313f08" }, "downloads": -1, "filename": "asyncframes-2.1.1.tar.gz", "has_sig": false, "md5_digest": "29974d0fcd79b4874c4dfb598b397f1e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 23153, "upload_time": "2019-01-14T20:40:14", "url": "https://files.pythonhosted.org/packages/79/e9/6cf4736e2e2a7f25ebdb89da2bbaf9c988190302d9d0d52e89a3f5efc622/asyncframes-2.1.1.tar.gz" } ], "2.2.0": [ { "comment_text": "", "digests": { "md5": "33f373f93c22547fe88d16fbef4fce67", "sha256": "dd29f4572922e9ccbc47780d7ec7505cf12e50f9b0320a905603618455f274e5" }, "downloads": -1, "filename": "asyncframes-2.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "33f373f93c22547fe88d16fbef4fce67", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17133, "upload_time": "2019-02-18T18:18:04", "url": "https://files.pythonhosted.org/packages/be/f8/2009420996f91dc588d097f03bc6b9d931698e240c9f255566f8051b65ac/asyncframes-2.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "25aa1e4f2d41698d988e88a4ccff336b", "sha256": "2a260052016fa2afd667adad68855e443e05903ac6f67d977f12c36fc2b92f73" }, "downloads": -1, "filename": "asyncframes-2.2.0.tar.gz", "has_sig": false, "md5_digest": "25aa1e4f2d41698d988e88a4ccff336b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 24201, "upload_time": "2019-02-18T18:18:05", "url": "https://files.pythonhosted.org/packages/ad/19/6538aba7a75d4441975b30f1f82c23f47034f943c547e274534cb7e3b683/asyncframes-2.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "33f373f93c22547fe88d16fbef4fce67", "sha256": "dd29f4572922e9ccbc47780d7ec7505cf12e50f9b0320a905603618455f274e5" }, "downloads": -1, "filename": "asyncframes-2.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "33f373f93c22547fe88d16fbef4fce67", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17133, "upload_time": "2019-02-18T18:18:04", "url": "https://files.pythonhosted.org/packages/be/f8/2009420996f91dc588d097f03bc6b9d931698e240c9f255566f8051b65ac/asyncframes-2.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "25aa1e4f2d41698d988e88a4ccff336b", "sha256": "2a260052016fa2afd667adad68855e443e05903ac6f67d977f12c36fc2b92f73" }, "downloads": -1, "filename": "asyncframes-2.2.0.tar.gz", "has_sig": false, "md5_digest": "25aa1e4f2d41698d988e88a4ccff336b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 24201, "upload_time": "2019-02-18T18:18:05", "url": "https://files.pythonhosted.org/packages/ad/19/6538aba7a75d4441975b30f1f82c23f47034f943c547e274534cb7e3b683/asyncframes-2.2.0.tar.gz" } ] }