[Spaces] Add fetch_space_logs + hf spaces logs command (#4091)
* [Spaces] Add fetch_space_logs + hf spaces logs command
Agents and scripts currently have no way to read Space build/run logs
programmatically — the endpoint is only reachable via raw curl. This
adds a public API to close that gap.
- HfApi.fetch_space_logs(repo_id, *, build=False, follow=False) yields
log lines as Iterable[str]. build=True switches to container build
logs; default is the running app's stdout/stderr.
- `hf spaces logs <repo_id> [--build] [-f] [-n N]` mirrors the Python
API at the CLI level, with 404/403 mapped to clean CLIError messages.
The helper trusts the "stream close = done" server contract (confirmed
against moon-landing's SpaceLogs.svelte onClose handler) and does not
poll SpaceStage; read timeout + bounded retries handle the
misbehaving-upstream case. Structure mirrors _fetch_running_job_sse but
without the status-check backstop. Tests use the mock-based pattern
from hf jobs logs (no new VCR cassettes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update generated CLI reference for hf spaces logs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: catch HfHubHTTPError instead of httpx.HTTPStatusError
hf_raise_for_status() raises HfHubHTTPError (inherits HTTPError), not
httpx.HTTPStatusError. The previous handler was dead code, causing
404/403 errors to fall through to the retry loop instead of raising
immediately. Spotted by cursor bugbot on PR review.
Note: the same bug exists in _fetch_running_job_sse — not fixed here
to keep the diff focused, but worth a follow-up.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update docs/source/en/guides/manage-spaces.md
Co-authored-by: Lucain <lucainp@gmail.com>
* Refactor: share SSE streaming loop between Spaces and Jobs
Extracts `HfApi._stream_sse_events` to unify the retry/backoff/dedup
loop previously duplicated across `_fetch_space_logs_sse` and
`_fetch_running_job_sse`. Addresses Wauplin and Cursor Bugbot review
comments on PR #4091.
Also fixes a dead `except httpx.HTTPStatusError` handler that affected
both Spaces and Jobs: `hf_raise_for_status` raises `HfHubHTTPError`
(subclass of `httpx.HTTPError`, not `HTTPStatusError`), so 404/403 in
follow mode used to fall through to the broad retry arm and stall for
~25s. The new helper catches `HfHubHTTPError` before the broad arm, so
permanent errors fail fast. Live-verified: `hf spaces logs missing/x -f`
now errors in <1s instead of ~25s.
CLI cleanups on `hf spaces logs` per Wauplin:
- Switch from `print()` to `out.text(line.strip())` (new mode-aware
printer from #3979).
- Drop the redundant local `HfHubHTTPError` block — it's already
handled by the global CLI error mapper.
Also tightens `_fetch_running_job_sse` typing by splitting the legacy
`double_check_job_has_finished_on_status_code_or_error` mixed tuple
into `tolerated_status_codes: tuple[int, ...]` and
`tolerated_exception_types: tuple[type[Exception], ...]`, eliminating a
runtime type-discrimination step.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Drop dead `httpx.ReadTimeout` entry from fetch_job_metrics
The entry in `tolerated_exception_types` was never consulted: the SSE
helper's `is_no_new_line_timeout` check short-circuits the tolerated
tuple lookup for any ReadTimeout, so the tuple entry was dead code
(pre-existing on `main` before #4091, preserved faithfully through the
refactor). ReadTimeout tolerance continues to work via the
`is_no_new_line_timeout` path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update src/huggingface_hub/cli/spaces.py
Co-authored-by: Lucain <lucainp@gmail.com>
* Update tests/test_cli.py
Co-authored-by: Lucain <lucainp@gmail.com>
* Update tests/test_cli.py
Co-authored-by: Lucain <lucainp@gmail.com>
* Address review feedback on fetch_space_logs
- Promote "Debug a failing Space" heading to ### (matches PR #4108 style)
- Add hint when run logs are empty, suggesting --build as alternative
- Add tests covering the empty-logs hint for both run and build modes
- Regenerate CLI reference docs to include hf spaces logs command
* Update tests/test_cli.py
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Lucain <lucainp@gmail.com>