Python SDK
ML training loops, Rake-style scripts, AI agents.
The Python SDK is the primary integration path for long-running Python work - model training loops, scraping pipelines, batch jobs, AI agents. The `@track` decorator is one line above any function and gives you an @agent Live Activity that starts when the function is entered, then ends green or red depending on whether the function returned or threw.
Two flavors are exported. `@track` is the simple decorator; `ChirpAgent` is a context manager for finer control - manual lifecycle, multiple status updates, custom dismissal policy. Both rely on the same lightweight HTTP client (stdlib `urllib`, no third-party deps).
Prerequisites
- Python ≥ 3.9.
- Chirp installed on your phone, signed in.
Setup
- 1
Install + authenticate
chirp loginis a one-time pairing - opens a browser, drops a token at~/.chirprc. The SDK auto-discovers it. CI environments useCHIRP_API_KEYinstead.shellpip install chirp-sdk chirp login - 2
Wrap a function with `@track`
The simplest pattern. Decorate any function and Chirp owns its lifecycle: starts the activity on call, ends green on return or red on exception. Works for sync and async functions.
train.pyfrom chirp import track @track("model training", theme="#818cf8") def train(): for epoch in range(10): train_one_epoch() train() # phone shows the Live Activity for the entire call - 3
Use `ChirpAgent` for fine-grained control
When the function shape doesn't fit a decorator (e.g. you want to keep an activity alive across multiple top-level entry points, or branch the lifecycle yourself), open a context manager.
pythonfrom chirp import ChirpAgent with ChirpAgent(name="data backfill", theme="#818cf8") as a: a.update("reading source") rows = read_source() a.update(f"{len(rows)} rows fetched") write_destination(rows) a.done("done") # Auto-ends green on context exit, red if an exception escaped. - 4
Use the low-level client for other schemas
The high-level decorator and context manager use the built-in
@agentcard. For schema-specific layouts such as@deploy, callChirpClient.activity_start,activity_update, andactivity_enddirectly.pythonfrom chirp import ChirpClient client = ChirpClient() client.activity_start("@deploy", {"repo": "my-app", "stage": "build", "progress": 0.1}) client.activity_update("@deploy", {"stage": "deploy", "progress": 0.7}) client.activity_end("@deploy", {"stage": "done"}, dismissal_policy={"afterSeconds": 120})
Async / asyncio
from chirp import track
@track("scrape")
async def crawl(start_url):
async for page in crawler(start_url):
await archive(page)
import asyncio
asyncio.run(crawl("https://docs.example.com"))What you’ll see
When `train()` is called, an @agent activity starts on your phone with the label "model training". `ChirpAgent.update()` refreshes the status line while work runs. When the function returns, the activity ends green; if it raises, the activity ends red with the exception summary. Multiple concurrent decorated functions get their own activities.
Troubleshooting
- I get `chirp.errors.NoCredentialsError: ~/.chirprc not found`.
- Run
chirp loginonce on the machine. In CI environments where you can't run that, setCHIRP_API_KEYinstead - the SDK reads it as a fallback. - My activity ends red even though the function completed successfully.
- Check the function isn't catching an exception silently. The decorator inspects what the wrapped function actually returned vs. threw - if you
try/exceptinside, the SDK sees a clean return. - I need a progress bar or another template-specific layout.
- Use
ChirpClientwith a built-in schema such as@deploy,@training, or@monitor. The high-leveltrackandChirpAgenthelpers intentionally target the generic@agentcard.