Python SDK
The Python SDK is published on PyPI as chio-sdk and imported as chio. Pure Python, no native build steps: Ed25519 runs on pure25519, canonical JSON on the standard library, HTTP on httpx. Python 3.11 or newer.
Package name vs. import name
chio-sdk. The top-level import is chio. Framework and orchestrator integrations ship as separate packages (chio-fastapi, chio-temporal, and so on): see Companion packages.Installation
$ pip install chio-sdk
$ uv add chio-sdk
$ poetry add chio-sdkImport the top-level package as chio:
from chio import ChioClient, ChioSession, ReceiptQueryClient
from chio.invariants import verify_receipt, verify_capability
from chio.auth import discover_oauth_metadata, perform_authorization_code_flowThe chio package exposes the following submodules: auth, client, errors, invariants, models, nested, receipt_query, session, transport, and version.
ChioClient
ChioClient opens authenticated chio MCP HTTP sessions. The with_static_bearer classmethod is the shortest path for development; production deployments should construct the client with an OAuth token source.
from chio import ChioClient
client = ChioClient.with_static_bearer(
base_url="https://edge.example.com/mcp",
auth_token="dev-token",
)
session = client.initialize()ChioSession
ChioSession exposes the common MCP surface plus lower-level escape hatches for custom JSON-RPC work.
list_tools()call_tool(name, arguments=None)list_resources(),read_resource(uri)list_prompts(),get_prompt(name, arguments=None)list_tasks(),get_task(task_id),get_task_result(task_id),cancel_task(task_id)request(),request_result(),notification(),send_envelope()close()
tools = session.list_tools()
for t in tools:
print(t["name"], t.get("description"))
result = session.call_tool("read_file", {"path": "./README.md"})
print(result["content"])
session.close()Invariants
chio.invariants contains the pure verification primitives. Every function is synchronous, dependency-light, and safe to call from any thread or async context.
from chio.invariants import (
canonicalize_json_str,
sha256_hex_bytes,
sha256_hex_utf8,
sign_utf8_message_ed25519,
verify_utf8_message_ed25519,
sign_json_str_ed25519,
verify_json_str_signature_ed25519,
parse_receipt_json,
verify_receipt,
verify_receipt_json,
parse_capability_json,
verify_capability,
verify_capability_json,
parse_signed_manifest_json,
verify_signed_manifest,
)Canonical JSON
from chio.invariants import canonicalize_json_str
canonical = canonicalize_json_str('{"b":2,"a":1}')
assert canonical == '{"a":1,"b":2}'Hashing
from chio.invariants import sha256_hex_utf8, sha256_hex_bytes
sha256_hex_utf8("hello world")
sha256_hex_bytes(b"\x01\x02\x03")Receipts
from chio.invariants import parse_receipt_json, verify_receipt
receipt = parse_receipt_json(json_string)
result = verify_receipt(receipt)
assert result.signature_valid
assert result.parameter_hash_validCapabilities
from chio.invariants import parse_capability_json, verify_capability
cap = parse_capability_json(json_string)
status = verify_capability(cap)
assert status.signature_valid
assert status.time_status in ("valid", "not_yet_valid", "expired")Ed25519
Ed25519 signing and verification use pure25519, a pure-Python implementation chosen so the SDK installs cleanly on restricted runners (Lambda, App Engine, serverless containers) without a native toolchain. If you need native performance, swap in cryptography via the optional chio-sdk[fast] extra.
from chio.invariants import sign_json_str_ed25519, verify_json_str_signature_ed25519
sig = sign_json_str_ed25519('{"key":"value"}', private_key_hex=seed_hex)
ok = verify_json_str_signature_ed25519(
'{"key":"value"}',
signature=sig.signature,
public_key_hex=public_key_hex,
)
assert okReceiptQueryClient
ReceiptQueryClient wraps GET /v1/receipts/query, injects the bearer token, and exposes both a one-shot and an iterator API.
from chio import ReceiptQueryClient
client = ReceiptQueryClient(
base_url="https://receipts.example.com",
auth_token="service-token",
)
response = client.query({
"capabilityId": "cap_7f3a...e91d",
"toolServer": "srv-files",
"toolName": "read_file",
"outcome": "deny",
"since": 1744500000,
"until": 1744600000,
"minCost": 1,
"maxCost": 1000,
"limit": 50,
})
print(response["totalCount"], response.get("nextCursor"))Use paginate() to drive the cursor automatically:
for page in client.paginate({"toolServer": "srv-files"}):
for receipt in page:
print(receipt["id"], receipt["decision"]["verdict"])OAuth and PKCE
chio.auth ships the helpers needed to discover a chio edge's OAuth configuration, drive an authorization-code flow with PKCE, and exchange a code for an access token.
from chio.auth import (
discover_oauth_metadata,
perform_authorization_code_flow,
exchange_access_token,
)
metadata = discover_oauth_metadata("https://edge.example.com")
tokens = perform_authorization_code_flow(
metadata=metadata,
client_id="chio-cli",
redirect_uri="http://127.0.0.1:53682/callback",
scope="chio.read chio.invoke",
)
fresh = exchange_access_token(
metadata=metadata,
refresh_token=tokens.refresh_token,
client_id="chio-cli",
)Companion Packages
Framework adapters, orchestrator operators, and agent-framework bindings ship as separate PyPI packages so your base install stays lean. Each one depends on chio-sdk and uses a distinct top-level import (for example import chio_fastapi, not chio.fastapi).
| Area | Install | Import |
|---|---|---|
| FastAPI | pip install chio-fastapi | import chio_fastapi |
| Django | pip install chio-django | import chio_django |
| ASGI (raw) | pip install chio-asgi | import chio_asgi |
| Airflow | pip install chio-airflow | import chio_airflow |
| Temporal | pip install chio-temporal | import chio_temporal |
| Prefect | pip install chio-prefect | import chio_prefect |
| Dagster | pip install chio-dagster | import chio_dagster |
| Ray | pip install chio-ray | import chio_ray |
| LangChain | pip install chio-langchain | import chio_langchain |
| LangGraph | pip install chio-langgraph | import chio_langgraph |
| LlamaIndex | pip install chio-llamaindex | import chio_llamaindex |
| CrewAI | pip install chio-crewai | import chio_crewai |
| AutoGen | pip install chio-autogen | import chio_autogen |
| Observability | pip install chio-observability | import chio_observability |
| Streaming | pip install chio-streaming | import chio_streaming |
Each companion package wraps a sidecar policy decision, attaches the resulting receipt IDs to the response, and raises a typed deny error on policy violation. A FastAPI example:
from fastapi import FastAPI
from chio_fastapi import ChioMiddleware
app = FastAPI()
app.add_middleware(
ChioMiddleware,
sidecar_url="http://localhost:7391",
bearer_token="dev-token",
)
@app.post("/tools/read_file")
def read_file(path: str, request):
# request.state.chio_receipt_id is set on allow.
return {"ok": True}Error Types
ChioError: base SDK exception.ChioTransportError: network or transport-level failure.ChioQueryError: non-2xx response from the receipt query endpoint.ChioRpcError: JSON-RPC error returned by the hosted MCP edge.ChioInvariantError: parsing or verification failure in the invariants layer.
from chio import ChioError, ChioQueryError, ChioTransportError
try:
response = client.query({"capabilityId": "cap_abc"})
except ChioQueryError as err:
print("query failed", err.status, err)
except ChioTransportError as err:
print("network failed", err)
except ChioError as err:
print("chio error", err)Conformance
The Python SDK passes the cross-language conformance suite through green wave 5: canonical JSON output, SHA-256 digests, Ed25519 signatures, receipt verification, capability verification, and manifest verification all produce byte-identical results against the Rust reference kernel.
$ cd packages/sdk/chio-py && pytest
$ pytest tests/conformance -vExample project
packages/sdk/chio-py/examples/governed_hello.py: it initializes a session, lists tools, calls a tool with a DPoP proof, verifies the receipt offline, and queries the receipt store for history.