mirror of
https://github.com/langchain-ai/h2.git
synced 2026-06-30 22:47:54 -04:00
Rename 'hyper-h2' to simply 'h2' (#1246)
This commit is contained in:
committed by
GitHub
parent
5bfbb6742a
commit
94b89b88ed
@@ -4,6 +4,9 @@ Release History
|
||||
dev
|
||||
---
|
||||
|
||||
**Note:** The GitHub repository has been renamed to ``python-hyper/h2``, previously
|
||||
was ``python-hyper/hyper-h2``. **The name of the package on PyPI is unchanged**
|
||||
|
||||
**API Changes (Backward Incompatible)**
|
||||
|
||||
-
|
||||
|
||||
+15
-14
@@ -1,15 +1,15 @@
|
||||
===============================
|
||||
hyper-h2: HTTP/2 Protocol Stack
|
||||
===============================
|
||||
=========================
|
||||
h2: HTTP/2 Protocol Stack
|
||||
=========================
|
||||
|
||||
.. image:: https://github.com/python-hyper/hyper-h2/workflows/CI/badge.svg
|
||||
:target: https://github.com/python-hyper/hyper-h2/actions
|
||||
.. image:: https://github.com/python-hyper/h2/workflows/CI/badge.svg
|
||||
:target: https://github.com/python-hyper/h2/actions
|
||||
:alt: Build Status
|
||||
.. image:: https://codecov.io/gh/python-hyper/hyper-h2/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-hyper/hyper-h2
|
||||
.. image:: https://codecov.io/gh/python-hyper/h2/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-hyper/h2
|
||||
:alt: Code Coverage
|
||||
.. image:: https://readthedocs.org/projects/hyper-h2/badge/?version=latest
|
||||
:target: https://hyper-h2.readthedocs.io/en/latest/
|
||||
.. image:: https://readthedocs.org/projects/h2/badge/?version=latest
|
||||
:target: https://h2.readthedocs.io
|
||||
:alt: Documentation Status
|
||||
.. image:: https://img.shields.io/badge/chat-join_now-brightgreen.svg
|
||||
:target: https://gitter.im/python-hyper/community
|
||||
@@ -45,17 +45,17 @@ To install it, just run:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install h2
|
||||
$ python -m pip install h2
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Documentation is available at https://hyper-h2.readthedocs.io/ .
|
||||
Documentation is available at https://h2.readthedocs.io .
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
``hyper-h2`` welcomes contributions from anyone! Unlike many other projects we
|
||||
``h2`` welcomes contributions from anyone! Unlike many other projects we
|
||||
are happy to accept cosmetic contributions and small contributions, in addition
|
||||
to large feature requests and changes.
|
||||
|
||||
@@ -67,10 +67,11 @@ please `read the contribution guidelines`_.
|
||||
License
|
||||
=======
|
||||
|
||||
``hyper-h2`` is made available under the MIT License. For more details, see the
|
||||
``h2`` is made available under the MIT License. For more details, see the
|
||||
``LICENSE`` file in the repository.
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
``hyper-h2`` is maintained by Cory Benfield, with contributions from others.
|
||||
``h2`` was authored by Cory Benfield and is maintained
|
||||
by the members of `python-hyper <https://github.com/orgs/python-hyper/people>`_.
|
||||
|
||||
@@ -10,7 +10,7 @@ Priority
|
||||
build a HTTP/2 priority tree, and the effect that should have on sending data
|
||||
from a server.
|
||||
|
||||
Hyper-h2 does not enforce any priority logic by default for servers. This is
|
||||
h2 does not enforce any priority logic by default for servers. This is
|
||||
because scheduling data sends is outside the scope of this library, as it
|
||||
likely requires fairly substantial understanding of the scheduler being used.
|
||||
|
||||
@@ -26,7 +26,7 @@ Related Events
|
||||
|
||||
.. versionadded:: 2.4.0
|
||||
|
||||
In the 2.4.0 release hyper-h2 added support for signaling "related events".
|
||||
In the 2.4.0 release h2 added support for signaling "related events".
|
||||
These are a HTTP/2-only construct that exist because certain HTTP/2 events can
|
||||
occur simultaneously: that is, one HTTP/2 frame can cause multiple state
|
||||
transitions to occur at the same time. One example of this is a HEADERS frame
|
||||
@@ -35,17 +35,17 @@ cause three events to fire (one of the various request/response received
|
||||
events, a :class:`PriorityUpdated <h2.events.PriorityUpdated>` event, and a
|
||||
:class:`StreamEnded <h2.events.StreamEnded>` event).
|
||||
|
||||
Ordinarily hyper-h2's logic will emit those events to you one at a time. This
|
||||
Ordinarily h2's logic will emit those events to you one at a time. This
|
||||
means that you may attempt to process, for example, a
|
||||
:class:`DataReceived <h2.events.DataReceived>` event, not knowing that the next
|
||||
event out will be a :class:`StreamEnded <h2.events.StreamEnded>` event.
|
||||
hyper-h2 *does* know this, however, and so will forbid you from taking certain
|
||||
h2 *does* know this, however, and so will forbid you from taking certain
|
||||
actions that are a violation of the HTTP/2 protocol.
|
||||
|
||||
To avoid this asymmetry of information, events that can occur simultaneously
|
||||
now carry properties for their "related events". These allow users to find the
|
||||
events that can have occurred simultaneously with each other before the event
|
||||
is emitted by hyper-h2. The following objects have "related events":
|
||||
is emitted by h2. The following objects have "related events":
|
||||
|
||||
- :class:`RequestReceived <h2.events.RequestReceived>`:
|
||||
|
||||
@@ -96,7 +96,7 @@ is emitted by hyper-h2. The following objects have "related events":
|
||||
same time as receiving this data.
|
||||
|
||||
|
||||
.. warning:: hyper-h2 does not know if you are looking for related events or
|
||||
.. warning:: h2 does not know if you are looking for related events or
|
||||
expecting to find events in the event stream. Therefore, it will
|
||||
always emit "related events" in the event stream. If you are using
|
||||
the "related events" event pattern, you will want to be careful to
|
||||
@@ -167,11 +167,11 @@ When To Send
|
||||
~~~~~~~~~~~~
|
||||
|
||||
In addition to knowing how much data to send (see :ref:`advanced-sending-data`)
|
||||
it is important to know when to send data. For hyper-h2, this amounts to
|
||||
it is important to know when to send data. For h2, this amounts to
|
||||
knowing when to call :meth:`data_to_send
|
||||
<h2.connection.H2Connection.data_to_send>`.
|
||||
|
||||
Hyper-h2 may write data into its send buffer at two times. The first is
|
||||
h2 may write data into its send buffer at two times. The first is
|
||||
whenever :meth:`receive_data <h2.connection.H2Connection.receive_data>` is
|
||||
called. This data is sent in response to some control frames that require no
|
||||
user input: for example, responding to PING frames. The second time is in
|
||||
@@ -179,7 +179,7 @@ response to user action: whenever a user calls a method like
|
||||
:meth:`send_headers <h2.connection.H2Connection.send_headers>`, data may be
|
||||
written into the buffer.
|
||||
|
||||
In a standard design for a hyper-h2 consumer, then, that means there are two
|
||||
In a standard design for a h2 consumer, then, that means there are two
|
||||
places where you'll potentially want to send data. The first is in your
|
||||
"receive data" loop. This is where you take the data you receive, pass it into
|
||||
:meth:`receive_data <h2.connection.H2Connection.receive_data>`, and then
|
||||
@@ -240,16 +240,16 @@ Working With Flow Control
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The amount of flow control window a ``DATA`` frame consumes is the sum of both
|
||||
its contained application data *and* the amount of padding used. hyper-h2 shows
|
||||
its contained application data *and* the amount of padding used. h2 shows
|
||||
this to the user in a :class:`DataReceived <h2.events.DataReceived>` event by
|
||||
using the :data:`flow_controlled_length
|
||||
<h2.events.DataReceived.flow_controlled_length>` field. When working with flow
|
||||
control in hyper-h2, users *must* use this field: simply using
|
||||
control in h2, users *must* use this field: simply using
|
||||
``len(datareceived.data)`` can eventually lead to deadlock.
|
||||
|
||||
When data has been received and given to the user in a :class:`DataReceived
|
||||
<h2.events.DataReceived>`, it is the responsibility of the user to re-open the
|
||||
flow control window when the user is ready for more data. hyper-h2 does not do
|
||||
flow control window when the user is ready for more data. h2 does not do
|
||||
this automatically to avoid flooding the user with data: if we did, the remote
|
||||
peer could send unbounded amounts of data that the user would need to buffer
|
||||
before processing.
|
||||
@@ -258,7 +258,7 @@ To re-open the flow control window, then, the user must call
|
||||
:meth:`increment_flow_control_window
|
||||
<h2.connection.H2Connection.increment_flow_control_window>` with the
|
||||
:data:`flow_controlled_length <h2.events.DataReceived.flow_controlled_length>`
|
||||
of the received data. hyper-h2 requires that you manage both the connection
|
||||
of the received data. h2 requires that you manage both the connection
|
||||
and the stream flow control windows separately, so you may need to increment
|
||||
both the stream the data was received on and stream ``0``.
|
||||
|
||||
@@ -269,10 +269,10 @@ flow control windows. You can find out how much data you can send on a given
|
||||
stream by using the :meth:`local_flow_control_window
|
||||
<h2.connection.H2Connection.local_flow_control_window>` method, which will do
|
||||
all of these calculations for you. If you attempt to send more than this amount
|
||||
of data on a stream, hyper-h2 will throw a :class:`ProtocolError
|
||||
of data on a stream, h2 will throw a :class:`ProtocolError
|
||||
<h2.exceptions.ProtocolError>` and refuse to send the data.
|
||||
|
||||
In hyper-h2, receiving a ``WINDOW_UPDATE`` frame causes a :class:`WindowUpdated
|
||||
In h2, receiving a ``WINDOW_UPDATE`` frame causes a :class:`WindowUpdated
|
||||
<h2.events.WindowUpdated>` event to fire. This will notify you that there is
|
||||
potentially more room in a flow control window. Note that, just because an
|
||||
increment of a given size was received *does not* mean that that much more data
|
||||
@@ -301,7 +301,7 @@ control strategies. While particular high performance or specific-use-case
|
||||
applications may gain value from directly controlling the emission of
|
||||
``WINDOW_UPDATE`` frames, the average application can use a
|
||||
lowest-common-denominator strategy to emit those frames. As of version 2.5.0,
|
||||
hyper-h2 now provides this automatic strategy for users, if they want to use
|
||||
h2 now provides this automatic strategy for users, if they want to use
|
||||
it.
|
||||
|
||||
This automatic strategy is built around a single method:
|
||||
|
||||
+5
-5
@@ -1,15 +1,15 @@
|
||||
Hyper-h2 API
|
||||
============
|
||||
h2 API
|
||||
======
|
||||
|
||||
This document details the API of Hyper-h2.
|
||||
This document details the API of h2.
|
||||
|
||||
Semantic Versioning
|
||||
-------------------
|
||||
|
||||
Hyper-h2 follows semantic versioning for its public API. Please note that the
|
||||
h2 follows semantic versioning for its public API. Please note that the
|
||||
guarantees of semantic versioning apply only to the API that is *documented
|
||||
here*. Simply because a method or data field is not prefaced by an underscore
|
||||
does not make it part of Hyper-h2's public API. Anything not documented here is
|
||||
does not make it part of h2's public API. Anything not documented here is
|
||||
subject to change at any time.
|
||||
|
||||
Connection
|
||||
|
||||
+27
-27
@@ -2,7 +2,7 @@ Getting Started: Writing Your Own HTTP/2 Server
|
||||
===============================================
|
||||
|
||||
This document explains how to get started writing fully-fledged HTTP/2
|
||||
implementations using Hyper-h2 as the underlying protocol stack. It covers the
|
||||
implementations using h2 as the underlying protocol stack. It covers the
|
||||
basic concepts you need to understand, and talks you through writing a very
|
||||
simple HTTP/2 server.
|
||||
|
||||
@@ -17,10 +17,10 @@ return to this documentation.
|
||||
Connections
|
||||
-----------
|
||||
|
||||
Hyper-h2's core object is the
|
||||
h2's core object is the
|
||||
:class:`H2Connection <h2.connection.H2Connection>` object. This object is an
|
||||
abstract representation of the state of a single HTTP/2 connection, and holds
|
||||
all the important protocol state. When using Hyper-h2, this object will be the
|
||||
all the important protocol state. When using h2, this object will be the
|
||||
first thing you create and the object that does most of the heavy lifting.
|
||||
|
||||
The interface to this object is relatively simple. For sending data, you
|
||||
@@ -54,7 +54,7 @@ this document, we'll do just that.
|
||||
|
||||
Some important subtleties of ``H2Connection`` objects are covered in
|
||||
:doc:`advanced-usage`: see :ref:`h2-connection-advanced` for more information.
|
||||
However, one subtlety should be covered, and that is this: Hyper-h2's
|
||||
However, one subtlety should be covered, and that is this: h2's
|
||||
``H2Connection`` object doesn't do I/O. Let's talk briefly about why.
|
||||
|
||||
I/O
|
||||
@@ -74,19 +74,19 @@ into bytes to send. So there's no reason to have lots of different versions of
|
||||
this core protocol code: one for Twisted, one for gevent, one for threading,
|
||||
and one for synchronous code.
|
||||
|
||||
This is why we said at the top that Hyper-h2 is a *HTTP/2 Protocol Stack*, not
|
||||
a *fully-fledged implementation*. Hyper-h2 knows how to transform bytes into
|
||||
This is why we said at the top that h2 is a *HTTP/2 Protocol Stack*, not
|
||||
a *fully-fledged implementation*. h2 knows how to transform bytes into
|
||||
events and back, but that's it. The I/O and smarts might be different, but
|
||||
the core HTTP/2 logic is the same: that's what Hyper-h2 provides.
|
||||
the core HTTP/2 logic is the same: that's what h2 provides.
|
||||
|
||||
Not doing I/O makes Hyper-h2 general, and also relatively simple. It has an
|
||||
Not doing I/O makes h2 general, and also relatively simple. It has an
|
||||
easy-to-understand performance envelope, it's easy to test (and as a result
|
||||
easy to get correct behaviour out of), and it behaves in a reproducible way.
|
||||
These are all great traits to have in a library that is doing something quite
|
||||
complex.
|
||||
|
||||
This document will talk you through how to build a relatively simple HTTP/2
|
||||
implementation using Hyper-h2, to give you an understanding of where it fits in
|
||||
implementation using h2, to give you an understanding of where it fits in
|
||||
your software.
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ When writing a HTTP/2 implementation it's important to know what the remote
|
||||
peer is doing: if you didn't care, writing networked programs would be a lot
|
||||
easier!
|
||||
|
||||
Hyper-h2 encodes the actions of the remote peer in the form of *events*. When
|
||||
h2 encodes the actions of the remote peer in the form of *events*. When
|
||||
you receive data from the remote peer and pass it into your ``H2Connection``
|
||||
object (see :ref:`h2-connection-basic`), the ``H2Connection`` returns a list
|
||||
of objects, each one representing a single event that has occurred. Each
|
||||
@@ -112,11 +112,11 @@ concept, not just a HTTP/2 one. Other events are extremely HTTP/2-specific:
|
||||
for example, :class:`PushedStreamReceived <h2.events.PushedStreamReceived>`
|
||||
refers to Server Push, a very HTTP/2-specific concept.
|
||||
|
||||
The reason these events exist is that Hyper-h2 is intended to be very general.
|
||||
This means that, in many cases, Hyper-h2 does not know exactly what to do in
|
||||
The reason these events exist is that h2 is intended to be very general.
|
||||
This means that, in many cases, h2 does not know exactly what to do in
|
||||
response to an event. Your code will need to handle these events, and make
|
||||
decisions about what to do. That's the major role of any HTTP/2 implementation
|
||||
built on top of Hyper-h2.
|
||||
built on top of h2.
|
||||
|
||||
A full list of events is available in :ref:`h2-events-api`. For the purposes
|
||||
of this example, we will handle only a small set of events.
|
||||
@@ -129,7 +129,7 @@ Armed with the knowledge you just obtained, we're going to write a very simple
|
||||
HTTP/2 web server. The goal of this server is to write a server that can handle
|
||||
a HTTP GET, and that returns the headers sent by the client, encoded in JSON.
|
||||
Basically, something a lot like `httpbin.org/get`_. Nothing fancy, but this is
|
||||
a good way to get a handle on how you should interact with Hyper-h2.
|
||||
a good way to get a handle on how you should interact with h2.
|
||||
|
||||
For the sake of simplicity, we're going to write this using the Python standard
|
||||
library, in Python 3. In reality, you'll probably want to use an asynchronous
|
||||
@@ -137,7 +137,7 @@ framework of some kind: see the `examples directory`_ in the repository for
|
||||
some examples of how you'd do that.
|
||||
|
||||
Before we start, create a new file called ``h2server.py``: we'll use that as
|
||||
our workspace. Additionally, you should install Hyper-h2: follow the
|
||||
our workspace. Additionally, you should install h2: follow the
|
||||
instructions in :doc:`installation`.
|
||||
|
||||
Step 1: Sockets
|
||||
@@ -324,7 +324,7 @@ Let's do that next.
|
||||
Step 3: Sending the Preamble
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Hyper-h2 makes doing connection setup really easy. All you need to do is call
|
||||
h2 makes doing connection setup really easy. All you need to do is call
|
||||
the
|
||||
:meth:`initiate_connection <h2.connection.H2Connection.initiate_connection>`
|
||||
method, and then send the corresponding data. Let's update our ``handle``
|
||||
@@ -348,7 +348,7 @@ new method in there:
|
||||
:meth:`data_to_send <h2.connection.H2Connection.data_to_send>`.
|
||||
|
||||
When you make function calls on your ``H2Connection`` object, these will often
|
||||
want to cause HTTP/2 data to be written out to the network. But Hyper-h2
|
||||
want to cause HTTP/2 data to be written out to the network. But h2
|
||||
doesn't do any I/O, so it can't do that itself. Instead, it writes it to an
|
||||
internal buffer. You can retrieve data from this buffer using the
|
||||
``data_to_send`` method. There are some subtleties about that method, but we
|
||||
@@ -477,17 +477,17 @@ there: ``:status``. This is a HTTP/2-specific header, and it's used to hold the
|
||||
HTTP status code that used to go at the top of a HTTP response. Here, we're
|
||||
saying the response is ``200 OK``, which is successful.
|
||||
|
||||
To send headers in Hyper-h2, you use the
|
||||
To send headers in h2, you use the
|
||||
:meth:`send_headers <h2.connection.H2Connection.send_headers>` function.
|
||||
|
||||
Next, we want to send the body data. To do that, we use the
|
||||
:meth:`send_data <h2.connection.H2Connection.send_data>` function. This also
|
||||
takes a stream ID. Note that the data is binary: Hyper-h2 does not work with
|
||||
takes a stream ID. Note that the data is binary: h2 does not work with
|
||||
unicode strings, so you *must* pass bytestrings to the ``H2Connection``. The
|
||||
one exception is headers: Hyper-h2 will automatically encode those into UTF-8.
|
||||
one exception is headers: h2 will automatically encode those into UTF-8.
|
||||
|
||||
The last thing to note is that on our call to ``send_data``, we set
|
||||
``end_stream`` to ``True``. This tells Hyper-h2 (and the remote peer) that
|
||||
``end_stream`` to ``True``. This tells h2 (and the remote peer) that
|
||||
we're done with sending data: the response is over. Because we know that
|
||||
``hyper`` will have ended its side of the stream, when we end ours the stream
|
||||
will be totally done with.
|
||||
@@ -703,7 +703,7 @@ see something like the following output from ``hyper``:
|
||||
Here you can see the HTTP/2 request 'special headers' that ``hyper`` sends.
|
||||
These are similar to the ``:status`` header we have to send on our response:
|
||||
they encode important parts of the HTTP request in a clearly-defined way. If
|
||||
you were writing a client stack using Hyper-h2, you'd need to make sure you
|
||||
you were writing a client stack using h2, you'd need to make sure you
|
||||
were sending those headers.
|
||||
|
||||
Congratulations!
|
||||
@@ -737,10 +737,10 @@ it, there are a few directions you could investigate:
|
||||
|
||||
.. _event loop: https://en.wikipedia.org/wiki/Event_loop
|
||||
.. _httpbin.org/get: https://httpbin.org/get
|
||||
.. _examples directory: https://github.com/python-hyper/hyper-h2/tree/master/examples
|
||||
.. _standard library's socket module: https://docs.python.org/3.5/library/socket.html
|
||||
.. _examples directory: https://github.com/python-hyper/h2/tree/master/examples
|
||||
.. _standard library's socket module: https://docs.python.org/3/library/socket.html
|
||||
.. _Application Layer Protocol Negotiation: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation
|
||||
.. _get your certificate here: https://raw.githubusercontent.com/python-hyper/hyper-h2/master/examples/twisted/server.crt
|
||||
.. _get your private key here: https://raw.githubusercontent.com/python-hyper/hyper-h2/master/examples/twisted/server.key
|
||||
.. _get your certificate here: https://raw.githubusercontent.com/python-hyper/h2/master/examples/twisted/server.crt
|
||||
.. _get your private key here: https://raw.githubusercontent.com/python-hyper/h2/master/examples/twisted/server.key
|
||||
.. _PyOpenSSL: http://pyopenssl.readthedocs.org/
|
||||
.. _Eventlet example: https://github.com/python-hyper/hyper-h2/blob/master/examples/eventlet/eventlet-server.py
|
||||
.. _Eventlet example: https://github.com/python-hyper/h2/blob/master/examples/eventlet/eventlet-server.py
|
||||
|
||||
@@ -6,7 +6,7 @@ example of how to build a concurrent networking framework using Python 3.5's
|
||||
new ``async``/``await`` syntax.
|
||||
|
||||
This example is notable for demonstrating the correct use of HTTP/2 flow
|
||||
control with Hyper-h2. It is also a good example of the brand new syntax.
|
||||
control with h2. It is also a good example of the brand new syntax.
|
||||
|
||||
.. literalinclude:: ../../examples/curio/curio-server.py
|
||||
:language: python
|
||||
|
||||
@@ -3,7 +3,7 @@ Code Examples
|
||||
|
||||
This section of the documentation contains long-form code examples. These are
|
||||
intended as references for developers that would like to get an understanding
|
||||
of how Hyper-h2 fits in with various Python I/O frameworks.
|
||||
of how h2 fits in with various Python I/O frameworks.
|
||||
|
||||
Example Servers
|
||||
---------------
|
||||
|
||||
@@ -7,7 +7,7 @@ to provide a high-level synchronous API on top of the `libev`_ or `libuv`_
|
||||
event loop.
|
||||
|
||||
This example is inspired by the curio one and also demonstrates the correct use
|
||||
of HTTP/2 flow control with Hyper-h2 and how gevent can be simple to use.
|
||||
of HTTP/2 flow control with h2 and how gevent can be simple to use.
|
||||
|
||||
.. literalinclude:: ../../examples/gevent/gevent-server.py
|
||||
:language: python
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Hyper-h2: A pure-Python HTTP/2 protocol stack
|
||||
=============================================
|
||||
h2: A pure-Python HTTP/2 protocol stack
|
||||
=======================================
|
||||
|
||||
Hyper-h2 is a HTTP/2 protocol stack, written entirely in Python. The goal of
|
||||
Hyper-h2 is to be a common HTTP/2 stack for the Python ecosystem,
|
||||
h2 is a HTTP/2 protocol stack, written entirely in Python. The goal of
|
||||
h2 is to be a common HTTP/2 stack for the Python ecosystem,
|
||||
usable in all programs regardless of concurrency model or environment.
|
||||
|
||||
To achieve this, Hyper-h2 is entirely self-contained: it does no I/O of any
|
||||
To achieve this, h2 is entirely self-contained: it does no I/O of any
|
||||
kind, leaving that up to a wrapper library to control. This ensures that it can
|
||||
seamlessly work in all kinds of environments, from single-threaded code to
|
||||
Twisted.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Hyper-h2 is a pure-python project. This means installing it is extremely
|
||||
h2 is a pure-python project. This means installing it is extremely
|
||||
simple. To get the latest release from PyPI, simply run:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install h2
|
||||
$ python -m pip install h2
|
||||
|
||||
Alternatively, feel free to download one of the release tarballs from
|
||||
`our GitHub page`_, extract it to your favourite directory, and then run
|
||||
@@ -15,4 +15,4 @@ Alternatively, feel free to download one of the release tarballs from
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
.. _our GitHub page: https://github.com/python-hyper/hyper-h2
|
||||
.. _our GitHub page: https://github.com/python-hyper/h2
|
||||
|
||||
+10
-10
@@ -2,16 +2,16 @@ Low-Level Details
|
||||
=================
|
||||
|
||||
.. warning:: This section of the documentation covers low-level implementation
|
||||
details of hyper-h2. This is most likely to be of use to hyper-h2
|
||||
details of h2. This is most likely to be of use to h2
|
||||
developers and to other HTTP/2 implementers, though it could well
|
||||
be of general interest. Feel free to peruse it, but if you're
|
||||
looking for information about how to *use* hyper-h2 you should
|
||||
looking for information about how to *use* h2 you should
|
||||
consider looking elsewhere.
|
||||
|
||||
State Machines
|
||||
--------------
|
||||
|
||||
hyper-h2 is fundamentally built on top of a pair of interacting Finite State
|
||||
h2 is fundamentally built on top of a pair of interacting Finite State
|
||||
Machines. One of these FSMs manages per-connection state, and another manages
|
||||
per-stream state. Almost without exception (see :ref:`priority` for more
|
||||
details) every single frame is unconditionally translated into events for
|
||||
@@ -96,7 +96,7 @@ The other action taken by the side-effect functions defined here is returning
|
||||
:ref:`events <h2-events-basic>`. Most of these events are returned directly to
|
||||
the user, and reflect the specific state transition that has taken place, but
|
||||
some of the events are purely *internal*: they are used to signal to other
|
||||
parts of the hyper-h2 codebase what action has been taken.
|
||||
parts of the h2 codebase what action has been taken.
|
||||
|
||||
The major use of the internal events functionality at this time is for
|
||||
validating header blocks: there are different rules for request headers than
|
||||
@@ -105,7 +105,7 @@ internal events are used to determine *exactly what* kind of data the user is
|
||||
attempting to send, and using that information to do the correct kind of
|
||||
validation. This approach ensures that the final source of truth about what's
|
||||
happening at the protocol level lives inside the FSM, which is an extremely
|
||||
important design principle we want to continue to enshrine in hyper-h2.
|
||||
important design principle we want to continue to enshrine in h2.
|
||||
|
||||
A visual representation of this FSM is shown below:
|
||||
|
||||
@@ -139,20 +139,20 @@ situation where it is invalid to receive a ``PRIORITY`` frame. This means that
|
||||
including it in the stream FSM would require that we allow ``SEND_PRIORITY``
|
||||
and ``RECV_PRIORITY`` in all states.
|
||||
|
||||
This is not a totally onerous task: however, another key note is that hyper-h2
|
||||
This is not a totally onerous task: however, another key note is that h2
|
||||
uses the *absence* of a stream state machine to flag a closed stream. This is
|
||||
primarily for memory conservation reasons: if we needed to keep around an FSM
|
||||
for every stream we've ever seen, that would cause long-lived HTTP/2
|
||||
connections to consume increasingly large amounts of memory. On top of this,
|
||||
it would require us to create a stream FSM each time we received a ``PRIORITY``
|
||||
frame for a given stream, giving a malicious peer an easy route to force a
|
||||
hyper-h2 user to allocate nearly unbounded amounts of memory.
|
||||
h2 user to allocate nearly unbounded amounts of memory.
|
||||
|
||||
For this reason, hyper-h2 circumvents the stream FSM entirely for ``PRIORITY``
|
||||
For this reason, h2 circumvents the stream FSM entirely for ``PRIORITY``
|
||||
frames. Instead, these frames are treated as being connection-level frames that
|
||||
*just happen* to identify a specific stream. They do not bring streams into
|
||||
being, or in any sense interact with hyper-h2's view of streams. Their stream
|
||||
details are treated as strictly metadata that hyper-h2 is not interested in
|
||||
being, or in any sense interact with h2's view of streams. Their stream
|
||||
details are treated as strictly metadata that h2 is not interested in
|
||||
beyond being able to parse it out.
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Negotiating HTTP/2
|
||||
==================
|
||||
|
||||
`RFC 7540`_ specifies three methods of negotiating HTTP/2 connections. This document outlines how to use Hyper-h2 with each one.
|
||||
`RFC 7540`_ specifies three methods of negotiating HTTP/2 connections. This document outlines how to use h2 with each one.
|
||||
|
||||
.. _starting-alpn:
|
||||
|
||||
@@ -10,12 +10,12 @@ HTTPS URLs (ALPN)
|
||||
|
||||
Starting HTTP/2 for HTTPS URLs is outlined in `RFC 7540 Section 3.3`_. In this case, the client and server use a TLS extension to negotiate HTTP/2: `ALPN`_. How to use ALPN is currently not covered in this document: please consult the documentation for either the :mod:`ssl module <python:ssl>` in the standard library, or the :mod:`PyOpenSSL <pyopenssl:OpenSSL.SSL>` third-party modules, for more on this topic.
|
||||
|
||||
This method is the simplest to use once the TLS connection is established. To use it with Hyper-h2, after you've established the connection and confirmed that HTTP/2 has been negotiated with `ALPN`_, create a :class:`H2Connection <h2.connection.H2Connection>` object and call :meth:`H2Connection.initiate_connection <h2.connection.H2Connection.initiate_connection>`. This will ensure that the appropriate preamble data is placed in the data buffer. You should then immediately send the data returned by :meth:`H2Connection.data_to_send <h2.connection.H2Connection.data_to_send>` on your TLS connection.
|
||||
This method is the simplest to use once the TLS connection is established. To use it with h2, after you've established the connection and confirmed that HTTP/2 has been negotiated with `ALPN`_, create a :class:`H2Connection <h2.connection.H2Connection>` object and call :meth:`H2Connection.initiate_connection <h2.connection.H2Connection.initiate_connection>`. This will ensure that the appropriate preamble data is placed in the data buffer. You should then immediately send the data returned by :meth:`H2Connection.data_to_send <h2.connection.H2Connection.data_to_send>` on your TLS connection.
|
||||
|
||||
At this point, you're free to use all the HTTP/2 functionality provided by Hyper-h2.
|
||||
At this point, you're free to use all the HTTP/2 functionality provided by h2.
|
||||
|
||||
.. note::
|
||||
Although Hyper-h2 is not concerned with negotiating protocol versions, it is important to note that support for `ALPN`_ is not available in the standard library of Python versions < 2.7.9.
|
||||
Although h2 is not concerned with negotiating protocol versions, it is important to note that support for `ALPN`_ is not available in the standard library of Python versions < 2.7.9.
|
||||
As a consequence, clients may encounter various errors due to protocol versions mismatch.
|
||||
|
||||
Server Setup Example
|
||||
@@ -47,18 +47,18 @@ HTTP URLs (Upgrade)
|
||||
|
||||
Starting HTTP/2 for HTTP URLs is outlined in `RFC 7540 Section 3.2`_. In this case, the client and server use the HTTP Upgrade mechanism originally described in `RFC 7230 Section 6.7`_. The client sends its initial HTTP/1.1 request with two extra headers. The first is ``Upgrade: h2c``, which requests upgrade to cleartext HTTP/2. The second is a ``HTTP2-Settings`` header, which contains a specially formatted string that encodes a HTTP/2 Settings frame.
|
||||
|
||||
To do this with Hyper-h2 you have two slightly different flows: one for clients, one for servers.
|
||||
To do this with h2 you have two slightly different flows: one for clients, one for servers.
|
||||
|
||||
Clients
|
||||
~~~~~~~
|
||||
|
||||
For a client, when sending the first request you should manually add your ``Upgrade`` header. You should then create a :class:`H2Connection <h2.connection.H2Connection>` object and call :meth:`H2Connection.initiate_upgrade_connection <h2.connection.H2Connection.initiate_upgrade_connection>` with no arguments. This method will return a bytestring to use as the value of your ``HTTP2-Settings`` header.
|
||||
|
||||
If the server returns a ``101`` status code, it has accepted the upgrade, and you should immediately send the data returned by :meth:`H2Connection.data_to_send <h2.connection.H2Connection.data_to_send>`. Now you should consume the entire ``101`` header block. All data after the ``101`` header block is HTTP/2 data that should be fed directly to :meth:`H2Connection.receive_data <h2.connection.H2Connection.receive_data>` and handled as normal with Hyper-h2.
|
||||
If the server returns a ``101`` status code, it has accepted the upgrade, and you should immediately send the data returned by :meth:`H2Connection.data_to_send <h2.connection.H2Connection.data_to_send>`. Now you should consume the entire ``101`` header block. All data after the ``101`` header block is HTTP/2 data that should be fed directly to :meth:`H2Connection.receive_data <h2.connection.H2Connection.receive_data>` and handled as normal with h2.
|
||||
|
||||
If the server does not return a ``101`` status code then it is not upgrading. Continue with HTTP/1.1 as normal: you may throw away your :class:`H2Connection <h2.connection.H2Connection>` object, as it is of no further use.
|
||||
|
||||
The server will respond to your original request in HTTP/2. Please pay attention to the events received from Hyper-h2, as they will define the server's response.
|
||||
The server will respond to your original request in HTTP/2. Please pay attention to the events received from h2, as they will define the server's response.
|
||||
|
||||
Client Example
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
Release Process
|
||||
===============
|
||||
|
||||
Because of Hyper-h2's place at the bottom of the dependency tree, it is
|
||||
Because of h2's place at the bottom of the dependency tree, it is
|
||||
extremely important that the project maintains a diligent release schedule.
|
||||
This document outlines our process for managing releases.
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Hyper-h2 follows `semantic versioning`_ of its public API when it comes to
|
||||
numbering releases. The public API of Hyper-h2 is strictly limited to the
|
||||
h2 follows `semantic versioning`_ of its public API when it comes to
|
||||
numbering releases. The public API of h2 is strictly limited to the
|
||||
entities listed in the :doc:`api` documentation: anything not mentioned in that
|
||||
document is not considered part of the public API and is not covered by the
|
||||
versioning guarantees given by semantic versioning.
|
||||
@@ -17,7 +17,7 @@ versioning guarantees given by semantic versioning.
|
||||
Maintenance
|
||||
-----------
|
||||
|
||||
Hyper-h2 has the notion of a "release series", given by a major and minor
|
||||
h2 has the notion of a "release series", given by a major and minor
|
||||
version number: for example, there is the 2.1 release series. When each minor
|
||||
release is made and a release series is born, a branch is made off the release
|
||||
tag: for example, for the 2.1 release series, the 2.1.X branch.
|
||||
@@ -32,7 +32,7 @@ backported.
|
||||
Supported Release Series'
|
||||
-------------------------
|
||||
|
||||
The developers of Hyper-h2 commit to supporting the following release series:
|
||||
The developers of h2 commit to supporting the following release series:
|
||||
|
||||
- The most recent, as identified by the first two numbers in the highest
|
||||
version currently released.
|
||||
|
||||
@@ -10,7 +10,7 @@ shortcuts have been taken to ensure ease of implementation and understanding.
|
||||
The main advantages of this example are:
|
||||
|
||||
1. It properly demonstrates HTTP/2 flow control management.
|
||||
2. It demonstrates how to plug hyper-h2 into a larger, more complex
|
||||
2. It demonstrates how to plug h2 into a larger, more complex
|
||||
application.
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
asyncio-server.py
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
A fully-functional WSGI server, written using hyper-h2. Requires asyncio.
|
||||
A fully-functional WSGI server, written using h2. Requires asyncio.
|
||||
|
||||
To test it, try installing httpbin from pip (``pip install httpbin``) and then
|
||||
running the server (``python asyncio-server.py httpbin:app``).
|
||||
|
||||
This server does not support HTTP/1.1: it is a HTTP/2-only WSGI server. The
|
||||
purpose of this code is to demonstrate how to integrate hyper-h2 into a more
|
||||
purpose of this code is to demonstrate how to integrate h2 into a more
|
||||
complex application, and to demonstrate several principles of concurrent
|
||||
programming.
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ class H2Protocol(Protocol):
|
||||
(':authority', AUTHORITY),
|
||||
(':scheme', 'https'),
|
||||
(':path', PATH),
|
||||
('user-agent', 'hyper-h2/1.0.0'),
|
||||
]
|
||||
self.conn.send_headers(1, request_headers, end_stream=True)
|
||||
self.request_made = True
|
||||
|
||||
@@ -174,7 +174,6 @@ class H2Protocol(Protocol):
|
||||
(':authority', AUTHORITY),
|
||||
(':scheme', 'https'),
|
||||
(':path', PATH),
|
||||
('user-agent', 'hyper-h2/1.0.0'),
|
||||
('content-length', str(self.file_size)),
|
||||
]
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ setup(
|
||||
long_description_content_type='text/x-rst',
|
||||
author='Cory Benfield',
|
||||
author_email='cory@lukasa.co.uk',
|
||||
url='https://github.com/python-hyper/hyper-h2',
|
||||
url='https://github.com/python-hyper/h2',
|
||||
packages=find_packages(where="src"),
|
||||
package_data={'': ['LICENSE', 'README.rst', 'CHANGELOG.rst']},
|
||||
package_dir={'': 'src'},
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
hyper-h2
|
||||
h2
|
||||
~~
|
||||
|
||||
A HTTP/2 implementation.
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ class DummyLogger:
|
||||
An Logger object that does not actual logging, hence a DummyLogger.
|
||||
|
||||
For the class the log operation is merely a no-op. The intent is to avoid
|
||||
conditionals being sprinkled throughout the hyper-h2 code for calls to
|
||||
conditionals being sprinkled throughout the h2 code for calls to
|
||||
logging functions when no logger is passed into the corresponding object.
|
||||
"""
|
||||
def __init__(self, *vargs):
|
||||
@@ -101,7 +101,7 @@ class H2Configuration:
|
||||
|
||||
:param normalize_inbound_headers: Controls whether the headers received by
|
||||
this object are normalized according to the rules of RFC 7540.
|
||||
Disabling this setting may lead to hyper-h2 emitting header blocks that
|
||||
Disabling this setting may lead to h2 emitting header blocks that
|
||||
some RFCs forbid, e.g. with multiple cookie fields.
|
||||
|
||||
.. versionadded:: 3.0.0
|
||||
|
||||
+12
-12
@@ -806,8 +806,8 @@ class H2Connection:
|
||||
:class:`FrameTooLargeError <h2.exceptions.FrameTooLargeError>` will be
|
||||
raised.
|
||||
|
||||
Hyper-h2 does this to avoid buffering the data internally. If the user
|
||||
has more data to send than hyper-h2 will allow, consider breaking it up
|
||||
h2 does this to avoid buffering the data internally. If the user
|
||||
has more data to send than h2 will allow, consider breaking it up
|
||||
and buffering it externally.
|
||||
|
||||
:param stream_id: The ID of the stream on which to send the data.
|
||||
@@ -1097,10 +1097,10 @@ class H2Connection:
|
||||
The explicit method of advertising can be done as long as the
|
||||
connection is active. The implicit method can only be done after the
|
||||
client has sent the request headers and before the server has sent the
|
||||
response headers: outside of those points, Hyper-h2 will forbid sending
|
||||
response headers: outside of those points, h2 will forbid sending
|
||||
the Alternative Service advertisement by raising a ProtocolError.
|
||||
|
||||
The ``field_value`` parameter is specified in RFC 7838. Hyper-h2 does
|
||||
The ``field_value`` parameter is specified in RFC 7838. h2 does
|
||||
not validate or introspect this argument: the user is required to
|
||||
ensure that it's well-formed. ``field_value`` corresponds to RFC 7838's
|
||||
"Alternative Service Field Value".
|
||||
@@ -1109,13 +1109,13 @@ class H2Connection:
|
||||
advertising Alternative Services. The implicit method of
|
||||
advertising Alternative Services has a number of subtleties
|
||||
and can lead to inconsistencies between the server and
|
||||
client. Hyper-h2 allows both mechanisms, but caution is
|
||||
client. h2 allows both mechanisms, but caution is
|
||||
strongly advised.
|
||||
|
||||
.. versionadded:: 2.3.0
|
||||
|
||||
:param field_value: The RFC 7838 Alternative Service Field Value. This
|
||||
argument is not introspected by Hyper-h2: the user is responsible
|
||||
argument is not introspected by h2: the user is responsible
|
||||
for ensuring that it is well-formed.
|
||||
:type field_value: ``bytes``
|
||||
|
||||
@@ -1173,17 +1173,17 @@ class H2Connection:
|
||||
stream is closed.
|
||||
|
||||
.. warning:: RFC 7540 allows for servers to change the priority of
|
||||
streams. However, hyper-h2 **does not** allow server
|
||||
streams. However, h2 **does not** allow server
|
||||
stacks to do this. This is because most clients do not
|
||||
adequately know how to respond when provided conflicting
|
||||
priority information, and relatively little utility is
|
||||
provided by making that functionality available.
|
||||
|
||||
.. note:: hyper-h2 **does not** maintain any information about the
|
||||
RFC 7540 priority tree. That means that hyper-h2 does not
|
||||
.. note:: h2 **does not** maintain any information about the
|
||||
RFC 7540 priority tree. That means that h2 does not
|
||||
prevent incautious users from creating invalid priority
|
||||
trees, particularly by creating priority loops. While some
|
||||
basic error checking is provided by hyper-h2, users are
|
||||
basic error checking is provided by h2, users are
|
||||
strongly recommended to understand their prioritisation
|
||||
strategies before using the priority tools here.
|
||||
|
||||
@@ -2028,9 +2028,9 @@ def _add_frame_priority(frame, weight=None, depends_on=None, exclusive=None):
|
||||
def _decode_headers(decoder, encoded_header_block):
|
||||
"""
|
||||
Decode a HPACK-encoded header block, translating HPACK exceptions into
|
||||
sensible hyper-h2 errors.
|
||||
sensible h2 errors.
|
||||
|
||||
This only ever returns bytestring headers: hyper-h2 may emit them as
|
||||
This only ever returns bytestring headers: h2 may emit them as
|
||||
unicode later, but internally it processes them as bytestrings only.
|
||||
"""
|
||||
try:
|
||||
|
||||
+11
-11
@@ -311,7 +311,7 @@ class RemoteSettingsChanged(Event):
|
||||
its settings. It contains a complete inventory of changed settings,
|
||||
including their previous values.
|
||||
|
||||
In HTTP/2, settings changes need to be acknowledged. hyper-h2 automatically
|
||||
In HTTP/2, settings changes need to be acknowledged. h2 automatically
|
||||
acknowledges settings changes for efficiency. However, it is possible that
|
||||
the caller may not be happy with the changed setting.
|
||||
|
||||
@@ -322,7 +322,7 @@ class RemoteSettingsChanged(Event):
|
||||
|
||||
.. versionchanged:: 2.0.0
|
||||
Prior to this version the user needed to acknowledge settings changes.
|
||||
This is no longer the case: hyper-h2 now automatically acknowledges
|
||||
This is no longer the case: h2 now automatically acknowledges
|
||||
them.
|
||||
"""
|
||||
def __init__(self):
|
||||
@@ -414,10 +414,10 @@ class StreamReset(Event):
|
||||
The StreamReset event is fired in two situations. The first is when the
|
||||
remote party forcefully resets the stream. The second is when the remote
|
||||
party has made a protocol error which only affects a single stream. In this
|
||||
case, Hyper-h2 will terminate the stream early and return this event.
|
||||
case, h2 will terminate the stream early and return this event.
|
||||
|
||||
.. versionchanged:: 2.0.0
|
||||
This event is now fired when Hyper-h2 automatically resets a stream.
|
||||
This event is now fired when h2 automatically resets a stream.
|
||||
"""
|
||||
def __init__(self):
|
||||
#: The Stream ID of the stream that was reset.
|
||||
@@ -561,12 +561,12 @@ class AlternativeServiceAvailable(Event):
|
||||
|
||||
This event always carries the origin to which the ALTSVC information
|
||||
applies. That origin is either supplied by the server directly, or inferred
|
||||
by hyper-h2 from the ``:authority`` pseudo-header field that was sent by
|
||||
by h2 from the ``:authority`` pseudo-header field that was sent by
|
||||
the user when initiating a given stream.
|
||||
|
||||
This event also carries what RFC 7838 calls the "Alternative Service Field
|
||||
Value", which is formatted like a HTTP header field and contains the
|
||||
relevant alternative service information. Hyper-h2 does not parse or in any
|
||||
relevant alternative service information. h2 does not parse or in any
|
||||
way modify that information: the user is required to do that.
|
||||
|
||||
This event can only be fired on the client end of a connection.
|
||||
@@ -576,13 +576,13 @@ class AlternativeServiceAvailable(Event):
|
||||
def __init__(self):
|
||||
#: The origin to which the alternative service field value applies.
|
||||
#: This field is either supplied by the server directly, or inferred by
|
||||
#: hyper-h2 from the ``:authority`` pseudo-header field that was sent
|
||||
#: h2 from the ``:authority`` pseudo-header field that was sent
|
||||
#: by the user when initiating the stream on which the frame was
|
||||
#: received.
|
||||
self.origin = None
|
||||
|
||||
#: The ALTSVC field value. This contains information about the HTTP
|
||||
#: alternative service being advertised by the server. Hyper-h2 does
|
||||
#: alternative service being advertised by the server. h2 does
|
||||
#: not parse this field: it is left exactly as sent by the server. The
|
||||
#: structure of the data in this field is given by `RFC 7838 Section 3
|
||||
#: <https://tools.ietf.org/html/rfc7838#section-3>`_.
|
||||
@@ -600,11 +600,11 @@ class AlternativeServiceAvailable(Event):
|
||||
class UnknownFrameReceived(Event):
|
||||
"""
|
||||
The UnknownFrameReceived event is fired when the remote peer sends a frame
|
||||
that hyper-h2 does not understand. This occurs primarily when the remote
|
||||
peer is employing HTTP/2 extensions that hyper-h2 doesn't know anything
|
||||
that h2 does not understand. This occurs primarily when the remote
|
||||
peer is employing HTTP/2 extensions that h2 doesn't know anything
|
||||
about.
|
||||
|
||||
RFC 7540 requires that HTTP/2 implementations ignore these frames. hyper-h2
|
||||
RFC 7540 requires that HTTP/2 implementations ignore these frames. h2
|
||||
does so. However, this event is fired to allow implementations to perform
|
||||
special processing on those frames if needed (e.g. if the implementation
|
||||
is capable of handling the frame itself).
|
||||
|
||||
+1
-1
@@ -528,7 +528,7 @@ class H2StreamStateMachine:
|
||||
# For this reason, our state machine implementation below allows for
|
||||
# PUSH_PROMISE frames both in the IDLE state (as in the diagram), but also
|
||||
# in the OPEN, HALF_CLOSED_LOCAL, and HALF_CLOSED_REMOTE states.
|
||||
# Essentially, for hyper-h2, PUSH_PROMISE frames are effectively sent on
|
||||
# Essentially, for h2, PUSH_PROMISE frames are effectively sent on
|
||||
# two streams.
|
||||
#
|
||||
# The _transitions dictionary contains a mapping of tuples of
|
||||
|
||||
@@ -4,17 +4,17 @@ State Machine Visualizer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This code provides a module that can use graphviz to visualise the state
|
||||
machines included in hyper-h2. These visualisations can be used as part of the
|
||||
documentation of hyper-h2, and as a reference material to understand how the
|
||||
machines included in h2. These visualisations can be used as part of the
|
||||
documentation of h2, and as a reference material to understand how the
|
||||
state machines function.
|
||||
|
||||
The code in this module is heavily inspired by code in Automat, which can be
|
||||
found here: https://github.com/glyph/automat. For details on the licensing of
|
||||
Automat, please see the NOTICES.visualizer file in this folder.
|
||||
|
||||
This module is very deliberately not shipped with the rest of hyper-h2. This is
|
||||
because it is of minimal value to users who are installing hyper-h2: its use
|
||||
is only really for the developers of hyper-h2.
|
||||
This module is very deliberately not shipped with the rest of h2. This is
|
||||
because it is of minimal value to users who are installing h2: its use
|
||||
is only really for the developers of h2.
|
||||
"""
|
||||
import argparse
|
||||
import collections
|
||||
@@ -200,13 +200,13 @@ def build_digraph(state_machine):
|
||||
|
||||
def main():
|
||||
"""
|
||||
Renders all the state machines in hyper-h2 into images.
|
||||
Renders all the state machines in h2 into images.
|
||||
"""
|
||||
program_name = sys.argv[0]
|
||||
argv = sys.argv[1:]
|
||||
|
||||
description = """
|
||||
Visualize hyper-h2 state machines as graphs.
|
||||
Visualize h2 state machines as graphs.
|
||||
"""
|
||||
epilog = """
|
||||
You must have the graphviz tool suite installed. Please visit
|
||||
|
||||
Reference in New Issue
Block a user