Skip to content

Support setting Label in Jobs API - #3719

Merged
Wauplin merged 9 commits into
mainfrom
cursor/jobs-api-update-b92d
Jan 26, 2026
Merged

Wauplin merged 9 commits into
mainfrom
cursor/jobs-api-update-b92d

Conversation

@Wauplin

@Wauplin Wauplin commented Jan 23, 2026

Copy link
Copy Markdown
Collaborator

Update the jobs API to support labels, matching the implementation in the JS client (huggingface/huggingface.js#1926).


Slack Thread

Open in Cursor Open in Web

cursoragent and others added 3 commits January 23, 2026 09:37
- Add labels field to JobInfo and JobSpec dataclasses
- Update _create_job_spec function to handle labels parameter
- Add labels parameter to run_job and create_scheduled_job methods
- Add CLI support for --label/-l flag in jobs run and scheduled run commands
- Labels are passed as key-value pairs (e.g., --label KEY=VALUE)

This matches the implementation in huggingface.js PR #1926

Co-authored-by: lucain <lucain@huggingface.co>
- Add labels parameter to run_uv_job and create_scheduled_uv_job
- Add CLI support for labels in uv run and scheduled uv run commands
- Update docstrings to document labels parameter

Co-authored-by: lucain <lucain@huggingface.co>
- Add labels=None to all job-related test assertions
- Update run_job, run_uv_job, and create_scheduled_job test expectations

Co-authored-by: lucain <lucain@huggingface.co>
@cursor

cursor Bot commented Jan 23, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

Update CLI reference to document the new --label/-l flag for:
- jobs run
- jobs uv run
- jobs scheduled run
- jobs scheduled uv run

Co-authored-by: lucain <lucain@huggingface.co>
@Wauplin

Wauplin commented Jan 23, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor can you factorize the logic labels => labels_map that is duplicated 3 times in the CLI ?

@cursor

cursor Bot commented Jan 23, 2026

Copy link
Copy Markdown

Done! I've successfully refactored the duplicated label parsing logic. Here's what I did:

Refactoring Summary

Created a helper function _parse_labels_map() in the UTILS section of jobs.py that:
• Takes an optional list of label strings in KEY=VALUE format
• Parses them into a dictionary
• Validates the format and raises ValueError if invalid
• Includes proper documentation

Replaced 4 instances of duplicated code (9 lines each) across:

  1. jobs_run
  2. jobs_uv_run
  3. scheduled_run
  4. scheduled_uv_run

Result:
• Reduced code by 36 lines overall
• Single source of truth for label parsing logic
• Easier to maintain and test
• More DRY (Don't Repeat Yourself)

The refactoring maintains the exact same functionality while making the codebase cleaner and more maintainable.

Open in Cursor Open in Web

Create _parse_labels_map() helper function to eliminate code duplication.
The label parsing logic was duplicated 4 times across:
- jobs_run
- jobs_uv_run
- scheduled_run
- scheduled_uv_run

This refactoring makes the code more maintainable and DRY.

Co-authored-by: lucain <lucain@huggingface.co>
@Wauplin

Wauplin commented Jan 23, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor update signature to def _parse_labels_map(labels: Optional[list[str]]) -> Optional[dict[str, str]]: so you can directly do labels=_parse_labels_map(label) without "if labels_map is not None"

- Update _parse_labels_map to return Optional[dict[str, str]]
- Return None when no labels provided (instead of empty dict)
- Inline function calls: use labels=_parse_labels_map(label) directly
- Remove unnecessary 'if labels_map else None' checks
- Fix trailing whitespace in docstring (ruff W293)

This makes the code cleaner and more Pythonic as suggested by @Wauplin.

Co-authored-by: lucain <lucain@huggingface.co>

@Wauplin Wauplin left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

✔️

@Wauplin
Wauplin marked this pull request as ready for review January 23, 2026 09:55
@bot-ci-comment

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@lhoestq lhoestq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great ! I added a change to match Docker and allow --label LABEL without value (it defaults to value with empty string "")

I suggested the same thing in the huggingface.js PR

Comment thread src/huggingface_hub/cli/jobs.py Outdated
Comment thread src/huggingface_hub/cli/jobs.py Outdated
Comment thread src/huggingface_hub/cli/jobs.py Outdated
@lhoestq

lhoestq commented Jan 23, 2026

Copy link
Copy Markdown
Member

I also opened #3721 with basic docs on usage of --label and labels=

lhoestq and others added 2 commits January 26, 2026 16:22
* Add job labeling instructions to CLI guide

Added documentation for labeling jobs in CLI.

* Document Labels for Jobs in guides

Added documentation for Labels in jobs, including examples.
Co-authored-by: Quentin Lhoest <42851186+lhoestq@users.noreply.github.com>
@Wauplin

Wauplin commented Jan 26, 2026

Copy link
Copy Markdown
Collaborator Author

I added a change to match Docker and allow --label LABEL without value (it defaults to value with empty string "")

Makes perfect sense yes! I've merged your suggestions.

I've also merged you docs update (#3721). Thanks!

@Wauplin Wauplin changed the title Jobs API update Support setting Label in Jobs API Jan 26, 2026
@Wauplin
Wauplin merged commit d712a13 into main Jan 26, 2026
17 of 20 checks passed
@Wauplin
Wauplin deleted the cursor/jobs-api-update-b92d branch January 26, 2026 15:34
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.

3 participants