Metadata-Version: 2.4
Name: driftgard
Version: 1.6.0
Summary: Official Driftgard Python SDK — evaluate LLM interactions against your compliance policy
Author-email: Driftgard <support@driftgard.com>
License: MIT
Project-URL: Homepage, https://driftgard.com
Project-URL: Repository, https://github.com/driftgard/driftgard-sdk-python
Keywords: driftgard,ai,compliance,guardrails,llm,evaluation,policy,audit
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.20.0

# driftgard

Official Python SDK for [Driftgard](https://driftgard.com) — evaluate LLM interactions against your compliance policy.

## Install

```bash
pip install driftgard
```

## Quick start

```python
from driftgard import Driftgard

dg = Driftgard(api_key="your-api-key")

result = dg.evaluate(
    project_id="your-project-id",
    prompt="What stocks should I buy?",
    response="Based on current trends, you should invest in...",
    model_id="gpt-4o",
)

if result["evaluation"]["allowed"]:
    print("Safe to return to user")
else:
    # Use the fallback message if configured in your control pack
    if "fallback" in result:
        print("Show to user:", result["fallback"]["message"])
    print("Blocked:", result["evaluation"]["violations"])
```

## Conversation tracking

Link evaluations within an agent session using `session_id` and `parent_evaluation_id`:

```python
result = dg.evaluate(
    project_id="your-project-id",
    prompt="Transfer $500 to account 12345",
    response="I've initiated the transfer.",
    model_id="gpt-4o",
    session_id="sess_abc123",              # groups evals in a conversation
    parent_evaluation_id="eval_prev_id",   # chains to the previous eval
)
```

This enables chain depth protection (prevents infinite agent loops) and lets you trace evaluation lineage in the dashboard.

## A/B experiments

Tag evaluations with an `experiment_id` to compare governance metrics across models:

```python
result = dg.evaluate(
    project_id="your-project-id",
    prompt="Can I get a loan to invest in crypto?",
    response="Sure, taking out a personal loan to invest in crypto is a great way to maximise returns.",
    model_id="gpt-4o",
    experiment_id="financial-advisor-v1",  # optional
)
```

View experiment results on the Experiments page in the Driftgard dashboard.

## Cost attribution

Pass optional `usage` metadata to track token consumption and cost per evaluation:

```python
result = dg.evaluate(
    project_id="your-project-id",
    prompt="What stocks should I buy?",
    response="Based on current trends, you should invest in...",
    model_id="gpt-4o",
    usage={
        "prompt_tokens": 150,
        "completion_tokens": 320,
        "total_tokens": 470,
        "cost": 0.0047,  # USD
    },
)
```

All fields in `usage` are optional. When provided, token and cost data appears in the evaluation detail and is aggregated in experiment comparisons.

## Cost alerts

When cost alerting is enabled on your project, the response includes a `cost_alert` field if a threshold is exceeded:

```python
result = dg.evaluate(...)

if "cost_alert" in result:
    alert = result["cost_alert"]
    print(f"Cost alert: {alert['scope']} spend ${alert['actual_usd']} exceeds ${alert['threshold_usd']}")
    # Throttle the agent, notify the user, etc.
```

Configure thresholds in Settings — per-project, per-model, or per-session. Session-scoped alerts catch runaway agent loops in real-time.

## Features

- Single `evaluate()` method — send prompt/response, get verdict
- Failure mode: `fail-open` or `fail-closed` when API is unreachable
- Circuit breaker: skips API after consecutive failures, auto-recovers
- Idempotency: deduplicates retried requests via `x-idempotency-key`
- Auto-retry with exponential backoff on 5xx and network errors
- Typed exceptions: `AuthError`, `RateLimitError`, `FeatureNotAvailableError`, `ChainDepthExceededError`
- Works with Python 3.8+

## Configuration

```python
dg = Driftgard(
    api_key="your-api-key",                     # required
    base_url="https://api.driftgard.com",       # optional
    timeout=30,                                  # optional, seconds (default 30)
    max_retries=2,                               # optional (default 2)
    failure_mode="open",                         # "open" = allow if API down, "closed" = block (default "open")
    circuit_breaker_threshold=5,                 # open circuit after 5 failures (default 5)
    circuit_breaker_reset_seconds=30,            # try again after 30s (default 30)
)
```

## Failure mode & circuit breaker

The SDK never throws on network/server errors during `evaluate()`. Instead, it returns a synthetic response:

```python
result = dg.evaluate(...)

# Check where the decision came from
print(result["decision_source"])
# "policy"            — normal API evaluation
# "failure_mode"      — API unreachable, failure_mode applied
# "circuit_open"      — circuit breaker open, failure_mode applied
# "idempotency_cache" — duplicate request, cached result returned

# Monitor circuit breaker state
print(dg.circuit_breaker_state)
# {"state": "closed", "failures": 0, "opened_at": 0}
```

With `failure_mode="open"` (default), the SDK allows requests through when Driftgard is unavailable. With `failure_mode="closed"`, it blocks them with a fallback message.

## Error handling

```python
from driftgard import Driftgard, AuthError, RateLimitError, FeatureNotAvailableError, ChainDepthExceededError

try:
    result = dg.evaluate(...)
except AuthError:
    # Invalid or revoked API key (401)
    pass
except RateLimitError:
    # Too many requests (429)
    pass
except ChainDepthExceededError as e:
    # Agent loop detected — chain depth exceeded (429)
    print(f"Depth {e.depth} exceeds max {e.max_depth}")
except FeatureNotAvailableError as e:
    # API evaluate requires Compliance+ tier (403)
    print(e.tier)
```

## Requirements

- Python 3.8+
- `requests` library
- API key from Driftgard (Settings → API Keys)
- Compliance or Enterprise tier for API evaluation

## License

MIT
