Official Python SDK for Platos — agents, threads, realtime streaming.
Project description
platos-client (Python)
Official Python SDK for Platos — the open-source agent runtime.
Agents · threads · realtime streaming · approvals · budgets · background operations · monitoring.
Install
pip install platos-client
# or
uv add platos-client
Requires Python >=3.10.
Quick start
import asyncio
from platos_client import PlatosClient
async def main():
async with PlatosClient(
base_url="https://platos.your-domain.com",
session_token="<minted by your backend — see Auth below>",
) as client:
agents = await client.agents.list()
print(f"agents in scope: {[a['name'] for a in agents]}")
thread = await client.threads.create(agent_id=agents[0]["id"])
async for event in client.threads.send(thread["id"], "Summarise today's inbox."):
if event["type"] == "token":
print(event["text"], end="", flush=True)
elif event["type"] == "done":
print()
break
asyncio.run(main())
Auth — session tokens (recommended)
Platos is multi-tenant. Browsers and untrusted callers must never hold a raw serviceSecret. The pattern:
- Backend mints a session token signed with your entity's
serviceSecret(use@platosdev/token-mintfrom npm or any JWT library — the wire format is plain HS256). - Client calls
PlatosClient(session_token=...). The token is a short-lived JWT carrying your scope tuple(organizationId, projectId, environmentId). - Refresh by re-minting on the server; pass
on_token_refresh=...so the client retries automatically on401.
async def refresh():
async with httpx.AsyncClient() as http:
r = await http.post("/api/platos-session")
return r.json()["token"]
client = PlatosClient(
base_url="https://platos.example.com",
session_token=current_token,
on_token_refresh=refresh,
)
User identity passthrough (userMeta)
If your agent needs to know which of your users is speaking, sign a userMeta: { name, email } claim into the session token on your backend. ScopeGuard surfaces it as {{user.name}} / {{user.email}} in prompts and dynamic blocks, and the trace's identity columns get populated. See Auth modes docs.
Direct-header mode (server-to-server)
For trusted server-to-server use only — never the browser:
client = PlatosClient(
base_url="http://platos:3100",
api_key=os.environ["PLATOS_INTERNAL_TOKEN"],
scope={
"organizationId": "org_...",
"projectId": "prj_...",
"environmentId": "env_...",
},
)
Streaming events
client.threads.send(...) returns an async iterator of dict events. Common types:
event["type"] |
When it fires |
|---|---|
connected / disconnected / reconnecting |
WebSocket lifecycle |
token |
Streaming text chunk (event["text"]) |
thinking |
Reasoning / extended-thinking chunk |
tool_call |
Agent invoked a tool (name, params, callId) |
tool_result |
Tool returned (name, result, optional display hint) |
approval_needed |
HITL gate — call client.approvals.resolve(...) to continue |
artifact_start / artifact_delta / artifact_committed |
Streaming artifact build |
safety_flags |
PII / safety filter hits |
done |
Turn finished (carries usage cost summary) |
error |
Server-side error (carries message + extras) |
Error handling
from platos_client import (
PlatosError,
PlatosAuthError,
PlatosRateLimitError,
PlatosValidationError,
PlatosServerError,
PlatosNetworkError,
)
try:
async for evt in client.threads.send(thread_id, "..."):
...
except PlatosAuthError:
# 401 / 403 — refresh token
...
except PlatosRateLimitError as e:
# 429 — wait e.retry_after_ms then retry
...
except PlatosValidationError:
# 400 — fix payload
...
except PlatosServerError:
# 5xx — likely transient
...
API surface
| Namespace | Methods |
|---|---|
client.agents |
list, get, list_versions |
client.threads |
create, list, get, messages, artifacts, send (streaming) |
client.approvals |
list, resolve (human-in-the-loop) |
client.budgets |
list, status (read-only — caps managed in the dashboard) |
client.monitoring |
runs, traces, cost_by_agent, cost_by_scope |
client.bgo |
tasks, runs, schedules, batches (background-operation engine; client.trigger is the deprecated alias) |
Cross-language parity
A TypeScript / JavaScript equivalent ships as @platosdev/client on npm. The wire shape is identical; switching between them in your stack is a port, not a rewrite.
Licence
Apache 2.0 — see LICENSE. Same as Platos itself.
Source + issues
- Repo: https://github.com/winsenlabs/platos
- Package directory:
packages/platos-client-py - Issues: https://github.com/winsenlabs/platos/issues
- Docs: https://platos.dev/docs/sdks
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 platos_client-0.1.0.tar.gz.
File metadata
- Download URL: platos_client-0.1.0.tar.gz
- Upload date:
- Size: 15.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"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 |
3a8edc1f3515b41193183bbc9cf5ac48951c654e59eff72ec1effe4fa8d23a94
|
|
| MD5 |
f38c8b103dcbfb591f0c06d9c776c255
|
|
| BLAKE2b-256 |
489b082f0ff817d4f35d238f43974aea3149f2a0bcca006010190dd379cc44a7
|
File details
Details for the file platos_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: platos_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"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 |
eb84a0acc2d91c67ba32ea7b11fe5b2fef9ac4b8ef5ebe34956912e66793fd28
|
|
| MD5 |
31aca935ca977a031f3e7b74ad521201
|
|
| BLAKE2b-256 |
6bdaf4b568865f33cc856befe7812390a29428d59889a8be27403b5212c77e6b
|