Metadata-Version: 2.4
Name: intellidoc-sdk
Version: 0.1.1
Summary: Python SDK for IntelliDoc document extraction service
Author: NIA
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27

# IntelliDoc SDK

SDK Python para o serviço de extração de texto [IntelliDoc](../README.md).

## Índice

- [Instalação](#instalação)
- [Início Rápido](#início-rápido)
- [Como Funciona](#como-funciona)
- [Referência da API](#referência-da-api)
- [Tratamento de Erros](#tratamento-de-erros)
- [Formatos Suportados](#formatos-suportados)

## Instalação

```bash
pip install intellidoc-sdk
```

Requisitos: Python 3.13+

## Início Rápido

```python
from intellidoc_sdk import IntelliDocClient

client = IntelliDocClient(url="http://intellidoc:8000", api_key="sua-chave")

# 1. Enviar documentos
docs = await client.submit(["contrato.pdf", "certidao.html", "foto.jpg"])

# 2. Obter resultados (chegam conforme ficam prontos)
async for result in client.get_results(docs):
    if result.error:
        # O documento falhou no processamento
        print(f"{result.filename} falhou: {result.error}")
    else:
        # O documento foi processado com sucesso
        print(f"{result.filename}: {result.text[:100]}...")
```

> **Importante**: sempre verifique `result.error` antes de usar `result.text`.
> Quando um documento falha, `result.text` é `None`. Acessar sem verificar
> causa `TypeError`.

## Como Funciona

O SDK abstrai a comunicação com a API REST do IntelliDoc em dois passos:

```
submit()                          get_results()
   |                                  |
   v                                  v
Envia arquivos via HTTP  --->  Faz polling automático
Retorna IDs na hora            Entrega resultados via async for
```

1. **`submit(files)`** envia os arquivos para o IntelliDoc e retorna imediatamente com os IDs atribuídos a cada documento
2. **`get_results(docs)`** faz polling interno no IntelliDoc e entrega cada resultado conforme o processamento termina

O consumidor não precisa implementar polling, retry ou controle de lote. O SDK cuida disso internamente. Se o número de arquivos exceder o limite por requisição, o SDK divide automaticamente em lotes.

## Referência da API

### `IntelliDocClient(url, api_key)`

```python
client = IntelliDocClient(url="http://intellidoc:8000", api_key="sua-chave")
```

| Parâmetro | Tipo | Descrição |
|-----------|------|-----------|
| `url` | `str` | URL do IntelliDoc |
| `api_key` | `str` | API key de autenticação |

O client também pode ser usado como context manager:

```python
async with IntelliDocClient(url="...", api_key="...") as client:
    docs = await client.submit(["doc.pdf"])
    async for result in client.get_results(docs):
        ...
# Conexão fechada automaticamente
```

### `submit(files)`

Envia arquivos para processamento. Retorna lista de `DocumentInfo` com ID e filename de cada documento.

```python
docs = await client.submit(["relatório.pdf", "imagem.png"])

for doc in docs:
    print(f"{doc.filename} → {doc.id}")
# relatório.pdf → 550e8400-e29b-41d4-a716-446655440000
# imagem.png → 661f9511-f3ac-42e5-b827-557766551111
```

**Parâmetros:**
- `files: list[str]` — Lista de caminhos de arquivos

**Retorna:** `list[DocumentInfo]`

### `get_results(docs)`

Faz polling e entrega resultados conforme cada documento termina de processar.

```python
async for result in client.get_results(docs):
    if result.error:
        # Documento falhou — text é None
        print(f"{result.filename} falhou: {result.error}")
    else:
        # Documento processado — error é None
        print(f"{result.filename}: {len(result.text)} caracteres")
```

**Parâmetros:**
- `docs: list[DocumentInfo]` — Retorno do `submit()`

**Yield:** `DocumentResult`

> Resultados chegam na ordem de conclusão, não na ordem de envio. O primeiro a terminar é o primeiro a ser entregue.

### Entidades

**`DocumentInfo`** — retornado por `submit()`

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `id` | `str` | ID do documento no IntelliDoc |
| `filename` | `str` | Nome do arquivo original |

**`DocumentResult`** — entregue por `get_results()`

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `id` | `str` | ID do documento |
| `filename` | `str` | Nome do arquivo original |
| `text` | `str \| None` | Texto extraído (`None` se falhou) |
| `error` | `str \| None` | Mensagem de erro (`None` se sucesso) |

> **Regra**: se `error` não é `None`, o documento falhou e `text` será `None`.
> Se `error` é `None`, o documento foi processado com sucesso e `text` contém o texto extraído.

## Tratamento de Erros

Existem dois tipos de erro:

### Erros de infraestrutura

Afetam toda a operação. O SDK levanta exceção. Isso acontece quando o IntelliDoc está fora do ar ou a API key é inválida:

```python
from intellidoc_sdk.exceptions import AuthenticationError, ServiceUnavailableError

try:
    docs = await client.submit(["arquivo.pdf"])
except AuthenticationError:
    # API key inválida ou ausente
    print("Verifique sua API key")
except ServiceUnavailableError:
    # IntelliDoc fora do ar ou inacessível
    print("Tente novamente mais tarde")
```

### Erros por documento

Afetam um documento específico. Os demais documentos continuam sendo processados normalmente. O erro vem no campo `result.error`:

```python
async for result in client.get_results(docs):
    if result.error:
        # Este documento falhou, mas os outros continuam
        print(f"{result.filename}: {result.error}")
    else:
        print(f"{result.filename}: {len(result.text)} caracteres extraídos")
```

### Lista de exceções

| Exceção | Quando |
|---------|--------|
| `AuthenticationError` | API key inválida (401/403) |
| `ValidationError` | Requisição rejeitada (400) |
| `ServiceUnavailableError` | IntelliDoc fora do ar |
| `IntelliDocError` | Base de todas as exceções do SDK |

## Formatos Suportados

| Formato | Extensões |
|---------|-----------|
| PDF | `.pdf` |
| DOCX | `.docx` |
| JPEG | `.jpg`, `.jpeg` |
| PNG | `.png` |
| TIFF | `.tif`, `.tiff` |
| BMP | `.bmp` |
| HTML | `.html`, `.htm` |
| XML | `.xml` |
| TXT | `.txt` |
