Skip to content

[CLI] Add spaces lifecycle commands: pause, restart, sleep#4155

Merged
hanouticelina merged 12 commits intomainfrom
cli-spaces-lifecycle
Apr 28, 2026
Merged

[CLI] Add spaces lifecycle commands: pause, restart, sleep#4155
hanouticelina merged 12 commits intomainfrom
cli-spaces-lifecycle

Conversation

@davanstrien
Copy link
Copy Markdown
Member

@davanstrien davanstrien commented Apr 27, 2026

Summary

Wraps three existing HfApi methods so Spaces lifecycle is controllable from the CLI:

  • hf spaces pause <id>pause_space
  • hf spaces restart <id> [--factory-reboot]restart_space
  • hf spaces sleep <id> --seconds Nset_space_sleep_time

CLI examples

$ hf spaces pause --help
Usage: hf spaces pause [OPTIONS] SPACE_ID

  Pause a Space.

Arguments:
  SPACE_ID  The space ID (e.g. `username/repo-name`).  [required]

Options:
  -y, --yes                       Answer Yes to prompt automatically.
  --format [agent|auto|human|json|quiet]
                                  Output format.  [default: auto]
  --token TEXT                    A User Access Token generated from
                                  https://huggingface.co/settings/tokens.
  -h, --help                      Show this message and exit.

Examples
  $ hf spaces pause username/my-space
  $ hf spaces pause username/my-space --yes

hf spaces restart --help and hf spaces sleep --help follow the same shape (with --factory-reboot and --seconds respectively).

Tests pass:

$ pytest tests/test_cli.py -k TestSpacesLifecycleCommands
tests/test_cli.py::TestSpacesLifecycleCommands::test_pause PASSED
tests/test_cli.py::TestSpacesLifecycleCommands::test_restart_factory_reboot PASSED
tests/test_cli.py::TestSpacesLifecycleCommands::test_sleep PASSED
3 passed in 0.40s

Live smoke test against a real Space pending — will add output before un-drafting.

Discussion point: confirmation prompts

pause and restart ship with an out.confirm() prompt + -y/--yes flag, mirroring volumes delete. This is a deliberate divergence from the established CLI rule (verified across repos.py, buckets.py, spaces.py, auth.py):

confirm = deletion, no confirm = state change

By that rule, pause/restart should not prompt — they parallel dev_mode --stop (which tears down a running container without asking).

Reasoning for diverging here: pausing/restarting wipes ephemeral storage on the Space's container. Users who haven't mounted a Volume can lose unsaved data. The same is true of the dashboard buttons, but a CLI invocation is easier to script/automate, which raises the blast radius.

sleep does not prompt (it's a config update, no container teardown).

Happy to remove the prompts if you'd rather stay consistent with the rest of the CLI — let me know.

Notes

  • space_id argument shape, -y/--yes shape (Answer Yes to prompt automatically.), and out.result(...) + out.hint(...) output style all match existing spaces.py patterns verbatim.
  • Docs guide at cli.md adds three terse subsections matching the existing tone (frame pause around billing, link to canonical docs for sleep).
  • package_reference/cli.md regenerated by make style (do not edit by hand).
  • Cross-linking from hub-docs/spaces-gpus.md (#pause, #sleep-time) is a separate follow-up PR.

Note

Medium Risk
Adds new hf spaces lifecycle commands that trigger remote runtime actions (pause/restart/factory reboot and sleep-time changes), so misuse could interrupt running Spaces or discard ephemeral data.

Overview
Adds new Spaces lifecycle controls to the hf CLI: hf spaces pause and hf spaces restart (optionally --factory-reboot) plus hf spaces settings --sleep-time for updating a Space’s sleep timeout.

Documentation is updated to describe these commands and warn that pausing/restarting tears down the container (ephemeral filesystem is lost), and the autogenerated CLI reference now includes the new subcommands and options.

Reviewed by Cursor Bugbot for commit 7d3a903. Bugbot is set up for automated code reviews on this repo. Configure here.

davanstrien and others added 2 commits April 27, 2026 16:32
Wraps existing HfApi methods (pause_space, restart_space,
set_space_sleep_time) so they're reachable from the CLI. Includes
--factory-reboot on restart and --seconds on sleep. Bundled as one PR
per Slack discussion (Apr 16/20).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a second `out.hint()` after pause and restart pointing users at
`hf spaces volumes set` for persisting data across container teardown,
plus a matching tip callout in the cli.md guide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@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.

davanstrien and others added 2 commits April 28, 2026 08:52
Drop output substring assertions (CLI tests should verify args
plumbing, not output formatting — pause_space/restart_space/
set_space_sleep_time are already tested in the HfApi suite). Add
api_cls.assert_called_once_with(token=None) to match the parity
established by TestRepoDeleteCommand and TestInferenceEndpointsCommands.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@davanstrien davanstrien marked this pull request as ready for review April 28, 2026 08:30
@davanstrien
Copy link
Copy Markdown
Member Author

Ran smoke tests locally now

Copy link
Copy Markdown
Contributor

@hanouticelina hanouticelina left a comment

Choose a reason for hiding this comment

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

Thanks!

Comment thread src/huggingface_hub/cli/spaces.py Outdated
Comment thread src/huggingface_hub/cli/spaces.py Outdated
Co-authored-by: célina <hanouticelina@gmail.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cfd8775. Configure here.

Comment thread src/huggingface_hub/cli/spaces.py Outdated
davanstrien and others added 3 commits April 28, 2026 11:31
Co-authored-by: célina <hanouticelina@gmail.com>
The accepted suggestion landed `return` at 7 spaces, breaking import
of `huggingface_hub.cli.spaces`. Re-indent to 8 and stub the mocked
`sleep_time` in `test_sleep` so it exercises the success path instead
of the new warning branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread tests/test_cli.py Outdated
davanstrien and others added 2 commits April 28, 2026 11:47
These tests only verified that the CLI delegates to the corresponding
HfApi method - effectively typer-wiring coverage with no behavior under
test. Per review feedback, drop them as too verbose for the value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per follow-up review feedback: empirical testing showed that the server
returns 400 for static, cpu-basic, and zero-a10g spaces, so
hf_raise_for_status throws before the runtime.sleep_time != seconds
check ever runs. The user already gets a clear server-side message;
keeping the post-hoc guard adds no value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Wauplin
Copy link
Copy Markdown
Contributor

Wauplin commented Apr 28, 2026

hf spaces sleep <id> --seconds N

I find this syntax quite misleading. I would expect a hf spaces sleep <id> to put the Space to sleep, i.e. exactly what hf spaces pause is doing. I would suggest either hf spaces settings <id> --sleep-time <SECONDS>, similar to the current hf repos settings <id> ... or hf spaces --set-sleep-time. Slight preference for the former for explicitness even though it's not consistent with the HfApi methods. Later we might do hf spaces settings <id> --hardware ... as well?

Otherwise hf spaces --set-sleep-time / hf spaces --set-hardware is also fine to be consistent with the HfApi calls. Happy to get some suggestions on this @davanstrien @hanouticelina

Discussion point: confirmation prompts

Good point discussing this. I would tend to think confirmation prompt is a bit too much for a pause/restart since by nature Space storage is ephemeral so we are not really deleting "hard storage". I would just go yolo on that

davanstrien and others added 2 commits April 28, 2026 11:59
Per Wauplin: Space runtime is ephemeral, so pause/restart don't
warrant a confirmation prompt. Drop out.confirm + --yes plumbing
on both commands and remove the corresponding examples from the
guide. Mount-a-Volume hints stay so users know how to persist
data across restarts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per Wauplin: 'hf spaces sleep <id>' reads as a transition action
(== pause), but the underlying API call is a configuration mutation.
Rename to 'hf spaces settings <id> --sleep-time N', mirroring the
existing 'hf repos settings' shape and opening a clean namespace
for future settings flags (--hardware, etc.) without proliferating
top-level verbs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hanouticelina
Copy link
Copy Markdown
Contributor

I have a preference for hf spaces settings <id> --sleep-time <SECONDS> as well

@davanstrien
Copy link
Copy Markdown
Member Author

  • Renamed sleep --secondssettings --sleep-time. Went with the settings shape since it mirrors hf repos settings and gives --hardware etc. a home later without new top-level verbs.
  • Dropped confirms on pause/restart
  • For secrets/variables later it might make sense to keep them as nested subgroups (hf spaces secrets set/rm/ls) like volumes — i.e. settings for single-value attributes, subgroups for keyed collections?

@Wauplin
Copy link
Copy Markdown
Contributor

Wauplin commented Apr 28, 2026

For secrets/variables later it might make sense to keep them as nested subgroups (hf spaces secrets set/rm/ls) like volumes — i.e. settings for single-value attributes, subgroups for keyed collections?

Yes, agree on this as well 👍

Copy link
Copy Markdown
Contributor

@Wauplin Wauplin left a comment

Choose a reason for hiding this comment

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

Thank you!

Copy link
Copy Markdown
Contributor

@hanouticelina hanouticelina left a comment

Choose a reason for hiding this comment

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

Thanks!

@hanouticelina hanouticelina merged commit 611b0ca into main Apr 28, 2026
18 of 21 checks passed
@hanouticelina hanouticelina deleted the cli-spaces-lifecycle branch April 28, 2026 12:12
davanstrien added a commit that referenced this pull request Apr 29, 2026
Replace conditional result_kwargs build-up with a single inline
out.result() call. out.result already filters None in human/agent
modes; JSON mode emits nulls for unset flags (predictable schema).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wauplin pushed a commit that referenced this pull request Apr 29, 2026
* [CLI] Add --hardware flag to hf spaces settings

Extends the settings command added in #4155 to also accept
--hardware <FLAVOR>, mapping to HfApi.request_space_hardware.
When both --hardware and --sleep-time are passed, the change is
sent in a single request_space_hardware call (the API accepts both
in one payload).

Mirrors the design rules from #4155: single-value attributes go on
settings (not as new top-level verbs), no confirm prompt (server
validates), generic 'specify at least one setting' error that does
not enumerate flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Match repos settings bullet style in spaces settings guide

Drop SECONDS/FLAVOR placeholders to align with the precedent at
'Update repo settings' which uses bare flag names + prose value
descriptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Restore one-line intro for spaces settings guide

Mirrors the sibling 'Pause a Space' / 'Restart a Space' sections
which open with a short 'Use hf spaces X to ...' sentence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Match #4155 echo style in spaces settings

Replace conditional result_kwargs build-up with a single inline
out.result() call. out.result already filters None in human/agent
modes; JSON mode emits nulls for unset flags (predictable schema).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Align --hardware help text with SpaceHardwareOpt wording

Match the existing 'Space hardware flavor (e.g. ...)' phrasing used
in cli/repos.py:97 and cli/jobs.py for consistency across the CLI.
Drop 'Only for Spaces' suffix since this command is already scoped
to Spaces.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Fix mypy: fold validation into routing if/elif/else

mypy CI flagged set_space_sleep_time(sleep_time=int|None) since the
upstream early-validation check could not narrow the local type.
Fold the 'specify at least one' check into the trailing else of the
routing branch so mypy narrows sleep_time correctly in the elif arm.

Matches the in-file 'else: raise CLIError(...)' pattern already used
elsewhere in spaces.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
davanstrien added a commit that referenced this pull request Apr 30, 2026
- `hf spaces secrets {set,delete}` wraps add_space_secret / delete_space_secret.
- `hf spaces variables {set,delete,ls}` wraps add/delete_space_variable and get_space_variables.
- Both `set` commands accept multiple `-s`/`-e` flags and `--secrets-file`/`--env-file`
  (dotenv) via the existing `parse_env_map` helper — no new parsing code.
- No `secrets ls`: Hub exposes secrets as write-only (no GET endpoint).
- Confirm + `--yes` on `secrets delete` only (lost-value risk); variables delete is
  replayable so it skips the prompt, per the #4155 rule.
- `set` is upsert (one API call per key — no bulk endpoint), not replace-collection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@huggingface-hub-bot
Copy link
Copy Markdown
Contributor

This PR has been shipped as part of the v1.13.0 release.

Wauplin added a commit that referenced this pull request May 4, 2026
* [CLI] Add hf spaces secrets and variables subgroups

- `hf spaces secrets {set,delete}` wraps add_space_secret / delete_space_secret.
- `hf spaces variables {set,delete,ls}` wraps add/delete_space_variable and get_space_variables.
- Both `set` commands accept multiple `-s`/`-e` flags and `--secrets-file`/`--env-file`
  (dotenv) via the existing `parse_env_map` helper — no new parsing code.
- No `secrets ls`: Hub exposes secrets as write-only (no GET endpoint).
- Confirm + `--yes` on `secrets delete` only (lost-value risk); variables delete is
  replayable so it skips the prompt, per the #4155 rule.
- `set` is upsert (one API call per key — no bulk endpoint), not replace-collection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [CLI] Apply review feedback: rename set→add, confirm on variables delete

- Rename `secrets set` / `variables set` to `add` (mirrors add_space_secret/
  add_space_variable, signals upsert vs volumes set's replace).
- Add confirm + `-y/--yes` to `variables delete` for parity with
  `secrets delete`. Kept the warning text intentionally asymmetric: secrets
  says "value cannot be recovered" (true: write-only API), variables uses
  the shorter volumes-style phrasing (the value is visible via `ls` before
  deletion).
- Remove now-stale per-command `--format` declarations. #4162 made --format
  global, so these were dead code that was breaking the import after the
  rebase.

Per @Wauplin review at #4170 (comment 4351208819).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Update docs/source/en/guides/cli.md

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

* Update src/huggingface_hub/cli/spaces.py

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

* [CLI] Regenerate CLI reference after suggestion commits

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Lucain <lucain@huggingface.co>
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