# quicprochat Python SDK Python client library for the [quicprochat](https://github.com/nicholasgasior/quicprochat) E2E encrypted messenger. ## Prerequisites - Python 3.10+ - A running quicprochat server ## Installation ```sh pip install quicprochat ``` For development: ```sh pip install -e ".[dev]" ``` ## Transport Backends ### 1. Async QUIC (pure Python) Uses [aioquic](https://github.com/aiortc/aioquic) for native QUIC transport with the v2 protobuf wire format. No Rust dependency required. ```python 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 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 `libquicprochat_ffi` via CFFI for full Rust crypto stack (MLS, hybrid KEM, OPAQUE) at native speed. ```sh # Build the FFI library first cargo build --release -p quicprochat-ffi ``` ```python 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 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 qpc v2 wire format: ``` [method_id:u16][req_id:u32][len:u32][protobuf payload] ``` Each RPC is sent over its own QUIC bidirectional stream. ## Structure - `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 (no codegen) - `quicprochat/wire.py` -- v2 wire format framing - `quicprochat/types.py` -- Data types and exceptions - `examples/bot.py` -- Async echo bot example - `examples/ffi_demo.py` -- Synchronous FFI example ## Running Tests ```sh pip install -e ".[dev]" pytest ```