The Python mirror of sdk/typescript/example (the
Next.js demo). It runs the codegraff agent in-process and exposes it as a
fast HTTP API on turboAPI's Zig HTTP
core. Request bodies are validated by dhi —
turboAPI's Pydantic-compatible model layer — before Python runs the handler.
| Endpoint | Shows |
|---|---|
GET / |
SDK version + server info |
POST /chat |
one agent turn, collapsed to a single markdown answer + tools_used |
POST /chat/stream |
streaming the agent's events to the client as SSE (StreamingResponse) |
GET /conversations?limit=20 |
conversation management via the SDK |
This example sits at the meeting point of two native runtimes, and that's worth being honest about up front:
- turboAPI requires Python 3.14t (free-threaded) and a Zig toolchain to build. See turboAPI's own README for its install specifics.
- codegraff currently ships
cp313wheels. The PyO3 crate (sdk/python/Cargo.toml) usespyo3 0.24withextension-moduleonly — noabi3, and it does not yet opt into free-threading (gil_used(false)). Two consequences:- There is no prebuilt wheel for a 3.14t interpreter, so for this example you
build codegraff from source against your 3.14t venv:
pip install maturin cd ../ # sdk/python (where pyproject.toml lives) maturin develop --release cd example
- Because the module doesn't declare free-thread support, importing it makes
CPython re-enable the GIL (you'll see a warning). The agent still works
— and
chat()already releases the GIL while it waits on the agent (py.allow_threadsinChatStreamHandle.next_event), so agent calls aren't GIL-bound regardless — you just don't get process-wide free-threading until codegraff declares it. Tracked as a follow-up.
- There is no prebuilt wheel for a 3.14t interpreter, so for this example you
build codegraff from source against your 3.14t venv:
Written against the verified turboAPI / dhi / codegraff APIs but not yet run in a 3.14t environment (none available here). If you have one set up, I can wire up an end-to-end smoke test.
pip install -r requirements.txt # turboapi + dhi
# build codegraff from source for your 3.14t interpreter (see above)
export CODEGRAFF_API_KEY="cg_sk_..." # your codegraff gateway key
# optional: export CODEGRAFF_MODEL="deepseek-v4-pro"
# optional: export HOST=0.0.0.0 PORT=8080
python3.14t app.py # http://127.0.0.1:8000Then hit it:
curl -s localhost:8000/chat \
-H 'content-type: application/json' \
-d '{"prompt":"Summarize what codegraff is in two sentences."}' | jq
# => { "conversation_id": "...", "text": "...", "tools_used": [] }
curl -N localhost:8000/chat/stream \
-H 'content-type: application/json' \
-d '{"prompt":"List three things you can do."}'
# => data: {"type": "ConversationStarted", "data": {"conversationId": "..."}}
# data: {"type": "TaskMessage", "data": {"content": {"kind": "Markdown", "text": "..."}}}
# ...
# data: [DONE]turboAPI validates request bodies with dhi.BaseModel, so this example already
runs on dhi in Python. dhi also ships a TypeScript/JS binding (Zig → WASM,
npm i dhi) with a Zod-4-compatible API (import { z } from 'dhi/schema').
The TS SDK (sdk/typescript) currently does no request validation at all — its
example routes just cast await req.json() — so dhi is a natural fit there too,
which would give both SDKs one validation story. See the dhi repo for the
cross-language/"works with anything" tracking issue.