Python SDK for Sepurux trace recording and uploads
Project description
Sepurux Python SDK
Record agent traces, run reliability campaigns, and instrument OpenAI or LangChain workflows — all from Python.
Install
pip install -e sdk
Quick start
import os
from sepurux import SepuruxClient
os.environ["SEPURUX_API_BASE_URL"] = "http://localhost:8000"
os.environ["SEPURUX_API_KEY"] = "sepurux-dev-key"
os.environ["SEPURUX_PROJECT_ID"] = "22222222-2222-2222-2222-222222222222"
with SepuruxClient.from_env() as client:
with client.trace("example_task", {"user_id": "u-123"}) as trace:
trace.model_step("plan", {"goal": "create issue"}, output={"ok": True})
trace.tool_call("jira.create_issue(commit)", {"summary": "SDK test"})
trace.tool_result("jira.create_issue(commit)", {"issue_id": "OPS-123"})
print("trace_id:", trace.trace_id)
This is the intended ergonomic path:
SepuruxClient.from_env()readsSEPURUX_API_BASE_URL,SEPURUX_API_KEY, andSEPURUX_PROJECT_IDclient.trace(...)records and uploads automatically on exittrace.trace_idandtrace.run_idare available after the context closes
LangSmith-style ergonomics
Auto-upload trace context
from sepurux import SepuruxClient
client = SepuruxClient.from_env()
with client.trace(
"checkout_refund",
{"ticket_id": "t-123"},
campaign_id="refund_reliability",
mutation_pack="sepurux.core.reliability",
) as trace:
trace.model_step("triage", {"text": "Refund the duplicate charge"})
trace.tool_call("payments.refund", {"payment_id": "pay_123", "amount": 4200})
trace.tool_result("payments.refund", {"refund_id": "rf_123", "status": "queued"})
print(trace.trace_id)
print(trace.run_id)
@traceable decorator
Works with both sync and async def functions:
from sepurux import SepuruxClient
client = SepuruxClient.from_env()
# Sync function
@client.traceable(campaign_id="refund_reliability")
def score_refund_risk(amount: int, currency: str) -> dict:
return {"risk": "medium", "approve": amount < 10000, "currency": currency}
result = score_refund_risk(4200, "usd")
# Async function — same decorator, awaitable result
@client.traceable(campaign_id="refund_reliability")
async def fetch_risk_score(payment_id: str) -> dict:
data = await some_async_api(payment_id)
return {"risk": data["score"]}
result = await fetch_risk_score("pay_123")
Global configuration
from sepurux import configure, trace, traceable
configure()
@traceable()
def classify_ticket(text: str) -> dict:
return {"label": "bug", "priority": "p2"}
with trace("support_session", {"channel": "email"}) as rec:
rec.model_step("classify", {"text": "checkout timed out"})
API
SepuruxClient
SepuruxClient(base_url, api_key=None, project_id=None, timeout=30, sdk_header=None)
SepuruxClient.from_env(...)
The SDK automatically sends X-Sepurux-SDK: py/<version> on requests.
Use sdk_header only if you need to override it manually.
Methods:
trace(task_name, task_input=None, campaign_id=None, mutation_pack=None) -> recordertraceable(name=None, campaign_id=None, mutation_pack=None) -> decoratorupload_trace(trace: dict) -> strlist_traces(limit=50, offset=0) -> list[dict]get_trace(trace_id, include_payload=False) -> dictget_trace_timeline(trace_id) -> list[dict]bootstrap_trace(trace_id) -> dictcreate_campaign(name, mutation_set, eval_set, mutation_pack_id=None) -> strpreflight_run_inputs(trace_id, campaign_id) -> Nonestart_run(trace_id, campaign_id, thresholds=None, preflight=False) -> strrun_pack(campaign_id, mutation_pack) -> strget_run(run_id) -> dictget_ci_run(run_id) -> dictget_campaign_failures(campaign_id, run_id=None) -> list[dict]get_campaign_reliability(campaign_id, run_id=None) -> dict
TraceBuilder
TraceBuilder outputs backend-compatible traces:
{
"trace_version": "0.1",
"source": "sdk",
"task": {"name": "...", "input": {}},
"events": []
}
Recommended tracing flow
Use client.trace(...), client.traceable(...), or the global trace(...) / traceable(...)
helpers as the default integration path. Legacy helpers like sepurux_trace(...) and
record_trace(...) remain available for compatibility, but they are deprecated and no longer
the documented path.
Server-side pack execution
result = client.run_campaign("demo_campaign", mutation_pack="core.reliability")
print(result["run_id"])
print(result["reliability_score"])
print([failure["type"] for failure in result["failures"]])
Integrations
OpenAI
instrument_openai wraps any openai.OpenAI (or AsyncOpenAI) client and
automatically records every chat.completions.create call as an llm_call
event. Tool calls present in the response are also recorded. No manual
instrumentation required.
pip install sepurux openai
import openai
from sepurux import SepuruxClient
from sepurux.integrations.openai import instrument_openai
client = SepuruxClient.from_env()
openai_client = openai.OpenAI()
with client.trace(
"customer_refund_flow",
{"ticket_id": "t-101"},
campaign_id=os.environ["SEPURUX_CAMPAIGN_ID"],
) as trace:
ai = instrument_openai(openai_client, recorder=trace)
response = ai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Classify this support ticket"}],
)
print(trace.trace_id)
print(trace.run_id)
What gets recorded automatically:
llm_callevent with model name, messages input, full response output, and latencytool_callevents for any function calls returned by the modelfailureevent if the API call raises an exception
For async usage, call await ai.chat.completions.acreate(...) — the wrapper
detects the async path automatically.
LangChain
SepuruxCallbackHandler automatically records LLM calls, tool calls, and agent
outputs from any LangChain chain or agent. Requires langchain-core:
pip install sepurux langchain-core
import os
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from sepurux.integrations.langchain import SepuruxCallbackHandler
handler = SepuruxCallbackHandler(
"customer_refund_flow",
{"ticket_id": "t-101"},
campaign_id=os.environ["SEPURUX_CAMPAIGN_ID"],
)
# Works with chains, agents, or any LangChain runnable
result = agent_executor.invoke(
{"input": "Process refund for ticket t-101"},
config={"callbacks": [handler]},
)
# Upload trace + start reliability run
handler.finish()
print(handler.trace_id)
print(handler.run_id)
Or use it as a context manager — finish() is called automatically on exit:
with SepuruxCallbackHandler("refund_flow", campaign_id="...") as handler:
result = chain.invoke(inputs, config={"callbacks": [handler]})
print(handler.trace_id)
What gets recorded automatically:
- LLM calls with model name, prompt input, generated output, and latency
- Tool calls with name and parsed arguments
- Tool results
- Agent final output
Optional environment variables:
SEPURUX_API_BASE_URL(defaulthttp://localhost:8000)SEPURUX_UI_BASE_URL(defaulthttp://localhost:3000)SEPURUX_API_KEYSEPURUX_PROJECT_IDSEPURUX_CAMPAIGN_ID(if provided, script starts a run)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sepurux-0.7.0.tar.gz.
File metadata
- Download URL: sepurux-0.7.0.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e96ac78c37c3a8aeda4e5e8663686407ba391cf4fd969a5b95e8c39f2bc9836
|
|
| MD5 |
c0968f42c89936b57cadfeb5e6c32358
|
|
| BLAKE2b-256 |
01cadf79bd6118309e309a261e8f2f23e127a9062ec2705c7bba2c84c65360c1
|
File details
Details for the file sepurux-0.7.0-py3-none-any.whl.
File metadata
- Download URL: sepurux-0.7.0-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df049e95c56ece45ff8e5fa5baa5834757b77f9a8c8221dad4d80a85da8a7ab8
|
|
| MD5 |
4cfb3b5053cd60d03dcb32f96a2bb7f0
|
|
| BLAKE2b-256 |
681fbe5d07648c9c027c543effc319db4d551a767139b45c1c3689915a51c7ac
|