Skip to main content

Quickstart (Python)

Get a CodeSpar commerce agent running in Python — sync for scripts and Django, async for FastAPI and LangChain. Under 5 minutes.

1 min read · updated

Quickstart (Python)

codesparv0.1.1

The 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

Install

pip install codespar

Or 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

charge.py
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.

charge.py
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.

agent.py
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()
agent.py
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

ClassUse from
CodeSparSync scripts, Jupyter, Flask / Django views
AsyncCodeSparFastAPI, async LangChain, anything on asyncio
Session / AsyncSessionReturned 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 classCauseFix
ConfigErrorMissing or malformed api_keySet CODESPAR_API_KEY or pass CodeSpar(api_key="csk_...")
NotConnectedErrorCalling a tool before a server finishes connectingUse manage_connections={"wait_for_connections": True} in create()
ApiErrorBackend returned non-2xxInspect error.code and error.message; retry or surface to user
StreamErrorSSE stream dropped mid-flightReconnect; partial results are in the final event if already emitted

Next steps

Last updated on