Python SDK for Relayly — self-hosted end-to-end encrypted WebSocket relay
Project description
relayly
Python SDK for Relayly — a self-hosted, end-to-end encrypted WebSocket relay for local-first apps.
Async-first (asyncio), with full feature parity with the Go and TypeScript SDKs.
Install
pip install relayly
Quick start
import asyncio
import relayly
async def main():
key = relayly.load_or_generate_key("~/.relayly/device.key")
client = await relayly.connect("wss://relay.example.com", relayly.Options(
device_id="my-laptop",
private_key=key,
))
async for msg in client.messages():
print(f"[{msg.from_device}]", msg.payload.decode())
asyncio.run(main())
Pairing
# Device A — request a code
code = await client.request_pair_code()
print("Share this code:", code.short)
print("QR URL:", code.qr_code_url("wss://relay.example.com"))
peer = await code.wait() # blocks until the other device pairs
print("Paired with", peer.id)
# Device B — accept the code
peer = await client.accept_pair("483921")
Sending messages
await client.send(peer.id, b"hello!")
await client.send(peer.id, "hello!".encode())
Reconnection
The client reconnects automatically with exponential backoff (1 s → 60 s).
relayly.Options(
device_id="my-laptop",
private_key=key,
reconnect_delay=2.0, # initial delay in seconds (default: 1.0)
max_reconnect_delay=30.0, # backoff ceiling (default: 60.0)
on_disconnect=lambda err: print("disconnected:", err),
on_reconnect=lambda: print("reconnected"),
)
Set reconnect_delay=-1 to disable automatic reconnection.
Key management
# Generate a fresh key
key = relayly.generate_key()
# Save and load manually
key.save_to_file("~/.relayly/device.key")
key = relayly.load_key_from_file("~/.relayly/device.key")
# Load or generate in one call (recommended)
key = relayly.load_or_generate_key("~/.relayly/device.key")
Options
| Option | Type | Default | Description |
|---|---|---|---|
device_id |
str |
— | Unique ID for this device. Required. |
private_key |
PrivateKey |
— | X25519 private key. Required. |
ping_interval |
float |
30.0 |
Keepalive ping interval (seconds). |
reconnect_delay |
float |
1.0 |
Initial reconnect delay. Set to -1 to disable. |
max_reconnect_delay |
float |
60.0 |
Backoff ceiling (seconds). |
on_disconnect |
Callable |
None |
Called with the exception when connection drops. |
on_reconnect |
Callable |
None |
Called after a successful reconnect. |
Requirements
- Python 3.11+
websockets >= 12.0PyNaCl >= 1.5.0
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file relayly-0.3.1.tar.gz.
File metadata
- Download URL: relayly-0.3.1.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e10250ad6234faf58e9772f77363cc5743a8241ef9e3b932920d35200adf7e38
|
|
| MD5 |
92759dc05dc98f4e4d56386ff3b333e2
|
|
| BLAKE2b-256 |
f1213e1e946e55fbc8ed4e0f2086210961f74d18c34dc9a4471537f081c92761
|
File details
Details for the file relayly-0.3.1-py3-none-any.whl.
File metadata
- Download URL: relayly-0.3.1-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
562edcbd69e91edc55e7ce9fb68b26cdab8950cdd4615c2a63f67034bdbbfb2e
|
|
| MD5 |
12462fa359e46be2de914146d52393cf
|
|
| BLAKE2b-256 |
3ff022c5745dc5f53424e5451c9d3dc358da89421c6a21aca19b1dc3d96352d6
|