Emet SDK for Python
Emet checks the claims an AI agent makes against the evidence behind them: the tool results and data the agent actually received. emet-sdk sends your agent's turns to Emet from the OpenTelemetry GenAI spans your framework already emits.
Early release: the API may change before 1.0.
uv add emet-sdk # or: pip install emet-sdk
How it works
import emet_sdk
from pydantic_ai import Agent
emet_sdk.configure(service_name="support-agent", on_delivery=emet_sdk.write_delivery_file(".emet/last-delivery.json"))
Agent.instrument_all()
@app.post("/chat")
async def chat(body: ChatIn, user=Depends(current_user)):
# Take these from your server's own auth and storage, never from the request body
thread = await threads.get_for_user(user, body.thread_id)
with emet_sdk.turn(tenant_ref=user.team_external_id, conversation_id=thread.id, user=user.email):
result = await agent.run(body.message)
return result.output
- Adds, never replaces.
configure()adds one span processor to your app'sTracerProvider. Logfire, Datadog or any other exporter keeps receiving the same spans, with the same sampling. Call it after your own tracing setup, such aslogfire.configure(); it creates a provider only when the app has none. - Opt in per turn. Only spans that start inside
turn()are sent. Other agents and HTTP spans are not. - Nothing written onto your spans. The tenant, conversation and user stay in the SDK and never reach your other exporters, or downstream services through baggage.
- No secrets, no system prompt. Secrets are redacted from everything sent, and the system prompt travels as a hash.
- The user is who triggered the turn, usually their email. Emet matches it to a member of your organization and stores it on the trace either way.
- Never in your way. Turns are sent on a background thread and never raise into your app. Without
EMET_APPLICATION_KEY, the app logs "Emet is off" once and runs as before. Callemet_sdk.flush()before a short-lived process exits; Emet also flushes for up to 5 seconds at exit. - Every turn reports back.
on_deliveryreceives a result per turn:sent,stopped(with the reason, such astimeoutorhttp_4xxand Emet's error code) orskipped, plus the trace, the span count and any tools Emet found missing arguments or results.write_delivery_filesaves the latest one foremet-cli check --last; it never holds the key, the tenant, the user or any content.
Supported: Python 3.10 or later; Pydantic AI (Python 3.11 or later). Google ADK is planned.
Development
uv sync
uv run pytest
uv run python -m tests.record_fixtures && uv run pytest --update-fixtures # rerecord, then review the diff
uv run ruff check . && uv run ruff format --check . && uv run pyright
To release, bump src/emet_sdk/_version.py and the changelog in a PR. Once it has merged, tag the merge commit vX.Y.Z and push the tag. The release workflow checks that the tag is on main and matches the version, builds and smoke-tests the wheel, then waits for approval in the release environment before publishing to PyPI through trusted publishing.
See CONTRIBUTING.md for how to contribute, and SECURITY.md to report a vulnerability.
License
Apache-2.0
Metadata
Release files for emet-sdk 0.1.0
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 | Actions |
|---|---|---|---|---|
| emet_sdk-0.1.0.tar.gz | 105.5 kB | With provenance | Details for emet_sdk-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| emet_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for emet_sdk-0.1.0-py3-none-any.whl |
Total release size: 133.9 kB
Release files / emet_sdk-0.1.0.tar.gz
| Download URL | emet_sdk-0.1.0.tar.gz |
|---|---|
| Size | 105.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
da86e9bd97d3720c15c90623071f4174358c56d0e3d241c57374c1b7d166696a
|
|
BLAKE2b-256 checksum How to use checksums |
b7fe5b30fd67a16bf7561b1d6c35bb1134e1f7224886aae76c0ffec3a14a8e85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 30, 2026.
Transparency logRelease files / emet_sdk-0.1.0-py3-none-any.whl
| Download URL | emet_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 28.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df6830d9dc6910a7f59d04bfd0addd1ec86ddb0b5ca36cadc646e262ff48fb42
|
|
BLAKE2b-256 checksum How to use checksums |
ec813548055f3d7df82010d4f10f7bbbaff45e1486277964a569d18d574a21a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 30, 2026.
Transparency logSecurity for emet-sdk 0.1.0
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 emet_sdk-0.1.0.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 30, 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.