This release is a pre-release and may not be stable for production use.
Mango Python SDK
Typed synchronous and asynchronous clients for every operation in Mango's
current OpenAPI: Agents, Environments and Work, Sessions and Threads, Events,
Resources, Files, Skills, Memory, Vaults, Webhooks, Deployments, and probes.
The distribution name is mango-sdk; Python imports use mango_sdk. This is an
alpha SDK, not a stable release. Mango's development API can change in place;
use an SDK version built for the server revision you deploy.
Install
Python 3.11 or newer is required. This checkout prepares 0.1.0a3.
Select a matching version or inspected wheel/source package from the
release record, which confirms
registry availability. The previously published alpha 1 has an earlier interface.
To use this checkout before publication or during development, from the repository root:
python3 -m venv .venv
.venv/bin/python -m pip install ./sdk/python
For SDK development, use cd sdk/python && uv sync --frozen. This creates an
isolated .venv, installs the editable package, and uses the checked-in lockfile.
No hosted-agent account or credential is required.
Start a Session
import os
from mango_sdk import Mango
with Mango(
base_url=os.environ.get("MANGO_URL", "http://localhost:8080"),
api_key=os.environ["MANGO_API_KEY"],
) as client:
# Omitted config defaults to self-hosted execution.
environment = client.environments.create(name="python-example")
agent = client.agents.create(name="assistant", model=os.environ["MANGO_MODEL"], system="Be concise and helpful.")
session = client.sessions.create(agent={"type": "agent", "id": agent["id"]}, environment_id=environment["id"])
client.sessions.events.send(session["id"], events=[{
"type": "user.message",
"content": [{"type": "text", "text": "Hello!"}],
}])
for event in client.sessions.events.iter(session["id"], order="asc"):
print(event)
Methods are grouped by resource: client.agents.create,
client.sessions.threads.list, and client.sessions.threads.events.stream.
Path IDs are positional in HTTP hierarchy order. Request fields and query filters
are keyword arguments; a prebuilt typed request can be expanded with **request.
Bracketed query names use types and created_at_gte; the transport preserves
the wire spelling and repeated values. base_url may include a reverse-proxy
prefix; do not append /v1. Public probes are under client.system.
Request and response dictionaries have static types in mango_sdk.models.
Tagged unions preserve literal discriminators; all component schemas are emitted.
Closed objects are TypedDicts, not runtime validation models. Open JSON objects,
including custom-tool input_schema, use dictionaries so JSON Schema keywords
such as properties, required, and $defs remain expressible. The server
validates their constraints. Omit a dictionary key to
leave a field unchanged; pass None only to send explicit JSON null on a nullable
field. False, 0, "", and [] are not silently dropped.
list_* returns one typed page. iter_* fetches all pages lazily, preserving
query filters. Files use after_id/before_id; other resources use next_page.
Do not use an unbounded iterator if you only need one page.
Async client and streaming
import asyncio
import os
from mango_sdk import AsyncMango
async def watch(session_id: str) -> None:
async with AsyncMango(api_key=os.environ["MANGO_API_KEY"]) as client:
session = await client.sessions.retrieve(session_id)
print(session["status"])
async with client.sessions.events.stream(
session_id, event_deltas=["agent.message"],
) as stream:
async for envelope in stream:
print(envelope.event, envelope.data)
if envelope.event in ("session.status_idle", "session.deleted"):
break
# asyncio.run(watch("sesn_..."))
Synchronous streaming uses with client.sessions.events.stream(id) as stream
and for envelope in stream. Always use the context manager, especially when
breaking early. Downloads use the same lifecycle and iter_bytes() (an async
iterator on the async client); read() explicitly buffers the complete payload.
The async streaming factory is deliberately not awaited; the context opens it.
Streams default to no read timeout and have no finite overall deadline. HTTP
connection/write/pool timeouts still apply. A custom httpx.Timeout can override
these through stream_timeout. Closing the stream or cancelling its consuming
async task releases the connection. Streams parse split UTF-8, comments,
multiline data, and CR/LF delimiters incrementally.
Unterminated SSE lines and complete SSE frame data are each limited to 64 MiB;
oversized input raises ResponseDecodeError and closes the stream. HTTP error
bodies are read only up to 64 KiB (APIError.body_truncated indicates truncation).
Streams are live-only. They do not replay prior events, do not support Last-Event-ID, and the SDK does not silently reconnect. For gap-free application recovery, open a stream first, list history while it remains open, then merge and deduplicate persisted events by ID. Preview frames are ephemeral and must not be treated as authoritative history. This SDK exposes those primitives but does not yet supply an automatic history-and-live merger.
Uploads, downloads, and errors
from mango_sdk import APIError, Mango, Upload
with Mango(api_key="workspace-key") as client:
with open("analysis.csv", "rb") as source:
uploaded = client.files.upload(file=Upload("analysis.csv", source, "text/csv"))
skill = client.skills.create(files=[
Upload("analysis/SKILL.md", b"---\nname: analysis\ndescription: Analyze data\n---\n"),
])
# Download the immutable upload using the same Workspace credential.
with client.files.download(uploaded["id"]) as stream:
for chunk in stream.iter_bytes():
consume(chunk) # Your application owns the destination.
try:
client.sessions.retrieve("sesn_missing")
except APIError as error:
print(error.status_code, error.type, error.request_id)
The caller owns file handles. Multipart uploads stream file contents through HTTPX; async multipart file reads use ordinary blocking file handles. For unusually slow sources, prepare local files outside the event loop first.
No HTTP request is automatically retried. An interrupted mutation may already
have committed. For example, correlate a tool-result action against persisted
events before resubmitting. Redirects are never followed, protecting bearer
credentials and avoiding mutation replay. Network failures remain normal HTTPX
exceptions; HTTP failures use APIError, while invalid JSON/SSE and broken cursor
progression use ResponseDecodeError and PaginationError respectively.
Development checks
uv sync --frozen
uv run python generate.py --check
uv run pytest
uv run mypy
uv run ruff check src tests generate.py examples
generate.py consumes ../openapi.json and ../operations.json. Regenerate the
shared snapshot first with go run ./scripts/sdk-contract from the repository
root, then run uv run python generate.py. Generated bindings are reproducible;
the handwritten HTTP transport is not generated from any vendor implementation.
Tests are offline and deterministic. The optional tests/conformance.py
targets Mango's own local HTTP-handler harness, not a live model or CMA service.
Metadata
Release files for mango-sdk 0.1.0a3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mango_sdk-0.1.0a3.tar.gz | 36.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mango_sdk-0.1.0a3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.0 kB
Release files / mango_sdk-0.1.0a3.tar.gz
| Download URL | mango_sdk-0.1.0a3.tar.gz |
|---|---|
| Size | 36.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
181313bdabb8defce25e7dbd1fd6fc9fda97496f0d9ea5564bfba256e3cd0718
|
|
BLAKE2b-256 checksum How to use checksums |
89caa428507b1aa2c11e0c1af6959babc4fbc1c7e62a1b5ffc4a167ff87dc485
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logRelease files / mango_sdk-0.1.0a3-py3-none-any.whl
| Download URL | mango_sdk-0.1.0a3-py3-none-any.whl |
|---|---|
| Size | 39.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e32e424015497c65bf88061be417a0cdd748bca4b3ee562c7bc9ce313924267a
|
|
BLAKE2b-256 checksum How to use checksums |
8ed5504399fa8b7df746c5c68ca713ad17a7f5b1266b474bd2b59b0a15e44582
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency log