A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
npx @tessl/cli install tessl/pypi-h11@0.16.0A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 that focuses on correctly parsing and generating HTTP messages at the byte level. h11 follows a "bring-your-own-I/O" architecture, containing no networking code and integrating with any network framework (synchronous, asynchronous, threaded, etc.). The library provides robust RFC 7230 compliant parsing with linear-time algorithms, bounded memory usage, and comprehensive spec conformance while remaining lightweight at ~800 lines of code.
pip install h11import h11Common usage imports:
from h11 import Connection, CLIENT, SERVER, Request, Response, Data, EndOfMessageimport h11
# Create a client connection
conn = h11.Connection(h11.CLIENT)
# Create and send a request
req = h11.Request(method=b'GET', target=b'/', headers=[(b'host', b'example.com')])
data = conn.send(req)
# Send data over your socket/transport
# End the request message
eom = h11.EndOfMessage()
data = conn.send(eom)
# Send data over your socket/transport
# Process incoming response data
conn.receive_data(received_bytes)
while True:
event = conn.next_event()
if event is h11.NEED_DATA:
# Need more data from socket
break
elif isinstance(event, h11.Response):
print(f"Response status: {event.status_code}")
elif isinstance(event, h11.Data):
print(f"Body data: {event.data}")
elif isinstance(event, h11.EndOfMessage):
print("Response complete")
breakh11 implements a symmetric state machine architecture where the same events are used for both client and server implementations:
The symmetric design enables the same events to represent HTTP requests and responses, making it suitable for clients, servers, proxies, and testing tools.
Core connection handling and state management for HTTP/1.1 protocol implementation.
class Connection:
def __init__(self, our_role, max_incomplete_event_size=16384): ...
def next_event(self): ...
def send(self, event): ...
def send_with_data_passthrough(self, event): ...
def receive_data(self, data): ...
def start_next_cycle(self): ...
def send_failed(self): ...
# Connection control sentinels
class NEED_DATA: ...
class PAUSED: ...Event classes representing different parts of HTTP messages - requests, responses, data, and connection lifecycle.
class Event: ...
class Request(Event): ...
class InformationalResponse(Event): ...
class Response(Event): ...
class Data(Event): ...
class EndOfMessage(Event): ...
class ConnectionClosed(Event): ...State constants and role definitions for managing HTTP/1.1 connection lifecycle and protocol compliance.
# Role constants
CLIENT = ...
SERVER = ...
# Connection state constants
IDLE = ...
SEND_RESPONSE = ...
SEND_BODY = ...
DONE = ...
MUST_CLOSE = ...
CLOSED = ...
ERROR = ...
SWITCHED_PROTOCOL = ...Protocol error hierarchy for handling HTTP/1.1 violations and connection errors.
class ProtocolError(Exception): ...
class LocalProtocolError(ProtocolError): ...
class RemoteProtocolError(ProtocolError): ...# Type aliases for headers
Headers = List[Tuple[bytes, bytes]]
# Event union type
Event = Union[
Request, InformationalResponse, Response,
Data, EndOfMessage, ConnectionClosed
]
# State machine result types
NextEventResult = Union[Event, Type[NEED_DATA], Type[PAUSED]]
SendResult = Optional[bytes]
SendWithDataResult = Optional[List[bytes]]