Move artifact and dataset reads onto the results reader - #49
Conversation
The four artifact routes joined the results root by hand, so a bad `output_fragment` or `ExecutionOutput.filename` could resolve outside it. They now go through `Reader.artifacts`, which guards containment. A `resolve_artifact` helper turns a containment failure into a 404 so the resolved path is never reported back.
Replaces the hand-rolled walk over `Dataset.__subclasses__()` with `DatasetFilter` and `select_datasets`, the query builder that backs `reader.datasets`. Fetching by slug now goes through `reader.datasets.get`. This changes three behaviours: - Only the latest version of each dataset is listed, so superseded versions no longer show up as duplicates. - Fetching by slug returns the latest version rather than failing when several versions share a slug. - An unknown `dataset_type` or facet key returns a 400 instead of being silently ignored. `name_contains` stays as a `slug ilike` on the built statement, because `DatasetFilter` has no slug axis and filtering in Python would break pagination and `total_count`.
✅ Deploy Preview for climate-ref canceled.
|
|
Warning Review limit reached
Next review available in: 101 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughDataset routes now use shared dataset queries and latest-version views. Execution and result routes resolve artifact paths through reader configuration, with invalid paths returning HTTP 404. ChangesDataset API
Execution artifact paths
Sequence Diagram(s)sequenceDiagram
participant DatasetRoute
participant SourceAdapter
participant select_datasets
participant Dataset
DatasetRoute->>SourceAdapter: select latest dataset versions
SourceAdapter->>select_datasets: build filtered query
select_datasets-->>DatasetRoute: paginated dataset views
DatasetRoute->>Dataset: build_from_view
Dataset-->>DatasetRoute: API dataset response
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8cd21b5b-0695-4be5-8a4d-63972c3ff7fa
📒 Files selected for processing (8)
backend/src/ref_backend/api/routes/datasets.pybackend/src/ref_backend/api/routes/executions.pybackend/src/ref_backend/api/routes/results.pybackend/src/ref_backend/core/file_handling.pybackend/src/ref_backend/models/datasets.pybackend/tests/test_api/test_routes/test_datasets.pychangelog/48.fix.mdchangelog/48.improvement.md
The route filters with `slug ilike '%name_contains%'`, so another dataset whose slug contains the selected one is a valid result. Assert containment rather than an exact single-item list.
Moves two areas of the API off hand-rolled queries and onto the
climate_refresults reader.Artifact paths
Four routes joined the results root by hand, so a bad
output_fragmentorExecutionOutput.filenamecould resolve to a path outside it. They now go throughReader.artifacts, which does the join with a containment check.GET /executions/{group_id}/logsGET /executions/{group_id}/metric_bundleGET /executions/{group_id}/archiveGET /results/{result_id}A
resolve_artifacthelper turns a containment failure into a 404, so the resolved path is never reported back to the caller.Dataset listing
The list endpoint walked
Dataset.__subclasses__()to find the concrete type for facet filtering. That is nowDatasetFilterplusselect_datasets, the query builder that also backsreader.datasetsandadapter.load_catalog. Fetching by slug goes throughreader.datasets.get.Three behaviours change:
dataset_typeor an unknown facet key returns a 400 instead of being silently ignored.name_containsstays as aslug ilikeapplied to the built statement.DatasetFilterhas no slug axis, and filtering in Python would break pagination andtotal_count. Worth raising upstream.Not included
reader.executionsis still blocked on three upstream gaps: noidonOutputView, nodataset_count, and Python-side pagination. Those are better filed as climate-ref issues than worked around here.Testing
Four new tests cover the unknown dataset type, the unknown facet, facet filtering and
name_contains. Full backend suite passes, along with ruff and mypy. The frontend pre-commit hooks fail on this branch and on a cleanmainalike, so they are untouched by this change.Summary by CodeRabbit
New Features
Bug Fixes
Tests