Skip to main content

Runtime requirements

  • Python 3.9+ — the package declares requires-python = ">=3.9" and is classified for 3.9 through 3.13. It uses standard-library typing (no pydantic) so 3.9 compatibility is structural, not incidental.
  • One runtime dependency: httpx>=0.27 — installed automatically. No requests, no aiohttp, no separate AG-UI protocol package.
  • Server-side only. The credential the SDK sends is a server-side secret. The SDK is not designed for, and must not be used from, browser/JS runtimes or any client an untrusted party can read. If you need browser-side code, that’s a separate (Clerk-session) integration path — see the Integration Guide.

Sync vs async

Both are first-class and maintained in lockstep — the async client is the await-ed mirror of the sync one, with the same constructor arguments, resource surface, and error classes. The one structural difference is streaming: ChatClient.stream() is a regular generator, AsyncChatClient.stream() is an async generator.

Type checking

  • All types are TypedDicts / Literals — no pydantic, no runtime validation. They exist purely for mypy/pyright/your editor.
  • The package is developed against mypy --strict (target python_version = "3.10" — a mypy capability limit, not a runtime gap: the package itself still supports 3.9).
  • Request/response bodies keep the API’s camelCase field names (providerId, systemPrompt, …) while methods and parameters use snake_case (external_user_id, idempotency_key, top_k, test_connection). Your code follows the Python names; the wire follows camelCase.

Framework compatibility

No framework-specific code exists in the SDK — it’s a plain httpx-based client, so it works anywhere Python does. The documented recipes are conventions, not requirements:
  • Flask / Django — use the sync PersonaClient, typically one control-plane instance at module scope plus per-request runtime-plane instances.
  • FastAPI / starlette / async apps — use AsyncPersonaClient in async def handlers.
  • Scripts, notebooks, cron jobs — either client; context managers (with/async with) handle cleanup for short-lived scripts.
  • Thread-safety: a PersonaClient keeps no per-call mutable state beyond the transport; when sharing across threads/event loops, prefer the connection-pool pattern (one shared httpx client, per-request PersonaClient instances) documented in Workflows.

Version compatibility

  • SDK version: 0.3.x (currently 0.3.0). The docs in this section track that release.
  • API version: the SDK calls the /api/v1/ Developer Platform API. The API is versioned by URL prefix and does not add custom versioning — the SDK follows the platform’s compatibility rules (no breaking changes to existing endpoints without approval).
  • Parity with the Node SDK: personaai mirrors @personaai/sdk’s resource surface — including Memory, Stores, and the Architect chat client (added in 0.3.0). Known differences as of this release:
    • Agent/CreateAgentInput/UpdateAgentInput lack storeMounts and interruptOn (the Node SDK’s Agent types have these; the Python SDK doesn’t yet).
    • No contextOverride or cancellation parameter on chat calls — wrap in asyncio.wait_for(...) for timeouts.
    • ChatResult has no error field — a failed run raises PersonaApiError rather than returning a structured error event.
    • No public HTTP escape hatch — the transport is internal; use httpx directly for unwrapped endpoints.

Platform limitations

  • Out of scope: Project/Members/Credentials management (creating Projects, inviting Members, minting/revoking credentials) — those routes are Clerk-session (human-admin) authenticated, a structurally different auth model the SDK deliberately doesn’t implement. Use Developer Studio.
  • Batch limits: bulk_delete(ids) accepts up to 100 ids per call (a larger request is rejected with a 400 before anything is deleted). Knowledge uploads: up to 10 files × 20MB per call, PDF/TXT/MD/JSON/CSV only.
  • Rate limits: the platform rate-limits API traffic; the SDK retries 429s up to max_retries honoring Retry-After. See Behavior & edge cases.
  • PersonaFile/Provider use id; everything else uses _id — see _id vs id.