Staso Python SDK
Trace explicitly instrumented agent runs and evaluate proposed tool calls before your code executes them.
Supported launch configuration
- Python 3.11+
- OpenAI Chat Completions, Anthropic Messages, or direct LiteLLM completion calls on the tested OpenAI route
- Synchronous or asynchronous, non-streaming calls
- An explicit
@st.agentroot and@st.toolon executed Python tools - Claude Code and Codex through one-command CLI setup
- Observe plus configured Guard policies in Audit or Enforce mode
Copy-paste launch sample
Use the canonical launch quickstart at https://staso.ai/docs/quickstart/launch. If you have a repository checkout, you can run the pinned copy in examples/launch_quickstart/:
pip install -r examples/launch_quickstart/requirements.txt
requirements.txt pins:
staso[openai]==0.5.15
openai==3.6.0
Set STASO_API_KEY, OPENAI_API_KEY, STASO_AGENT_NAME, STASO_ENVIRONMENT, STASO_WORKSPACE_SLUG, and STASO_SESSION_ID=launch-quickstart-first-trace, then run:
python examples/launch_quickstart/openai_guard_quickstart.py
The sample checks SDK delivery. Onboarding should wait for the dashboard/backend trace query before marking the first trace visible.
OpenAI quickstart
pip install "staso[openai]"
import json
import staso as st
from openai import OpenAI
st.init(api_key="ak_...", agent_name="weather-agent")
client = OpenAI()
TOOLS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the weather for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
]
@st.tool
def get_weather(city: str) -> dict:
return {"city": city, "temperature_c": 18}
@st.agent
def answer(question: str) -> dict | str:
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": question}],
tools=TOOLS,
)
except st.GuardBlocked as blocked:
return f"Blocked: {blocked.reason}"
tool_call = response.choices[0].message.tool_calls[0]
arguments = json.loads(tool_call.function.arguments)
return get_weather(**arguments)
print(answer("What is the weather in London?"))
delivery = st.shutdown(timeout=5)
if not delivery.ok:
raise RuntimeError(f"Trace delivery incomplete: {delivery.last_failure}")
st.init() patches an installed OpenAI SDK. The explicit decorators define the supported trace shape: @st.agent creates the root and @st.tool records the real tool duration, status, input, output, and error.
Guard evaluates tool proposals returned by the patched provider before the normal dispatch loop receives them. An audit finding records a would-block and lets the proposal continue. A block raises st.GuardBlocked.
@st.tool observes a Python function. It does not run Guard by itself. Check a direct tool call explicitly when it needs enforcement:
decision = st.guard("delete_record", {"record_id": "r_42"})
if decision.action == "block":
raise RuntimeError(decision.reason)
delete_record("r_42")
Anthropic
Install staso[anthropic] and use a non-streaming messages.create call under the same explicit decorators. See the Anthropic quickstart.
CLI agents
Connect Claude Code or Codex without changing application code:
pip install staso
staso setup --target claude-code # or codex
See the Claude Code quickstart, Codex quickstart, or CLI reference.
Pricing
Personal supports custom Python rules and your own LLM judge in Guard audit mode, with one Personal account per user. Saved-rule limits and execution allowances are separate.
Team capacity is purchased in units. Traces, Python rule runs, and LLM-judge evaluations each have an independent allowance shared across the organization's workspaces.
See current pricing and allowances for prices, included usage, retention, and saved-rule limits. Your signed-in quote shows the final amount, currency, and capacity. See how usage is counted before testing or running rules.
Allowances are shared across organization workspaces. See how usage is counted for Python-rule tests, billing-period resets, and capacity changes.
Capture boundaries
requested_modelrecords the request.modelrecords the provider-resolved ID when the response supplies one, and otherwise falls back to the request.providerrecords the provider identity.usage_available=Truemeans the provider returned usage, including valid zero-token values.Falsemeans the compatibility token counters are not evidence of known zero.- Cost is estimated by the Staso service for recognized models. Unknown usage or an unrecognized model stays unknown instead of becoming
$0. - Five independent categories default on:
request,system_prompt,tool_schema,tool_arguments, andoutput. Configure them withst.init(capture_<category>=...)orSTASO_CAPTURE_<CATEGORY>. - Suppression removes governed values before SDK payload serialization. Enabled content can still be redacted by the backend before storage; these are different states.
- The deprecated
capture_messages=Falsefallback suppressesrequestandsystem_promptonly. Explicit category controls win. - Span delivery is asynchronous. Call
st.flush()to wait for events accepted before that call, orst.shutdown()when the process is done. Both return aDeliveryReport; checkreport.okwhen delivery is required.report.rejectedandreport.last_rejectionexpose local queue drops that happened during automatic decorator cleanup. - Guard fails open when no policy decision is available by default. Use
fail_closed=TrueorSTASO_GUARD_FAIL_CLOSED=truefor calls that must block on explicit degradation.
For a warm serverless worker, flush after each invocation without stopping the shared client:
def handler(event, context):
result = answer(event["question"])
report = st.flush(timeout=2)
if not report.ok:
logger.warning("Staso delivery incomplete: %s", report.last_failure)
return result
Calling st.init() again retires the previous client. Inspect new_client.previous_shutdown_report to verify that drain without making initialization throw by default.
Documentation
- Python decorators
- OpenAI Chat Completions
- Anthropic Messages
- LiteLLM Python
- Claude Code
- Codex
- CLI setup
- Guard audit and block
- SDK setup
- Troubleshooting
Python 3.11+ | Apache 2.0
Metadata
Release files for staso 0.5.23
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| staso-0.5.23.tar.gz | 139.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| staso-0.5.23-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 316.1 kB
Release files / staso-0.5.23.tar.gz
| Download URL | staso-0.5.23.tar.gz |
|---|---|
| Size | 139.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d65e5683745174a8b4a0d056d8944c6c18eff01c9efbd196608f05f552ab8fe6
|
|
BLAKE2b-256 checksum How to use checksums |
a1facb46efa57cd95b2e657b9ff27f6ba26d88c2bd96dd7c0c3bf7e710a3e5fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / staso-0.5.23-py3-none-any.whl
| Download URL | staso-0.5.23-py3-none-any.whl |
|---|---|
| Size | 176.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b7c16f3b796f21020faa36ecaaf9ea83b0803f8b764726ad4e270195011de7de
|
|
BLAKE2b-256 checksum How to use checksums |
8eb93614797b07d33fcd20d9a198e453ffbc450873b4a8161913fb0cc4a50384
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for staso 0.5.23
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for staso-0.5.23.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.