Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
3.6 KiB
3.6 KiB
Python SDK
The Python SDK provides both async QUIC transport and synchronous Rust FFI backends.
Location: sdks/python/
Installation
pip install quicprochat
Transport Backends
Async QUIC (pure Python)
Uses aioquic for native QUIC transport with the v2 protobuf wire format. No Rust build required.
import asyncio
from quicprochat import QpqClient, ConnectOptions
async def main():
client = await QpqClient.connect(ConnectOptions(
addr="127.0.0.1:5001",
ca_cert_path="ca.pem",
))
health = await client.health()
print(f"Server: {health.status}")
# OPAQUE auth (requires external OPAQUE library)
resp = await client.login_start("alice", opaque_request)
token = await client.login_finish("alice", finalization, identity_key)
# Messaging
key, proof = await client.resolve_user("bob")
seq, proof = await client.send(key, b"hello")
messages = await client.receive_wait(my_key, timeout_ms=5000)
await client.close()
asyncio.run(main())
Rust FFI (synchronous)
Wraps libquicprochat_ffi via CFFI for full Rust crypto stack at native speed.
cargo build --release -p quicprochat-ffi
from quicprochat import QpqClient, ConnectOptions
client = QpqClient.connect_ffi(ConnectOptions(
addr="127.0.0.1:5001",
ca_cert_path="ca.pem",
))
client.ffi_login("alice", "password123")
client.ffi_send("bob", b"hello")
messages = client.ffi_receive(timeout_ms=5000)
client.close_sync()
Async API (QUIC)
| Method | Description |
|---|---|
QpqClient.connect(opts) |
Connect via QUIC |
client.health() |
Health check |
client.register_start(username, request) |
OPAQUE register start |
client.register_finish(username, upload, key) |
OPAQUE register finish |
client.login_start(username, request) |
OPAQUE login start |
client.login_finish(username, finalization, key) |
OPAQUE login finish |
client.resolve_user(username) |
Look up identity key |
client.resolve_identity(key) |
Reverse look up username |
client.create_channel(peer_key) |
Create DM channel |
client.send(recipient_key, payload) |
Send message |
client.receive(recipient_key) |
Fetch messages |
client.receive_wait(recipient_key, timeout_ms=5000) |
Long-poll |
client.ack(recipient_key, seq_up_to) |
Acknowledge messages |
client.upload_key_package(key, package) |
Upload MLS key package |
client.fetch_key_package(key) |
Fetch MLS key package |
client.upload_hybrid_key(key, hybrid_pk) |
Upload hybrid key |
client.fetch_hybrid_key(key) |
Fetch hybrid key |
client.delete_account() |
Delete account |
client.close() |
Disconnect (async) |
FFI API (synchronous)
| Method | Description |
|---|---|
QpqClient.connect_ffi(opts) |
Connect via Rust FFI |
client.ffi_login(username, password) |
Full OPAQUE login |
client.ffi_send(recipient, message) |
Send by username |
client.ffi_receive(timeout_ms=5000) |
Receive messages |
client.close_sync() |
Disconnect (sync) |
Exceptions
| Exception | Description |
|---|---|
QpqError |
Base exception for all SDK errors |
AuthError |
OPAQUE authentication failed |
TimeoutError |
Operation timed out |
ConnectionError |
Server connection failure |
Structure
| File | Purpose |
|---|---|
quicprochat/client.py |
High-level client API |
quicprochat/transport.py |
QUIC transport (aioquic) |
quicprochat/ffi.py |
Rust FFI transport (CFFI) |
quicprochat/proto.py |
Protobuf encode/decode |
quicprochat/wire.py |
v2 wire format framing |
quicprochat/types.py |
Data types and exceptions |