Files
quicproquo/sdks/python
Christian Nennemann a710037dde chore: rename quicproquo → quicprochat in Rust workspace
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.
2026-03-21 19:14:06 +01:00
..

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 API
  • quicproquo/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 framing
  • quicproquo/types.py -- Data types and exceptions
  • examples/bot.py -- Async echo bot example
  • examples/ffi_demo.py -- Synchronous FFI example

Running Tests

pip install -e ".[dev]"
pytest