[CLI] Surface job runtime fields in ps + inspect#4211
Conversation
Adds startedAt, finishedAt, and durations (schedulingSecs/runningSecs/totalSecs) to JobInfo, surfaces them in `hf jobs inspect`, and adds a DURATION column to `hf jobs ps`. The server-side change that exposes these fields in the jobs API response shipped recently; this is the CLI counterpart. Also adds a small `format_duration` helper to utils/_parsing.py (sibling of existing format_timesince) so the formatting logic stays reusable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
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. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4211 +/- ##
==========================================
+ Coverage 75.00% 77.38% +2.37%
==========================================
Files 145 171 +26
Lines 13978 19608 +5630
==========================================
+ Hits 10484 15173 +4689
- Misses 3494 4435 +941 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Matches the existing pattern for nested job dataclasses (JobOwner, JobStatus) which are re-exported from huggingface_hub.__init__, so users can type-annotate `job.durations` without reaching into the private _jobs_api module. Also brings the JobInfo docstring example up to date with the new started_at, finished_at, and durations fields. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 08a6f4b. Configure here.
`kwargs.get(camel) or kwargs.get(snake)` collapses a legitimate `0` to `None` because `0` is falsy. Switch to `dict.get(camel, dict.get(snake))` so the fallback fires only when the camelCase key is missing. Defensive: the server-side API doesn't emit `0` in practice (observed minimum is ~4s of container scheduling overhead). Flagged by Cursor Bugbot review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligns with `docker ps` / `kubectl get pods` conventions where DURATION means actual runtime. SCHEDULING jobs now show `--` instead of queue wait time, removing the surprising behaviour previously called out in the PR description. Per review feedback from @lhoestq. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per review feedback from @hanouticelina: - Rename the `hf jobs ps` column DURATION→RUNTIME so the header matches what the value shows (`running_secs`). - Rewrite the JobDurations / JobInfo.durations docstrings. The previous "`None` while the Job is still scheduling" framing was wrong: per the server-side rule in `compute_job_durations`, SCHEDULING returns `Some({totalSecs})` and `durations` is `None` only for some terminal jobs missing a `finished_at` timestamp. - Rename the partial-durations test to use the real `{totalSecs}` only shape (not the keys-present-with-null fixture, which never appears in production), and align the runtime-fields-default-none test fixture stage with its docstring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Updated PR description to reflect post-review state:
|
hanouticelina
left a comment
There was a problem hiding this comment.
Thank you, looks good to me 👍 ok to merge when the comment and merge conflicts are addressed!
Resolve JobInfo conflict from huggingface#4212 (initiator) by keeping both the runtime fields (started_at/finished_at/durations + JobDurations) and the new initiator field/dataclass. Add JobStage.SCHEDULING (+ docstring) per review — fixtures rely on it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This PR has been shipped as part of the v1.16.0 release. |

Not blocked by the upcoming
cli/jobs.pyout.*migration; this could land firstsince it's purely additive (new fields + new column).
Summary
Surfaces job runtime fields (
startedAt,finishedAt,durations) inhf jobs psandhf jobs inspect. The server-side change that exposes thesefields in the jobs API response landed recently; this is the CLI counterpart.
_jobs_api.py: newJobDurationsdataclass; three new fields onJobInfo__init__.py: re-exportJobDurationsalongside the existing job dataclassescli/jobs.py: newRUNTIMEcolumn inps(showsrunning_secs);inspectauto-surfaces viaasdictutils/_parsing.py: newformat_durationhelper (sibling offormat_timesince)format_durationunit testsTest plan
format_durationunit tests across all branches🤖 Generated with Claude Code
Note
Medium Risk
Mostly additive, but extends the public Jobs API surface (
JobStageenum andJobInfofields) which could affect downstream code that assumes a fixed set of stages/fields or relies on dataclass serialization.Overview
Surfaces server-provided job runtime metadata end-to-end by extending
JobInfowithstarted_at,finished_at, anddurations(newJobDurationsdataclass) and adding theSCHEDULINGstage toJobStage.Updates
hf jobs psto include a RUNTIME column derived fromdurations.running_secsusing a newformat_durationhelper, and re-exportsJobDurationsfromhuggingface_hub.__init__. Adds parsing/unit tests to cover full/partial/absent duration payloads and CLI table rendering.Reviewed by Cursor Bugbot for commit f0644af. Bugbot is set up for automated code reviews on this repo. Configure here.