update sdk with new adds - #467
Open
luke-e-schaefer wants to merge 13 commits into
Open
Conversation
Benchmark-paradigm parity with the EvaluationV2 UI: - Benchmark resource + client CRUD (create from item_ids/items/slice/dataset, list, get, update, delete, paginated items) - create_benchmark_evaluation_v2 (uncovered items score as FN; label config via rollup_groups / legacy matches / preset) - RollupGroup as the primary label configuration, wired through presets - EvaluationV2 exposes benchmark_id + rollup_groups - Benchmark leaderboard_ranking / leaderboard_f1_curve and evaluation filter_schema (require the scaleapi REST mirrors to be deployed) - v0.19.0 + changelog Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pre-existing W0718 on the batch-create per-job catch made pylint exit nonzero. Use disable-next on its own line so black's 79-char wrap can't displace the pragma. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The platform moved to the benchmark paradigm; dataset/slice-scoped eval creation never shipped. Removes create_evaluation_v2, create_evaluations_v2_batch, BatchEvaluationResult, and only_items_with_predictions from the SDK surface, and consolidates the unreleased 0.18.9 changelog section into the single 0.19.0 entry. Reading old evals (slice_id, exclusion fields) still works. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Same pass as the weights branch: the docstrings are published API docs, so they shouldn't explain how the platform stores or validates things. - `evaluation_v2_exclusions`: dropped the reference to the server-side validator by name (`parseEvaluationV2ExclusionRulesWithDiagnostics`) — a TypeScript function name has no business in the Python docs — and said what a caller can actually observe: invalid rules are reported with a reason instead of silently excluding nothing. - `_parse_json_field`: no longer describes JSONB columns, raw DB rows, or driver behaviour; it just normalizes a field that may arrive as a string. - `_parse_allowed_label_matches` / `_parse_rollup_groups`: made private and reworded off "the shapes the backend may return". They had public names, so autoapi would have published these internal parsers regardless of wording. - Reworded the leftover storage vocabulary in user-visible text: "row offset" → "offset", "one row of a ranking" → "one entry", "match rows" → "results". - CHANGELOG: "requires a scaleapi server with the REST leaderboard endpoints deployed" → "requires a Nucleus deployment with leaderboard support". The constraint is real and worth keeping; the internals aren't. pylint 10.00/10, mypy clean, ruff/black/isort clean, 59 tests passing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 28, 2026
jaypsiri
reviewed
Aug 6, 2026
Master's #468 (DE-8304) made uploads async-only and deleted nucleus/upload_response.py; this branch predated it, so every test fixture that appended items failed at the old sync-upload assertion. Resolve the CHANGELOG collision (both sides claimed 0.19.0) by releasing this feature set as 0.19.1 and bump pyproject.toml to match. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ey constants
- evaluation_v2_exclusions: ExclusionScope / ExclusionTarget / MetadataOp are
now Literal unions instead of bare str aliases, so the valid values are
checked rather than only documented in a comment. StrEnum is unavailable
here (the package supports Python 3.10).
- dataset.evaluation_label_schema: use the existing NucleusClient.get()
wrapper instead of a raw make_request(..., requests.get).
- constants: add the Evaluation V2 / benchmark / preset / leaderboard payload
keys and reference them from the new from_json / to_api_dict / request
builders, per CLAUDE.md ('All API payload keys are constants here').
Where the backend takes camelCase on request but returns snake_case, both
spellings get a constant (_CAMEL_ infix).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
evaluation_label_schema() now routes through NucleusClient.get(), which passes requests_command by keyword, so the test's positional args[2] lookup raised IndexError. Assert on call.kwargs instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Consistency pass over the new Evaluation V2 / benchmark surface: - create_benchmark_evaluation_v2 used a bare make_request for what is a plain POST; it now uses self.post() like every other new call site, and reads the response id via EVALUATION_ID_KEY. - Tests for wrapper-routed calls now all use the same idiom the rest of the file uses: mock client.connection.<verb>, then unpack (payload, route) from call_args[0]. This replaces the one-off kwargs assertion added for the label-schema test. - Drop _stub_create and the empty 'Batch create' header, dead since the batch-create surface was removed from this branch. The four remaining make_request calls (delete_evaluation_v2_preset, delete_benchmark, EvaluationV2.delete / .cancel) stay as they are: they all pass return_raw_response=True, which the Connection wrappers cannot express. Their tests keep the positional-args idiom, matching the call they assert on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary — v0.19.0: EvaluationV2, benchmark paradigm
Brings the SDK to parity with the Nucleus EvaluationV2 UI. Evaluation creation is benchmark-scoped only — dataset/slice-scoped creation (an unreleased earlier iteration of this branch) was removed before release as the platform moved to the benchmark paradigm.
Added
create_benchmark()(members fromitem_ids,(dataset_id, ref_id)itemspairs, aslice_id, or adataset_id— exactly one required; membership frozen at creation),list_benchmarks(),get_benchmark(),update_benchmark(),delete_benchmark(),list_benchmark_items(), plus theBenchmarkresource (refresh()/update()/delete()/items()/create_evaluation_v2()) innucleus/benchmark.py.create_benchmark_evaluation_v2(benchmark_id, model_run_id, ...)— every benchmark item is scored (uncovered items count as FN, keeping leaderboard scores comparable).EvaluationV2exposesbenchmark_id,rollup_groups,exclusion_rules,exclusion_stats. Noonly_items_with_predictions/ eval-scopeslice_id(invalid in the benchmark paradigm; the server rejects the former).RollupGroup(class_name+labels) as the primary label configuration on benchmark eval create and presets (create/update_evaluation_v2_preset(rollup_groups=...), mutually exclusive with legacyallowed_label_matches; parsed from both key casings). Preset seeding prefersrollup_groups, falling back to legacy matches.MetadataExclusionRule/LabelExclusionRule/BoxAreaExclusionRuleviaexclusion_ruleson eval create and presets.list/create/update/delete_evaluation_v2_preset+EvaluationV2Presetresource;preset=seeds benchmark eval creation (explicit args override).EvaluationV2.charts()(mAP, per-class AP, confusion matrix, PR/F1 curves, TIDE, AP by size) andexamples()(paginated TP/FP/FN;match_typeoptional) withEvaluationV2FilterArgsfiltering;cancel()/retry();Dataset.evaluation_label_schema().leaderboard_ranking(metric_type, benchmark_ids, ...)(metrics:MAP_50,MAP_50_95,AP_SMALL/MEDIUM/LARGE,PRECISION,RECALL,F1;scope/collapse) andleaderboard_f1_curve(benchmark_ids, ..., top_n=5).EvaluationV2.filter_schema()/get_evaluation_v2_filter_schema()return the evaluation's filter vocabulary (gt_labels,pred_labels,metadata_fieldswith inferred value types).EvaluationV2FilterSchema,LeaderboardRankingEntry,LeaderboardF1CurveEntry,BenchmarkItemsPage.Removed (relative to earlier commits on this branch — never released)
create_evaluation_v2(dataset/slice-scoped),create_evaluations_v2_batch,BatchEvaluationResult,only_items_with_predictions. Reading existing evals (including old slice-scoped ones) still works.Fixed
build_testpylint failure (pre-existingW0718on the per-job catch) — suppressed with a black-stable# pylint: disable-nextline.Tests / Version
tests/test_benchmarks.py,tests/test_leaderboard.py, plus rollup/benchmark coverage in the eval/preset test files (59 unit tests, mock-based).pyproject.toml→ 0.19.0; single consolidated CHANGELOG entry (the unreleased 0.18.9 section was folded in).resolves https://linear.app/scale-epd/issue/DE-8209
Greptile Summary
This PR brings the Python SDK to parity with the Nucleus EvaluationV2 UI under a benchmark paradigm: benchmarks are frozen ground-truth item sets that model runs are evaluated against, enabling comparable leaderboard scores across runs.
nucleus/benchmark.py,NucleusClient): full CRUD (create_benchmark,list_benchmarks,get_benchmark,update_benchmark,delete_benchmark,list_benchmark_items) plus aBenchmarkresource object withrefresh/update/delete/items/create_evaluation_v2.create_benchmark_evaluation_v2): supportsrollup_groups(new primary label config), legacyallowed_label_matches*, exclusion rules, and preset seeding; addscancel,retry,filter_schematoEvaluationV2; migratescharts()from GET to POST.evaluation_v2_preset.py,evaluation_v2_exclusions.py): newEvaluationV2Presetwith per-user CRUD;MetadataExclusionRule,LabelExclusionRule,BoxAreaExclusionRule;leaderboard_rankingandleaderboard_f1_curveclient methods backed by new server endpoints.Confidence Score: 5/5
charts()GET→POST migration matches the server's new requirement.BoxAreaExclusionRuleguard,update_benchmarkunable to clear optional fields, inconsistent key constants). None affect correctness of the live happy-path flows. The core benchmark CRUD, evaluation create, leaderboard, and preset flows are logically correct and covered by tests.allowed_label_matchesfallback withor) and nucleus/evaluation_v2_exclusions.py (BoxAreaExclusionRulemissing bound guard) are worth a second look before the next SDK release, but neither blocks this one.Important Files Changed
Benchmarkdataclass withfrom_json,refresh,update,delete,items, andcreate_evaluation_v2instance methods that delegate toNucleusClient; no logic issues found.RollupGroup,_parse_rollup_groups,_parse_allowed_label_matches,_parse_json_fieldhelpers; extendsEvaluationV2withbenchmark_id,rollup_groups,exclusion_rules,exclusion_stats; addscancel,retry,filter_schema; migrateschartsfrom GET+QS to POST; makesmatch_typeoptional inexamples. Logic is sound.MetadataExclusionRule,LabelExclusionRule,BoxAreaExclusionRule.BoxAreaExclusionRulelacks the client-side guard its docstring implies ("at least one bound required"), so an empty rule reaches the server before failing.EvaluationV2Presetdataclass withfrom_json,update,delete; handles both camelCase/snake_case response keys and JSON-encoded fields.allowed_label_matchesfallback usesorrather than an explicitis not Nonecheck, which incorrectly treats an empty list as absent.update_benchmarkcannot clear optional fields (None-guard silently no-ops);create_benchmark_evaluation_v2uses inline string literals for legacy label-match keys where constants exist.EvaluationV2FilterSchema,LeaderboardRankingEntry,LeaderboardF1CurveEntry,BenchmarkItemsPage; extends filter args withgt_area_rangeandslice_ids. Required fields on schema models look correct.Sequence Diagram
sequenceDiagram participant User participant NucleusClient participant API User->>NucleusClient: "create_benchmark(name, slice_id=...)" NucleusClient->>API: POST /benchmarks API-->>NucleusClient: "{benchmark_id, ...}" NucleusClient-->>User: Benchmark User->>NucleusClient: "create_benchmark_evaluation_v2(benchmark_id, model_run_id, rollup_groups=..., preset=...)" Note over NucleusClient: Seed from preset if no explicit label config NucleusClient->>API: "POST /benchmarks/{id}/evaluationsV2" API-->>NucleusClient: "{evaluation_id}" NucleusClient->>API: "GET /evaluationsV2/{evaluation_id}" API-->>NucleusClient: EvaluationV2 payload NucleusClient-->>User: EvaluationV2 User->>NucleusClient: evaluation.wait_for_completion() loop Poll status NucleusClient->>API: "GET /evaluationsV2/{id}" API-->>NucleusClient: status end User->>NucleusClient: "evaluation.charts(iou_threshold=0.5)" NucleusClient->>API: "POST /evaluationsV2/{id}/charts" API-->>NucleusClient: EvaluationV2Charts User->>NucleusClient: leaderboard_ranking(metric_type, benchmark_ids) NucleusClient->>API: POST /leaderboard/ranking API-->>NucleusClient: List[LeaderboardRankingEntry] NucleusClient-->>User: ranked entriesReviews (10): Last reviewed commit: "Route benchmark eval create through the ..." | Re-trigger Greptile