> ## Documentation Index
> Fetch the complete documentation index at: https://docs.woodwide.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Install and configure the woodwide Python client — typed methods, async support, and error handling.

The [`woodwide`](https://pypi.org/project/woodwide/) package is the official Python client for Wood Wide. It provides typed methods, Pydantic responses, and IDE autocomplete for training and inference workflows.

For your first upload → train → infer workflow, use the **Python (SDK)** tab in the [API quickstart](/api-reference/getting-started). This page covers installation, configuration, and SDK-specific features.

<CardGroup cols={2}>
  <Card title="PyPI" icon="box" href="https://pypi.org/project/woodwide/">
    Install, release history, and package README.
  </Card>

  <Card title="API quickstart" icon="rocket" href="/api-reference/getting-started">
    First workflow with an SDK tab alongside curl and JavaScript.
  </Card>
</CardGroup>

<Note>
  The SDK source repository is not public yet. Use the [PyPI project page](https://pypi.org/project/woodwide/) for the package README, or inspect methods in Python with `help(client.api.models.prediction.train)`.
</Note>

***

## Install

Requires **Python 3.9+**.

```bash theme={null}
pip install woodwide
```

<Note>
  Pin a version in production. Check [PyPI](https://pypi.org/project/woodwide/) for the latest release.
</Note>

***

## Configure authentication

```bash theme={null}
export WOOD_WIDE_AI_API_KEY="sk_your_api_key_here"
export WOOD_WIDE_BASE_URL="https://api.woodwide.ai"
```

```python theme={null}
from woodwide import WoodWide

client = WoodWide()  # reads env vars; or pass api_key= / base_url=
```

<Info>
  The SDK uses `WOOD_WIDE_AI_API_KEY` and `WOOD_WIDE_BASE_URL`. The HTTP API and CLI use `WOODWIDE_API_KEY` and `WOODWIDE_BASE_URL` — same keys, different env names. Set `WOOD_WIDE_BASE_URL` explicitly; do not rely on the client default.
</Info>

Verify authentication:

```python theme={null}
me = client.auth.retrieve_me()
print(me)
```

<Warning>
  Never commit API keys to source control.
</Warning>

***

## Async client

Use `AsyncWoodWide` with `await` on each call:

```python theme={null}
import asyncio
from pathlib import Path
from woodwide import AsyncWoodWide

async def main() -> None:
    async with AsyncWoodWide() as client:
        dataset = await client.api.datasets.upload(
            file=Path("train.csv"),
            name="async_train",
        )
        print(dataset.id)

asyncio.run(main())
```

Optional `aiohttp` backend: `pip install woodwide[aiohttp]`

***

## Errors and retries

The SDK raises typed exceptions (`AuthenticationError`, `RateLimitError`, etc.) and retries connection errors and many 5xx responses by default.

```python theme={null}
import woodwide
from woodwide import WoodWide

client = WoodWide(max_retries=3)

try:
    client.auth.retrieve_me()
except woodwide.AuthenticationError:
    print("Check WOOD_WIDE_AI_API_KEY")
except woodwide.APIStatusError as e:
    print(e.status_code, e.response.text)
```

See the [PyPI package README](https://pypi.org/project/woodwide/) for timeouts, logging, and HTTP configuration.

***

## Model types

Training and inference are grouped by task:

| Task       | Train                                     | Infer                                                          |
| ---------- | ----------------------------------------- | -------------------------------------------------------------- |
| Prediction | `client.api.models.prediction.train(...)` | `client.api.models.prediction.infer(model_id, dataset_id=...)` |
| Clustering | `client.api.models.clustering.train(...)` | `client.api.models.clustering.infer(...)`                      |
| Anomaly    | `client.api.models.anomaly.train(...)`    | `client.api.models.anomaly.infer(...)`                         |
| Embedding  | `client.api.models.embedding.train(...)`  | `client.api.models.embedding.infer(...)`                       |
| Factors    | `client.api.models.factors.train(...)`    | `client.api.models.factors.infer(...)`                         |
| Search     | HTTP API only                             | HTTP API only                                                  |

See [Capabilities](/capabilities/overview) for task-specific examples with SDK tabs. Search and some HTTP-only options (such as anomaly `per_row` output) are not in the SDK yet — use the HTTP tabs on those pages.

***

## Next steps

<CardGroup cols={2}>
  <Card title="API quickstart" icon="rocket" href="/api-reference/getting-started">
    First workflow with an SDK tab alongside curl and JavaScript.
  </Card>

  <Card title="CLI" icon="terminal" href="/cli">
    Script the same workflow from the shell.
  </Card>
</CardGroup>
