Python SDK for building Etches — Etch Labs agents that expose capabilities as named handlers, emit a standard event stream while they work, and can be invoked in streaming or non-streaming mode.
An Etch is a generator-based agent: you write handlers that yield progress events (reasoning, tool_call, tool_result) and a terminal result. The SDK handles event normalization, tool wiring, run draining, token metrics, and SSE adapters so you can focus on your domain logic.
pip install -e etch_sdk
# Optional: FastAPI SSE helpers
pip install -e "etch_sdk[server]"Requires Python 3.9+.
from etch_sdk import Etch, EtchContext, etch_tool, handler
class GreetingEtch(Etch):
name = "greeting_etch"
@etch_tool("lookup", reason=lambda ctx, user_id: f"Looking up {user_id}...")
def lookup(self, ctx: EtchContext, user_id: str) -> dict:
names = {"alice": "Alice", "bob": "Bob"}
if user_id not in names:
return {"ok": False, "error": "unknown user"}
return {"ok": True, "name": names[user_id]}
@handler("greet")
def greet(self, ctx: EtchContext, user_id: str):
yield from ctx.reason(f"Preparing a greeting for `{user_id}`.")
data = yield from self.use_tool(ctx, "lookup", user_id=user_id)
if not data.get("ok"):
yield ("greet_result", {"ok": False, "error": data["error"]})
return
yield ("greet_result", {"ok": True, "message": f"Hello, {data['name']}!"})
etch = GreetingEtch()
# Non-streaming
result = etch.run("greet", user_id="alice")
print(result.result)
# Streaming
for event in etch.stream("greet", user_id="bob"):
print(event.kind, event.payload)Runnable examples live in examples/.
| Guide | Description |
|---|---|
| Getting started | Install, core concepts, your first Etch |
| Handlers | @handler, subclassing, Etch.from_handlers() |
| Tools | @etch_tool, call_tool, caching, acknowledgments |
| Events | Event kinds, terminal results, trace format |
| Invocation | run(), stream(), __call__, EtchRunResult |
| Streaming & HTTP | SSE formatting, FastAPI integration |
| Metrics | Token counting and run statistics |
| Examples | Walkthrough of the included example Etches |
etch_sdk/
├── README.md
├── docs/ # Detailed guides
├── examples/ # Runnable sample Etches
├── pyproject.toml
└── src/etch_sdk/
├── etch.py # Etch base class
├── context.py # EtchContext (per-run state)
├── events.py # EtchEvent types
├── tools.py # @etch_tool decorator
├── run.py # collect_run, drain
├── result.py # EtchRunResult
├── streaming.py # SSE adapters
└── metrics.py # Token metrics
from etch_sdk import (
Etch,
EtchContext,
EtchEvent,
EtchRunResult,
etch_tool,
handler,
collect_run,
drain,
build_metrics,
count_tokens,
format_sse,
stream_sse,
)See the Invocation and Events guides for full API details.