Python SDK
vagary-voice is the pip-installable Python developer SDK (ADR-122 — vagary-core-sdks is retired as a public identity; "core" is internal platform architecture, not a customer's product). A product pip installs it and
imports a typed client instead of hand-rolling HTTP against a capability's contract.
It ships two things:
clients/— typed OpenAPI clients generated from each capability'scontracts/*/v1/openapi.yaml. Import the client for a capability instead of writing HTTP by hand.apimw/— reusable FastAPI / Starlette API-management middleware:IdempotencyMiddleware(Stripe-style per-(org, key)response replay), opaque base64url keyset cursor pagination, and anAPIVersionMiddleware+negotiate_versionhelper. A capability opts in by importing it — nothing in the SDK edits a capability's runtime.
These implement the platform's API conventions.
vagary-voice is not on PyPI yet (ADR-122; status + operator steps).
The name below is the canonical identity the release pipeline will publish — until then, call
capabilities directly with requests (see the
getting-started walkthrough for a runnable example) instead of treating the
pip install below as something that will succeed today.
Install
pip install vagary-voice
Import a typed client + the middleware:
import apimw
from clients.eval_harness_client.api.default import eval_candidate
Using the middleware in your own capability
from fastapi import FastAPI
from apimw import IdempotencyMiddleware
app = FastAPI()
app.add_middleware(IdempotencyMiddleware) # in-memory store, 24h TTL, org from X-Org-Id
For cross-instance replay, pass a store= implementing the IdempotencyStore protocol
(e.g. a Redis-backed store). The tenant scope is mandatory — one org's idempotency key never
collides with another's.
Client generation
Clients are generated, never hand-edited, from the OpenAPI contracts. Only the
eval_harness_client reference is committed; a consumer generates the client(s) it needs:
# one-time: the pinned generator in a repo-local venv
python3 -m venv shared-sdks/.sdkgen-venv
shared-sdks/.sdkgen-venv/bin/pip install "openapi-python-client==0.29.0"
# regenerate every client from contracts/
SDKGEN_PY=1 bash shared-sdks/generate.sh
Publishing
Publishing a package version is operator-gated (it is irreversible). The build always runs; the upload only happens on an explicit confirmation with a configured registry token:
bash shared-sdks/publish-py.sh # build (sdist + wheel) + local-install smoke; NO upload
PUBLISH_CONFIRM=1 bash shared-sdks/publish-py.sh # build + upload (operator only)