Quickstart (Python)
Get a CodeSpar commerce agent running in Python — sync for scripts and Django, async for FastAPI and LangChain. Under 5 minutes.
Quickstart (Python)
codesparv0.1.1The codespar PyPI package exposes the same session model as the TypeScript SDK, in both sync and async flavours. Use CodeSpar from scripts, Jupyter notebooks, Flask, or Django views. Use AsyncCodeSpar from FastAPI, LangChain, or anything already on asyncio.
Prerequisites
- Python 3.10+
- A CodeSpar API key (codespar.dev/dashboard/settings)
- Optional: an LLM SDK (
anthropic,openai) if you want to build a full agent loop
Install
pip install codesparOr add to pyproject.toml:
[project]
dependencies = ["codespar>=0.1.1"]The package has a single runtime dependency (httpx). No async framework is pulled in — both flavours ship in the same wheel.
Set your API key
export CODESPAR_API_KEY="csk_live_your_key_here"Keys prefixed with csk_test_ route to sandbox servers that return mock data. Use csk_live_ for production.
Create a session + call a tool
from codespar import CodeSpar
cs = CodeSpar() # reads CODESPAR_API_KEY from env
with cs.create("user_123", preset="brazilian") as session:
result = session.execute(
"codespar_pay",
{"method": "pix", "amount": 15000, "currency": "BRL"},
)
print(result.data["pix_code"])
cs.close()Context-manager style closes the session automatically. Or call session.close() and cs.close() manually.
import asyncio
from codespar import AsyncCodeSpar
async def main():
async with AsyncCodeSpar() as cs:
async with await cs.create("user_123", preset="brazilian") as session:
result = await session.execute(
"codespar_pay",
{"method": "pix", "amount": 15000, "currency": "BRL"},
)
print(result.data["pix_code"])
asyncio.run(main())Natural-language agent loop
session.send(message) runs a Claude tool-use loop on the backend. No local agent framework needed.
from codespar import CodeSpar
cs = CodeSpar()
with cs.create("user_123", preset="brazilian") as session:
result = session.send(
"Charge R$150 via Pix for order #5678 and send a WhatsApp confirmation"
)
print(result.message)
for call in result.tool_calls:
print(f" → {call.tool_name}: {call.status} in {call.duration_ms}ms")
cs.close()import asyncio
from codespar import AsyncCodeSpar
async def main():
async with AsyncCodeSpar() as cs:
async with await cs.create("user_123", preset="brazilian") as session:
result = await session.send(
"Charge R$150 via Pix for order #5678 and send a WhatsApp confirmation"
)
print(result.message)
asyncio.run(main())Streaming
send_stream yields events as they happen — useful when you want to stream partial output to the user or to a log.
for event in session.send_stream("Charge R$150 via Pix"):
if event.type == "assistant_text":
print(event.content, end="", flush=True)
elif event.type == "tool_use":
print(f"\n→ calling {event.name}")
elif event.type == "done":
print(f"\nFinal: {event.result.message}")async for event in session.send_stream("Charge R$150 via Pix"):
if event.type == "assistant_text":
print(event.content, end="", flush=True)
elif event.type == "tool_use":
print(f"\n→ calling {event.name}")
elif event.type == "done":
print(f"\nFinal: {event.result.message}")Import surfaces
| Class | Use from |
|---|---|
CodeSpar | Sync scripts, Jupyter, Flask / Django views |
AsyncCodeSpar | FastAPI, async LangChain, anything on asyncio |
Session / AsyncSession | Returned by create() — same method names, sync vs async dispatch |
Both clients wrap the same REST API on api.codespar.dev. Start with sync, upgrade to async without changing the surrounding code — method names and return types match.
Common errors
| Error class | Cause | Fix |
|---|---|---|
ConfigError | Missing or malformed api_key | Set CODESPAR_API_KEY or pass CodeSpar(api_key="csk_...") |
NotConnectedError | Calling a tool before a server finishes connecting | Use manage_connections={"wait_for_connections": True} in create() |
ApiError | Backend returned non-2xx | Inspect error.code and error.message; retry or surface to user |
StreamError | SSE stream dropped mid-flight | Reconnect; partial results are in the final event if already emitted |
Next steps
Last updated on