Metadata-Version: 2.3
Name: syvain-metrics-api-client
Version: 0.0.207
Summary: Typed Python client for the Syvain Metrics REST API
Requires-Dist: niquests>=3.16.0
Requires-Dist: pydantic>=2.13.3
Requires-Dist: typing-extensions>=4.15.0
Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
Requires-Dist: ruff>=0.15.12 ; extra == 'dev'
Requires-Dist: ty>=0.0.34 ; extra == 'dev'
Requires-Python: >=3.10
Provides-Extra: dev
Description-Content-Type: text/markdown

# Syvain Metrics API Client

Typed Python client for the [Syvain Metrics](https://metrics.syvain.com/) REST
API.

This package maps directly onto the REST surface for experiments, folders,
metric query endpoints, annotations, and ingestion keys. If you only need to
record metrics from a training or evaluation job, use
`syvain-metrics-collector` instead.

## Install

```bash
uv add syvain-metrics-api-client
```

## Authentication

Use an explicit API key:

```python
from syvain_metrics_api_client import SyvainMetricsApiClient

client = SyvainMetricsApiClient("ak_org_...")
```

Use installed Syvain CLI auth:

```python
client = SyvainMetricsApiClient("local")
```

`local` reads `~/.config/syvain-metrics/auth.json`.

## Usage

```python
from syvain_metrics_api_client import SyvainMetricsApiClient

client = SyvainMetricsApiClient("local")

experiment = client.create_experiment(
    "mamba-run-001",
    description="Baseline mamba training run",
    metadata={"model": "mamba"},
).experiment

client.ingest_metrics(
    experiment.id,
    [
        {
            "client_event_id": "mamba-run-001/loss/1",
            "name": "loss",
            "value": 0.42,
            "step": 1,
            "metadata": {"split": "train"},
        }
    ],
)

series = client.query_metric_series(
    [
        {
            "experiment_id": experiment.id,
            "metric_name": "loss",
            "metadata_filter": [
                {"key": "split", "value": '"train"'},
            ],
        }
    ],
    order={"axis": "step", "direction": "asc"},
)
catalog = client.query_metrics_catalog([experiment.id])
```

`query_metric_series(...)` uses the lossless series query API. It returns a
list of column batches grouped by experiment, metric name, and complete
metadata object. Each batch has parallel `data.steps`, `data.timestamp`, and
`data.value` arrays. Metadata filter values and returned metadata values use
the Series DB canonical JSON-string representation; omit `value` to require
only that the metadata key exists. Set `metric_name` on a selection to query
one metric, or omit it to query every metric in the experiment.

Every metric must include a stable `client_event_id`. Reuse the same value when
retrying the same event so ingestion can remain idempotent.

Metric names must be nonempty printable ASCII and at most 256 bytes. The client
also requires the canonical `s`-prefixed, percent-encoded Series DB key segment
to be at most 512 bytes. Characters such as `/`, spaces, `+`, and parentheses
are supported and encoded internally; the original human-readable name is
returned by queries.

Metric metadata is validated against the series backend contract before a
request is sent: it must be a flat `str -> str` mapping with at most 32 keys,
128 UTF-8 bytes per key, 512 UTF-8 bytes per value, and 4096 UTF-8 bytes in its
canonical JSON representation.

Ingest and annotation creation calls mint and cache ingestion keys per
experiment. General API calls use the configured API key directly.

## Client Surface

Folders:

- `list_folders(...)`
- `create_folder(...)`
- `get_folder(...)`
- `patch_folder(...)`
- `rename_folder(...)`
- `move_folder(...)`

Experiments:

- `list_experiments(...)`
- `create_experiment(...)`
- `get_experiment(...)`
- `update_experiment_status(...)`
- `move_experiment(...)`

Metrics:

- `query_metric_series(...)`
- `query_metrics_catalog(...)`
- `ingest_metrics(...)`

Ingestion keys:

- `list_ingestion_keys(...)`
- `create_ingestion_key(...)`
- `revoke_ingestion_key(...)`
- `forget_ingestion_credential(...)`

Annotations:

- `list_annotations(...)`
- `create_annotation(...)`

Authentication:

- `auth_status()`

## Host and Timeouts

The client defaults to `https://metrics.syvain.com`.

```python
client = SyvainMetricsApiClient(
    "ak_org_...",
    host="https://metrics.syvain.com",
    timeout=10.0,
    ingest_timeout=60.0,
)
```

`timeout` applies to ordinary API calls. `ingest_timeout` applies to metric and
annotation ingestion calls.

## Write Retries and Idempotency

The client retries transient request failures for write operations. Except for
metric ingestion, POST and PATCH requests send a generated `Idempotency-Key`
header and reuse that key across retry attempts for the same logical request.

Metric ingestion does not send a request-level idempotency key. Its idempotency
is controlled by each metric's `client_event_id`. Use deterministic IDs derived
from the run, metric name, step, and series metadata when the same event may be
retried by caller code.

## Errors

All package-specific failures inherit from `MetricsApiError`.

- `MetricsApiRequestError`: the API returned an HTTP error or could not be
  reached
- `MetricsApiResponseError`: the API returned a successful response that did
  not match the expected schema
- `MetricsApiAuthError`: local CLI auth was requested but unavailable or
  invalid
