Metadata-Version: 2.4
Name: vix11
Version: 1.0.1
Summary: Vix11 SDK - AI Agent Security Platform. KYA passports, 11-layer abuse detection, Agent Trust Score.
Author-email: Vix11 <hello@vix11.com>
License: MIT
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 :: Security
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.25.0
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Dynamic: requires-python

# Vix11 Python SDK

Official Python SDK for the [Vix11](../../README.md) AI agent security platform. Provides synchronous and asynchronous clients, plus ASGI middleware for FastAPI and Starlette.

## Installation

```bash
pip install vix11
```

Requires Python 3.10+. The SDK depends on [httpx](https://www.python-httpx.org/) for HTTP transport.

## Quick Start

```python
from vix11 import Vix11Client

client = Vix11Client(
    base_url="https://vix11.example.com",
    agent_id="my-agent",
    api_key="your-api-key",
)

result = client.detect(endpoint="/api/chat", payload='{"prompt": "hello"}')

if result.action == "block":
    print("Request blocked")
else:
    print("Request allowed")

client.close()
```

## Async Client

For async applications, use `AsyncVix11Client`:

```python
from vix11 import AsyncVix11Client

async def main():
    client = AsyncVix11Client(
        base_url="https://vix11.example.com",
        agent_id="my-agent",
        api_key="your-api-key",
    )

    result = await client.detect(endpoint="/api/chat", payload='{"prompt": "hello"}')
    print(result.action)

    await client.close()
```

## FastAPI Middleware

The SDK includes ASGI middleware that intercepts every HTTP request, runs it through the Vix11 detection pipeline, and blocks or throttles suspicious traffic automatically.

```python
from fastapi import FastAPI
from vix11 import AsyncVix11Client
from vix11.middleware import Vix11Middleware

app = FastAPI()

client = AsyncVix11Client(
    base_url="https://vix11.example.com",
    agent_id="my-agent",
    api_key="your-api-key",
)

app.add_middleware(Vix11Middleware, client=client)

@app.post("/api/chat")
async def chat():
    return {"reply": "Hello!"}
```

**Middleware behavior:**

- `block` action: responds with `403` and a JSON error body.
- `throttle` action: responds with `429` and a `retryAfterMs` field.
- `allow` / `shadow-ban`: passes the request through to the application.
- On detection failure, the middleware **fails open** and lets the request through.

The middleware also works with plain Starlette applications.

## API Reference

### `Vix11Client(base_url, agent_id, api_key=None, timeout=5.0)`

Creates a synchronous client instance.

### `AsyncVix11Client(base_url, agent_id, api_key=None, timeout=5.0)`

Creates an asynchronous client instance.

### `detect(endpoint, payload, **params) -> DetectResponse`

Run the 11-layer detection pipeline against a request.

| Parameter  | Type   | Required | Description                |
|------------|--------|----------|----------------------------|
| `endpoint` | `str`  | Yes      | Target endpoint path       |
| `payload`  | `str`  | Yes      | Request body as a string   |
| `**params` | `Any`  | No       | Additional fields (e.g., `ip`) |

Returns a `DetectResponse` with an `action` field (`allow`, `block`, `throttle`, `shadow-ban`).

### `shield(endpoint, payload, **params) -> ShieldResponse`

Run the shielded-request flow combining passport verification with the detection pipeline.

Parameters and return type follow the same pattern as `detect`.

### `get_detection_stats() -> dict`

Retrieve detection pipeline statistics, including per-layer performance.

### `get_analytics_summary(from_ts=None, to_ts=None) -> dict`

Retrieve the analytics summary for a time range, including the "$X saved" metric.

| Parameter | Type        | Required | Description              |
|-----------|-------------|----------|--------------------------|
| `from_ts` | `int/None`  | No       | Start timestamp (epoch)  |
| `to_ts`   | `int/None`  | No       | End timestamp (epoch)    |

### `get_analytics_events(page=1, limit=50) -> dict`

Retrieve paginated detection events.

| Parameter | Type  | Required | Description      |
|-----------|-------|----------|------------------|
| `page`    | `int` | No       | Page number      |
| `limit`   | `int` | No       | Events per page  |

### `get_compliance_report() -> dict`

Retrieve the current OWASP ASI compliance report.

### `health() -> dict`

Check API health. Returns `{"status": "ok"}` when operational.

### `close() / await close()`

Close the underlying httpx client and release resources.

## Error Handling

All API errors are raised as `Vix11Error` exceptions.

```python
from vix11.types import Vix11Error

try:
    result = client.detect(endpoint="/api/chat", payload="...")
except Vix11Error as e:
    print(f"HTTP status: {e.status}")
    print(f"Error message: {e.message}")
```

**`Vix11Error` attributes:**

| Attribute | Type  | Description                  |
|-----------|-------|------------------------------|
| `status`  | `int` | HTTP status code             |
| `message` | `str` | Human-readable error message |

## Context Manager Usage

Both clients support context managers to ensure proper resource cleanup.

**Synchronous:**

```python
from vix11 import Vix11Client

with Vix11Client(
    base_url="https://vix11.example.com",
    agent_id="my-agent",
) as client:
    result = client.detect(endpoint="/api/chat", payload="...")
    print(result.action)
# client is automatically closed here
```

**Asynchronous:**

```python
from vix11 import AsyncVix11Client

async with AsyncVix11Client(
    base_url="https://vix11.example.com",
    agent_id="my-agent",
) as client:
    result = await client.detect(endpoint="/api/chat", payload="...")
    print(result.action)
# client is automatically closed here
```

## Configuration

| Option     | Type          | Required | Default | Description                           |
|------------|---------------|----------|---------|---------------------------------------|
| `base_url` | `str`         | Yes      | --      | Base URL of the Vix11 API             |
| `agent_id` | `str`         | Yes      | --      | Agent identifier sent with requests   |
| `api_key`  | `str / None`  | No       | `None`  | API key for authenticated requests    |
| `timeout`  | `float`       | No       | `5.0`   | Request timeout in seconds            |

## License

MIT
