Metadata-Version: 2.4
Name: gateplex-python
Version: 0.2.3
Summary: Gateplex Python SDK — real-time AI governance firewall
Project-URL: Homepage, https://gateplex.ai
Project-URL: Documentation, https://docs.gateplex.ai
Project-URL: Repository, https://github.com/gateplex/gateplex-python
Project-URL: Bug Tracker, https://github.com/gateplex/gateplex-python/issues
Author-email: Gateplex <sdk@gateplex.ai>
License: MIT
Keywords: ai,compliance,governance,guardrails,llm,pii,safety
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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-httpx; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Description-Content-Type: text/markdown

# Gateplex Python SDK

Real-time AI governance firewall for LLM applications. Drop-in intercept logging, PII detection, spend controls, and human-in-the-loop approval workflows — deployable inside your VPC.

## Installation

```bash
pip install gateplex-python
```

## Quick start

```python
from gateplex import GateplexClient

client = GateplexClient(api_key="gp-...")

response = client.log_intercept(
    agent_id="<your-agent-uuid>",
    event_type="llm_call",
    input="Summarise the patient record for John Smith",
    output="John Smith, DOB 1982-03-14, diagnosis: ...",
)

if response.is_blocked:
    raise RuntimeError("Request blocked by governance policy")

print(response.verdict, response.pii_types_detected)
```

## Verdict values

| Verdict | Meaning |
|---|---|
| `ALLOW` | Request passed all rules |
| `FLAG` | Request flagged for audit; execution continues |
| `BLOCK` | Request blocked; raise `GateplexBlockedError` |
| `PENDING_APPROVAL` | Awaiting human reviewer approval |

`log_intercept` automatically raises `GateplexBlockedError` on a `BLOCK` verdict.

## Human-in-the-loop approvals

```python
from gateplex import GateplexClient, GateplexRejectedError

client = GateplexClient(api_key="gp-...")

try:
    response = client.log_intercept(
        agent_id="<agent-uuid>",
        event_type="llm_call",
        input=user_prompt,
        output=llm_output,
        wait_for_approval=True,   # blocks until reviewer acts
        poll_timeout=600,         # seconds (default 300)
    )
except GateplexRejectedError as e:
    print("Reviewer rejected the request:", e)
```

You can also poll manually:

```python
response = client.log_intercept(...)

if response.is_pending_approval:
    approval = client.wait_for_approval(response.intercept_id)
    print(approval.status, approval.reviewer_note)
```

## InterceptResponse fields (v0.2.3)

```python
response.intercept_id        # str
response.verdict             # "ALLOW" | "FLAG" | "BLOCK" | "PENDING_APPROVAL"
response.reasoning           # str — human-readable explanation
response.triggered_rules     # List[str] — rule IDs/names that fired
response.pii_types_detected  # List[str] — e.g. ["EMAIL", "SSN"]
response.transaction_amount  # Optional[float]
response.requires_approval   # bool

# Convenience properties
response.is_allowed
response.is_flagged
response.is_blocked
response.is_pending_approval
```

## ApprovalStatus fields (v0.2.3)

```python
approval.intercept_id   # str
approval.status         # "PENDING" | "APPROVED" | "REJECTED"
approval.reviewed_by    # Optional[str]
approval.reviewed_at    # Optional[str] — ISO 8601
approval.reviewer_note  # Optional[str]

approval.is_approved
approval.is_rejected
approval.is_pending
```

## Background batch logging

```python
# Fire-and-forget — does not block the hot path
client.batch_intercept(
    agent_id="<agent-uuid>",
    event_type="llm_call",
    input=prompt,
    output=completion,
)

# Drain the queue before process exit
client.flush()
```

## LLM library integrations

```python
from gateplex.integrations import OpenAIPatcher, AnthropicPatcher
import openai

openai_client = openai.OpenAI(api_key="sk-...")
patcher = OpenAIPatcher(client, agent_id="<agent-uuid>", openai_client=openai_client)
patcher.patch()
# All openai_client.chat.completions.create calls are now logged automatically
patcher.unpatch()
```

## @monitor decorator

```python
from gateplex.integrations import monitor

@monitor(client, agent_id="<agent-uuid>", event_type="llm_call")
def call_llm(input: str) -> str:
    return my_llm(input)
```

## Exceptions

| Exception | When raised |
|---|---|
| `GateplexAuthError` | Invalid or missing API key |
| `GateplexAPIError` | HTTP error from the Gateplex API |
| `GateplexValidationError` | Malformed request payload |
| `GateplexBlockedError` | Verdict is `BLOCK` |
| `GateplexRejectedError` | Human reviewer rejected a `PENDING_APPROVAL` intercept |

## Context manager

```python
with GateplexClient(api_key="gp-...") as client:
    client.log_intercept(...)
```

## Changelog

### 0.2.3
- `InterceptResponse` gains `verdict`, `reasoning`, `triggered_rules`, `pii_types_detected`, `transaction_amount`, `requires_approval`, and `is_*` convenience properties.
- New `ApprovalStatus` dataclass.
- `GateplexClient.wait_for_approval()` — polls until approval resolves.
- `log_intercept` gains `wait_for_approval` parameter.
- New `GateplexBlockedError` and `GateplexRejectedError` exceptions.
- `Guardrail` gains `requires_approval` field.

### 0.2.2
- `@monitor` decorator and `OpenAIPatcher` / `AnthropicPatcher` integrations.

### 0.2.1
- Initial public release.
