meadows-client
Client-side Socket.IO transport for MEADOWS: connect, reconnect, JWT handshake. No domain logic — shared by
meadows-botand future non-browser clients.
What this package contains
client.py—MeadowClientwrappingsocketio.AsyncClient- JWT handshake on
/chatnamespace connect - Auto-reconnect (delegated to socketio)
send_message()constructs a valid protocolMessagebefore emittingon(event, handler)for user-registered handlersemit(event, data)escape hatch for non-message eventsregister_label_subscription()/unregister_label_subscription()for label routingon_label_assigned()callback registration for subscription matchescall_rpc()— async RPC via labels (send request, await response)
- JWT handshake on
Install
cd meadows-client
uv pip install -e .
Test
uv run pytest -q
Usage
Pre-signed JWT (recommended)
from meadows.client import MeadowClient
from meadows.protocol import EventName, JWTRole, build_claims
client = MeadowClient(
server_url="http://localhost:8080",
claims=build_claims(name="alice", role=JWTRole.USER),
token="<pre-signed-jwt>",
)
client.on(EventName.MESSAGE, lambda data: print("got:", data))
await client.connect()
await client.send_message(content="hello world", group_id="general")
Generate a token with inv user-jwt or inv bot-jwt on the server.
Raw signing key (local dev / TUI only)
client = MeadowClient(
server_url="http://localhost:8080",
claims=build_claims(name="alice", role=JWTRole.USER),
jwt_secret=b"<shared key bytes>",
)
Protocol contract
This client never sends a frame that violates meadows.protocol. The
send_message() method constructs a valid Message envelope before
emitting, so the server-side chokepoint never sees an invalid frame from us.
Label subscriptions
# Subscribe to labels matching a JSON Logic predicate
client.register_label_subscription(
"sentiment-alerts",
{"regex_match": [{"var": "label"}, "^sentiment$"]},
scope="global",
deliver="label_only",
)
# Handle matched labels
client.on_label_assigned("sentiment-alerts")(lambda data: print(data))
Subscriptions are replayed on reconnect.
RPC via labels
# Send an RPC request and await the response (async)
result = await client.call_rpc("service:math", "add 2 3", origin="bot-math-svc")
call_rpc creates an RPC_REQUEST message, routes it via label subscriptions, and resolves when the matching RPC_RESPONSE arrives. Raises asyncio.TimeoutError on timeout.
API
async def call_rpc(
self,
service_label: str, # Label to route to (e.g. "service:math")
content: str, # Request payload
*,
origin: str | None = None, # Label origin (defaults to caller identity)
semver: str = "1.0.0", # Label semver
timeout: float = 30.0, # Seconds before TimeoutError
group_id: str = "general", # Group for persistence
) -> str # Response content
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 meadows_client-0.1.0.tar.gz.
File metadata
- Download URL: meadows_client-0.1.0.tar.gz
- Upload date:
- Size: 88.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a72f119ed1ce66f70958173ad4c05c05be3792c19a6248ca621b1012b1f62a4
|
|
| MD5 |
42c028a9c9f37a3c1dcfb2a660931b6e
|
|
| BLAKE2b-256 |
fb217af0fa7a256f0939a5fdefa4b2b93d1e9c14fef8196fb885cea545bb6ca1
|
File details
Details for the file meadows_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: meadows_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9eb90d9ca09caf5925f4c87f2bf5f3c412978bbd32593ec75c7b75c9b75d794
|
|
| MD5 |
6e090a6d5edbf3d2fac42afe59562e7c
|
|
| BLAKE2b-256 |
2ed7563ca02d83feb5f69272d7120e7cf42b309299b5d751f957e0d35b7d49c9
|