feat(sdk): add Python SDK with QUIC and FFI transport backends
Implements quicproquo-py with two transport backends: - Async QUIC transport via aioquic with v2 protobuf wire format - Synchronous Rust FFI transport via CFFI wrapping libquicproquo_ffi Includes manual protobuf encode/decode (no codegen), full RPC coverage (auth, delivery, channels, users, keys, health), PyPI-ready packaging, async echo bot and FFI demo examples, and 15 passing unit tests.
This commit is contained in:
60
sdks/python/examples/ffi_demo.py
Normal file
60
sdks/python/examples/ffi_demo.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Example: synchronous messaging using the Rust FFI backend.
|
||||
|
||||
Requires libquicproquo_ffi to be built:
|
||||
cargo build --release -p quicproquo-ffi
|
||||
|
||||
Set QPQ_LIB_PATH if the library is not in the default search path.
|
||||
|
||||
Usage:
|
||||
python ffi_demo.py --server 127.0.0.1:5001 \
|
||||
--ca-cert ca.pem --user alice --pass secret
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
from quicproquo import QpqClient, ConnectOptions
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="qpq FFI demo")
|
||||
parser.add_argument("--server", default="127.0.0.1:5001")
|
||||
parser.add_argument("--ca-cert", default="ca.pem")
|
||||
parser.add_argument("--server-name", default="")
|
||||
parser.add_argument("--user", required=True)
|
||||
parser.add_argument("--pass", dest="password", required=True)
|
||||
parser.add_argument("--recipient", required=True, help="recipient username")
|
||||
parser.add_argument("--message", default="hello from Python SDK!")
|
||||
args = parser.parse_args()
|
||||
|
||||
opts = ConnectOptions(
|
||||
addr=args.server,
|
||||
ca_cert_path=args.ca_cert,
|
||||
server_name=args.server_name,
|
||||
)
|
||||
|
||||
client = QpqClient.connect_ffi(opts)
|
||||
|
||||
try:
|
||||
print(f"Connected to {args.server}")
|
||||
|
||||
client.ffi_login(args.user, args.password)
|
||||
print(f"Logged in as {args.user}")
|
||||
|
||||
client.ffi_send(args.recipient, args.message.encode("utf-8"))
|
||||
print(f"Sent message to {args.recipient}")
|
||||
|
||||
print("Waiting for messages (5s)...")
|
||||
messages = client.ffi_receive(timeout_ms=5000)
|
||||
for msg in messages:
|
||||
print(f" received: {msg}")
|
||||
|
||||
finally:
|
||||
client.close_sync()
|
||||
print("Disconnected.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user