Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to the [Nucleus Python Client](https://github.com/scaleapi/n
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.21.3](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.21.3) - 2026-08-25

### Added
- **`Model.model_runs()`.** Lists the ids of every model run for a model — the model-scoped counterpart to `Dataset.model_runs()`, which only lists a single dataset's runs. Pass `include_versions=True` to union runs across the model's version lineage (its version root and all descendants). Results are scoped server-side to runs on datasets you can read.

```python
run_ids = model.model_runs()
```

> **Server dependency:** requires the `GET /nucleus/model/:modelId/modelRun` route in scaleapi. Unit tests pass regardless; live calls 404 until that deploys.

## [0.21.2](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.21.2) - 2026-08-17

### Added
Expand Down
19 changes: 19 additions & 0 deletions nucleus/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,25 @@ def create_run(
run.add_predictions(predictions)
return run

def model_runs(self, include_versions: bool = False) -> List[str]:
"""List the ids of every model run for this model. ::

run_ids = model.model_runs()

Args:
include_versions: Also include runs from other versions in this
model's lineage — its version root and all descendants. Defaults
to False, returning only runs whose ``model_id`` is this model.

Returns:
The model run ids (``run_*``). Scoped server-side to runs on datasets
you can read, so a run on a dataset you can't access is omitted.
"""
route = f"model/{self.id}/modelRun"
if include_versions:
route += "?family=true"
return self._client.make_request({}, route, requests.get)

def evaluate(self, scenario_test_names: List[str]) -> AsyncJob:
"""Evaluates this on the specified Unit Tests. ::

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ignore = ["E501", "E741", "E731", "F401"] # Easy ignore for getting it running

[tool.poetry]
name = "scale-nucleus"
version = "0.21.2"
version = "0.21.3"
description = "The official Python client library for Nucleus, the Data Platform for AI"
license = "MIT"
authors = ["Scale AI Nucleus Team <nucleusapi@scaleapi.com>"]
Expand Down
40 changes: 40 additions & 0 deletions tests/test_model_runs_listing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from unittest.mock import MagicMock

import requests

from nucleus import Model


def _model_with_client():
client = MagicMock()
model = Model(
model_id="prj_123",
name="my-model",
reference_id="my-ref",
metadata=None,
client=client,
)
return model, client


def test_model_runs_returns_ids_and_hits_the_route():
model, client = _model_with_client()
client.make_request.return_value = ["run_a", "run_b"]

result = model.model_runs()

assert result == ["run_a", "run_b"]
payload, route, requests_command = client.make_request.call_args.args
assert payload == {}
assert route == "model/prj_123/modelRun"
assert requests_command is requests.get


def test_model_runs_include_versions_appends_family_query():
model, client = _model_with_client()
client.make_request.return_value = []

model.model_runs(include_versions=True)

_, route, _ = client.make_request.call_args.args
assert route == "model/prj_123/modelRun?family=true"