Python SDK
The official Jettson SDK for Python. httpx-backed, sync today, async in the next release.
Three lines, one agent. The Python SDK is the fastest path from pip install to a running agent.
Install
pip install jettsonRequires Python 3.9 or later. One runtime dep (httpx).
Quickstart
import os
from jettson import Jettson
client = Jettson(api_key=os.environ["JETTSON_API_KEY"])
agent = client.agents.spawn(
task="Browse https://news.ycombinator.com and return the top story title."
)
result = client.agents.wait(agent.agent_id)
print(result.final_result)Get an API key at /console/api-keys.
Constructor
Jettson(
api_key: str, # required
base_url: str = "https://jettson.dev/api/v1",
max_retries: int = 3,
timeout_seconds: float = 60.0,
)Use as a context manager to release the HTTP connection pool on exit:
with Jettson(api_key=os.environ["JETTSON_API_KEY"]) as client:
agent = client.agents.spawn(task="…")
final = client.agents.wait(agent.agent_id)Agents
agents.spawn(task, ...)
agent = client.agents.spawn(
task="Research linear.app",
name="research-run-001",
region="lhr", # "iad" | "lhr" | "syd"
idempotency_key="spawn:abc:1", # dedupe accidental retries
)Returns immediately with status="spawning".
agents.wait(agent_id, ...)
result = client.agents.wait(
agent.agent_id,
timeout_seconds=300,
poll_interval_seconds=1.0,
max_poll_interval_seconds=5.0,
)Polls until status is completed / error / stopped. Raises AgentTimeoutError if the deadline lapses.
agents.get(agent_id) / agents.list(...) / agents.cancel(agent_id)
agent = client.agents.get("ag_…")
cursor = None
while True:
page = client.agents.list(limit=50, cursor=cursor)
for a in page.data:
print(a.agent_id, a.status)
cursor = page.next_cursor
if not cursor:
break
client.agents.cancel("ag_…")Memory
memory.put(...)
client.memory.put(
key="brand_color",
value="Brand primary color is #FF5733",
namespace="user_profile",
tags=["brand"],
importance=8,
expires_in_days=90,
)memory.get(key, namespace=)
m = client.memory.get("brand_color", namespace="user_profile")
if m:
print(m.value)Returns None (not an exception) if no memory matches.
memory.search(...)
results = client.memory.search(
query="what color is the brand?",
namespace="user_profile",
mode="hybrid", # "hybrid" | "semantic" | "keyword"
limit=10,
min_score=0.4,
)
for r in results:
print(f"{r.key}: {r.value} (score={r.score:.2f})")memory.list / delete / dedupe / consolidate / namespaces / export / import_
All ten public-API memory endpoints are covered. Signatures mirror the Memory API reference.
# Note the trailing underscore — `import` is a Python keyword.
result = client.memory.import_([
{"key": "brand_color", "value": "#FF5733", "namespace": "user_profile"},
])
print(result.imported, result.failed)Error handling
Every HTTP failure raises a typed exception. Catch the base class for any Jettson-side failure, or narrow:
from jettson import (
JettsonAuthError,
JettsonRateLimitError,
JettsonQuotaExceededError,
JettsonValidationError,
JettsonNotFoundError,
JettsonServerError,
JettsonNetworkError,
AgentTimeoutError,
)
try:
client.agents.spawn(task="…")
except JettsonRateLimitError as err:
print(f"Backing off {err.retry_after_seconds}s")
except JettsonQuotaExceededError as err:
print(f"Hit quota: {err.used}/{err.limit} on {err.plan}")Idempotent spawns
client.agents.spawn(
task="…",
idempotency_key=f"spawn:{user_id}:{request_id}",
)The server returns the same agent for repeat calls inside a short window.
Regions
Multi-region warm pool is live in iad / lhr / syd. Pin a region per spawn:
client.agents.spawn(task="…", region="lhr")If you don't specify one, the server tries iad first then falls back to other regions before cold-spawning.
Retries
Automatic retries on:
- 429 — honors
Retry-Afterheader (3 attempts) - 5xx — exponential backoff 1s → 2s → 4s (3 attempts)
- Network failure — one retry after the initial backoff
# Disable retries
Jettson(api_key=..., max_retries=0)Type hints
The SDK is fully typed. All dataclasses are frozen + hashable:
from jettson import Agent, Memory, MemorySearchResult, AgentStatus, Region
def is_completed(agent: Agent) -> bool:
return agent.status == "completed"Async (coming soon)
AsyncJettson ships in the next release with the same surface area. Until then, the sync client integrates cleanly with asyncio.to_thread:
import asyncio
async def spawn_async(task: str) -> str:
agent = await asyncio.to_thread(client.agents.spawn, task=task)
final = await asyncio.to_thread(client.agents.wait, agent.agent_id)
return final.final_result or ""Source
github.com/jettsondev/jettson-sdk-python — MIT, ~1k LOC + tests.
Related
- Node SDK
- API reference — the surface the SDK wraps
- Memory concepts — what
memory.*is doing under the hood