Metadata-Version: 2.4
Name: causilo-client
Version: 0.10.2
Summary: Python client for the Causilo inference API
Author: Nums AI
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://nums.world
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: pandas>=2.0
Requires-Dist: pyarrow>=15
Requires-Dist: requests>=2.32
Requires-Dist: google-auth>=2.28

# causilo-client

Python client for the Causilo inference API. Send a table with the answers
filled in and a table with them blank; get a prediction for every blank row.

## Install

```bash
pip install -U causilo-client
```

Python 3.11 or newer. `pandas`, `pyarrow`, `requests` and `google-auth` are
pulled in automatically.

The import name is `causilo_client`. `causilo` on PyPI is the model package,
and the two can be installed side by side. Code written against the earlier
`radix` name changes the import and the class name: `from causilo_client import
Causilo`, and `Radix(...)` becomes `Causilo(...)`. Nothing else moved.

## Use

```python
import os

from causilo_client import Causilo

cx = Causilo(
    os.environ["CAUSILO_ENDPOINT"],
    key_file=os.environ["CAUSILO_KEY_FILE"],
)

pred = cx.predict(context_df, query_df, target="churned", model="causilo-clf")
```

`context_df` holds the target column; `query_df` does not. The feature columns
must match in name and order across the two. The endpoint URL and the
credential are issued to you at handover; neither is published here.

Authentication takes either a service account key file (`key_file=`) or a
bearer token issued by the operator (`token=`). Which one applies is agreed
before handover.

## Moving from another tabular API

The shapes are close enough that most code moves in an afternoon. `fit` and
`predict` collapse into one `predict(context, query, ...)`: the context table
is the training data with the target column filled in, the query table the
rows to predict without it, and nothing is stored between calls unless you ask
for a context to be kept. The `output_type` names are the usual ones
(`probas`, `preds`, `mean`, `median`, `quantiles`); `quantiles` must lie
strictly inside (0, 1), and some APIs accept the endpoints. Tables travel as
Parquet rather than CSV or JSON, so pass DataFrames and let the client encode
them. Datetime, timedelta, Period and decimal columns are refused with a clear
message rather than silently mishandled; split dates into numeric parts first.
Model knobs such as `n_estimators` are not request parameters here; the server
reports what it applied in `metadata.served_by`.

## Where it works

The client talks to the hosted API and to any deployment of the container
that sits behind a plain HTTPS address: Cloud Run, an Azure ML managed
endpoint, a load balancer in front of ECS. It does not talk to a SageMaker
endpoint. SageMaker's runtime API requires AWS-signed requests and routes
only `/invocations` and `/ping`, so `/usage`, `/limits` and `/cancel` do not
exist there; use `boto3` as shown in `deploy/aws/README.md`.

## What else is there

| | |
|---|---|
| `predict_with_metadata(...)` | The prediction and the metadata the server attached: the settings it applied, `classes` for the column order of a probability matrix, `served_by` naming the image and the weights that answered, `quota` with what is left of the month |
| `predict_cached(...)` | The same first call, plus a handle. Use it when the same context table will be queried again: the server keeps the encoded context and later queries send only the query rows. That saves the upload and the encoding, not the charge: cells are counted over context and query rows together on every call. Returns `(prediction, handle)` |
| `CachedContext` | The handle. `handle.predict(query)` for each later question, `handle.release()` when finished, or use it as a context manager. If the server's copy has gone -- it expired, or another caller's context needed the room -- the handle re-sends the table and carries on rather than raising |
| `list_contexts()`, `release_context(id)` | What this credential is holding, and letting one go by id |
| `usage()` | The month's figures for this credential without spending any of it; `metered: false` when no cap applies |
| `health()`, `wake()` | Whether the service is ready; `wake()` waits for a cold instance to come up before a first call |
| `to_batch_parquet(...)` | Packs a context and a query table into the single Parquet file a batch job takes |
| `MODELS` | The model keys this version knows |

Every failure is a `CausiloError` with `.status`, `.error_code` and
`.request_id`, the identifier to quote when reporting a problem. The subclasses
say what to do: `CausiloValidationError` (fix the request), `CausiloTooLarge`
(the message names what fits), `CausiloQuotaExceeded` (a cell quota is spent;
`.scope` is `caller`, `daily` or `tenant`, with `.limit`, `.used`,
`.resets_at`), `CausiloRateLimited` (too many requests in one minute or hour;
the client already waited out `Retry-After` three times before raising it, and
`.scope`, `.limit`, `.used`, `.resets_at` say which window), `CausiloOverloaded`
(retry once the queue drains; `CausiloRateLimited` is a subclass of it),
`CausiloUnavailable` (already retried three times), `CausiloAuthError` (the
credential was refused) and `CausiloTimeout`. Timeouts are the one failure the
client will not retry: the server is still computing, so instead it tells the
server the call was abandoned, and `.refunded` says how many cells came back.
The default `timeout` is 900 seconds. The `RadixError` family of names from
releases before 0.8.19 remains importable as aliases of the same classes, so an
`except RadixError` written earlier still catches everything.

The integration guide covers the call arguments, the input rules, the response
metadata, what each error means, and what the client does on your behalf when a
call times out.
