Skip to content

Control plane client

HTTP client for projects, datasets, experiments, metrics, alerts and live runs. Client groups its methods by resource (client.datasets, client.experiments, ...); each resource is documented below.

Client

Client(base_url: str | None = None, *, timeout: float = 30.0, transport: BaseTransport | None = None, api_key: str | None = None, project_id: str | None = None)

Platform control-plane client (projects, datasets, experiments, …).

api_key is fixed at construction (pass explicitly or via Opengrade.client).

base_url instance-attribute

base_url = resolved

projects instance-attribute

projects = _ProjectsResource(self._http, self._project)

datasets instance-attribute

datasets = _DatasetsResource(self._http, self._project)

experiments instance-attribute

experiments = _ExperimentsResource(self._http, self._project)

metrics_packs instance-attribute

metrics_packs = _MetricsPacksResource(self._http, self._project)

metrics_sets instance-attribute

metrics_sets = _MetricsSetsResource(self._http, self._project)

evaluators instance-attribute

evaluators = _EvaluatorsResource(self._http, self._project)

live_runs instance-attribute

live_runs = _LiveRunsResource(self._http, self._project)

alerts instance-attribute

alerts = _AlertsResource(self._http, self._project)

trace_scores instance-attribute

trace_scores = _TraceScoresResource(self._http, self._project)

app_configs instance-attribute

app_configs = AppConfigClient(self._http)

health

health() -> HealthResponse

close

close() -> None

client.projects

_ProjectsResource(http: _HttpTransport, project: ProjectResolver)

create

create(*, name: str, slug: str | None = None) -> ProjectResponse

list

list(*, slug: str | None = None, name: str | None = None, limit: int | None = None, offset: int = 0) -> list[ProjectResponse]

get_by_slug

get_by_slug(slug: str) -> ProjectResponse

get

get(project_id: str | None = None) -> ProjectResponse

set_retention

set_retention(retention_days: int | None, project_id: str | None = None) -> None

Keep retention_days of production data (traces, live answers, scores, alert events); None falls back to the server's RETENTION_DAYS.

client.datasets

_DatasetsResource(http: _HttpTransport, project: ProjectResolver)

create

create(project_id: str | None = None, *, name: str, version: int = 1, description: str | None = None, task_type: str = 'rag_qa') -> DatasetResponse

list

list(project_id: str | None = None, *, task_type: str | None = None, name: str | None = None, limit: int | None = None, offset: int = 0) -> list[DatasetResponse]

get

get(dataset_id: str) -> DatasetDetailResponse

add_item

add_item(dataset_id: str, *, input: str | RagChatInput, expected_output: str | None = None, actual_output: str | None = None, context: RagItemContext | None = None, metadata: RagItemMetadata | None = None, source_trace_id: str | None = None, source_span_id: str | None = None) -> DatasetItemResponse

create_with_items

create_with_items(project_id: str | None = None, *, name: str, items: list[dict[str, Any]], version: int = 1, description: str | None = None, task_type: str = 'rag_qa') -> DatasetResponse

ensure_items

ensure_items(dataset_id: str, items: list[dict[str, Any]]) -> int

Resume uploading until the dataset has len(items) rows; return stored count.

import_items

import_items(dataset_id: str, *, path: str | Path | None = None, file: tuple[str, bytes] | None = None, format: str | None = None, content_type: str | None = None) -> ImportDatasetItemsResponse

client.experiments

_ExperimentsResource(http: _HttpTransport, project: ProjectResolver)

create

create(project_id: str | None = None, *, name: str, dataset_id: str, model_config: dict[str, Any] | None = None, version: str | None = None, git: dict[str, Any] | None = None, baseline_experiment_id: str | None = None, app_config_id: str | None = None, app_config_alias: str | None = None, metrics_set_id: str | None = None) -> ExperimentResponse

list

list(project_id: str | None = None, *, name: str | None = None, limit: int | None = None, offset: int = 0) -> list[ExperimentResponse]

get

get(experiment_id: str) -> ExperimentResponse

set_alias

set_alias(alias: str, experiment_id: str, *, project_id: str | None = None, note: str | None = None, force: bool = False) -> ExperimentAliasResponse

get_alias

get_alias(alias: str, *, project_id: str | None = None) -> ExperimentAliasResponse

list_aliases

list_aliases(project_id: str | None = None) -> list[ExperimentAliasResponse]

alias_history

alias_history(alias: str, *, project_id: str | None = None, limit: int = 50) -> list[ExperimentAliasEventResponse]

delete_alias

delete_alias(alias: str, *, project_id: str | None = None) -> None

list_outputs

list_outputs(experiment_id: str, *, keys: list[tuple[str, int]] | None = None) -> list[ExperimentItemOutputResponse]

upsert_outputs

upsert_outputs(experiment_id: str, items: list[dict[str, Any]]) -> UpsertExperimentOutputsResponse

Write per-item outputs; keys left out of an item keep their stored value.

submit_client_results

submit_client_results(experiment_id: str, metrics: list[dict[str, Any]]) -> list[EvaluationRunResponse]

Store scores computed client-side: one evaluation run per metric.

Each metric is {"name", "results": [{"dataset_item_id", "score", "label", "explanation", "metadata"}], "threshold"?, "config"?}. Bump config when the metric code changes so compare flags it instead of reporting a delta.

log_metrics

log_metrics(experiment_id: str, metrics: Mapping[str, float]) -> dict[str, float]

Upsert experiment-level scalars (last value per key wins); returns all of them.

get_metrics

get_metrics(experiment_id: str) -> dict[str, float]

update_params

update_params(experiment_id: str, params: Mapping[str, Any]) -> ExperimentResponse

Merge params into model_config.

The server answers 409 once an evaluation has started or the experiment has evaluation runs, or when it was created from an app config.

evaluate_pack

evaluate_pack(experiment_id: str, *, metrics_set_id: str | None = None, save_as_default: bool = False, poll_interval: float = 1.0, timeout: float = 600.0) -> EvaluateResponse

Start pack scoring (202) and poll until the experiment finishes.

summary

summary(experiment_id: str, *, run_ids: list[str] | None = None, evaluator_ids: list[str] | None = None, group_by: str | None = None) -> ExperimentSummaryResponse

Aggregates per evaluator; group_by (item metadata key) adds per-group rows.

compare

compare(experiment_id: str, baseline_id: str, *, evaluator_ids: list[str] | None = None, candidate_run_ids: list[str] | None = None, baseline_run_ids: list[str] | None = None, group_by: str | None = None) -> ExperimentCompareResponse

Candidate vs baseline; group_by (item metadata key) adds per-group deltas.

client.metrics_packs

_MetricsPacksResource(http: _HttpTransport, project: ProjectResolver)

ensure

ensure(project_id: str | None = None) -> MetricsPackResponse

get

get(project_id: str | None = None) -> MetricsPackResponse

client.metrics_sets

_MetricsSetsResource(http: _HttpTransport, project: ProjectResolver)

list

list(project_id: str | None = None, *, name: str | None = None, limit: int | None = None, offset: int = 0) -> list[MetricsSetResponse]

get

get(metrics_set_id: str) -> MetricsSetResponse

create

create(project_id: str | None = None, *, name: str, entries: list[dict[str, Any]], description: str | None = None) -> MetricsSetResponse

client.evaluators

_EvaluatorsResource(http: _HttpTransport, project: ProjectResolver)

Project evaluators (server metrics). Custom LLM judges: config.kind="custom_judge".

Prefer opengrade.LlmJudge for judges: it creates/reuses the evaluator for you.

list

list(project_id: str | None = None) -> list[EvaluatorResponse]

create

create(project_id: str | None = None, *, name: str, type: str, config: dict[str, Any], version: int = 1) -> EvaluatorResponse

preview

preview(project_id: str | None = None, *, config: dict[str, Any], output: Any, input: Any = None, expected_output: Any = None, documents: list[dict[str, Any]] | None = None, metadata: dict[str, Any] | None = None) -> EvaluatorPreviewResponse

Run config on one sample without saving anything (calls the judge model).

client.alerts

_AlertsResource(http: _HttpTransport, project: ProjectResolver)

Server-side alert rules on production metrics (checked every minute by the server).

list

list(project_id: str | None = None) -> list[AlertRuleResponse]

create

create(project_id: str | None = None, *, name: str, metric: str, threshold: float, operator: str = 'gt', window_minutes: int = 60, min_samples: int | None = None, score_name: str | None = None, score_source: str | None = None, webhook_url: str | None = None, webhook_format: str = 'json', repeat_minutes: int | None = None, enabled: bool = True, environment: str | None = None, version: str | None = None, condition: str = 'threshold', baseline_minutes: int | None = None) -> AlertRuleResponse

metric: error_rate, latency_p50_ms/p90/p99, traffic, cost_usd, total_tokens, needs_review, score_mean or score_fail_rate (with score_name).

condition:

  • "threshold": the metric vs threshold.
  • "change" (drift): relative change vs the previous baseline_minutes (default: one window). threshold=-0.2, operator="lt" fires on a 20% drop.
  • "anomaly": z-score vs the past windows of the previous baseline_minutes (default: 24 windows). threshold=3, operator="abs" fires on a 3-sigma spike or drop.

operator: "gt", "lt" or "abs" (either direction; change/anomaly).

get

get(rule_id: str) -> AlertRuleResponse

update

update(rule_id: str, **fields: Any) -> AlertRuleResponse

Change the given fields; None clears score_name/score_source/webhook_url/ repeat_minutes.

delete

delete(rule_id: str) -> None

test

test(rule_id: str) -> AlertEventResponse

Send a test notification to the rule's webhook.

events

events(project_id: str | None = None, *, limit: int = 50) -> list[AlertEventResponse]

client.live_runs

_LiveRunsResource(http: _HttpTransport, project: ProjectResolver)

submit

submit(project_id: str | None = None, *, question: str, answer: str, documents: list[dict[str, Any]] | None = None, metadata: dict[str, Any] | None = None, external_id: str | None = None, metrics_set_id: str | None = None) -> LiveInteractionResponse

list

list(project_id: str | None = None, *, judge_status: str | None = None, search: str | None = None, failed_only: bool = False, since: str | None = None, until: str | None = None, metadata: list[str] | None = None, limit: int = 50, offset: int = 0) -> ListLiveInteractionsResponse

get

get(interaction_id: str) -> LiveInteractionResponse

promote

promote(interaction_id: str, *, dataset_id: str, expected_output: Any, expected_doc_ids: list[str] | None = None) -> DatasetItemResponse

rescore

rescore(interaction_id: str) -> LiveInteractionResponse

client.trace_scores

_TraceScoresResource(http: _HttpTransport, project: ProjectResolver)

log

log(project_id: str | None, scores: list[dict[str, Any]]) -> TraceScoresAccepted

Upsert scores on traces: {"trace_id", "name", "value"?, "label"?, "explanation"?, "threshold"?, "source"?, "author"?, "metadata"?} (max 500).

AsyncClient

AsyncClient(base_url: str | None = None, *, timeout: float = 30.0, transport: AsyncBaseTransport | None = None, api_key: str | None = None, project_id: str | None = None)

Async platform control-plane client (projects, live_runs, trace_scores).

api_key defaults to opengrade.set_api_key() / OPENGRADE_API_KEY.

base_url instance-attribute

base_url = resolved

projects instance-attribute

projects = _AsyncProjectsResource(self._http, self._project)

live_runs instance-attribute

live_runs = _AsyncLiveRunsResource(self._http, self._project)

trace_scores instance-attribute

trace_scores = _AsyncTraceScoresResource(self._http, self._project)

health async

health() -> HealthResponse

aclose async

aclose() -> None

AppConfigClient

AppConfigClient(http: _HttpTransport)

App config registry calls. Obtained via Client(...).app_configs / og.client.app_configs.

create_app_config

create_app_config(project_id: str, name: str, *, prompt: dict[str, Any] | None = None, model: dict[str, Any] | None = None, retrieval: dict[str, Any] | None = None, description: str | None = None) -> AppConfigResponse

list_app_configs

list_app_configs(project_id: str, *, name: str | None = None, latest: bool = False) -> list[AppConfigResponse]

set_alias

set_alias(project_id: str, alias: str, app_config_id: str) -> AppConfigAliasResponse

get_aliases

get_aliases(project_id: str) -> list[AppConfigAliasResponse]