[Jobs] Add --expose <port> option to expose job ports through the jobs proxy#4316
Conversation
Adds an `expose` boolean parameter to `run_job`, `run_uv_job`,
`create_scheduled_job`, `create_scheduled_uv_job` and a matching `--expose`
flag on the four `hf jobs (...) run` CLI commands. When set, the Jobs API
exposes every port the container listens on through the public jobs proxy.
The wire payload (`expose: { enabled: true }`) and the auth model (HF token
with read access to the job's namespace) are already supported on the
backend.
|
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. |
|
(to be updated once https://github.com/huggingface-internal/moon-landing/pull/18499 is merged -forward list of ports instead of boolean value) |
c359927 to
9395e77
Compare
9395e77 to
0e73a22
Compare
Backend now expects `expose: { ports: [u16] }` (was `{ enabled: bool }`).
- API: `expose: list[int] | None` on `run_job`, `run_uv_job`,
`create_scheduled_job`, `create_scheduled_uv_job`.
- Serialization: `expose=[8000, 8001]` -> `{"ports": [8000, 8001]}`.
- CLI: `--expose` is now repeatable (`--expose 8000 --expose 8001`),
not a boolean.
- Docstrings + CLI reference + parametrized test updated to cover
the new list/None shape.
0e73a22 to
5a2e804
Compare
|
Would be cool to match docker CLI syntac with We designed EDIT: ah I get that there is no notion of external port, since the URL is used instead, nvm |
Yeah originally thought the same as well but in the end |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort 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 7eee9d0. Configure here.
| job_spec["volumes"] = [vol.to_dict() for vol in volumes] | ||
| # expose ports through the jobs proxy | ||
| if expose: | ||
| job_spec["expose"] = {"ports": expose} |
There was a problem hiding this comment.
JobSpec drops expose on read
Medium Severity
_create_job_spec now sends expose in the job spec for scheduled jobs, but JobSpec never reads that field from API responses. After creating a scheduled job with --expose, inspect_scheduled_job / hf jobs scheduled inspect cannot surface the configured ports because the value is discarded during parsing.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7eee9d0. Configure here.
|
This PR has been shipped as part of the v1.19.0 release. |


Summary
Add a repeatable
--expose <port>flag on the four job-runner CLI commands and a matchingexpose: list[int] | Noneparameter on the Python API:HfApi.run_job(..., expose=None)/hf jobs run --expose 8000 --expose 8001 ...HfApi.run_uv_job(..., expose=None)/hf jobs uv run --expose 8000 ...HfApi.create_scheduled_job(..., expose=None)/hf jobs scheduled run --expose 8000 ...HfApi.create_scheduled_uv_job(..., expose=None)/hf jobs scheduled uv run --expose 8000 ...When set, the request payload includes
expose: { ports: [...] }, which tells the Jobs backend to register each port on the public jobs proxy. The job is then reachable athttps://<job_id>--<port>.hf.jobs. Access still requires an HF token with read access to the job's namespace.Example
Notes
None(omitexposefrom the payload). Pass a non-empty list to declare ports; an empty list is also accepted and serializes to{"ports": []}(same as no expose).test_serialize_exposecoversNone, empty list, single port, and multi-port.Note
Medium Risk
Exposes container ports on a public jobs domain (token-gated); changes job API payloads and
JobStatusshape, but behavior is opt-in and scoped to Jobs.Overview
Adds port exposure for Hugging Face Jobs so workloads can be reached through the jobs proxy instead of only via logs/SSH-style workflows.
The Python API gains an optional
expose: list[int]onrun_job,run_uv_job,create_scheduled_job, andcreate_scheduled_uv_job._create_job_specsendsexpose: { "ports": [...] }when the list is non-empty;Noneand[]leave the field out of the payload. Job responses now surfaceexpose_urlsonJobStatus(from APIexposeUrls), documented onJobInfo.The CLI adds a repeatable
--expose INTEGERonhf jobs run,hf jobs uv run,hf jobs scheduled run, andhf jobs scheduled uv run. After starting a job,run/uv runprint a hint with the public URLs and note that access needs an HF token with read access to the job namespace. CLI reference docs are updated for all four commands.Tests expect
expose=Noneon existing job CLI mocks and addtest_serialize_exposefor job spec serialization.Reviewed by Cursor Bugbot for commit 7eee9d0. Bugbot is set up for automated code reviews on this repo. Configure here.