wsproto: Pure-Python WebSocket Protocol Implementation

1.3.2 · active · verified Sat Mar 28

wsproto is a pure-Python, sans-I/O implementation of the WebSocket protocol stack (RFC 6455) and its per-message compression extension (RFC 7692). It provides a low-level, state-machine-driven API, allowing developers to embed WebSocket communication into various programming paradigms without dictating network or concurrency models. The current version is 1.3.2, with releases occurring on an irregular but active basis as needed by the `python-hyper` community.

Warnings

Install

Imports

Quickstart

wsproto is a 'sans-I/O' library, meaning it handles the protocol state machine but not network communication. The quickstart demonstrates a simulated client-server interaction by manually passing bytes between two `WSConnection` instances. In a real application, `client_ws.send()`'s output would be written to a network socket, and `client_ws.receive_data()` would consume bytes read from that socket. Events are processed by iterating `ws.events()`.

from wsproto import WSConnection, ConnectionType
from wsproto.events import Request, AcceptConnection, TextMessage, CloseConnection
import socket
import os

# Example: Simple WebSocket client interaction (sans-I/O)
# This code demonstrates the wsproto logic; actual network I/O is omitted for brevity.
# In a real application, 'send_bytes_to_network' and 'receive_bytes_from_network'
# would interact with a socket or other I/O primitive.

def simulate_client_server_interaction():
    client_ws = WSConnection(ConnectionType.CLIENT)
    server_ws = WSConnection(ConnectionType.SERVER)

    # Client initiates handshake
    client_handshake_request = client_ws.send(Request(host="example.com", target="/"))
    print(f"Client sends handshake request: {client_handshake_request!r}")

    # Server receives handshake request
    server_ws.receive_data(client_handshake_request)
    for event in server_ws.events():
        if isinstance(event, Request):
            print(f"Server receives client Request: {event}")
            server_handshake_response = server_ws.send(AcceptConnection())
            print(f"Server sends handshake response: {server_handshake_response!r}")
            break

    # Client receives handshake response
    client_ws.receive_data(server_handshake_response)
    for event in client_ws.events():
        if isinstance(event, AcceptConnection):
            print(f"Client receives Server Acceptance: {event}")
            break

    # Client sends a message
    client_message_bytes = client_ws.send(TextMessage(data="Hello from client!"))
    print(f"Client sends message: {client_message_bytes!r}")

    # Server receives the message
    server_ws.receive_data(client_message_bytes)
    for event in server_ws.events():
        if isinstance(event, TextMessage):
            print(f"Server receives message: {event.data!r}")
            if event.message_finished:
                # Server echoes back
                server_response_bytes = server_ws.send(TextMessage(data=f"Echo: {event.data.decode()}"))
                print(f"Server sends echo: {server_response_bytes!r}")
                break

    # Client receives server's echo
    client_ws.receive_data(server_response_bytes)
    for event in client_ws.events():
        if isinstance(event, TextMessage):
            print(f"Client receives echo: {event.data.decode()!r}")
            break

    # Client initiates close
    client_close_bytes = client_ws.send(CloseConnection(code=1000, reason="Done"))
    print(f"Client sends close frame: {client_close_bytes!r}")

    # Server receives close
    server_ws.receive_data(client_close_bytes)
    for event in server_ws.events():
        if isinstance(event, CloseConnection):
            print(f"Server receives CloseConnection: {event}")
            server_close_response = server_ws.send(event.response())
            print(f"Server sends close response: {server_close_response!r}")
            break

    # Client receives server's close response
    client_ws.receive_data(server_close_response)
    for event in client_ws.events():
        if isinstance(event, CloseConnection):
            print(f"Client receives CloseConnection response: {event}")
            break

simulate_client_server_interaction()

view raw JSON →