Skip to content

Add dataset tags to SDK for identification (DE-7033) - #456

Merged
vinay553 merged 1 commit into
masterfrom
vinayparakala/de-7033-add-dataset-tags-to-sdk
May 8, 2026
Merged

Add dataset tags to SDK for identification (DE-7033)#456
vinay553 merged 1 commit into
masterfrom
vinayparakala/de-7033-add-dataset-tags-to-sdk

Conversation

@vinay553

@vinay553 vinay553 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add tags field to DatasetInfo model so dataset.info() returns dataset tags
  • Add get_tags(), add_tags(), remove_tags() methods to Dataset class for programmatic tag management
  • Enables customers (e.g. Redwoods) to identify via API whether a dataset was labeled by Scale or another vendor

Test plan

  • Verify dataset.info() returns tags for a dataset with tags set in the UI
  • Verify dataset.add_tags(["Labeled by: Scale"]) adds tags
  • Verify dataset.get_tags() returns the current tag list
  • Verify dataset.remove_tags(["Labeled by: Scale"]) removes tags
  • Verify backward compatibility — dataset.info() works against a server that doesn't yet return tags (defaults to [])

🤖 Generated with Claude Code

Greptile Summary

  • Adds tags field to DatasetInfo (with a null-coercing validator for backward compatibility) and three new Dataset methods — get_tags(), add_tags(), and remove_tags() — that delegate to a new /dataset/{id}/tags endpoint.
  • remove_tags uses HTTP DELETE with a JSON body, which works with the current make_request plumbing but may be silently stripped by some intermediary infrastructure.
  • The coerce_null_tags Pydantic validator is missing the @classmethod decorator, relying on a pylint: disable comment instead of following the recommended v1 style.

Confidence Score: 5/5

Safe to merge — no P0 or P1 issues; only P2 style suggestions.

The change is well-scoped, backward-compatible (null-coercing validator + field default), and consistent with existing codebase patterns. Both findings are P2: a missing @classmethod decorator on the validator and a note about DELETE-with-body infrastructure risk. Neither blocks correctness.

No files require special attention; nucleus/dataset.py and dataset_info.py are the only changed files worth reviewing closely.

Important Files Changed

Filename Overview
nucleus/data_transfer_object/dataset_info.py Adds tags: List[str] = [] field with a null-coercing validator for backward compatibility; validator is missing @classmethod decorator.
nucleus/dataset.py Adds get_tags(), add_tags(), and remove_tags() methods; consistent with existing make_request patterns; remove_tags uses HTTP DELETE with a JSON body.
tests/test_dataset.py Adds test_dataset_tags covering happy path, idempotency, and type-safety guard; comprehensive coverage of the new API surface.
CHANGELOG.md Adds 0.18.2 changelog entry describing the new dataset tags feature.
pyproject.toml Bumps version from 0.18.1 to 0.18.2.

Sequence Diagram

sequenceDiagram
    participant User
    participant Dataset
    participant NucleusClient
    participant API

    User->>Dataset: dataset.info()
    Dataset->>NucleusClient: "make_request({}, dataset/{id}/info, GET)"
    NucleusClient->>API: "GET /dataset/{id}/info"
    API-->>NucleusClient: "{tags: [...], ...}"
    NucleusClient-->>Dataset: response dict
    Dataset-->>User: "DatasetInfo(tags=[...])"

    User->>Dataset: dataset.get_tags()
    Dataset->>NucleusClient: "make_request({}, dataset/{id}/tags, GET)"
    NucleusClient->>API: "GET /dataset/{id}/tags"
    API-->>NucleusClient: "{tags: [...]}"
    NucleusClient-->>Dataset: response[tags]
    Dataset-->>User: List[str]

    User->>Dataset: dataset.add_tags([Labeled by Scale])
    Dataset->>NucleusClient: "make_request({tags:[...]}, dataset/{id}/tags, POST)"
    NucleusClient->>API: "POST /dataset/{id}/tags"
    API-->>NucleusClient: "{tags: [...]}"
    NucleusClient-->>Dataset: response[tags]
    Dataset-->>User: List[str]

    User->>Dataset: dataset.remove_tags([Labeled by Scale])
    Dataset->>NucleusClient: "make_request({tags:[...]}, dataset/{id}/tags, DELETE)"
    NucleusClient->>API: "DELETE /dataset/{id}/tags body:{tags:[...]}"
    API-->>NucleusClient: "{tags: [...]}"
    NucleusClient-->>Dataset: response[tags]
    Dataset-->>User: List[str]
Loading

Fix All in Cursor Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
nucleus/data_transfer_object/dataset_info.py:38-39
Pydantic v1's `@validator` is a classmethod under the hood, but the recommended practice (and what mypy expects) is to also apply `@classmethod` explicitly. Without it, type checkers may infer `cls` as the first argument type incorrectly, and the `# pylint: disable=no-self-argument` suppression is papering over the real fix.

```suggestion
    @validator("tags", pre=True, always=True)  # pylint: disable=used-before-assignment
    @classmethod
    def coerce_null_tags(cls, v):
```

### Issue 2 of 2
nucleus/dataset.py:474-477
`remove_tags` passes a request body via `requests.delete`. The `requests` library supports this, and `make_request` correctly forwards it as `json=payload`. However, some HTTP intermediaries (proxies, load balancers, AWS API Gateway) silently strip bodies from DELETE requests, which would cause the server to receive an empty `tags` list and could delete all tags instead of just the specified ones. If the backend supports a query-parameter approach or a dedicated `DELETE /dataset/{id}/tags/{tag}` sub-resource route, that would be more reliable across infrastructure.

Reviews (9): Last reviewed commit: "Add dataset tags to SDK for identificati..." | Re-trigger Greptile

@vinay553
vinay553 force-pushed the vinayparakala/de-7033-add-dataset-tags-to-sdk branch 2 times, most recently from 3eff859 to 8f06f7a Compare April 6, 2026 21:52
@vinay553
vinay553 requested a review from a team April 6, 2026 21:56
@vinay553
vinay553 force-pushed the vinayparakala/de-7033-add-dataset-tags-to-sdk branch from 8f06f7a to bf092a2 Compare April 6, 2026 21:57

@edwinpav edwinpav left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some unit/integration tests that call this on the datasets used by the tests?

@vinay553
vinay553 force-pushed the vinayparakala/de-7033-add-dataset-tags-to-sdk branch from bf092a2 to ccb48bc Compare April 8, 2026 21:42
@vinay553
vinay553 force-pushed the vinayparakala/de-7033-add-dataset-tags-to-sdk branch from ccb48bc to 9561851 Compare May 8, 2026 15:48
Expose dataset tags through the Python SDK so customers can identify
datasets labeled by Scale vs other vendors via the API.

- Add `tags` field to DatasetInfo model (returned by dataset.info())
- Add get_tags(), add_tags(), remove_tags() methods to Dataset class
- Use POST /tags/remove instead of DELETE to avoid proxy body-stripping
- Use pydantic v1/v2 compat shim for null-coercion validator
- Guard against passing a bare string instead of a list

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vinay553
vinay553 force-pushed the vinayparakala/de-7033-add-dataset-tags-to-sdk branch from 9561851 to ce37cc4 Compare May 8, 2026 16:00
@vinay553
vinay553 merged commit 5c4b847 into master May 8, 2026
7 of 8 checks passed
@vinay553
vinay553 deleted the vinayparakala/de-7033-add-dataset-tags-to-sdk branch May 8, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants