{ "info": { "author": "Cory Benfield", "author_email": "cory@lukasa.co.uk", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "Priority: A HTTP/2 Priority Implementation\n==========================================\n\nPriority is a pure-Python implementation of the priority logic for HTTP/2, set\nout in `RFC 7540 Section 5.3 (Stream Priority)`_. This logic allows for clients\nto express a preference for how the server allocates its (limited) resources to\nthe many outstanding HTTP requests that may be running over a single HTTP/2\nconnection.\n\nSpecifically, this Python implementation uses a variant of the implementation\nused in the excellent `H2O`_ project. This original implementation is also the\ninspiration for `nghttp2's`_ priority implementation, and generally produces a\nvery clean and even priority stream. The only notable changes from H2O's\nimplementation are small modifications to allow the priority implementation to\nwork cleanly as a separate implementation, rather than being embedded in a\nHTTP/2 stack directly.\n\nWhile priority information in HTTP/2 is only a suggestion, rather than an\nenforceable constraint, where possible servers should respect the priority\nrequests of their clients.\n\nUsing Priority\n--------------\n\nPriority has a simple API. Streams are inserted into the tree: when they are\ninserted, they may optionally have a weight, depend on another stream, or\nbecome an exclusive dependent of another stream.\n\n.. code-block:: python\n\n >>> p = priority.PriorityTree()\n >>> p.insert_stream(stream_id=1)\n >>> p.insert_stream(stream_id=3)\n >>> p.insert_stream(stream_id=5, depends_on=1)\n >>> p.insert_stream(stream_id=7, weight=32)\n >>> p.insert_stream(stream_id=9, depends_on=7, weight=8)\n >>> p.insert_stream(stream_id=11, depends_on=7, exclusive=True)\n\nOnce streams are inserted, the stream priorities can be requested. This allows\nthe server to make decisions about how to allocate resources.\n\nIterating The Tree\n~~~~~~~~~~~~~~~~~~\n\nThe tree in this algorithm acts as a gate. Its goal is to allow one stream\n\"through\" at a time, in such a manner that all the active streams are served as\nevenly as possible in proportion to their weights.\n\nThis is handled in Priority by iterating over the tree. The tree itself is an\niterator, and each time it is advanced it will yield a stream ID. This is the\nID of the stream that should next send data.\n\nThis looks like this:\n\n.. code-block:: python\n\n >>> for stream_id in p:\n ... send_data(stream_id)\n\nIf each stream only sends when it is 'ungated' by this mechanism, the server\nwill automatically be emitting stream data in conformance to RFC 7540.\n\nUpdating The Tree\n~~~~~~~~~~~~~~~~~\n\nIf for any reason a stream is unable to proceed (for example, it is blocked on\nHTTP/2 flow control, or it is waiting for more data from another service), that\nstream is *blocked*. The ``PriorityTree`` should be informed that the stream is\nblocked so that other dependent streams get a chance to proceed. This can be\ndone by calling the ``block`` method of the tree with the stream ID that is\ncurrently unable to proceed. This will automatically update the tree, and it\nwill adjust on the fly to correctly allow any streams that were dependent on\nthe blocked one to progress.\n\nFor example:\n\n.. code-block:: python\n\n >>> for stream_id in p:\n ... send_data(stream_id)\n ... if blocked(stream_id):\n ... p.block(stream_id)\n\nWhen a stream goes from being blocked to being unblocked, call the ``unblock``\nmethod to place it back into the sequence. Both the ``block`` and ``unblock``\nmethods are idempotent and safe to call repeatedly.\n\nAdditionally, the priority of a stream may change. When it does, the\n``reprioritize`` method can be used to update the tree in the wake of that\nchange. ``reprioritize`` has the same signature as ``insert_stream``, but\napplies only to streams already in the tree.\n\nRemoving Streams\n~~~~~~~~~~~~~~~~\n\nA stream can be entirely removed from the tree by calling ``remove_stream``.\nNote that this is not idempotent. Further, calling ``remove_stream`` and then\nre-adding it *may* cause a substantial change in the shape of the priority\ntree, and *will* cause the iteration order to change.\n\nLicense\n-------\n\nPriority is made available under the MIT License. For more details, see the\nLICENSE file in the repository.\n\nAuthors\n-------\n\nPriority is maintained by Cory Benfield, with contributions from others. For\nmore details about the contributors, please see CONTRIBUTORS.rst in the\nrepository.\n\n\n.. _RFC 7540 Section 5.3 (Stream Priority): https://tools.ietf.org/html/rfc7540#section-5.3\n.. _nghttp2's: https://nghttp2.org/blog/2015/11/11/stream-scheduling-utilizing-http2-priority/\n.. _H2O: https://h2o.examp1e.net/\n\n\nChangelog\n=========\n\n1.3.0 (2017-01-27)\n------------------\n\n**API Changes**\n\n- Throw ``PriorityLoop`` when inserting or reprioritising a stream that\n depends on itself.\n- Throw ``BadWeightError`` when creating or reprioritising a stream with a\n weight that is not an integer between 1 and 256, inclusive.\n- Throw ``PseudoStreamError`` when trying to reprioritise, remove, block or\n unblock stream 0.\n- Add a new ``PriorityError`` parent class for the exceptions that can be\n thrown by priority.\n\n1.2.2 (2016-11-11)\n------------------\n\n**Bugfixes**\n\n- Allow ``insert_stream`` to be called with ``exclusive=True`` but no explicit\n ``depends_on`` value.\n\n1.2.1 (2016-10-26)\n------------------\n\n**Bugfixes**\n\n- Allow insertion of streams that have parents in the idle or closed states.\n This would previously raise a KeyError.\n\n1.2.0 (2016-08-04)\n------------------\n\n**Security Fixes**\n\n- CVE-2016-6580: All versions of this library prior to 1.2.0 are vulnerable to\n a denial of service attack whereby a remote peer can cause a user to insert\n an unbounded number of streams into the priority tree, eventually consuming\n all available memory.\n\n This version adds a ``TooManyStreamsError`` exception that is raised when\n too many streams are inserted into the priority tree. It also adds a keyword\n argument to the priority tree, ``maximum_streams``, which limits how many\n streams may be inserted. By default, this number is set to 1000.\n Implementations should strongly consider whether they can set this value\n lower.\n\n1.1.1 (2016-05-28)\n------------------\n\n**Bugfixes**\n\n- 2.5x performance improvement by swapping from ``queue.PriorityQueue`` to\n ``heapq``.\n\n1.1.0 (2016-01-08)\n------------------\n\n**API Changes**\n\n- Throw ``DuplicateStreamError`` when inserting a stream that is already in the\n tree.\n- Throw ``MissingStreamError`` when reprioritising a stream that is not in the\n tree.\n\n1.0.0 (2015-12-07)\n------------------\n\n- Initial release.\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://python-hyper.org/priority/", "keywords": "", "license": "MIT License", "maintainer": "", "maintainer_email": "", "name": "priority", "package_url": "https://pypi.org/project/priority/", "platform": "", "project_url": "https://pypi.org/project/priority/", "project_urls": { "Homepage": "http://python-hyper.org/priority/" }, "release_url": "https://pypi.org/project/priority/1.3.0/", "requires_dist": null, "requires_python": "", "summary": "A pure-Python implementation of the HTTP/2 priority tree", "version": "1.3.0" }, "last_serial": 5536897, "releases": { "0.0.1": [], "1.0.0": [ { "comment_text": "", "digests": { "md5": "0849c82e952b4d400b314d078f4338bf", "sha256": "cb3b5e961d60f4996f793b4b4de83b2783e8f1460d0c6df159e5a95bb619d694" }, "downloads": -1, "filename": "priority-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0849c82e952b4d400b314d078f4338bf", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 9221, "upload_time": "2015-12-07T16:16:15", "url": "https://files.pythonhosted.org/packages/05/02/e0106097f720318c93102be86c10abd1d996f0973b0e6506c63ea7375e04/priority-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "21a559d304ce4d358acfdb2c9444b79b", "sha256": "c6972f1763ffd0f6aba4e273641e40b24caf7af21f73b2f21de8f907dcadac28" }, "downloads": -1, "filename": "priority-1.0.0.tar.gz", "has_sig": false, "md5_digest": "21a559d304ce4d358acfdb2c9444b79b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9702, "upload_time": "2015-12-07T16:16:04", "url": "https://files.pythonhosted.org/packages/65/80/218f3578e585d81938d7e5ed205440c35ea6c311ea409195733fda82dd28/priority-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "53d446edbe9cfc2f7979fa734999edad", "sha256": "e126a39b54f1f7a7c1ce64bcf06c6cf6fc12597d542e384893b7d01887192520" }, "downloads": -1, "filename": "priority-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "53d446edbe9cfc2f7979fa734999edad", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 9547, "upload_time": "2016-01-08T10:05:40", "url": "https://files.pythonhosted.org/packages/2a/1f/13b32db2ff800435d6f3b729aec5e737a36312ac78577252326dfccada07/priority-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "72ec2464d7ab996a5853e56bed65107e", "sha256": "016c818e597f13067def0fb440c931e75d8f3d9a94b0f10bf8e22c26093d065b" }, "downloads": -1, "filename": "priority-1.1.0.tar.gz", "has_sig": false, "md5_digest": "72ec2464d7ab996a5853e56bed65107e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10755, "upload_time": "2016-01-08T10:05:32", "url": "https://files.pythonhosted.org/packages/ff/02/98e68e2286cf80e7559d1d668f791b47d1acbb11de73076e45357de2985c/priority-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "d45da7ff8cd7eec2c96874a6cfae28fa", "sha256": "ab0b1badaa76d96e861b30176ece4fea6cd93803f0e88d7d994dbaccd3ad0e8c" }, "downloads": -1, "filename": "priority-1.1.1-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "d45da7ff8cd7eec2c96874a6cfae28fa", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9638, "upload_time": "2016-05-29T03:23:32", "url": "https://files.pythonhosted.org/packages/5d/7f/cec4ee78fb5c0f5aeb2ee0a23af116938d7d2fb4dacb375f2229111ab076/priority-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "91f8bde553a770d20da196753a04e298", "sha256": "c0b8b069ad4037b5a106432074f484046b52beefeff4911ce17e2d625a3f3d60" }, "downloads": -1, "filename": "priority-1.1.1.tar.gz", "has_sig": true, "md5_digest": "91f8bde553a770d20da196753a04e298", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10883, "upload_time": "2016-05-29T03:23:34", "url": "https://files.pythonhosted.org/packages/9a/17/a9b88bcd7189c574368f280be8c9df630dee26e77440762a9503c9afb1e3/priority-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "75c387dd19156793d0629d5c8b8d25c0", "sha256": "95307cca84f01400b912629b6b08d835fb5a45541a25ebb19f25c3ab0641a983" }, "downloads": -1, "filename": "priority-1.2.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "75c387dd19156793d0629d5c8b8d25c0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10751, "upload_time": "2016-08-04T08:28:18", "url": "https://files.pythonhosted.org/packages/80/18/72ca6694445459d53715adc46d154da4d4a3b3b696cf3e3d36011993aeea/priority-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "14301d637469c387d7a9a34181cd9f2f", "sha256": "70468e7f43c4bb19cd966d63f78367d8c5af68828611aa3f3e5d77b8948cd2d4" }, "downloads": -1, "filename": "priority-1.2.0.tar.gz", "has_sig": true, "md5_digest": "14301d637469c387d7a9a34181cd9f2f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12064, "upload_time": "2016-08-04T08:28:21", "url": "https://files.pythonhosted.org/packages/f1/a9/cf5ed4bf33362dfca6a644c845ab176b942952e921d4cf83c1786bd72fc5/priority-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "1ee6926d4d5fd1b18a8522e79beb9cd7", "sha256": "86f6d11780eceea998d0ce782174fca923d0687c90c0ff654c18f18bac241f9e" }, "downloads": -1, "filename": "priority-1.2.1-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "1ee6926d4d5fd1b18a8522e79beb9cd7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10987, "upload_time": "2016-10-26T09:25:32", "url": "https://files.pythonhosted.org/packages/20/58/aec79f2fc642ffc1ac975b7ea3d0a6f1d9a39acecce7f58c81b8a441f185/priority-1.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "63e3e7fdc35b10d7a07403e0dc30022e", "sha256": "21e3b5a3b64cda106556023c9ac1223a026a45252536dd33b992a35e557280a4" }, "downloads": -1, "filename": "priority-1.2.1.tar.gz", "has_sig": true, "md5_digest": "63e3e7fdc35b10d7a07403e0dc30022e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12558, "upload_time": "2016-10-26T09:25:34", "url": "https://files.pythonhosted.org/packages/20/87/2244cf64e9e3ecda5e8f609d75d0aa206b61534374d83c5fc7b898b7ddab/priority-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "9f8672d110507c9a25da686d7c5977a1", "sha256": "b584e83e1bf24227fb7ef8db5903510ed95eaec43a9dda22fcdc7dea52f957f3" }, "downloads": -1, "filename": "priority-1.2.2-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "9f8672d110507c9a25da686d7c5977a1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11077, "upload_time": "2016-11-11T10:37:02", "url": "https://files.pythonhosted.org/packages/99/74/7070bf3bca73e228fee5d63ba23d33b22339a95da00b41ebf63d66b44c16/priority-1.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a0d67faa20ede780bbb7f3949c5685ae", "sha256": "6cd04ba9d2ce1a6a25ceb5f52674c3f400cf21ff948fcfcf76afd6c8a9b19c07" }, "downloads": -1, "filename": "priority-1.2.2.tar.gz", "has_sig": true, "md5_digest": "a0d67faa20ede780bbb7f3949c5685ae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12779, "upload_time": "2016-11-11T10:37:07", "url": "https://files.pythonhosted.org/packages/92/3a/af4e98d54440cfefeb12438b6afd59d88bbe796ae8850a1faac1fafc0f7c/priority-1.2.2.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "a4634bf9c0a37d43b25859e757df5523", "sha256": "be4fcb94b5e37cdeb40af5533afe6dd603bd665fe9c8b3052610fc1001d5d1eb" }, "downloads": -1, "filename": "priority-1.3.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "a4634bf9c0a37d43b25859e757df5523", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11720, "upload_time": "2017-01-27T11:00:52", "url": "https://files.pythonhosted.org/packages/de/96/2f4b8da7be255cd41e825c398efd11a6706ff86e66ae198f012204aa2a4f/priority-1.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4f1ff52f7fa448e9d9cb46337ae86d1e", "sha256": "6bc1961a6d7fcacbfc337769f1a382c8e746566aaa365e78047abe9f66b2ffbe" }, "downloads": -1, "filename": "priority-1.3.0.tar.gz", "has_sig": true, "md5_digest": "4f1ff52f7fa448e9d9cb46337ae86d1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13827, "upload_time": "2017-01-27T11:00:54", "url": "https://files.pythonhosted.org/packages/ba/96/7d0b024087062418dfe02a68cd6b195399266ac002fb517aad94cc93e076/priority-1.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a4634bf9c0a37d43b25859e757df5523", "sha256": "be4fcb94b5e37cdeb40af5533afe6dd603bd665fe9c8b3052610fc1001d5d1eb" }, "downloads": -1, "filename": "priority-1.3.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "a4634bf9c0a37d43b25859e757df5523", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11720, "upload_time": "2017-01-27T11:00:52", "url": "https://files.pythonhosted.org/packages/de/96/2f4b8da7be255cd41e825c398efd11a6706ff86e66ae198f012204aa2a4f/priority-1.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4f1ff52f7fa448e9d9cb46337ae86d1e", "sha256": "6bc1961a6d7fcacbfc337769f1a382c8e746566aaa365e78047abe9f66b2ffbe" }, "downloads": -1, "filename": "priority-1.3.0.tar.gz", "has_sig": true, "md5_digest": "4f1ff52f7fa448e9d9cb46337ae86d1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13827, "upload_time": "2017-01-27T11:00:54", "url": "https://files.pythonhosted.org/packages/ba/96/7d0b024087062418dfe02a68cd6b195399266ac002fb517aad94cc93e076/priority-1.3.0.tar.gz" } ] }