Skip to main content

zespan

LLM observability for Python. Trace every AI call — latency, tokens, cost, errors — with one init().

Install

pip install zespan

Optional extras:

pip install "zespan[otel]"             # OpenTelemetry export
pip install "zespan[llamaindex]"       # LlamaIndex integration
pip install "zespan[haystack]"         # Haystack integration
pip install "zespan[semantic-kernel]"  # Semantic Kernel integration

Quick start

import zespan

zespan.init(
    api_key="zsp_your_key_here",
    project_id="your_project_id",
)
zespan.autopatch()

Get your API key and project ID from app.zespan.com → Project Settings → API Keys.

After init() + autopatch(), all calls to OpenAI, Anthropic, Google GenAI, and other installed providers are automatically traced.

Auto-instrumentation

autopatch() detects and patches every AI provider that is installed:

import zespan
import openai

zespan.init(api_key="zsp_...", project_id="proj_...")
zespan.autopatch()

client = openai.OpenAI()
# This call is automatically traced
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)

Supported providers:

Function Provider
patch_openai() OpenAI
patch_anthropic() Anthropic
patch_google() Google Generative AI
patch_openrouter() OpenRouter
patch_bedrock() AWS Bedrock
patch_mistral() Mistral
patch_groq() Groq
patch_litellm() LiteLLM

Patch individual providers manually:

from zespan import patch_openai, patch_anthropic

patch_openai()
patch_anthropic()

Configuration

zespan.init(
    api_key="zsp_...",           # required
    project_id="proj_...",       # required — links traces to a project
    environment="production",    # default: "production"
    store_prompts=False,         # store prompt/completion text (default: False)
    redact_keys=["password", "secret", "token", "api_key"],  # keys to redact
    sample_rate=1.0,             # 0.0–1.0, fraction of events to send
    debug=False,                 # log SDK activity to console
    batch_size=50,               # events per batch flush
    flush_interval=2.0,          # seconds between batch flushes
)

User and session context

Tag traces with user ID, session ID, or custom metadata:

from zespan import with_zespan_context

with with_zespan_context(
    user_id="user_123",
    session_id="sess_abc",
    tags={"feature": "chat"},
):
    # All AI calls inside are tagged with this context
    client.chat.completions.create(...)

Works as a decorator too:

@with_zespan_context(user_id="user_123")
def handle_request():
    client.chat.completions.create(...)

Agent tracing

Group multi-step agent workflows into a single trace:

from zespan import with_agent

with with_agent(
    name="SupportAgent",
    role="specialist",
    framework="custom",
    tools=[{"name": "lookup_order", "description": "Look up order by ID"}],
) as agent:
    agent.log_plan(["Look up order", "Check policy", "Draft reply"])

    order = agent.trace_tool(
        "lookup_order",
        {"order_id": "123"},
        lambda: fetch_order("123"),
    )

    agent.delegate_to("RefundAgent", "refund requested")

    # Wrapped LLM calls inside here inherit agent context
    client.chat.completions.create(...)

Agent span types emitted:

span_kind When
agent Agent start/end
planning log_plan()
tool trace_tool()
handoff delegate_to()

Manual spans

Trace custom operations that aren't LLM calls:

from zespan import start_span

with start_span(name="document-retrieval", span_kind="retrieval") as span:
    docs = vector_store.search(query)
    span.end(status="success")

Framework integrations

LangChain

from zespan import ZespanCallbackHandler

handler = ZespanCallbackHandler()

chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])

Google ADK

from zespan import ZespanADKTracer

tracer = ZespanADKTracer()
# pass tracer to your ADK runner

Or wrap a specific agent:

from zespan import wrap_adk_agent

traced_agent = wrap_adk_agent(my_agent, name="MyAgent")

LlamaIndex

from zespan import ZespanLlamaIndexCallbackHandler
from llama_index.core import Settings

handler = ZespanLlamaIndexCallbackHandler()
Settings.callback_manager.add_handler(handler)

Haystack

from zespan import ZespanHaystackTracer

tracer = ZespanHaystackTracer()
# use as Haystack tracer

Semantic Kernel

from zespan import instrument_semantic_kernel

instrument_semantic_kernel(kernel)

CrewAI

CrewAI uses OTEL-based instrumentation. Set the env vars Zespan exposes:

from zespan.integrations.crewai_handler import get_crewai_env_vars

env = get_crewai_env_vars()
# apply env to your process before launching CrewAI

AutoGen

from zespan import injectAutoGenContext, extractAutoGenContext

# Inject trace context into an AutoGen message
msg = injectAutoGenContext(msg, trace_id="trace_123")

# Extract it on the receiving end
ctx = extractAutoGenContext(msg)

Prompt management

Fetch versioned prompts from Zespan with 5-minute client-side cache:

import zespan

client = zespan.get_client()

# Latest version
prompt = await client.prompts.get("support-reply")

# Specific version or label
prompt = await client.prompts.get("support-reply", version=3)
prompt = await client.prompts.get("support-reply", label="production")

# Compile variables
text = client.prompts.compile(prompt, {"user_name": "Alice", "product": "Pro"})

Guardrails

Check content against your configured guardrail rules before or after LLM calls:

import zespan

check = zespan.check_guardrails(
    text=user_message,
    phase="pre",
)

if not check["allowed"]:
    return "Request blocked by content policy."

response = client.chat.completions.create(...)

post_check = zespan.check_guardrails(
    text=response.choices[0].message.content,
    phase="post",
)

return post_check["modifiedText"] or response.choices[0].message.content

Flush on exit

The SDK flushes automatically on process exit via atexit. For short-lived scripts or serverless functions, flush manually:

import zespan

zespan.get_client().flush()

Async support

All SDK methods work in async contexts. Context propagation uses Python's contextvars so async tasks inherit their parent's trace context automatically.

import asyncio
import zespan
from zespan import with_zespan_context

zespan.init(api_key="zsp_...", project_id="proj_...")
zespan.autopatch()

async def main():
    with with_zespan_context(user_id="user_123"):
        response = await async_openai_client.chat.completions.create(...)

asyncio.run(main())

OpenTelemetry

Enable native OTEL export alongside Zespan:

zespan.init(
    api_key="zsp_...",
    enable_otel=True,
    otel_endpoint="http://localhost:4318",
    otel_service_name="my-service",
)

Metadata

Release files for zespan 1.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zespan 1.6.0
File Size Uploaded
zespan-1.6.0.tar.gz 221.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zespan 1.6.0
File Interpreter ABI Platform
zespan-1.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 363.0 kB

Release files / zespan-1.6.0.tar.gz

Download URL zespan-1.6.0.tar.gz
Size 221.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4e9319f80dd45126de1745825a837f3563fce554586d3871f8e5b814197235f1
BLAKE2b-256 checksum
How to use checksums
5fc9bb0c5e003a753eb3e63cc14c9016ffdd79fa613e8eb7d00cae0cf858b92c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.17.0 {"ci":null,"cpu":"AMD64","implementation":{"name":"CPython","version":"3.14.2"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.18 30 Sep 2025","python":"3.14.2","system":{"name":"Windows","release":"11"}} HTTPX2/2.4.0

Release files / zespan-1.6.0-py3-none-any.whl

Download URL zespan-1.6.0-py3-none-any.whl
Size 141.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1f19f64fcd4b191fe0c5a53ea11d174aa4dffbdd8d83f17bbf1c6341d7dd622b
BLAKE2b-256 checksum
How to use checksums
08898c112a44aa4a6a9ce62b61a369a692ff53c161515268a726270479c0d853
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.17.0 {"ci":null,"cpu":"AMD64","implementation":{"name":"CPython","version":"3.14.2"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.18 30 Sep 2025","python":"3.14.2","system":{"name":"Windows","release":"11"}} HTTPX2/2.4.0

Release history Release notifications | RSS feed

1.6.1

2 release files

This release

1.6.0 This release

2 release files

1.4.9

2 release files

1.4.8

2 release files

1.4.7

2 release files

1.4.6

2 release files

1.4.5

2 release files

1.4.4

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page