Python SDK for Provy: prove your AI agents actually worked
Project description
provy-sdk
Python SDK for Provy: prove your AI agents actually worked.
Send every session, agent step and evaluation with an ingest key. No database credentials and no Provy-side configuration — close a session and it appears on your dashboard.
A note on names. You may see
argusinside: environment variables such asARGUS_INGEST_KEYandARGUS_URLstill work, and OpenTelemetry attributes are stillargus.*. Argus is the original codename, and those names are kept for wire compatibility so existing integrations keep working. Everything you actually type isprovy.
Reliability
Telemetry that silently disappears is worse than none, so this client is built not to lose spans:
- Retries transient failures with backoff, honouring
Retry-After. A timeout or a 503 delays your data rather than destroying it. - Buffers and batches spans, flushing on a background thread and again at process exit, so a short script cannot end with telemetry still in memory.
- Never silent. Anything dropped is counted and logged, and the counts are readable at
client.buffer_stats. Telemetry being switched off is announced too, once, on stderr. - Never duplicates. Every span carries an id, so the server can recognise a retried write as the same span rather than a second one.
- Never raises into your agent. A failed send is our problem, not a crash in your pipeline.
Install
pip install provy-sdk
The base install is the ingest client only (just requests). Optional extras:
| Extra | Adds | For |
|---|---|---|
provy-sdk[otel] |
OpenTelemetry SDK | streaming existing OTel spans via ProvyExporter |
provy-sdk[judge] |
anthropic |
running the LLM-as-judge in your own pipeline (circuit breakers) |
provy-sdk[engine] |
supabase |
the legacy direct-to-database path (prefer the ingest API instead) |
Connect
Get an ingest key from Provy: Agent Fleets → your fleet → Reveal key. Set it in your environment:
export PROVY_API_KEY=provy_...
export PROVY_EMIT=1 # required, see below
# optional, defaults to the hosted app:
export PROVY_URL=https://provy.ai
That key authenticates your fleet. It is the only credential you need. Keys issued before mid-2026
begin with argus_ and still work.
PROVY_EMIT: read this before your first run
Nothing is sent unless PROVY_EMIT=1 is set (or you pass enabled=True to the client). With it
unset the client is a deliberate no-op: open_session() returns a local id, everything else does
nothing, and your code runs unchanged.
This exists so a laptop run holding production credentials cannot write into your production Provy. Set it in the environments that should report (production, staging, CI) and leave it off on your machine.
The client logs one warning to stderr the first time it suppresses anything, so a run that reports nothing tells you why. Before 0.5.1 it did not, and the only clue was an empty dashboard.
Quickstart — direct ingest
from provy import ProvyClient
provy = ProvyClient() # reads PROVY_API_KEY from the environment
session_id = provy.open_session("premarket")
provy.trace(
session_id = session_id,
agent = "research",
step_type = "agent_step", # llm_call | tool_call | agent_step | decision | error
outcome = "Generated AAPL thesis",
latency_ms = 1240,
tokens_in = 800,
tokens_out = 150,
)
provy.close_session(session_id, result_summary="Trade plan ready")
Open Sessions in Provy — your run appears within seconds.
The decorator form auto-traces a function:
@provy.trace_fn(agent="research", step_type="agent_step")
def run_research(ticker):
...
run_research("AAPL", session_id=session_id)
Already on OpenTelemetry?
If your pipeline emits OTel spans (LangChain, CrewAI, AutoGen, LlamaIndex, or raw OTel), attach the exporter and stream them — no per-step calls:
pip install "provy-sdk[otel]"
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from provy import ProvyExporter
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(ProvyExporter(api_key="provy_...")))
Provy auto-detects the convention (OpenInference, OpenLLMetry/Traceloop, Langfuse, OTel GenAI) and builds the session from your spans.
Quality scoring
By default Provy runs the LLM-as-judge server-side on the traces you send — no SDK code, no key of yours. Configure criteria in Eval Manager and scores appear on the Quality page.
Run the judge in your own pipeline only when you want the verdict before an output is used (circuit breakers):
pip install "provy-sdk[judge]" # adds anthropic
from provy import evaluate_session_outputs
evaluate_session_outputs(session_id, {"research": research_output_text})
Needs ANTHROPIC_API_KEY in your environment. Same judge core as the server side.
Business outcomes
For metrics you compute yourself (no LLM), write them with write_eval() — they land in Outcomes:
from provy import write_eval
write_eval(
session_id = session_id,
eval_name = "approval_rate",
agent = "risk",
score = 0.6,
passed = True,
threshold = 0.2,
reasoning = "3 of 5 proposals approved",
)
API reference
ProvyClient(ingest_key=None, base_url=None)
Reads PROVY_API_KEY / PROVY_URL from the environment when arguments are omitted (legacy ARGUS_INGEST_KEY / ARGUS_URL still work).
| Method | When to call |
|---|---|
open_session(session_type, external_id=None, metadata=None) |
start of a run; returns session_id |
trace(session_id, agent, step_type, outcome, ...) |
each step; returns the span id |
close_session(session_id, status="completed", result_summary=None, terminal_reason=None) |
end of the run |
trace_fn(agent, step_type="agent_step") |
decorator that auto-traces a function |
ProvyExporter(api_key, endpoint=None)
OTel SpanExporter. Attach to any TracerProvider. Needs the otel extra.
evaluate_session_outputs(session_id, agent_outputs)
Client-side LLM-as-judge. Needs the judge extra and ANTHROPIC_API_KEY.
write_eval(session_id, eval_name, agent, score, passed, threshold, reasoning, layer=5)
Writes one business-outcome eval row.
Legacy:
TraceLogger(direct database writes via theengineextra) predates the ingest API. New pipelines should useProvyClient.TraceLoggerremains for existing internal pipelines.
Examples
examples/otel_quickstart.py— stream OTel spans to Provyexamples/github-actions-otel.yml— run a pipeline in GitHub Actions and stream to Provy
Support
Open an issue at github.com/amitgarg73/provy-sdk.
Project details
Release history Release notifications | RSS feed
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 provy_sdk-0.5.1.tar.gz.
File metadata
- Download URL: provy_sdk-0.5.1.tar.gz
- Upload date:
- Size: 50.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6e65fadcb9a088897c10fb111d6e0fec01976c7f8d53f890a3d272687f4d5cd
|
|
| MD5 |
908b905852f75638e505575c382936ad
|
|
| BLAKE2b-256 |
86616552d95473d209675f89c1ca5467b24cc69ba63a244257a2a1061f599bbe
|
Provenance
The following attestation bundles were made for provy_sdk-0.5.1.tar.gz:
Publisher:
publish.yml on amitgarg73/provy-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provy_sdk-0.5.1.tar.gz -
Subject digest:
d6e65fadcb9a088897c10fb111d6e0fec01976c7f8d53f890a3d272687f4d5cd - Sigstore transparency entry: 2329671651
- Sigstore integration time:
-
Permalink:
amitgarg73/provy-sdk@049c420c026ee39dad1c0c07e153f7a76df2b41b -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/amitgarg73
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@049c420c026ee39dad1c0c07e153f7a76df2b41b -
Trigger Event:
push
-
Statement type:
File details
Details for the file provy_sdk-0.5.1-py3-none-any.whl.
File metadata
- Download URL: provy_sdk-0.5.1-py3-none-any.whl
- Upload date:
- Size: 43.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
335aaf05e565d5c5cf8b3a308c2b335292931d0db236b6bb2a32dc3fa806d335
|
|
| MD5 |
0aca2b2fc8f214645c21f8f0f0c90d4f
|
|
| BLAKE2b-256 |
2cf65b581c56bfae2526811c3e56edbac1d859f074b2f18201334b804c9fdf89
|
Provenance
The following attestation bundles were made for provy_sdk-0.5.1-py3-none-any.whl:
Publisher:
publish.yml on amitgarg73/provy-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provy_sdk-0.5.1-py3-none-any.whl -
Subject digest:
335aaf05e565d5c5cf8b3a308c2b335292931d0db236b6bb2a32dc3fa806d335 - Sigstore transparency entry: 2329671907
- Sigstore integration time:
-
Permalink:
amitgarg73/provy-sdk@049c420c026ee39dad1c0c07e153f7a76df2b41b -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/amitgarg73
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@049c420c026ee39dad1c0c07e153f7a76df2b41b -
Trigger Event:
push
-
Statement type: