Metadata-Version: 2.4
Name: flaxflow
Version: 1.0.0
Summary: Official Python SDK for the FlaxFlow Engine API — AI document processing.
Project-URL: Homepage, https://www.flaxia.com.br
Project-URL: Documentation, https://www.flaxia.com.br/engine-api
Project-URL: Source, https://github.com/flaxflow/FlaxFlow.PortalAI.Backend
Author: FlaxFlow
License: MIT
Keywords: ai,document,extraction,flaxflow,ocr,sdk
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pydantic<3,>=2
Provides-Extra: dev
Requires-Dist: datamodel-code-generator>=0.25; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# flaxflow — Python SDK

Official Python SDK for the **FlaxFlow Engine API** — AI-powered document processing
(extraction, classification, webhooks).

```bash
pip install flaxflow
```

## Authentication

The SDK authenticates with an **API key** (`sk_...`). Create one in the FlaxFlow app under
**Settings → API keys**, then pass it to the client or set `FLAXFLOW_API_KEY`.

```python
from flaxflow import FlaxFlow

fx = FlaxFlow(api_key="sk_...")  # or FlaxFlow() reading FLAXFLOW_API_KEY
```

## Quickstart

```python
from flaxflow import FlaxFlow

fx = FlaxFlow(api_key="sk_...")

# 1. Create a document class from a sample — the AI infers the fields to extract
doc = fx.documents.create_from_sample("invoice-sample.pdf")

# 2. Process a real document against that class
job = fx.processing.process_document("invoice-001.pdf", document_id=str(doc.document_id))
print(job.result)        # -> {"invoice_number": "123", "total_amount": "99.90", ...}

# 3. Or extract with a free-form prompt, no document class needed
job = fx.processing.process_with_prompt(
    "invoice-001.pdf",
    prompt="Extract invoice number, issue date and total amount",
)
print(job.result)
```

The file argument accepts a **path**, raw **bytes**, or any file-like object. For paths the
`documentType` is inferred from the extension; otherwise pass `document_type=`.

## Resources

| Resource | Highlights |
|----------|------------|
| `fx.documents` | `create_from_sample`, `create_manual`, `update`, `list`, `delete` |
| `fx.processing` | `process_document`, `process_with_prompt`, `process_many` |
| `fx.jobs` | `list`, `get`, `get_batch`, `analytics`, `download_document` |
| `fx.classifiers` | `create`, `list`, `get`, `update`, `set_models`, `delete` |
| `fx.webhooks` | `create`, `list`, `update`, `delete`, `delivery_logs` |
| `fx.api_keys` | `create`, `list`, `delete` |

### Batch processing

```python
batch = fx.processing.process_many(
    ["a.pdf", "b.pdf", "c.pdf"],
    classifier_id="<classifier_id>",   # let the classifier pick the right class
)
print(batch.batch_id, len(batch.jobs))
```

### Webhooks

```python
hook = fx.webhooks.create("https://example.com/hooks/flaxflow",
                          event_types=["job.completed", "job.failed"])
print(hook.secret)   # HMAC-SHA256 signing secret — shown only once
```

## Error handling

Every failure raises a subclass of `FlaxFlowError`:

```python
from flaxflow import FlaxFlow, AuthenticationError, NotFoundError, RateLimitError

try:
    fx.jobs.get("does-not-exist")
except NotFoundError:
    ...
except RateLimitError as e:
    print("slow down", e.status_code)
except AuthenticationError:
    print("check your API key")
```

## Configuration

| Option | Default | Env var |
|--------|---------|---------|
| `api_key` | – (required) | `FLAXFLOW_API_KEY` |
| `base_url` | `https://api.flaxia.com.br` | `FLAXFLOW_BASE_URL` |
| `timeout` | `60` seconds | – |

`FlaxFlow` is a context manager — use `with FlaxFlow(...) as fx:` to close the HTTP client
automatically.

## Types

Response objects are [pydantic](https://docs.pydantic.dev) models generated from the API's
OpenAPI spec, so you get full editor autocompletion and validation. Field names are
`snake_case` in Python (the wire format stays `camelCase`).

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
bash scripts/generate.sh   # regenerate models from ../openapi.json
pytest
```

## Publishing (maintainers)

Configure o token PyPI no GitHub (uma vez):

```bash
bash scripts/configure-pypi.sh   # cole o token pypi-...
```

Push em `main` com mudanças nesta pasta publica automaticamente a versão em
`pyproject.toml`. Antes de cada release, aumente `version` (ex.: `1.0.1`).

The generated models live in `src/flaxflow/_generated/` and are produced from
`sdks/openapi.json` (exported from the backend via `cargo run --bin export_openapi`).

> Async support (`AsyncFlaxFlow`) is planned. The sync client is fully featured today.
