# traceprotocol
[](https://pypi.org/project/traceprotocol/)
[](LICENSE)
**Python SDK for TRACE Protocol**
Open, vendor-neutral SDK for the TRACE Protocol's **Action → Policy → Evidence** loop.
- 📦 **Package**: `traceprotocol`
- 🔌 **Protocol**: HTTP/JSON (`/actions`, `/evidence`, `/policy`)
- 🧪 **Simple & testable**: requests-based, no heavy dependencies
- 🧱 **License**: Apache-2.0
---
## Install
```bash
pip install traceprotocol
```
> **Reference server** (for local development):
>
> ```bash
> cd server
> npm i && npm run dev # → http://localhost:8787
> ```
---
## Quickstart
```python
from trace_client import TraceClient, Actor
trace = TraceClient(endpoint="http://localhost:8787")
decision = trace.propose(
type="send_email",
actor=Actor(kind="agent", name="mail-bot", provider="openai"),
target="mailto:sarah@acme.com",
params={"subject": "Pricing", "body": "Hi!"}
)
print("status:", decision["status"])
# Dev-only: simulate approval on the reference server
if decision["status"] == "requires_approval":
import requests
requests.post(f"http://localhost:8787/approve/{decision['actionId']}")
print("approved:", decision["actionId"])
# Perform the side effect (send email, open PR, etc.) then attach evidence
trace.evidence(decision["actionId"], [
{"name": "email_sent", "pass": True, "note": "msgId=123"}
])
```
---
## High-level helper (`with_action`)
A convenience wrapper that handles propose → (optional approval) → run → evidence.
```python
import asyncio
from trace_client import TraceClient, Actor, with_action
trace = TraceClient(endpoint="http://localhost:8787")
async def send_email():
# simulate sending, return metadata used in evidence
return {"id": "msg_123"}
async def on_approval(info):
# dev shortcut: simulate human approval on the reference server
import requests
requests.post(f"http://localhost:8787/approve/{info['actionId']}")
print("approved:", info["actionId"])
async def main():
await with_action(
trace=trace,
type="send_email",
actor=Actor(kind="agent", name="mail-bot"),
target="mailto:sarah@acme.com",
params={"subject": "Pricing", "body": "Hi!"},
on_approval=on_approval,
run=send_email,
evidence_on_success=lambda res: [{"name": "email_sent", "pass": True, "note": f"id={res['id']}"}],
evidence_on_error=lambda err: [{"name": "email_failed", "pass": False, "note": str(err)}],
)
asyncio.run(main())
```
---
## API
### `TraceClient(endpoint: str | None = None)`
* `endpoint` defaults to `http://localhost:8787` if omitted.
### `propose(*, type, actor, target=None, params=None, id=None, timestamp=None) -> Decision`
Registers an **Action** and returns a **Decision**:
```python
{
"actionId": "a_123",
"status": "approved" | "rejected" | "requires_approval" | "observed",
"checks": ["reviewer_approval"] # present when gating
}
```
### `evidence(action_id, checks) -> {"verified": True}`
Attach **Evidence** checks to an action:
```python
trace.evidence("a_123", [
{"name": "reviewer_approval", "pass": True, "approver": "@admin"}
])
```
> Python reserves the keyword `pass`. If you use our `Check` helper (`pass_`), the client will map it to the wire key `pass` automatically.
### `policy(action_type: str | None = None) -> dict`
Fetch compiled policy, optionally filtered by `actionType`:
```python
trace.policy("send_email") # -> { "rules": [...] }
```
### `with_action(...) -> Any`
Orchestrates the full loop:
* `on_approval(info)` — optional async hook for human/API approval
* `run()` — async function that performs the side effect
* `evidence_on_success(result)` / `evidence_on_error(err)` — map to checks
---
## Examples
Working examples are available in the main repository:
- `examples/python/send_email.py` - Low-level API usage
- `examples/python/send_email_with_action.py` - High-level `with_action` helper
**Run the examples:**
```bash
# Install the package
pip install traceprotocol
# Start the reference server
cd server && npm install && npm run dev
# Run examples (from repository root)
python examples/python/send_email.py
python examples/python/send_email_with_action.py
```
---
## Testing
```bash
python3 -m pip install -r sdk/python/trace_client/requirements-dev.txt
pytest sdk/python/trace_client/tests -q
```
Tests are fully mocked via `responses` (no network).
We cover: propose/evidence happy path, policy fetch/filter, approval flows, error evidence, and API error handling.
---
## Versioning
* **v0.1**: observer mode + optional human-in-the-loop; TS & Python SDK parity
* Roadmap: Checkers API (programmatic checks), signatures & hash-chain evidence
---
## License
Apache-2.0 © TRACE Labs — Stewards of the TRACE Protocol
Raw data
{
"_id": null,
"home_page": null,
"name": "traceprotocol",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "trace, protocol, agent, governance, audit, evidence",
"author": "TRACE Labs",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/a8/b9/932237bd1ef587433ed493fa57774ff2485234acf73c325d96c1e7aeea18/traceprotocol-0.1.0.tar.gz",
"platform": null,
"description": "\n# traceprotocol\n\n[](https://pypi.org/project/traceprotocol/)\n[](LICENSE)\n\n**Python SDK for TRACE Protocol**\n\nOpen, vendor-neutral SDK for the TRACE Protocol's **Action \u2192 Policy \u2192 Evidence** loop.\n\n- \ud83d\udce6 **Package**: `traceprotocol`\n- \ud83d\udd0c **Protocol**: HTTP/JSON (`/actions`, `/evidence`, `/policy`)\n- \ud83e\uddea **Simple & testable**: requests-based, no heavy dependencies\n- \ud83e\uddf1 **License**: Apache-2.0\n\n---\n\n## Install\n\n```bash\npip install traceprotocol\n```\n\n> **Reference server** (for local development):\n>\n> ```bash\n> cd server\n> npm i && npm run dev # \u2192 http://localhost:8787\n> ```\n\n---\n\n## Quickstart\n\n```python\nfrom trace_client import TraceClient, Actor\n\ntrace = TraceClient(endpoint=\"http://localhost:8787\")\n\ndecision = trace.propose(\n type=\"send_email\",\n actor=Actor(kind=\"agent\", name=\"mail-bot\", provider=\"openai\"),\n target=\"mailto:sarah@acme.com\",\n params={\"subject\": \"Pricing\", \"body\": \"Hi!\"}\n)\n\nprint(\"status:\", decision[\"status\"])\n\n# Dev-only: simulate approval on the reference server\nif decision[\"status\"] == \"requires_approval\":\n import requests\n requests.post(f\"http://localhost:8787/approve/{decision['actionId']}\")\n print(\"approved:\", decision[\"actionId\"])\n\n# Perform the side effect (send email, open PR, etc.) then attach evidence\ntrace.evidence(decision[\"actionId\"], [\n {\"name\": \"email_sent\", \"pass\": True, \"note\": \"msgId=123\"}\n])\n```\n\n---\n\n## High-level helper (`with_action`)\n\nA convenience wrapper that handles propose \u2192 (optional approval) \u2192 run \u2192 evidence.\n\n```python\nimport asyncio\nfrom trace_client import TraceClient, Actor, with_action\n\ntrace = TraceClient(endpoint=\"http://localhost:8787\")\n\nasync def send_email():\n # simulate sending, return metadata used in evidence\n return {\"id\": \"msg_123\"}\n\nasync def on_approval(info):\n # dev shortcut: simulate human approval on the reference server\n import requests\n requests.post(f\"http://localhost:8787/approve/{info['actionId']}\")\n print(\"approved:\", info[\"actionId\"])\n\nasync def main():\n await with_action(\n trace=trace,\n type=\"send_email\",\n actor=Actor(kind=\"agent\", name=\"mail-bot\"),\n target=\"mailto:sarah@acme.com\",\n params={\"subject\": \"Pricing\", \"body\": \"Hi!\"},\n on_approval=on_approval,\n run=send_email,\n evidence_on_success=lambda res: [{\"name\": \"email_sent\", \"pass\": True, \"note\": f\"id={res['id']}\"}],\n evidence_on_error=lambda err: [{\"name\": \"email_failed\", \"pass\": False, \"note\": str(err)}],\n )\n\nasyncio.run(main())\n```\n\n---\n\n## API\n\n### `TraceClient(endpoint: str | None = None)`\n\n* `endpoint` defaults to `http://localhost:8787` if omitted.\n\n### `propose(*, type, actor, target=None, params=None, id=None, timestamp=None) -> Decision`\n\nRegisters an **Action** and returns a **Decision**:\n\n```python\n{\n \"actionId\": \"a_123\",\n \"status\": \"approved\" | \"rejected\" | \"requires_approval\" | \"observed\",\n \"checks\": [\"reviewer_approval\"] # present when gating\n}\n```\n\n### `evidence(action_id, checks) -> {\"verified\": True}`\n\nAttach **Evidence** checks to an action:\n\n```python\ntrace.evidence(\"a_123\", [\n {\"name\": \"reviewer_approval\", \"pass\": True, \"approver\": \"@admin\"}\n])\n```\n\n> Python reserves the keyword `pass`. If you use our `Check` helper (`pass_`), the client will map it to the wire key `pass` automatically.\n\n### `policy(action_type: str | None = None) -> dict`\n\nFetch compiled policy, optionally filtered by `actionType`:\n\n```python\ntrace.policy(\"send_email\") # -> { \"rules\": [...] }\n```\n\n### `with_action(...) -> Any`\n\nOrchestrates the full loop:\n\n* `on_approval(info)` \u2014 optional async hook for human/API approval\n* `run()` \u2014 async function that performs the side effect\n* `evidence_on_success(result)` / `evidence_on_error(err)` \u2014 map to checks\n\n---\n\n## Examples\n\nWorking examples are available in the main repository:\n\n- `examples/python/send_email.py` - Low-level API usage\n- `examples/python/send_email_with_action.py` - High-level `with_action` helper\n\n**Run the examples:**\n\n```bash\n# Install the package\npip install traceprotocol\n\n# Start the reference server\ncd server && npm install && npm run dev\n\n# Run examples (from repository root)\npython examples/python/send_email.py\npython examples/python/send_email_with_action.py\n```\n\n---\n\n## Testing\n\n```bash\npython3 -m pip install -r sdk/python/trace_client/requirements-dev.txt\npytest sdk/python/trace_client/tests -q\n```\n\nTests are fully mocked via `responses` (no network).\nWe cover: propose/evidence happy path, policy fetch/filter, approval flows, error evidence, and API error handling.\n\n---\n\n## Versioning\n\n* **v0.1**: observer mode + optional human-in-the-loop; TS & Python SDK parity\n* Roadmap: Checkers API (programmatic checks), signatures & hash-chain evidence\n\n---\n\n## License\n\nApache-2.0 \u00a9 TRACE Labs \u2014 Stewards of the TRACE Protocol\n",
"bugtrack_url": null,
"license": null,
"summary": "TRACE Protocol Python SDK \u2014 Action \u2192 Policy \u2192 Evidence",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://traceprotocol.org",
"Repository": "https://github.com/trace-protocol/trace-protocol"
},
"split_keywords": [
"trace",
" protocol",
" agent",
" governance",
" audit",
" evidence"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "86e90b43a1099673e35e4cd59188464c557bbc3c9ca2c33d0174e27b70766d5f",
"md5": "229d74f28dd3cd4220c3bda74f5c7528",
"sha256": "d5277ea6f92ca9a919391f0928522a5d997a6bdab3a31b071e3163780bb20176"
},
"downloads": -1,
"filename": "traceprotocol-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "229d74f28dd3cd4220c3bda74f5c7528",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 7255,
"upload_time": "2025-10-17T06:31:51",
"upload_time_iso_8601": "2025-10-17T06:31:51.161998Z",
"url": "https://files.pythonhosted.org/packages/86/e9/0b43a1099673e35e4cd59188464c557bbc3c9ca2c33d0174e27b70766d5f/traceprotocol-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a8b9932237bd1ef587433ed493fa57774ff2485234acf73c325d96c1e7aeea18",
"md5": "ba06239457d35c51330cdebddf2b35aa",
"sha256": "c4143e44dbd0ec4d02a06c4d95fd6ed0491ea72c51967a888673d2d8cbd55ec3"
},
"downloads": -1,
"filename": "traceprotocol-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "ba06239457d35c51330cdebddf2b35aa",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 8605,
"upload_time": "2025-10-17T06:31:52",
"upload_time_iso_8601": "2025-10-17T06:31:52.199694Z",
"url": "https://files.pythonhosted.org/packages/a8/b9/932237bd1ef587433ed493fa57774ff2485234acf73c325d96c1e7aeea18/traceprotocol-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-17 06:31:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "trace-protocol",
"github_project": "trace-protocol",
"github_not_found": true,
"lcname": "traceprotocol"
}