Metadata-Version: 2.4
Name: letscomplai
Version: 0.1.0
Summary: Python SDK for LetsComplai PII/PHI redaction and compliance gateway
License-Expression: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: responses>=0.18.0; extra == "dev"
Requires-Dist: build>=1.2.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Dynamic: license-file

# LetsComplai Python SDK

Python SDK for the LetsCompl.ai PII/PHI redaction engine and compliance API gateway.

## Installation

```bash
pip install letscomplai
```

## Usage

### Local Redaction

```python
from letscomplai import redact

payload = {
    "name": "The patient John Doe was diagnosed.",
    "email": "test@example.com",
    "ssn": "000-12-3456",
}

result = redact(payload)
print(result["redacted"])
# {
#     "name": "patient [REDACTED_NAME] was diagnosed.",
#     "email": "[REDACTED_EMAIL]",
#     "ssn": "[REDACTED_SSN]"
# }
print(result["hits"])  # ['SSN', 'EMAIL', 'NAME']
```

### Remote Evaluation

```python
from letscomplai import LetsComplaiClient

client = LetsComplaiClient(api_key="your-api-key")

result = client.evaluate({
    "patient_notes": "Mr. John Smith has a history of asthma.",
})
print(result)
```

By default, `evaluate()` redacts PII/PHI **locally, before the payload is sent to the gateway** — raw sensitive data never leaves your process. Pass `redact=False` as an explicit opt-out to send the raw, unredacted payload:

```python
client.evaluate(payload, redact=False)  # explicit opt-out — sends the raw payload
```

`evaluate()` also accepts `rules` (a list of rule keys to restrict evaluation to a subset instead of the full workspace policy) and `pinned_versions` (a dict mapping ruleset key to a historical version number, for audit replay):

```python
client.evaluate(payload, rules=["ftc_budget_cap"], pinned_versions={"ftc_budget_cap": 2})
```

Passing `rules` makes the response's `policyScope` `"filtered"` instead of `"full"`, with `evaluatedRules` listing exactly which rule keys ran. **A `"filtered"` response is not a complete compliance decision** — it only reflects the requested subset, not the workspace's full active policy. Omit `rules` to evaluate everything.

### Guarding an action

```python
from letscomplai import LetsComplaiClient

client = LetsComplaiClient(api_key="your-api-key")
result = client.guard_action(
    {"action": "payout", "amount": 1200},
    lambda: payments.create_payout(amount=1200),
)
```

`guard_action` raises `ComplianceBlockedError` if the verdict is `blocked`, and (by default) `ComplianceUnavailableError` if the gateway is unreachable, before the action callable runs.

### Async client

```python
from letscomplai import AsyncLetsComplaiClient

client = AsyncLetsComplaiClient(api_key="your-api-key")
result = await client.evaluate({"action": "payout", "amount": 1200})
await client.aclose()
```

`AsyncLetsComplaiClient` mirrors `LetsComplaiClient`'s `evaluate`/`guard_action`/`redact_local` methods for asyncio applications.

> LetsCompl.ai is a technical enforcement tool, not a legal compliance service. Verdicts do not constitute legal advice.

For timeout, fail-open/fail-closed, retry, SLA, and local-enforcement behavior, see [docs/operations/client-availability.md](https://github.com/akventures-ai/letscomplai/blob/main/docs/operations/client-availability.md).
