Metadata-Version: 2.4
Name: rescale-ai-client
Version: 0.2.0
Summary: Standalone HTTP client for hosted and local Rescale AI inference servers
Project-URL: Repository, https://github.com/rescale/rescale-ai-client
Author: Rescale
License-Expression: Apache-2.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Requires-Dist: cryptography>=42
Requires-Dist: numpy>=1.24
Requires-Dist: pydantic>=2.7
Requires-Dist: python-multipart>=0.0.27
Provides-Extra: dev
Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Provides-Extra: jupyter
Requires-Dist: jupyter-bokeh>=4.0; extra == 'jupyter'
Requires-Dist: panel>=1.0; extra == 'jupyter'
Requires-Dist: pyvista>=0.40; extra == 'jupyter'
Requires-Dist: trame>=2.0; extra == 'jupyter'
Provides-Extra: mesh
Requires-Dist: pyvista>=0.40; extra == 'mesh'
Provides-Extra: optimization
Requires-Dist: scipy>=1.10; extra == 'optimization'
Provides-Extra: ssh
Requires-Dist: paramiko>=3.4; extra == 'ssh'
Description-Content-Type: text/markdown

# rescale-ai-client

Standalone Python client for [Rescale AI](https://rescale.com) hosted and local inference servers.
Communicates over the shared HTTP API. No `rescale_ai` package dependency.

## Installation

```bash
pip install rescale-ai-client
```

For mesh loading, prediction plotting, or VTK mesh helpers (`.vtp` and `.vtm`):

```bash
pip install "rescale-ai-client[mesh]"
```

For interactive 3D notebook plots:

```bash
pip install "rescale-ai-client[mesh,jupyter]"
```

This extra also installs `jupyter_bokeh`, which Panel needs for interactive rendering
in VSCode notebooks.

For development (do not run unless making local changes to the `rescale-ai-client` library)

```bash
pip install -e ".[dev]"
```

## Quickstart

### Launch Local Jupyter Notebook:

```
cd <path_to_workspace>/rescale-ai-client
source .venv/bin/activate
python -m ensurepip --upgrade
python -m pip install --upgrade pip
pip install uv
jupyter notebook
```

See `example/notebooks/quickstart.ipynb` for an example Jupyter notebook to get started. The directory contains other more advanced examples. 

### Retrieve Server-Available Models:

```python
from rescale_ai_client import InferenceClient

client = InferenceClient.connect(base_url="http://127.0.0.1:65432") # Connects to local Inference Runner. Modify to connect to remote Host & Port
catalog = client.list_models()

model = catalog.model("MyModel").latest()
prediction = client.run_inference(
    "/path/to/case.vtm",
    parameters={"mach": 0.82},
    model_name=model.model_name,
    version_number=model.version_number,
)

print(prediction.global_predictions)
prediction.save("/tmp/result.vtm")
```

### No-mesh Core Install, Summary-Only Inference:

```python
from rescale_ai_client import InferenceClient

client = InferenceClient.connect(base_url="http://127.0.0.1:65432") # Connects to local Inference Runner. Modify to connect to remote Host & Port
summary = client.run_inference_summary(
    "/path/to/case.vtm",
    parameters={"mach": 0.82},
    model_name="MyModel",
    version_number=7,
)

print(summary.global_predictions)
print(summary.prediction_id)
```

### Offline Install Bundle:

This installation path used when downloading an inference bundle directly from the Web UI.

```python
from rescale_ai_client import InferenceClient

client = InferenceClient.connect(base_url="http://127.0.0.1:65432") # Connects to local Inference Runner. Modify to connect to remote Host & Port

installed = client.install_bundle(
    "/path/to/MyModel_v0_local_inference.zip"
)

prediction = client.run_inference(
    "/path/to/case.vtm",
    parameters={"mach": 0.82},
    model_version_path=installed.model_version_path,
)

print(installed.model_name, installed.version_number)
print(prediction.global_predictions)
```

### `extensions` for Optional Future Data

Most JSON request methods accept an optional `extensions={...}` payload. This is the additive
escape hatch for future server features that should not force a client upgrade.

#### Example: Send Optional Request Hints During Prediction:

```python
from rescale_ai_client import InferenceClient

client = InferenceClient.connect(base_url="http://127.0.0.1:65432") # Connects to local Inference Runner. Modify to connect to remote Host & Port

summary = client.run_inference_summary(
    "/path/to/case.vtm",
    parameters={"mach": 0.82},
    model_name="MyModel",
    version_number=7,
    extensions={
        "rescale": {
            "ui_session": "demo-123",
            "include_debug": True,
        }
    },
)

print(summary.extensions)
print(summary.warnings)
```

#### Example: Read Capability-Style or Server-Added Metadata from Typed Responses:

```python
from rescale_ai_client import InferenceClient

client = InferenceClient.connect(base_url="http://127.0.0.1:65432")

server_info = client.server_info()
print(server_info.capabilities)

metadata = client.get_model_version_metadata(
    model_name="MyModel",
    version_number=7,
)
print(metadata.extensions)
print(metadata.warnings)
```

Design rules:

- `extensions` are optional and additive
- unknown request extensions are ignored by the server
- unknown response extensions are ignored by clients
- if a field becomes core contract, it should graduate into a typed top-level field

## API

### `InferenceClient.connect(*, base_url=None, host=None, port=None, url=None, timeout=600.0)`

Factory method. If omitted, defaults to local loopback at `http://127.0.0.1:65432`. `base_url` first. `host` / `port` and `url` remain convenience inputs. Scheme-less non-local endpoints default to HTTPS; explicit HTTP for non-local endpoints raises an `InsecureConnectionWarning` and stores the message on `client.insecure_transport_warning`.

// Give example here: connecting to my most recent Workstation
### `InferenceClient.connect_via_ssh(*, ssh_user_host, remote_port=65432, ...)`

SSH tunnel helper. `ssh_user_host` required. If `remote_port` is omitted, defaults to `65432`.

### `run_inference(vtp, parameters=None, *, model=None, model_version_path=None, model_name=None, model_uuid=None, version_number=None, ...)`

Canonical Python entrypoint. The `vtp` argument name is kept for compatibility, but path inputs may be `.vtp` or `.vtm`; `.vtm` paths are sent to the inference server so block structure is preserved. Same shape for hosted and local servers. CamelCase aliases still work, but new code should use snake_case.
JSON request methods also accept `extensions=...` for optional future payloads.

### `run_inference_summary(...)`

Lightweight entrypoint for core installs without the optional mesh dependencies. Returns typed prediction metadata plus global scalar outputs without constructing a `pyvista` mesh.

### `list_models(...)`

Returns a typed `ListModelsResult` with helpers like `.model("name")`, `.get("name", version_number=7)`, and `.model("name").latest()`.

### `inspect_bundle(...)` / `install_bundle(...)`

Inspect, upload, and install an offline local-inference bundle zip into the local installer. `install_bundle(...)` is idempotent: same content is a no-op, changed content updates the installed version.

### `get_model_version_metadata(version_number, *, model_name=None, model_uuid=None, ...)`

Fetches typed metadata for one model version.

### `get_loaded_model()`

Returns the server's current active-model bookkeeping status.

### `server_info()`

Returns typed inference server capability and compatibility metadata:

- `api_version`
- `supported_api_versions`
- `schema_revision`
- `server_build`
- `capabilities`

### `Client`

Compatibility alias for one release. Use `InferenceClient` for new code.

## Advanced

### Protocol Sync
The committed wire DTOs under `src/rescale_ai_client/_generated/` are generated from the
closed-source inference server OpenAPI schema snapshot at
`openapi/inference-server.openapi.json`.

Update flow:

```bash
# from the closed-source rescale_ai repo
PYTHONPATH=/path/to/rescale_ai \
  /path/to/rescale_ai/.venv/bin/python \
  - <<'PY'
from pathlib import Path
from rescale_ai.inference.server.openapi_compat import export_openapi_schema

export_openapi_schema(
    Path("/path/to/rescale-ai-client/openapi/inference-server.openapi.json")
)
PY

# from this repo
python scripts/generate_protocol_models.py
python scripts/generate_protocol_models.py --check
```

### Releasing

Releases are published by GitHub Actions with `uv build` and `uv publish`.

#### One-Time Setup:

1. In GitHub, create an environment named `pypi` under **Settings -> Environments**.
2. In PyPI, add a trusted publisher for:
   - Owner: `rescale`
   - Repository: `rescale-ai-client`
   - Workflow: `release.yml`
   - Environment: `pypi`

No PyPI API token needs to be stored in GitHub secrets for this workflow. PyPI issues
a short-lived publishing credential to the tagged GitHub Actions run through OIDC.

#### Publish a Release:

```bash
uv version 0.1.1
git commit -am "Release 0.1.1"
git tag -a v0.1.1 -m v0.1.1
git push origin main
git push origin v0.1.1
```

The workflow runs tests, verifies generated protocol models, builds both wheel and
source distributions, smoke-tests both artifacts, and publishes to PyPI.

## License

Apache-2.0
