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. For a published alpha version, install by its exact version in a virtual environment:
python -m pip install 'mango-sdk==0.1.0a1'
To install this checkout instead, 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:
environment = client.create_environment(body={"name": "python-example"})
agent = client.create_agent(body={
"name": "assistant",
"model": os.environ["MANGO_MODEL"],
"system": "Be concise and helpful.",
})
session = client.create_session(body={
"agent": {"type": "agent", "id": agent["id"]},
"environment_id": environment["id"],
})
client.send_session_events(session["id"], body={"events": [{
"type": "user.message",
"content": [{"type": "text", "text": "Hello!"}],
}]})
for event in client.iter_session_events(session["id"], order="asc"):
print(event)
All methods use the OpenAPI operationId in snake_case (createAgent becomes
create_agent), with positional path identifiers and keyword-only body and
query parameters. Bracketed query names become Python names: types[] becomes
types, and created_at[gte] becomes created_at_gte. The wire retains the
original spelling and repeats array parameters correctly. base_url can include
a reverse-proxy path prefix; do not append /v1 yourself.
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.get_session(session_id)
print(session["status"])
async with client.stream_session_events(
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.stream_session_events(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.upload_file(body={
"file": Upload("analysis.csv", source, "text/csv"),
})
skill = client.create_skill(body={"files": [
Upload("analysis/SKILL.md", b"---\nname: analysis\ndescription: Analyze data\n---\n"),
]})
# Only downloadable Session-scoped Files can be downloaded; client uploads cannot.
for output in client.iter_files(scope_id="sesn_..."):
with client.download_file(output["id"]) as stream:
for chunk in stream.iter_bytes():
consume(chunk) # Your application owns the destination.
try:
client.get_session("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 examples/conformance.py
targets Mango's own local HTTP-handler harness, not a live model or CMA service.
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 mango_sdk-0.1.0a1.tar.gz.
File metadata
- Download URL: mango_sdk-0.1.0a1.tar.gz
- Upload date:
- Size: 38.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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 |
d5b2bf2337484b6b46e8ab0b4806e39c7f1bf77f97739d96eebade58bd9b44ae
|
|
| MD5 |
d010902589099e06fc3b8337af8323ab
|
|
| BLAKE2b-256 |
b85eb03ec6cf23ab2ac7cb05a1256dd44ea63d99989b61c62e02b8e30aca2b1f
|
File details
Details for the file mango_sdk-0.1.0a1-py3-none-any.whl.
File metadata
- Download URL: mango_sdk-0.1.0a1-py3-none-any.whl
- Upload date:
- Size: 41.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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 |
9fdbc8f287b2561ab430d20e314b8b93b2fd22b406de57094da25f3192ddcff0
|
|
| MD5 |
12a2e58b5ecb12e4753fa5520128b413
|
|
| BLAKE2b-256 |
64feaff3be1b6dd034df7da1f845bd6197762f305a2261c738df453d60d9b22b
|