h11

0.16.0 · active · verified Fri Mar 27

h11 is a pure-Python, bring-your-own-I/O implementation of HTTP/1.1, heavily inspired by hyper-h2. It contains no networking code whatsoever — you supply the bytes in and out — making it usable with any I/O model: synchronous, threaded, asyncio, trio, or custom. It models the HTTP exchange as a strict state machine emitting typed event objects (Request, Response, Data, EndOfMessage, etc.) and enforces spec conformance on both incoming and outgoing messages. Current version is 0.16.0, released in 2025 as a security fix; releases are infrequent and focused on correctness. It has no dependencies outside the Python standard library.

Warnings

Install

Imports

Quickstart

Minimal synchronous HTTP/1.1 client using a raw socket. Demonstrates Connection setup, sending a Request + EndOfMessage, and draining events in a loop.

import socket
import ssl
import h11

HOST = "httpbin.org"
PORT = 443

ctx = ssl.create_default_context()
sock = ctx.wrap_socket(
    socket.create_connection((HOST, PORT)),
    server_hostname=HOST,
)

conn = h11.Connection(our_role=h11.CLIENT)

# Send request
sock.sendall(conn.send(h11.Request(
    method="GET",
    target="/get",
    headers=[("Host", HOST), ("Connection", "close")],
)))
sock.sendall(conn.send(h11.EndOfMessage()))

# Receive events
while True:
    event = conn.next_event()
    if event is h11.NEED_DATA:
        data = sock.recv(4096)
        conn.receive_data(data)
        continue
    if isinstance(event, h11.Response):
        print("Status:", event.status_code)
    elif isinstance(event, h11.Data):
        print("Body chunk:", event.data[:80])
    elif isinstance(event, (h11.EndOfMessage, h11.ConnectionClosed)):
        break

sock.close()

view raw JSON →