Python client for WSE (WebSocket Engine) -- real-time event streaming
Project description
wse-client
Python client for WSE (WebSocket Engine) -- real-time event streaming with auto-reconnection, compression, encryption, and connection resilience.
Feature parity with the TypeScript client. Pure Python, no Rust dependency.
Installation
pip install wse-client
Optional extras:
pip install wse-client[crypto] # E2E encryption (ECDH + AES-GCM)
pip install wse-client[msgpack] # MessagePack binary encoding
pip install wse-client[orjson] # Faster JSON (de)serialization
pip install wse-client[all] # Everything
Quick Start
Async (recommended)
from wse_client import AsyncWSEClient
async with AsyncWSEClient("ws://localhost:5006/wse", token="jwt...") as client:
await client.subscribe(["notifications", "trades"])
async for event in client:
print(event.type, event.payload)
Sync
from wse_client import SyncWSEClient
client = SyncWSEClient("ws://localhost:5006/wse", token="jwt...")
client.connect()
client.subscribe(["notifications"])
event = client.recv(timeout=5.0)
print(event.type, event.payload)
client.close()
Callbacks
client = SyncWSEClient("ws://localhost:5006/wse", token="jwt...")
@client.on("notifications")
def handle(event):
print(event.payload)
@client.on("*")
def catch_all(event):
print(f"[{event.type}] {event.payload}")
client.connect()
client.run_forever()
API Reference
AsyncWSEClient
| Method | Description |
|---|---|
connect() |
Open WebSocket connection |
disconnect() |
Close connection gracefully |
send(type, payload, priority=5) |
Send a message |
send_with_retry(type, payload, max_retries=5) |
Send with exponential backoff |
send_batch(messages) |
Send multiple messages in one frame |
subscribe(topics) |
Subscribe to event topics |
unsubscribe(topics) |
Unsubscribe from topics |
request_snapshot(topics) |
Request current state for topics |
on(event_type) |
Register event handler (decorator) |
off(event_type, handler) |
Remove event handler |
recv(timeout=None) |
Receive next event explicitly |
force_reconnect() |
Force a reconnection |
change_endpoint(url) |
Switch to a different server |
get_stats() |
Connection and message statistics |
Properties: is_connected, is_ready, is_fully_ready, state, connection_quality, subscribed_topics, queue_size
Context manager and async iterator:
async with AsyncWSEClient(url) as client: # auto connect/disconnect
async for event in client: # async iterator
...
SyncWSEClient
Same API as AsyncWSEClient but blocking. Runs the async client in a background daemon thread.
Additional methods:
| Method | Description |
|---|---|
run_forever() |
Block and dispatch events to callbacks |
recv(timeout=None) |
Block until next event (raises WSETimeoutError) |
WSEEvent
@dataclass(frozen=True, slots=True)
class WSEEvent:
type: str # Event type ("t" field)
payload: dict[str, Any] # Event data ("p" field)
id: str | None = None # Message ID
sequence: int | None = None # Sequence number
timestamp: str | None = None # ISO 8601 timestamp
version: int = 1 # Protocol version
category: str | None = None # Message category (system/snapshot/update)
priority: int | None = None # Message priority (1-10)
Features
Auto-Reconnection
Automatic reconnection with configurable strategy:
from wse_client import AsyncWSEClient, ReconnectConfig, ReconnectMode
client = AsyncWSEClient(
"ws://localhost:5006/wse",
reconnect=ReconnectConfig(
mode=ReconnectMode.EXPONENTIAL, # or LINEAR, FIBONACCI, ADAPTIVE
base_delay=1.0,
max_delay=30.0,
factor=1.5,
jitter=True,
),
)
Message Priority
from wse_client import MessagePriority
await client.send("alert", {"msg": "critical"}, priority=MessagePriority.CRITICAL)
await client.send("log", {"msg": "debug info"}, priority=MessagePriority.BACKGROUND)
Compression
Built-in zlib compression for messages over 1 KB. Transparent -- no configuration needed.
E2E Encryption
ECDH P-256 key exchange with AES-GCM-256 encryption (requires cryptography):
pip install wse-client[crypto]
Wire-compatible with the TypeScript client and Rust server.
Circuit Breaker
Prevents connection storms. Opens after 5 consecutive failures, retries after 60s cooldown.
Rate Limiting
Token bucket rate limiter (1000 tokens, 100/sec refill). Prevents message flooding.
Event Sequencing
Automatic duplicate detection (sliding window) and out-of-order event buffering (up to 100 gap).
Network Quality Monitoring
Real-time latency, jitter, and packet loss tracking:
stats = client.get_stats()
print(stats["network"]["quality"]) # EXCELLENT / GOOD / FAIR / POOR
print(stats["network"]["latency_ms"]) # Round-trip time
print(stats["network"]["jitter_ms"]) # Latency variance
Connection Pool
Multi-endpoint support with health scoring and load balancing:
from wse_client import ConnectionPool, LoadBalancingStrategy
pool = ConnectionPool(
["ws://server1:5006/wse", "ws://server2:5006/wse"],
strategy=LoadBalancingStrategy.WEIGHTED_RANDOM,
)
url = pool.select_endpoint()
Wire Protocol
The client speaks WSE wire protocol v1:
- Text frames: Category prefix (
WSE{,S{,U{) + JSON envelope - Binary frames: Codec prefix (
C:zlib,M:msgpack,E:AES-GCM) + payload - Heartbeat: JSON PING/PONG every 15s with latency tracking
Full protocol spec: PROTOCOL.md
Requirements
- Python 3.11+
websockets >= 13.0
Optional:
cryptography >= 43.0(E2E encryption)msgpack >= 1.0(binary encoding)orjson >= 3.10(fast JSON)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wse_client-1.4.0.tar.gz.
File metadata
- Download URL: wse_client-1.4.0.tar.gz
- Upload date:
- Size: 35.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52939f2896a9f60f2ee080f50169673c31f5856bce00f86fc0ac84142fca0be9
|
|
| MD5 |
a0e3200ee1a6b6689a36e13110c1e3f3
|
|
| BLAKE2b-256 |
6bee02e8283068367bb17488b30aacb24eff5543d1ca0f5ec884eea89f749b45
|
Provenance
The following attestation bundles were made for wse_client-1.4.0.tar.gz:
Publisher:
release.yml on silvermpx/wse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wse_client-1.4.0.tar.gz -
Subject digest:
52939f2896a9f60f2ee080f50169673c31f5856bce00f86fc0ac84142fca0be9 - Sigstore transparency entry: 984993065
- Sigstore integration time:
-
Permalink:
silvermpx/wse@721db8895ea4233a5ebcd311e862411b52a534e1 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/silvermpx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@721db8895ea4233a5ebcd311e862411b52a534e1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wse_client-1.4.0-py3-none-any.whl.
File metadata
- Download URL: wse_client-1.4.0-py3-none-any.whl
- Upload date:
- Size: 36.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3426f231ff3a9cdb67b9c479a289d17ff9977e931cd1d1c29fa4145aae869b1f
|
|
| MD5 |
48370034569f02b10df6c59ab1998070
|
|
| BLAKE2b-256 |
1e1b0238466d1aacbb0832e23e5b20926a667ff233279e71f27bf92cab9ed3b5
|
Provenance
The following attestation bundles were made for wse_client-1.4.0-py3-none-any.whl:
Publisher:
release.yml on silvermpx/wse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wse_client-1.4.0-py3-none-any.whl -
Subject digest:
3426f231ff3a9cdb67b9c479a289d17ff9977e931cd1d1c29fa4145aae869b1f - Sigstore transparency entry: 984993067
- Sigstore integration time:
-
Permalink:
silvermpx/wse@721db8895ea4233a5ebcd311e862411b52a534e1 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/silvermpx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@721db8895ea4233a5ebcd311e862411b52a534e1 -
Trigger Event:
push
-
Statement type: