# Python SDK

> The Python client for the LevelFour API: the sync and async constructors, the options they take, and how to override them for one call.

Source: https://docs.levelfour.ai/sdks/python


`levelfour` is the Python client for the LevelFour API, in a sync form and an async one. Everything here is about the client itself. What each method takes and returns lives on the reference page for its sub-client, listed below.

## Installation

```bash
pip install levelfour
```

## Client setup

### Sync client

```python
from levelfour import LevelFour

client = LevelFour(
    api_key="l4_live_...",
    base_url="https://api.levelfour.ai",
    timeout=30.0,
    max_retries=2,
)
```

With `LEVELFOUR_API_KEY` in the environment, the constructor takes nothing:

```python
client = LevelFour()
```

> **Tip**
>
> Prefer the empty constructor and the environment variable. An `api_key` written as an argument reaches version control with the file, and it stays in the history after you delete the line. [Authentication](/authentication#security-best-practices) covers keeping a key out of your source.

`LevelFour` works as a context manager:

```python
with LevelFour() as client:
    summary = client.recommendations.get_savings_by_provider()
```

### Async client

```python
import asyncio
from levelfour import AsyncLevelFour

async def main():
    async with AsyncLevelFour() as client:
        summary = await client.recommendations.get_savings_by_provider()

asyncio.run(main())
```

### Constructor options

| Parameter     | Type                     | Default                     |
| ------------- | ------------------------ | --------------------------- |
| `api_key`     | `str \| None`            | `LEVELFOUR_API_KEY` env var |
| `base_url`    | `str`                    | `https://api.levelfour.ai`  |
| `timeout`     | `float`                  | `30.0`                      |
| `max_retries` | `int`                    | `2`                         |
| `http_client` | `httpx.Client \| None`   | Built-in                    |
| `headers`     | `dict[str, str] \| None` | `None`                      |

> **Note**
>
> One type changes with the client you built. `http_client` takes an `httpx.Client` on `LevelFour` and an `httpx.AsyncClient` on `AsyncLevelFour`.

### Cloning a client

`with_options` returns a copy of the client with the options you name changed:

```python
long_timeout_client = client.with_options(timeout=60.0)
```

## What the client exposes

Every sub-client hangs off the client you just built. The reference pages carry each method with its parameters, its response shape and a worked example.

| Attribute                      | Reference                                     |
| ------------------------------ | --------------------------------------------- |
| `client.recommendations`       | [Recommendations](/resources/recommendations) |
| `client.recommendations.audit` | [Savings](/resources/savings)                 |
| `client.costs`                 | [Costs](/resources/costs)                     |
| `client.providers`             | [Providers](/resources/providers)             |
| `client.webhooks`              | [Webhooks](/webhooks)                         |
| `client.auth`                  | [Authentication](/authentication)             |
| `client.cost_alerts`           | [Cost Alerts](/resources/cost-alerts)         |

## Pagination

Methods that return paginated results return a `SyncPager`, or an `AsyncPager` on the async client.

[Pagination](/pagination) has the iteration forms, sync and async, alongside the response envelope and the page size limit.

## Request options

Override the client's defaults for one call:

```python
from levelfour.core.request_options import RequestOptions

opts: RequestOptions = {
    "timeout_in_seconds": 60,
    "max_retries": 5,
    "additional_headers": {"X-Request-Id": "abc123"},
}

summary = client.recommendations.get_savings_by_provider(request_options=opts)
```

| Option                        | Type             | Description                    |
| ----------------------------- | ---------------- | ------------------------------ |
| `timeout_in_seconds`          | `int`            | Override request timeout       |
| `max_retries`                 | `int`            | Override max retry attempts    |
| `additional_headers`          | `dict[str, Any]` | Extra headers for this request |
| `additional_query_parameters` | `dict[str, Any]` | Extra query parameters         |
| `additional_body_parameters`  | `dict[str, Any]` | Extra body parameters          |

## Next

* [Resources](/resources) has every method with its parameters and response shape, in Python alongside TypeScript and Go
* [Error handling](/error-handling) is the exception hierarchy, what each error carries, and which failures the client retries
* [Webhooks](/webhooks) is the verifier, the signature headers, the event types and the payloads
* [Authentication](/authentication) covers `LEVELFOUR_API_KEY`, key scopes, rotation and revocation
* [API Quickstart](/api-quickstart) is install, key, first call
* [TypeScript SDK](/sdks/typescript) and [Go SDK](/sdks/go) cover the same surface in the other two languages
