traceprotocol


Nametraceprotocol JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryTRACE Protocol Python SDK — Action → Policy → Evidence
upload_time2025-10-17 06:31:52
maintainerNone
docs_urlNone
authorTRACE Labs
requires_python>=3.9
licenseNone
keywords trace protocol agent governance audit evidence
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# traceprotocol

[![PyPI version](https://img.shields.io/pypi/v/traceprotocol.svg)](https://pypi.org/project/traceprotocol/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](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[![PyPI version](https://img.shields.io/pypi/v/traceprotocol.svg)](https://pypi.org/project/traceprotocol/)\n[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](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"
}
        
Elapsed time: 3.63559s