Rename all crate directories, package names, binary names, proto package/module paths, ALPN strings, env var prefixes, config filenames, mDNS service names, and plugin ABI symbols from quicproquo/qpq to quicprochat/qpc.
quicproquo Python SDK
Python client library for the quicproquo E2E encrypted messenger.
Prerequisites
- Python 3.10+
- A running quicproquo server
Installation
pip install quicproquo
For development:
pip install -e ".[dev]"
Transport Backends
1. Async QUIC (pure Python)
Uses aioquic for native QUIC transport with the v2 protobuf wire format. No Rust dependency required.
import asyncio
from quicproquo 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 for crypto)
server_resp = await client.login_start("alice", opaque_request_bytes)
# ... process server_resp with OPAQUE library ...
token = await client.login_finish("alice", finalization, identity_key)
# Resolve a user
key, proof = await client.resolve_user("bob")
# Send a message
seq, proof = await client.send(recipient_key, b"hello")
# Receive messages (long-poll)
messages = await client.receive_wait(my_key, timeout_ms=5000)
for msg in messages:
print(f"[{msg.seq}] {msg.data}")
await client.close()
asyncio.run(main())
2. Rust FFI (synchronous)
Wraps libquicproquo_ffi via CFFI for full Rust crypto stack (MLS, hybrid KEM, OPAQUE) at native speed.
# Build the FFI library first
cargo build --release -p quicproquo-ffi
from quicproquo 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 from Python!")
messages = client.ffi_receive(timeout_ms=5000)
for msg in messages:
print(msg)
client.close_sync()
API Reference
Connection
| Method | Transport | Description |
|---|---|---|
QpqClient.connect(opts) |
QUIC | Async connect to server |
QpqClient.connect_ffi(opts) |
FFI | Sync connect via Rust FFI |
client.close() |
QUIC | Async disconnect |
client.close_sync() |
Both | Sync disconnect |
Authentication (QUIC)
| Method | Description |
|---|---|
client.register_start(username, request) |
Start OPAQUE registration |
client.register_finish(username, upload, identity_key) |
Complete registration |
client.login_start(username, request) |
Start OPAQUE login |
client.login_finish(username, finalization, identity_key) |
Complete login |
client.set_session_token(token) |
Set pre-existing session token |
Authentication (FFI)
| Method | Description |
|---|---|
client.ffi_login(username, password) |
Full OPAQUE login (Rust handles crypto) |
Messaging (QUIC)
| Method | Description |
|---|---|
client.health() |
Server health check |
client.resolve_user(username) |
Look up identity key |
client.resolve_identity(key) |
Reverse look up username |
client.create_channel(peer_key) |
Create 1:1 DM channel |
client.send(recipient_key, payload) |
Send a message |
client.receive(recipient_key) |
Fetch queued messages |
client.receive_wait(recipient_key, timeout_ms=5000) |
Long-poll for messages |
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.delete_account() |
Permanently delete account |
Messaging (FFI)
| Method | Description |
|---|---|
client.ffi_send(recipient, message) |
Send message by username |
client.ffi_receive(timeout_ms=5000) |
Receive pending messages |
Wire Format
The SDK implements the qpq v2 wire format:
[method_id:u16][req_id:u32][len:u32][protobuf payload]
Each RPC is sent over its own QUIC bidirectional stream.
Structure
quicproquo/client.py-- High-level client APIquicproquo/transport.py-- QUIC transport (aioquic)quicproquo/ffi.py-- Rust FFI transport (CFFI)quicproquo/proto.py-- Protobuf encode/decode (no codegen)quicproquo/wire.py-- v2 wire format framingquicproquo/types.py-- Data types and exceptionsexamples/bot.py-- Async echo bot exampleexamples/ffi_demo.py-- Synchronous FFI example
Running Tests
pip install -e ".[dev]"
pytest