Files
quicproquo/docs/sdk/python.md
Christian Nennemann 2e081ead8e chore: rename quicproquo → quicprochat in docs, Docker, CI, and packaging
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
2026-03-21 19:14:06 +01:00

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