# ITS-AI Python SDK

Typed, ergonomic Python client for the ITS-AI API with sync and async interfaces, robust error mapping, attempts, and helpful docs.

- Sync and async clients: `ItsAIClient` (requests) and `AsyncItsAIClient` (httpx)
- Strongly-typed results via dataclasses
- Attempts on 429/5xx with exponential backoff and `Retry-After` support
- Rich, typed error hierarchy mapped from API `type` and HTTP status
- Safe logging with masked API keys

## Installation
```bash
pip install its-ai
```
## Quick start

### Single text analysis

```python
from its_ai import ItsAIClient, AnalyzeTextResult

client = ItsAIClient(api_key="api_key")
try:
    result: AnalyzeTextResult = client.analyze_text("Your English text here.")
    print(result.answer)
finally:
    client.close()
```

With deep scan:

```python
with ItsAIClient(api_key="api_key") as client:
    result = client.analyze_text("Your English text here.", deep_scan=True)
    print(result.answer, result.segmentation_tokens)
```

### Batch analysis

```python
from its_ai import ItsAIClient, AnalyzeBatchItemResult

texts = [
    "Short text",  # might trigger LowWords
    "A sufficiently long English text ...",
]

with ItsAIClient(api_key="sk_live_your_key") as client:
    items: list[AnalyzeBatchItemResult] = client.analyze_batch(texts, deep_scan=False)
    for item in items:
        print(item.text, item.answer)
```

Chunking large batches automatically:

```python
with ItsAIClient(api_key="sk_live_your_key") as client:
    results = client.analyze_batch(texts, max_batch_size=50)
```

### Async usage

```python
import asyncio
from its_ai import AsyncItsAIClient

async def main():
    async with AsyncItsAIClient(api_key="sk_live_your_key") as client:
        res = await client.analyze_text("hello world", deep_scan=True)
        print(res)

asyncio.run(main())
```

## Errors and attempts

The client raises typed exceptions derived from `ItsAIError` based on the API error `type` and HTTP status. Common ones include:

- `ValidationError`, `AuthenticationFailed`, `PermissionDenied`, `NotFound`, `NotAcceptable`
- Domain errors: `LowWords`, `ManyWords`, `OnlyEnglish`, `RateLimitExceeded`, etc.

Idempotent POSTs are retried up to 3 times on 429/5xx with exponential backoff and `Retry-After` respected. Other 4xx are not retried.

```python
from its_ai import ItsAIClient, LowWords, ManyWords, OnlyEnglish, AuthenticationFailed

try:
    with ItsAIClient() as client:  # reads ITS_AI_API_KEY from env by default
        client.analyze_text("too short")
except LowWords as e:
    print("Text too short:", e.message)
except ManyWords:
    print("Text too long")
except OnlyEnglish:
    print("Only English is supported")
except AuthenticationFailed:
    print("Invalid/absent API key")
```

## Configuration

- `api_key`: string, required (defaults from `ITS_AI_API_KEY`)
- `base_url`: defaults to `https://api.its-ai.org` (trailing slashes trimmed)
- `timeout`: default 10s (override per-call via `timeout=`)
- `max_attempts`: default 3 (for 429/5xx)
- `max_batch_size` (batch-only): optional chunking of input texts

Headers are set automatically: `User-Agent: its-ai-python-sdk/<version>`, `Accept: application/json`, `Content-Type: application/json`.

## Logging

The package uses Python's `logging` under the logger name `its_ai`. Enable DEBUG to see request URLs, status codes, and trimmed payloads. The `api_key` is masked.

```python
import logging
logging.basicConfig(level=logging.DEBUG)
```

## Environment

- `ITS_AI_API_KEY` – used by default if `api_key` is not passed.
- `ITS_AI_E2E=1` – enable smoke tests to hit the real API in CI (optional).

## Testing

Run unit tests:

```bash
python -m pytest -q
```

Run smoke (real API) tests when you have a valid key:

```bash
export ITS_AI_API_KEY="sk_live_your_key"
export ITS_AI_E2E=1
python -m pytest -q
```

## API Reference (brief)

- `ItsAIClient.analyze_text(text: str, deep_scan: bool = False, *, timeout: float | None = None) -> AnalyzeTextResult`
- `ItsAIClient.analyze_batch(texts: list[str], deep_scan: bool = False, *, timeout: float | None = None, max_batch_size: int | None = None) -> list[AnalyzeBatchItemResult]`
- Async variants with the same signatures on `AsyncItsAIClient`.

## License

MIT

For API details and the hosted endpoint see `https://api.its-ai.org`.
