Python SDK¶
The SDK is a thin async client. It covers what a service account needs to do: register models, send data, upload baselines. Dashboards, drift detection, and alerting happen server-side automatically.
Install¶
pip install yaai-monitoring # just the client (httpx + pydantic)
pip install yaai-monitoring[gcp] # adds google-auth for GCP service accounts
Authentication¶
Two options:
# Explicit API key (recommended for most setups)
client = YaaiClient("http://localhost:8000/api/v1", api_key="yaam_...")
# Google Application Default Credentials (requires yaai[gcp])
# Uses GOOGLE_APPLICATION_CREDENTIALS, workload identity, or GCP metadata server
client = YaaiClient("http://localhost:8000/api/v1")
When no api_key is passed, the client uses Google ADC and refreshes tokens automatically.
Quick start¶
The fastest way to get going: copy the Model ID from the UI, then use get_or_create_version. You always provide the schema info (either a sample record or an explicit field list). If the version already exists the schema params are ignored; if it doesn't exist, a new version is created. This makes the call idempotent — it always succeeds regardless of prior state.
Option 1: Auto-infer schema from sample data¶
import asyncio
from yaai import YaaiClient
async def main():
async with YaaiClient("http://localhost:8000/api/v1", api_key="yaam_...") as client:
MODEL_ID = "your-model-uuid-here"
# Idempotent: creates version "v2" if it doesn't exist; returns it if it does.
# Schema is inferred from the sample record.
version = await client.get_or_create_version(
MODEL_ID,
"v2",
sample_data={"inputs": {"amount": 100.0, "country": "DE"}, "outputs": {"is_fraud": "false"}},
)
await client.add_inference(
model_version_id=version.id,
inputs={"amount": 42.0, "country": "US"},
outputs={"is_fraud": "false"},
)
asyncio.run(main())
Option 2: Define schema explicitly¶
import asyncio
from yaai import YaaiClient
from yaai.schemas.model import SchemaFieldCreate
async def main():
async with YaaiClient("http://localhost:8000/api/v1", api_key="yaam_...") as client:
MODEL_ID = "your-model-uuid-here"
# Same idempotent behaviour, but with an explicit schema definition.
version = await client.get_or_create_version(
MODEL_ID,
"v2",
schema_fields=[
SchemaFieldCreate(field_name="amount", direction="input", data_type="numerical"),
SchemaFieldCreate(field_name="country", direction="input", data_type="categorical"),
SchemaFieldCreate(field_name="is_fraud", direction="output", data_type="categorical"),
],
)
await client.add_inference(
model_version_id=version.id,
inputs={"amount": 42.0, "country": "US"},
outputs={"is_fraud": "false"},
)
asyncio.run(main())
Note:
sample_dataandschema_fieldsare mutually exclusive — pass exactly one. If you only need to look up a version without creating it, useget_version_by_labelinstead.## Usage The client is an async context manager: ```python import asyncio from yaai import YaaiClient from yaai.schemas.model import SchemaFieldCreate async def main(): async with YaaiClient("http://localhost:8000/api/v1", api_key="yaam_...") as client: # Register a model model = await client.create_model("fraud-detector") # Create a version with schema version = await client.create_model_version( model_id=model.id, version="v1.0", schema_fields=[ SchemaFieldCreate(field_name="amount", direction="input", data_type="numerical"), SchemaFieldCreate(field_name="country", direction="input", data_type="categorical"), SchemaFieldCreate(field_name="is_fraud", direction="output", data_type="categorical"), ], ) # Log a single inference await client.add_inference( model_version_id=version.id, inputs={"amount": 150.0, "country": "DE"}, outputs={"is_fraud": "false"}, ) # Log a batch (up to 10,000 records) await client.add_inferences( model_version_id=version.id, records=[ {"inputs": {"amount": 42.0, "country": "US"}, "outputs": {"is_fraud": "false"}}, {"inputs": {"amount": 9001.0, "country": "NG"}, "outputs": {"is_fraud": "true"}}, ], ) # Upload reference data (training distribution) await client.add_reference_data( model_id=model.id, model_version_id=version.id, records=[ {"inputs": {"amount": 85.0, "country": "DE"}, "outputs": {"is_fraud": "false"}}, # ... typically hundreds or thousands of records ], ) asyncio.run(main())
Methods at a glance¶
| Method | What it does |
|---|---|
create_model(name) |
Register a new model |
get_model(model_id) |
Fetch model details |
list_models() |
List all models |
delete_model(model_id) |
Delete a model and all its data |
create_model_version(model_id, version, schema_fields) |
Create a versioned schema |
get_version(model_id, version_id) |
Fetch full version details |
get_version_by_label(model_id, version) |
Look up a version by label (returns None if not found) |
get_or_create_version(model_id, version, *, sample_data, schema_fields) |
Idempotent upsert — always requires sample_data or schema_fields; returns existing or creates new |
add_inference(model_version_id, inputs, outputs) |
Log one inference |
add_inferences(model_version_id, records) |
Log a batch of inferences |
add_reference_data(model_id, model_version_id, records) |
Upload baseline data |
add_ground_truth(inference_id, label) |
Attach ground truth to an inference |
get_version_job(model_id, model_version_id) |
Get the drift job for a version |
get_job(job_id) |
Fetch job details |
update_job(job_id, **fields) |
Update job configuration |
trigger_job(job_id) |
Trigger a drift detection run |
backfill_job(job_id) |
Trigger historical drift backfill |
infer_schema(sample) |
Infer schema from a single sample |
infer_schema_batch(samples) |
Infer schema from multiple samples |
validate_schema(schema_fields, inputs, outputs) |
Validate a record against an inline schema |
validate_schema_batch(schema_fields, records) |
Validate a batch against an inline schema |
validate_model_version_schema(model_id, version_id, inputs, outputs) |
Validate a record against a version's schema |
validate_model_version_schema_batch(model_id, version_id, records) |
Validate a batch against a version's schema |
Full API reference¶
Auto-generated from source:
yaai.client.YaaiClient(base_url, *, api_key=None, target_audience=None)
¶
Async client for the yaai monitoring API.
Authenticates with either an explicit API key or Google Application
Default Credentials (ADC). When no api_key is provided the client
tries to obtain credentials via google.auth.default() — install
yaai[gcp] to enable this.
When target_audience is provided (recommended for Google SA auth),
the client requests an ID token scoped to that audience instead of a
generic access token. The audience must match the server's configured
GOOGLE_SA_AUDIENCE.
Usage::
# With API key
async with YaaiClient("http://localhost:8000/api/v1", api_key="yaam_...") as client:
model = await client.create_model("my-model")
# With Google ADC + ID token (recommended for service accounts)
async with YaaiClient("http://localhost:8000/api/v1", target_audience="https://yaai.example.com") as client:
model = await client.create_model("my-model")
# With Google ADC (access token fallback)
async with YaaiClient("http://localhost:8000/api/v1") as client:
model = await client.create_model("my-model")
Source code in yaai/client.py
get_version(model_id, version_id)
async
¶
Fetch full details for a specific model version.
Source code in yaai/client.py
get_version_by_label(model_id, version)
async
¶
Look up a model version by its label.
Returns the :class:ModelVersionSummary if a version with the given
label exists, or None otherwise.
Source code in yaai/client.py
get_or_create_version(model_id, version, *, sample_data=None, schema_fields=None, description=None, keep_previous_active=False)
async
¶
Idempotent version upsert: return existing or create new.
Always requires exactly one of sample_data or schema_fields
so the call is deterministic regardless of server state. If the
version already exists the creation parameters are ignored and the
existing :class:ModelVersionSummary is returned. If it doesn't
exist, a new version is created from the provided schema info.
For a pure lookup without creation parameters, use
:meth:get_version_by_label instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_id
|
UUID
|
The UUID of the parent model. |
required |
version
|
str
|
Human-readable version label (e.g. |
required |
sample_data
|
dict[str, dict] | None
|
A dict with |
None
|
schema_fields
|
list[SchemaFieldCreate] | None
|
An explicit list of :class: |
None
|
description
|
str | None
|
Optional description for the new version. |
None
|
keep_previous_active
|
bool
|
If True, existing active versions stay active when creating a new version. |
False
|
Returns:
| Type | Description |
|---|---|
ModelVersionRead | ModelVersionSummary
|
The matched :class: |
ModelVersionRead | ModelVersionSummary
|
exists, or a freshly created :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
Source code in yaai/client.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | |
get_version_job(model_id, model_version_id)
async
¶
Get the single job for a model version, or None if none exists.