Metadata-Version: 2.4
Name: counteraudit
Version: 0.1.1
Summary: HTTP client for the CounterAudit audit ingest API
Author: CounterAudit Contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/RunTimeAdmin/CounterAudit
Project-URL: Repository, https://github.com/RunTimeAdmin/CounterAudit
Project-URL: Documentation, https://github.com/RunTimeAdmin/CounterAudit/tree/main/packages/counteraudit-py
Keywords: counteraudit,audit,governance,compliance
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Dynamic: license-file

# counteraudit

Python client for the [CounterAudit](https://github.com/RunTimeAdmin/CounterAudit) API. Requires **Python 3.8+**.

## Install

```bash
pip install counteraudit
```

## Usage

```python
import os
from counteraudit import CounterAuditClient, CounterAuditError

# Initialize client
client = CounterAuditClient(
    base_url="https://api.counteraudit.io",
    api_key=os.environ["COUNTERAUDIT_API_KEY"],
    timeout=30,      # optional (seconds)
    max_retries=2    # optional (transient 429/5xx retry budget)
)

# Health check
print(client.health())
# {'ok': True, 'service': 'counteraudit-api', 'version': '0.8.0'}

# Ingest an event
result = client.ingest(
    connector_id="langchain-v0.3",
    raw_event={
        "run_id": "run-1",
        "model_id": "gpt-4o",
        "input": "hello"
    }
)
print(result["packet_id"], result["entry_hash"])

# Verify a packet
verification = client.verify(result["packet_id"])
print(verification["valid"])  # True
print(verification["rfc3161_verified"])

# Get agentic debt metrics
debt = client.dashboard_debt(days=30)
print(debt["agentic_debt_index"])
print(debt["by_connector"])

# List packets (paginated)
page = client.list_packets(limit=20)
print(len(page["packets"]))
if page["next_cursor"]:
    next_page = client.list_packets(cursor=page["next_cursor"])

# Proof-first wrappers (v1 naming)
record = client.proof.record(
    connector_id="langchain-v0.3",
    raw_event={"run_id": "run-2", "model_id": "gpt-4o", "input": "proof wrapper"}
)
verified = client.proof.verify(record["packet_id"])
chain = client.proof.chain_verify(org_id=os.environ.get("COUNTERAUDIT_ORG_ID", "00000000-0000-4000-8000-000000000001"))
exported = client.proof.export(limit=10)
print(verified["valid"], chain["valid"], exported["count"])
```

### Context manager

```python
with CounterAuditClient(base_url="...", api_key="...") as client:
    health = client.health()
    print(health)
# Session automatically closed
```

### Error handling

```python
try:
    client.verify("invalid-packet-id")
except CounterAuditError as e:
    print(f"Error {e.status_code}: {e.message}")
    print(f"Code: {e.error_code}, Request-ID: {e.request_id}")
    print(e.body)  # Full error response
```

## Reliability behavior

- configurable request timeout (`timeout`)
- transient retry policy (`max_retries`) on `429`/`5xx`
- richer error fields on `CounterAuditError`:
  - `status_code`
  - `error_code`
  - `request_id`
  - `body`

## API Reference

| Method | Maps to | Returns |
| -------- | --------- | --------- |
| `health()` | `GET /health` | Health dict |
| `ingest(connector_id, raw_event, org_id=None)` | `POST /v1/audit/ingest` | Ingest result |
| `verify(packet_id)` | `GET /v1/audit/verify/:id` | Verification result |
| `chain(org_id)` | `GET /v1/audit/chain/:org_id` | Chain summary |
| `list_packets(limit=None, cursor=None)` | `GET /v1/audit/packets` | Paginated list |
| `proof.record(connector_id, raw_event, org_id=None)` | `POST /v1/audit/ingest` | Ingest result |
| `proof.verify(packet_id)` | `GET /v1/audit/verify/:id` | Verification result |
| `proof.chain_verify(org_id)` | `GET /v1/audit/chain/:org_id` | Chain summary |
| `proof.export(limit=None, cursor=None)` | `GET /v1/audit/packets` | Paginated list |
| `list_connectors()` | `GET /v1/connectors` | Connectors list |
| `register_connector(...)` | `POST /v1/connectors/register` | Created connector |
| `update_connector(id, field_map=None, risk_defaults=None)` | `PATCH /v1/connectors/:id` | Updated connector |
| `delete_connector(connector_id)` | `DELETE /v1/connectors/:id` | None |
| `list_keys()` | `GET /v1/keys` | Keys list (masked) |
| `create_key(label=None)` | `POST /v1/keys` | Created key (plaintext once) |
| `delete_key(key_id)` | `DELETE /v1/keys/:id` | None |
| `dashboard_debt(days=None)` | `GET /v1/dashboard/debt` | Debt summary |

## Development

From the monorepo:

```bash
cd packages/counteraudit-py
pip install -e .
```

## License

MIT — see [LICENSE](../../LICENSE) in the repository root.
