Metadata-Version: 2.1
Name: gettraceai
Version: 0.1.0
Summary: Log every AI hiring decision with tamper-evident audit trails
Author-email: TraceAI <hello@traceai.dev>
License: MIT
Project-URL: Homepage, https://traceai.dev
Project-URL: Documentation, https://docs.traceai.dev
Project-URL: Repository, https://github.com/traceai/traceai-python
Keywords: ai,audit,compliance,hiring,traceability
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE

# TraceAI Python SDK

Log every AI hiring decision with tamper-evident audit trails. Built for UK regulatory compliance (UK GDPR, Equality Act, ICO guidance).

## Installation

```bash
pip install gettraceai
```

## Quick Start (5 lines)

```python
from gettraceai import TraceAI

trace = TraceAI(api_key="sk_live_...")

trace.log(
    decision_type="cv_screening",
    inputs={"candidate_id": "c_abc123", "cv_text": "Senior engineer..."},
    output={"score": 0.82, "decision": "shortlist"},
)
```

That's it. Every AI decision is now logged with a tamper-evident audit trail.

## Full Example

```python
from gettraceai import TraceAI

trace = TraceAI(
    api_key="sk_live_...",
    base_url="https://api.traceai.dev/v1",  # optional, for self-hosted
    timeout=10,   # seconds
    retries=3,    # retry 5xx errors
    silent=True,  # don't crash your pipeline on errors
)

# Log a single decision
result = trace.log(
    decision_type="cv_screening",
    inputs={"candidate_id": "c_abc123", "cv_text": "..."},
    output={"score": 0.82, "decision": "shortlist", "reasons": ["skills_match"]},
    model={"name": "gpt-4o", "version": "2025-03", "provider": "openai"},
    actor={"user_id": "recruiter_42", "role": "hiring_manager"},
    confidence=0.82,
    metadata={"department": "engineering", "location": "london"},
)
# result: {"id": "d_...", "hash": "...", "status": "logged"}

# Fire-and-forget (non-blocking)
trace.log_async(
    decision_type="cv_screening",
    inputs={"candidate_id": "c_def456"},
    output={"score": 0.45, "decision": "reject"},
)

# Batch log (up to 100 decisions)
trace.log_batch([
    {"decision_type": "cv_screening", "inputs": {"candidate_id": "c_1"}, "output": {"decision": "shortlist"}},
    {"decision_type": "cv_screening", "inputs": {"candidate_id": "c_2"}, "output": {"decision": "reject"}},
])
```

## Error Handling

By default (`silent=True`), the SDK **never crashes your pipeline**. Errors are logged to stderr and methods return `None`.

Set `silent=False` for strict mode during development:

```python
from gettraceai import TraceAI, TraceAIError

trace = TraceAI(api_key="sk_live_...", silent=False)

try:
    trace.log(decision_type="cv_screening", inputs={...}, output={...})
except TraceAIError as e:
    print(e.status_code)     # HTTP status code (if applicable)
    print(e.response_body)   # Parsed response body (if applicable)
```

## API Reference

### `TraceAI(api_key, base_url=None, timeout=10, retries=3, silent=True)`

Create a client instance.

### `trace.log(decision_type, inputs, output, model=None, actor=None, confidence=None, human_override=None, metadata=None)`

Log a single decision. Returns the API response dict or `None` on failure.

### `trace.log_async(...)`

Same parameters as `log()`, but runs in a background thread (fire-and-forget).

### `trace.log_batch(decisions)`

Log up to 100 decisions in a single request. Each decision dict must include `decision_type`, `inputs`, and `output`.

## License

MIT
