Metadata-Version: 2.5
Name: sovergate
Version: 0.1.0a1
Summary: EU AI Act compliance SDK — automatic, non-invasive audit logging for LLM calls
Project-URL: Homepage, https://sovergate.com
Project-URL: Repository, https://github.com/Sovergate/sdk-python
Project-URL: Issues, https://github.com/Sovergate/sdk-python/issues
Author: Roberto Postolovski
License-Expression: MIT
License-File: LICENSE
Keywords: anthropic,audit,compliance,eu-ai-act,gdpr,llm,observability,openai,pii
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Security
Classifier: Topic :: System :: Logging
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: anthropic>=2.0; extra == 'dev'
Requires-Dist: httpx2; extra == 'dev'
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: openai>=1.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# sovergate

Python SDK for [Sovergate](https://sovergate.com): EU AI Act Article 12 audit
logging for LLM calls, with PII scrubbed inside your own infrastructure.

> **Early access.** The SDK is published as an alpha and the hosted ingest
> service is not generally available yet. APIs may change before 1.0.

## How it works

Your app keeps calling OpenAI or Anthropic directly. Sovergate does not proxy
or intercept the request. After a call completes, the SDK takes a copy,
scrubs personal data **locally**, and sends the scrubbed copy to Sovergate
from a background thread.

```
Your app ─────────────────────────────► OpenAI / Anthropic
              │
              └──► scrub PII locally ──► Sovergate (background, fire and forget)
```

## Install

```bash
pip install --pre sovergate
```

`--pre` is needed while the SDK is in alpha. Requires Python 3.10+. No runtime
dependencies.

## Quick start

```python
import openai
import sovergate

sovergate.init(api_key="sov_prod_xxxx")
sovergate.instrument(openai)

# Your existing code is unchanged
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)
# The response is returned immediately; logging happens in the background
```

You can also instrument a client instance, sync or async:

```python
from openai import AsyncOpenAI

client = AsyncOpenAI()
sovergate.instrument(client)
```

### Anthropic

Pass a client instance (the `anthropic` module itself has no client to patch):

```python
import anthropic
import sovergate

client = anthropic.Anthropic()        # or anthropic.AsyncAnthropic()
sovergate.init(api_key="sov_prod_xxxx")
sovergate.instrument(client)
```

## Stable PII tokens (recommended)

By default, detected PII is replaced with positional placeholders
(`[EMAIL_REDACTED_1]`), which are not correlatable between logs. Pass a
`pii_key` to replace values with deterministic, irreversible HMAC-SHA256 tokens
instead. The same value always maps to the same token, so Sovergate can count
unique people, IBANs and so on without ever receiving the raw values.

```python
sovergate.init(api_key="sov_prod_xxxx", pii_key="<your-secret>")
```

The `pii_key` is your secret. Keep it stable, and never send it to us: it stays
on your infrastructure, and without it the tokens cannot be reversed.

## Options

```python
sovergate.init(
    api_key="sov_prod_xxxx",           # required
    base_url="https://...",            # default: https://api.sovergate.com
    pii_key="<your-secret>",           # optional, see above
    debug=True,                        # verbose output from the "sovergate" logger only
)
```

## What is sent to Sovergate

For each completed call, one JSON record:

| Field | Content |
|---|---|
| `model` | Model name returned by the provider |
| `messages` | Your prompt messages (and Anthropic `system` prompt), **after** PII scrubbing |
| `response` | The model's text output, **after** PII scrubbing |
| `prompt_tokens`, `completion_tokens` | Token counts from the provider |
| `latency_ms`, `timestamp` | Call duration and start time |
| `finish_reason` | Why the model stopped |
| `pii_detections` | Category and placeholder of each scrubbed item, never the original value |

Never sent: the raw prompt or response, your `pii_key`, your LLM provider API
key, or request headers.

### What the scrubber detects

Regex-based, applied to every text part of the prompt and response: email
addresses, IP addresses, IBANs (including the spaced format), card numbers,
phone numbers, dates of birth, ID numbers, and names that follow a title (Mr,
Mrs, Ms, Dr, Prof). Other personal data, such as names without a title, is
**not** detected yet, so keep data minimisation in mind when you build prompts.
The code is in [`sovergate/scrubber.py`](sovergate/scrubber.py).

## Guarantees

- Never blocks your call: logging runs in a background daemon thread
- Never raises: if setup fails, the SDK logs a warning on the `sovergate`
  logger and stays out of the way
- Returns the provider's response unchanged; `with_raw_response` keeps working
- Never changes your app's logging configuration, even with `debug=True`
- 2 second timeout on every HTTP call to Sovergate
- If Sovergate is unreachable, records are queued in memory (up to 10,000) and
  retried with exponential backoff

## Current limitations

- Streaming calls (`stream=True`) are passed through untouched but not logged yet.
- Calls made through `with_raw_response` are not logged.
- The retry queue is in memory, so queued records are lost if the process exits.

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

## Security

Please report vulnerabilities privately. See [SECURITY.md](SECURITY.md).

## License

[MIT](LICENSE)
