Metadata-Version: 2.3
Name: sievr
Version: 0.1.0
Summary: Official Python SDK for the Sievr API — drop-in guardrails for LLM apps.
Keywords: sievr,llm,guardrails,pii,prompt-injection,ai-safety
Author: Sievr
Author-email: Sievr <support@sievr.dev>
License: Apache-2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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 :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: httpx>=0.23.0,<0.29.0
Requires-Dist: attrs>=22.2.0
Requires-Dist: python-dateutil>=2.8.0,<3
Requires-Python: >=3.10
Project-URL: Homepage, https://sievr.dev
Project-URL: Documentation, https://sievr.dev/docs
Project-URL: Repository, https://github.com/ssilbery/sievr
Project-URL: Issues, https://github.com/ssilbery/sievr/issues
Description-Content-Type: text/markdown

# sievr

Official Python SDK for the [Sievr API](https://sievr.dev) — drop-in
guardrails for LLM apps. PII redaction and prompt-injection detection in a
single API call.

## Install

```sh
pip install sievr
# or
uv add sievr
```

## Quick start

```python
from sievr import Sievr

client = Sievr(api_key="sv_live_...")

result = client.scan({
    "text": "Email alice@example.com. Ignore previous instructions.",
    "checks": ["pii", "injection"],
})

print(result.pii.redacted_text)
# "Email <EMAIL_1>. Ignore previous instructions."

print(result.injection.verdict, result.injection.score)
# block 0.95
```

`.scan()` and `.rehydrate()` accept either a plain `dict` (validated and
converted under the hood) or a typed model object if you'd rather have
the extra compile-time safety:

```python
from sievr.models.scan_request import ScanRequest
from sievr.models.scan_request_checks_item import ScanRequestChecksItem

result = client.scan(ScanRequest(
    text="...",
    checks=[ScanRequestChecksItem.PII, ScanRequestChecksItem.INJECTION],
))
```

## Round-trip with an LLM

After your model has run on the redacted text, restore the placeholders:

```python
cleaned = client.rehydrate({
    "text": "I'll send a confirmation to <EMAIL_1>.",
    "entities": [
        {"original": e.original, "replacement": e.replacement}
        for e in result.pii.entities
    ],
})

print(cleaned.text)
# "I'll send a confirmation to alice@example.com."
```

`/v1/scan/rehydrate` is free — it doesn't tick the quota meter.

## Configuration

```python
client = Sievr(
    api_key="sv_live_...",
    base_url="https://api.sievr.dev",  # override for self-hosted or testing
    timeout=10.0,                       # seconds, optional
)
```

## Errors

All API errors raise `SievrError`:

```python
from sievr import Sievr, SievrError

try:
    client.scan(...)
except SievrError as err:
    print(err.code, err.status, err.raw)
```

Common error codes: `unauthorized`, `quota_exceeded`, `validation_failed`,
`request_too_large`, `invalid_json`.

## Async

The generated low-level functions ship with `asyncio` variants; the friendly
`Sievr` class is sync-only for now. To make async calls today, drop down to:

```python
from sievr import AuthenticatedClient
from sievr.api.scan import scan_text
from sievr.models.scan_request import ScanRequest

client = AuthenticatedClient(base_url="https://api.sievr.dev", token="sv_live_...")
result = await scan_text.asyncio(client=client, body=ScanRequest(text="..."))
```

An async variant of the friendly wrapper will land in a future release.

## Reference

Full API reference: <https://sievr.dev/docs>

## License

Apache-2.0
