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

# Python Client

> Call Nori from the synthefy package — one client for the hosted API and for local inference, with DataFrames and retries handled for you.

`synthefy` and `synthefy-nori` are two different packages. `synthefy-nori`
**is** the model; `synthefy` is the **client** that calls it. This page covers
the client.

Its one class, `SynthefyNoriClient`, runs the same `predict` call against the
hosted endpoint or against a local copy of the model, so you can develop on your
machine and ship to the API without changing the call.

<CardGroup cols={2}>
  <Card title="One call, either backend" icon="right-left">
    `mode="remote"` uses the hosted API, `mode="local"` runs in-process, and
    `mode="auto"` picks whichever is available.
  </Card>

  <Card title="Takes DataFrames" icon="table">
    Hand it a `DataFrame` and it aligns columns by name and encodes categoricals
    for you, rather than making you build a numeric matrix.
  </Card>

  <Card title="More options than these" icon="ellipsis">
    `predict` also accepts text columns (needs `pip install "synthefy[text]"`)
    and discrete-target snapping. See the docstring in
    [`nori_client.py`](https://github.com/Synthefy/synthefy/blob/main/src/synthefy/nori_client.py).
  </Card>

  <Card title="Retries built in" icon="rotate">
    Timeouts, connection errors, 429s and 5xx are retried with exponential
    backoff.
  </Card>
</CardGroup>

<Note>
  Use this page when you want the **hosted API**, or one code path that works both
  ways. To run the open-source model directly with no client in between, use
  `NoriRegressor` from [`synthefy-nori`](/nori/quickstart#local) instead.
</Note>

## Quickstart

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

Get a key from the [API key guide](/setup/api_key).

```python theme={null}
import os
from synthefy import SynthefyNoriClient

client = SynthefyNoriClient(
    api_key=os.environ["SYNTHEFY_NORI_API_KEY"],
    model="nori-30m",
)

X_train = [[0.0, 1.0], [1.0, 0.0], [0.5, 0.5], [0.2, 0.8]]
y_train = [0.1, 0.9, 0.5, 0.3]
X_test  = [[0.3, 0.7], [0.8, 0.2]]

print(client.predict(X_train, y_train, X_test))
```

```
[0.37, 0.72]
```

`predict` returns one float per row of `X_test`, in order. Pass `as_pandas=True`
to get a `pandas.Series` instead.

## Choosing a mode

`mode` decides where the model runs. It defaults to `"remote"`.

| `mode`               | Runs                                                  | Needs                                               |
| -------------------- | ----------------------------------------------------- | --------------------------------------------------- |
| `"remote"` (default) | the hosted endpoint                                   | an API key; no GPU, no download                     |
| `"local"`            | in-process, via `synthefy-nori`                       | `pip install "synthefy[local]"`; no key, no network |
| `"auto"`             | local when `synthefy-nori` is importable, else remote | nothing extra                                       |

```python theme={null}
# no key, no network — needs the local extra
client = SynthefyNoriClient(mode="local", model="nori-30m")

# one code path for both: local in development, hosted in production
client = SynthefyNoriClient(mode="auto", model="nori-30m")
```

`"auto"` resolves at construction, and the resolved value is readable on
`client.mode`, so you can log which backend you actually got.

## Predicting from DataFrames

Pass DataFrames and the client builds the numeric matrix for you. `X_test` is
aligned to `X_train` **by column name**, so column order does not matter; a
mismatch in the column *sets* raises.

```python theme={null}
preds = client.predict(df_train, y_train, df_test, as_pandas=True)
```

Non-numeric columns are encoded, fit on `X_train` and applied to `X_test`:

* **Default (`categorical_encoding="ordinal"`)** — each categorical column
  becomes one column of integer codes, from `X_train`'s categories in sorted
  order. A value seen only in `X_test` maps to `-1`; missing stays `NaN` and is
  imputed server-side.
* **`categorical_encoding="onehot"`** — one indicator column per category, and
  missing values get their own indicator.
* **`max_categorical_cardinality`** (default `100`) caps how many distinct
  values a categorical column may have. Above it the column is **dropped**, with
  a warning telling you to encode it yourself.

## Configuration

<AccordionGroup>
  <Accordion title="Constructor parameters" icon="sliders">
    | Parameter               | Default            | Description                                                                                                   |
    | ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------- |
    | `model`                 | **required**       | Size selector (`"nori-6m"`, `"nori-30m"`) or a raw gateway slug. No default; omitting it raises `ValueError`. |
    | `mode`                  | `"remote"`         | `"remote"`, `"local"`, or `"auto"`. See above.                                                                |
    | `api_key`               | `None`             | Remote mode only. Falls back to the `SYNTHEFY_NORI_API_KEY` environment variable.                             |
    | `timeout`               | `300.0`            | Per-request timeout in seconds.                                                                               |
    | `max_retries`           | `2`                | Retries on timeouts, connection errors, 429 and 5xx, with exponential backoff.                                |
    | `auth_scheme`           | `"Bearer"`         | The gateway needs `"Bearer"`; dedicated deployments use `"Api-Key"`.                                          |
    | `base_url` / `endpoint` | the hosted gateway | Point at a dedicated deployment instead.                                                                      |
    | `user_agent`            | `None`             | Custom `User-Agent` header.                                                                                   |
  </Accordion>

  <Accordion title="predict parameters" icon="code">
    | Parameter                     | Default             | Description                                                                                                                                                                                    |
    | ----------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `as_pandas`                   | `False`             | Return a `pandas.Series` instead of a list.                                                                                                                                                    |
    | `categorical_encoding`        | `"ordinal"`         | `"ordinal"` or `"onehot"`.                                                                                                                                                                     |
    | `max_categorical_cardinality` | `100`               | A non-numeric column with more distinct values than this is dropped, with a warning telling you to encode it yourself.                                                                         |
    | `discretize`                  | `None`              | Remote mode returns point predictions only, so `"snap-mean"` is the only strategy it supports; the others need `mode="local"`. See [Categorical & Ordinal Targets](/nori/categorical-targets). |
    | `text_columns`                | `None`              | Names the free-text columns. Needs `pip install "synthefy[text]"`.                                                                                                                             |
    | `timeout`                     | inherits the client | Override the timeout for one call.                                                                                                                                                             |
    | `extra_headers`               | `None`              | Additional HTTP headers.                                                                                                                                                                       |
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="API key" icon="key" href="/setup/api_key">
    Create the key this client authenticates with.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/nori/quickstart">
    The model sizes, and running the model directly without the client.
  </Card>
</CardGroup>
