Releases: huggingface/huggingface_hub
[v1.19.0] Trusted Publishers, hf:// URIs, and expose-ports for Jobs
🔐 Keyless CI/CD auth via OIDC token exchange
CI workflows can now authenticate to the Hub without storing an HF_TOKEN secret, using Trusted Publishers. Set HF_OIDC_RESOURCE to the repo (or username) you want to scope the token to, and huggingface_hub performs the OIDC exchange under the hood — no token, no setup code. GitHub Actions is supported out of the box (with permissions: id-token: write), and other providers can pass a pre-minted ID token via HF_OIDC_ID_TOKEN. Exchanged tokens are short-lived (1 hour), repo-scoped, and cached locally with automatic refresh.
# Publish a model without storing any HF_TOKEN secret
- name: Push the model
env:
HF_OIDC_RESOURCE: acme/awesome-model
run: hf upload acme/awesome-model ./model .- [Auth] Keyless CI/CD auth via OIDC token exchange by @hanouticelina in #4326
📚 Documentation: Trusted Publishers
🖥️ hf:// URIs for upload and download
hf upload and hf download now accept an hf:// URI in place of the positional repo ID. The URI encodes repo type, revision, and file path in a single string following the grammar hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>], so you no longer need separate --repo-type and --revision flags. When a URI is provided, it is the single source of truth — passing --repo-type or --revision on top of it raises an error, and a path in the URI cannot be combined with positional filenames (download) or path_in_repo (upload).
# Download a single file from a dataset at a given revision
hf download hf://datasets/HuggingFaceM4/FineVision@refs/pr/1/data/train.parquet
# Download an entire repo
hf download hf://datasets/google/fleurs
# Upload a file to a dataset on a specific branch
hf upload hf://datasets/Wauplin/my-cool-dataset@my-branch/data/train.csv ./train.csv📚 Documentation: CLI guide — hf:// URIs · Download guide · Upload guide
🚀 Expose job ports through the jobs proxy
Jobs can now expose container ports through the public jobs proxy using --expose <port> (CLI) or expose=[8000] (Python API). Each exposed port is reachable at https://<job_id>--<port>.hf.jobs and requires an HF token with read access to the job's namespace. This works on hf jobs run, hf jobs uv run, and their scheduled variants. Job responses now surface expose_urls on JobStatus.
# Expose a web server running on port 8000
> hf jobs run --expose 8000 python:3.12 python -m http.server 8000
✓ Job started
id: 6a2aa7cec4f53f9fc5aa4cff
url: https://huggingface.co/jobs/Wauplin/6a2aa7cec4f53f9fc5aa4cff
Hint: Exposed ports are reachable at (requires an HF token with read access to the job):
https://6a2aa7cec4f53f9fc5aa4cff--8000.hf.jobs
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...from huggingface_hub import run_job
run_job(image="python:3.12", command=["python", "-m", "http.server", "8000"], expose=[8000])📚 Documentation: Jobs guide
🖥️ CLI
- [CLI] Suppress hints in quiet output mode by @davanstrien in #4310
- [CLI] Agent-friendly hints + examples for hf jobs by @davanstrien in #4308
- [CLI] Accept web URLs in bucket CLI commands by @Wauplin in #4315
⚡ XetSession API migration
All Xet upload and download code has been migrated from the old function-based hf_xet API to the new session-based XetSession API (hf-xet >= 1.5.0). A global singleton get_xet_session() provides fork-safe, thread-safe, and SIGINT-safe session reuse across all call sites — repo commits, hf_hub_download, bucket uploads/downloads, and snapshot_download all share the same underlying Tokio runtime. Token refresh is now handled through a centralized xet_connection_info_refresh_url() builder, and progress reporting follows the new (group_report, item_reports) contract.
🔧 Other QoL Improvements
- [Auth] Take google colab token from env first by @Wauplin in #4323 —
get_token()now checksHF_TOKEN/HUGGING_FACE_HUB_TOKENand the on-disk token file before the Colab secrets vault, so an explicitlogin()or env variable always wins over the notebook's stored secret. - [Agent] Dynamic agent harness registry by @Wauplin in #4325 — Agent harness detection now fetches the registry from
GET /api/agent-harnessesinstead of using a hardcoded list, with a 24-hour on-disk cache and in-process caching for hot paths.
🐛 Bug and typo fixes
- [Fix] Remove private
_MISSING_TYPEimport from dataclasses module by @xsuchy in #4322 — fixesImportErroron Python 3.15 wheredataclasses._MISSING_TYPEwas removed upstream. - Fix ignored-pattern warning grammar in download CLI by @wunianze666-netizen in #4337 — corrects
"have being"to"have been"inhf downloadwarning output. - [fix] Transient location error due to CDN by @Wauplin in #4339 — fixes flaky
test_get_hf_file_metadata_from_a_lfs_fileby acceptingcdn.hf.coin addition toxethub.hf.coin the redirect URL check.
🏗️ Internal
- Post-release: bump version to 1.19.0.dev0 by @huggingface-hub-bot[bot] in #4313
- [CI] Run tests on internal workers by @Wauplin in #4321
- [Tests] Add xet/no_xet pytest markers to filter Xet vs non-Xet tests by @Wauplin in #4336
- Bump the actions group with 6 updates by @dependabot[bot] in #4332
- chore: update release.yml by @hf-security-analysis[bot] in #4334
- [CI] Remove .github/workflows/python-prerelease.yml by @Wauplin in #4335
[v1.18.0] Unified file copying, web URL support, and storage usage
🖥️ Unified hf cp command
A single hf cp command now handles all file-copy workflows (upload a local file, download from the Hub, or copy between two remote locations) with consistent hf:// URI syntax for both repositories and buckets. It is also available as hf repos cp and hf buckets cp; all three aliases are identical, so you can use whichever reads best for your workflow. You can stream from stdin (-) or to stdout (-), and a trailing / on the source path gives you rsync-style semantics (copy the folder contents, not the folder itself). Note that remote-to-remote copies only work within the same storage region, and bucket-to-repo is not yet supported.
# Upload a local file to a repo
hf cp ./model.safetensors hf://username/my-model/model.safetensors
# Download a file to stdout
hf cp hf://username/my-model/config.json - | jq .
# Copy between two Hub repos
hf cp hf://username/source-model/config.json hf://username/dest-model/config.json📚 Documentation: CLI guide — Copy files
🥚 Easter egg:explore your storage usage
🔗 Paste web URLs directly
parse_hf_uri now accepts Hugging Face web URLs so you can paste a link straight into the CLI or the library and it "just works".
# Copy-paste a URL from the website
hf cp https://huggingface.co/nvidia/LocateAnything-3B/blob/main/config.json - | jq '.architectures'📚 Documentation: HF URIs — Web URLs
🚨 Breaking change
On Lustre, GPFS, and some NFS mounts, flock(2) silently succeeds for every caller, which means filelock provides no mutual exclusion. When multiple hf_hub_download calls race for the same file, they can append to the same .incomplete file and silently corrupt the blob cache. This release fixes that by always downloading to a fresh temporary file instead of resuming an incomplete one, making the download path safe even when file locking is broken. filelock is still used as a "best-effort" hint to avoid unnecessary duplicate downloads, but correctness no longer depends on it. This is a breaking change: resuming a previously failed partial download is no longer possible. However, file resumability was already a niche use case only applicable when hf_xet is disabled.
🖥️ CLI
- [CLI] inline enum choices in the generated CLI skill by @hanouticelina in #4299
🐛 Bug and typo fixes
- Fix ~ user home not expanded in local_dir and cache_dir on file download by @Wauplin in #4293
- Do not fail on repo/bucket creation if HTTP 401 and already exists by @Wauplin in #4294
- Fix umask probe writing tmp file outside download dir by @Wauplin in #4305
📖 Documentation
- [Docs] Document missing endpoint and template_str parameters by @aicayzer in #4298
- [Docs] Document missing parameters in hf_hub_url and preupload_lfs_files by @aicayzer in #4300
- [Docs] Mention storage region limitation for server-side copy by @Wauplin in #4302
🏗️ Internal
- Post-release: bump version to 1.18.0.dev0 by @huggingface-hub-bot[bot] in #4291
- Bump the actions group with 2 updates by @dependabot[bot] in #4309
[v1.17.0] Cross-repo copies, ssh to Spaces, smarter CLI tables
📋 Copy files between repositories
You can now copy files or entire folders between different repositories on the Hub — model to model, model to dataset, any combination — without downloading or re-uploading data. CommitOperationCopy accepts src_repo_id and src_repo_type for cross-repo sources, and LFS blobs are deduplicated server-side via the /lfs-files/duplicate endpoint. Non-LFS files are fetched from the source repo and committed as regular payloads. copy_files and hf buckets cp now support repo-to-repo in addition to the existing bucket destinations.
>>> from huggingface_hub import copy_files
# Copy an entire folder
>>> copy_files(
... "hf://datasets/username/source-dataset/data/",
... "hf://datasets/username/target-dataset/data/",
... )📚 Documentation: Upload guide — Copy files between repositories
🖥️ SSH into a Space with hf spaces ssh
A new hf spaces ssh command opens an SSH session directly into a Space's Dev Mode container. If Dev Mode is not enabled yet, the CLI prompts you to enable it. You can also use --dry-run to print the SSH command without running it, or -i to forward a specific key. Your SSH public key must be registered in your HF user settings.
# SSH into a Space
$ hf spaces ssh username/my-space
# Print the SSH command without running it
$ hf spaces ssh username/my-space --dry-run📚 Documentation: CLI guide — SSH into a Space | Spaces guide — SSH into a Space
📂 List all your repos with hf repos ls
A new hf repos ls command lists all your repositories — models, datasets, spaces, and buckets — with storage size and percentage of namespace total, sorted by storage usage. It supports --type, --search, --namespace, and --limit (default 30, --limit 0 for all), plus the standard --format family.
# List all your repos
$ hf repos ls
# List all datasets under org with JSON output
$ hf repos ls --namespace my-org --type dataset --limit 0 --format json | jq '.[].id'📚 Documentation: CLI guide — List repos | Repository guide — List your repositories
📊 CLI tables auto-fit terminal width and right-align numbers
Human-mode CLI tables now use a column-aware algorithm that computes per-column width caps from the actual terminal width, shrinking only the widest columns when needed. Non-TTY output keeps the legacy fixed cap, and --no-truncate bypasses truncation entirely. Numeric columns (all int/float values) are automatically right-aligned.
# Tables adapt to your terminal width
$ hf models ls --search qwen3
# Force full values regardless of width
$ hf models ls --no-truncate- [CLI] Auto-fit human tables to terminal width by @hanouticelina in #4251
- [CLI] Auto right-align numeric columns in human table output by @Wauplin in #4288
📚 Documentation: CLI guide — Output formatting
🔧 Jobs hardware decoupled from Spaces, auto-synced with Hub API
Jobs now have their own JobHardware enum, independent of SpaceHardware, so the two catalogs can diverge as needed. The old JobHardware dataclass (return type of list_jobs_hardware()) has been renamed to JobHardwareInfo. CLI --flavor / --hardware flags use a new SoftChoice type that shows known values for autocomplete but accepts any string — older CLI versions won't reject new server-side flavors. A daily CI workflow (update-hardware-flavors.yaml) runs utils/check_hardware_flavors.py to sync both enums from the live Hub API and opens a bot PR when something changes.
# Unknown flavors pass through instead of raising a validation error
$ hf jobs run --flavor future-gpu-x99 python:3.12 echo "works with unknown flavors"📚 Documentation: Jobs guide
💔 Breaking Change
- [Inference] Remove Together ASR task to drop urllib3 dependency by @Wauplin in #4248
- [CLI] migrate
hf jobstooutsingleton by @hanouticelina in #4254
Note: The second item changes
hf jobs psandhf jobs scheduled psto use--format auto|human|agent|json|quiet(removing--format tableand-q). JSON output forhf jobs psnow flattenscommandto a string andstatusto a stage string.
🖥️ CLI
- [CLI] Migrate
extensions,lfs-enable-largefiles,versiontooutsingleton by @hanouticelina in #4284 - [CLI] Fix parent aliases leaking into subcommand headers in CLI reference by @Wauplin in #4253
📊 Jobs
- [Jobs] Add update_job_labels and update_scheduled_job_labels by @Wauplin in #4252
- feat: add rtx-pro-6000 hardware flavors by @christophe-rannou in #4259
📚 Documentation: Jobs guide — Update labels | Jobs guide — Hardware
🔧 Other QoL Improvements
- Fix failing on read-only file system even if the non-existence of file is already cached by @ydshieh in #4274
- [CLI] Add
clickas an explicit dependency (typer 0.26.0 fix) by @hanouticelina in #4270
📖 Documentation
- [Docs] Document missing parameters in lfs, hf_file_system, and repocard_data by @kratos0718 in #4289
🐛 Bug and typo fixes
- fix
local_files_onlygrammar by @hunterhogan in #4255 - Fix typos in comments and debug log message by @Sanjays2402 in #4278
🏗️ Internal
- Post-release: bump version to 1.17.0.dev0 by @huggingface-hub-bot[bot] in #4247
- ci(release): migrate PyPI publish to Trusted Publishing + attestations by @XciD in #4249
- [CI] Add import check with base dependencies only by @Wauplin in #4250
- [Internal] Update style bot permissions by @hanouticelina in #4260
- chore: enable Dependabot weekly GitHub Actions bumps by @hf-dependantbot-rollout[bot] in #4262
- Bump actions in the actions group by @dependabot[bot] in #4263
- chore: update release.yml by @hf-security-analysis[bot] in #4264
- fix(release.yml): restore env: block on 'Detect version' step by @paulinebm in #4267
- [Internal] Cap typer below 0.26.0 (CLI incompatibility) by @hanouticelina in #4272
- [Internal] Run pinact (lock versions in workflow files) by @Wauplin in #4275
- [Internal] Use Comment bot in model card gh action by @Wauplin in #4277
- [CI] fix collection test by making its name unique by @Wauplin in #4279
- Bump astral-sh/setup-uv from 7.6.0 to 8.1.0 in the actions group by @dependabot[bot] in #4281
- [CLI] Drop legacy printing helpers from
_cli_utils.pyby @hanouticelina in #4285
[v1.16.4] hot fix: Fix `typer>=0.26.0` compatibility
Full Changelog: v1.16.1...v1.16.4
[v1.16.1] [Hot-fix] [Inference] Remove Together ASR task to drop urllib3 dependency
Full Changelog: v1.16.0...v1.16.1
[v1.16.0] Together goes multimodal on Inference Providers, CLI improvements, and token security
⚡ Together goes multimodal on Inference Providers
Together now supports five additional task types beyond chat and text-to-image on Inference Providers:
feature_extractiontext_to_speechEDIT: hot-fix v1.16.1 removed this task (see #4248) to fix a dependency issue. We will add it back in a future release.automatic_speech_recognitionimage_to_imagetext_to_video
from huggingface_hub import InferenceClient
client = InferenceClient(provider="together")
# Embeddings
embeddings = client.feature_extraction("Hello world", model="intfloat/multilingual-e5-large-instruct")
# Text-to-speech
audio = client.text_to_speech("Hello world", model="hexgrad/Kokoro-82M", extra_body={'voice': 'af_heart'})
# Text-to-video
video = client.text_to_video("A cat on the moon", model="Wan-AI/Wan2.2-T2V-A14B")- [Inference] Add embeddings, TTS, ASR, image-to-image and video tasks for Together by @nbroad1881 in #4164
📚 Documentation: Inference guide
🔗 Centralized hf:// URI parsing
All scattered ad-hoc hf:// URI parsers throughout the codebase have been consolidated onto the new parse_hf_uri/parse_hf_mount helpers. This brings consistent parsing behavior, a new is_hf_uri public helper for validating URIs, and proper handling of @ in filenames (now treated as literal). The CLI error handler now catches HfUriError and displays a clean message instead of a raw traceback.
🚨 Breaking Changes
This migration includes several breaking changes: BucketUrl.handle has been renamed to BucketUrl.uri (type changed from str to HfUri, use .to_uri() for the string form), Volume.to_hf_handle() has been renamed to Volume.to_uri(), single-segment repo IDs (e.g. gpt2) are no longer supported in HfFileSystem paths or CLI -v flags — you must use the namespace/name format instead.
📚 Documentation: CLI guide | Buckets guide
🖥️ CLI
Global --no-truncate flag for CLI tables
A new --no-truncate global formatting flag disables the ... shortening of scalar values in human-mode tables, letting you see full IDs, names, and other long text at a glance. List- and dict-valued columns (e.g. tags) remain shortened in human mode since they can be arbitrarily long; use --format json for those. When any cell is truncated, human tables now print a one-line hint at the bottom pointing you to the right flag.
# Show full scalar values in table output
hf models ls --no-truncate- [CLI] Add global
--no-truncateflag for human tables by @hanouticelina in #4229
📚 Documentation: CLI guide
Miscellaneous
- [CLI] Surface job runtime fields in ps + inspect by @davanstrien in #4211
- [CLI] Parse
initiatorfield on jobs API responses by @davanstrien in #4212 - [CLI] Support hf:// URIs in cache rm by @abhinavgautam01 in #4235
- [CLI] Expose linked repos in PaperInfo by @mishig25 in #4240
- [CLI] Raise error when both --local-dir and --cache-dir are provided by @Wauplin in #4245
🔒 Token file permissions hardened
Token files written by huggingface_hub (~/.cache/huggingface/token and ~/.cache/huggingface/stored_tokens) were previously created with Python's default modes, leaving them world-readable on most systems. This PR sets file permissions to 0o600 and parent directory permissions to 0o700 after every write, bringing huggingface_hub in line with industry-standard tools like GitHub CLI, AWS CLI, and Google Cloud SDK. Pre-existing installations will converge to safe permissions on the next token save. The chmod calls are wrapped in try/except for Windows, which doesn't support POSIX modes.
📊 Jobs
- Use server-side support to tail job logs by @coyotte508 in #4202
- [Jobs] Add
ephemeral_storagefield toJobHardwareby @Wauplin in #4233
🐛 Bug and typo fixes
📖 Documentation
🏗️ Internal
- Post-release: bump version to 1.16.0.dev0 by @huggingface-hub-bot[bot] in #4230
- Fix catch-all empty string in CI pytest --only-rerun by @albertvillanova in #4239
- [Internal] Silence
tyinvalid-type-formonWebhooksServerannotations by @hanouticelina in #4242 - [CI] make test_model_info_with_security for robust by @Wauplin in #4246
[v1.15.0] Region-aware buckets & repos, `hf skills list`, polished CLI help and more
🌍 Pick a region when creating buckets and repos
create_bucket and create_repo now accept an optional region argument ("us" or "eu") so you can pin a new bucket or repo to a specific cloud region at creation time. The same option is exposed on the CLI via a --region flag on hf buckets create and hf repos create.
>>> from huggingface_hub import create_bucket, create_repo
>>> create_bucket("my-bucket", region="us")
>>> create_repo("my-model", region="eu")$ hf buckets create my-bucket --region us
$ hf repos create username/my-model --region eu🧩 Discover marketplace skills with hf skills list
A new hf skills list (alias ls) command lists every skill available in the Hugging Face marketplace and shows whether each one is already installed in the four supported locations (project, global, project Claude, global Claude). Handy when you want to check what's installable and what you've already got before running hf skills add.
$ hf skills ls
NAME DESCRIPTION PROJECT PROJECT (CLAUDE) GLOBAL GLOBAL (CLAUDE)
--------------------------- ----------------------------------- ------- ---------------- ------ ---------------
hf-cli Execute Hugging Face Hub operati... yes yes yes yes 🎨 Polished --help output with ANSI styling
hf --help and every subcommand now render with underlined section headings and bold option/command names, making the help screens much easier to scan in a terminal. The new styling is automatically disabled when NO_COLOR is set or when the CLI detects it's running under an AI agent, so script and agent output stays clean.
🖥️ CLI
- [CLI] Check Homebrew registry for updates when installed via brew by @Wauplin in #4204 —
hf updateno longer suggests a version that isn't onbrewyet for Homebrew installs. - [CLI] No traceback on LocalEntryNotFoundError by @Wauplin in #4190 — offline/cache-miss errors now print a clean message instead of a Python traceback (set
HF_DEBUG=1for the full stack).
🐛 Bug and typo fixes
- Make HF_HUB_ENABLE_HF_TRANSFER deprecation warning visible to users by @Adithya191101 in #4220
- Fix hint message to use 'hf skills update' by @Pierrci in #4206
📖 Documentation
- [docs] Drop duplicated Key Features list from hf jobs CLI section by @davanstrien in #4222
🏗️ Internal
- [CI] Harden style-bot workflow against TOCTOU by @paulinebm in #4183
- Only sync skill if SKILL.md has changed by @evalstate in #4210
[v1.14.0] Handle Spaces secrets & variables from CLI and other improvements
🖥️ Manage Space secrets and variables from the CLI
You can now manage Space secrets and environment variables directly from the command line with two new hf spaces subgroups: secrets and variables. Use hf spaces secrets to add, list, and delete write-only secrets, and hf spaces variables to add, list, and delete readable environment variables. Both add commands support multiple -s/-e flags and --secrets-file/-env-file for loading from dotenv files. On the Python side, HfApi.get_space_secrets() returns secret metadata (key, description, updated timestamp) without ever revealing values.
# List secrets (values are write-only — only keys and timestamps are shown)
$ hf spaces secrets ls username/my-space
# Add secrets
$ hf spaces secrets add username/my-space -s OPENAI_API_KEY=sk-...
$ hf spaces secrets add username/my-space --secrets-file .env.secrets
# Delete a secret (confirmation prompt, use --yes to skip)
$ hf spaces secrets delete username/my-space OPENAI_API_KEY --yes
# List, add, and delete variables (values are readable)
$ hf spaces variables ls username/my-space
$ hf spaces variables add username/my-space -e MODEL_ID=gpt2 -e MAX_TOKENS=512
$ hf spaces variables delete username/my-space MAX_TOKENS --yes- [CLI] Add hf spaces secrets and variables subgroups by @davanstrien in #4170
- [CLI] Add get_space_secrets + hf spaces secrets ls by @Wauplin in #4182
📚 Documentation: CLI guide · Manage your Space
🪣 Rsync-style trailing slash for bucket folder copies
hf buckets cp now supports rsync-style trailing slash semantics when copying folders. A trailing / on the source path copies only the folder's contents to the destination, while omitting it nests the folder itself — matching the behavior you'd expect from rsync. This makes it possible to flatten directory structures during copies, which was not possible before. Additionally, copy_files now raises an explicit EntryNotFoundError when the source path resolves to no files, instead of silently succeeding with zero operations.
# Without trailing slash: "logs" dir is nested => dst/logs/...
$ hf buckets cp hf://buckets/username/src-bucket/logs hf://buckets/username/dst/
# With trailing slash: only contents of "logs" are copied => dst/...
$ hf buckets cp hf://buckets/username/src-bucket/logs/ hf://buckets/username/dst/- [Buckets] Support rsync-style trailing slash in copy_files by @Wauplin in #4187
- [CLI] Raise error when copy_files source doesn't exist by @Wauplin in #4186
📚 Documentation: Buckets guide · CLI guide
💔 Breaking Change
- [CLI] Rename
hf skills upgrade->hf skills updateby @hanouticelina in #4176 —hf skills upgradeno longer exists; usehf skills updateinstead. - [CLI] Add
out.status()by @hanouticelina in #4171 — status updates (spinners/progress) onhf extensions installandhf spaces dev-modeare now suppressed when using--format json,--quiet, or--format agent.
🖥️ CLI
- [CLI] Add hints and example to
hf datasets leaderboardby @Wauplin in #4174 - [CLI] Shortcut
hf updatewhen already on latest version by @julien-c in #4177 - [CLI] Remove progress bars on skills update by @Wauplin in #4179
- [CLI] Increase default --limit from 10 to 30 for list commands by @Wauplin in #4181
- [CLI] Support hf -v to print version by @Wauplin in #4185
- [CLI] migrate
hf skillsto bucket by @hanouticelina in #4175
🐛 Bug and typo fixes
- Update typer dependency version in setup.py by @tomaarsen in #4193
🏗️ Internal
- Post-release: bump version to 1.14.0.dev0 by @huggingface-hub-bot[bot] in #4172
- [Release] Move social drafts to minor-release and archive release notes to bucket by @Wauplin in #4173
- Update unit test warnings check to ignore unrelated deprecation warnings by @seanses in #4188
- [internal] Untrack useless files by @Wauplin in #4191
[v1.13.0] new CLI commands and formatting, and HF URI parsing
🖥️ New CLI commands: repo cards, file listings, and dataset leaderboards
This release adds three new CLI capabilities for exploring Hub content. hf models card, hf datasets card, and hf spaces card fetch the README of any repo and print it to stdout, with --metadata (YAML frontmatter as JSON) and --text (prose only) flags for splitting the card into its structured and unstructured parts. Calling hf models ls <repo_id>, hf datasets ls <repo_id>, or hf spaces ls <repo_id> now switches from listing repos to listing files inside that repo, with --tree, -R, -h, and --revision options mirroring the existing hf buckets ls behavior. And hf datasets leaderboard <dataset_id> surfaces model scores submitted to a benchmark dataset, making it easy to compare models by score from the terminal.
# Get model card metadata as JSON
hf models card google/gemma-4-31B-it --metadata --format json
# List files in a model repo (tree view with sizes)
hf models ls meta-llama/Llama-3.2-1B-Instruct --tree -h
# Show top 5 models on SWE-bench
hf datasets leaderboard SWE-bench/SWE-bench_Verified --limit 5📚 Documentation: CLI guide
- [CLI] Add hf models card and hf datasets card commands by @davanstrien in #4118
- [CLI] Add file listing to models/datasets/spaces ls by @Wauplin in #4166
- [CLI] add
hf datasets leaderboardby @hanouticelina in #4154
🚀 Manage Spaces from the CLI
Three new hf spaces subcommands bring full lifecycle control to the terminal. hf spaces pause and hf spaces restart stop or rebuild a Space (with --factory-reboot for a clean rebuild), and hf spaces settings lets you configure sleep time and hardware in one call. A companion hf spaces hardware command lists all available hardware flavors with pricing, so you can discover options before changing settings. Pause and restart include a confirmation prompt (-y to skip) since they tear down the running container.
# Pause a Space when not in use (not billed while paused)
hf spaces pause username/my-space
# Restart with a GPU
hf spaces settings username/my-space --hardware t4-medium --sleep-time 3600
# List available hardware options
hf spaces hardware📚 Documentation: CLI guide — Spaces
- [CLI] Add spaces lifecycle commands: pause, restart, sleep by @davanstrien in #4155
- [CLI] Add
hf spaces hardwarecommand by @Wauplin in #4169 - [CLI] Add
--hardwareflag tohf spaces settingsby @davanstrien in #4163
🔃 hf update replaces the auto-update prompt
The blocking interactive Y/n auto-update prompt at CLI startup is gone. It was catching too many non-interactive contexts (CI runners, Homebrew post-install hooks, Jupyter notebooks) and hanging automation. In its place, a single yellow stderr warning suggests running hf update — a new command that detects how hf was installed (Homebrew, standalone installer, or pip) and runs the right upgrade command. Set HF_HUB_DISABLE_UPDATE_CHECK=1 to silence the startup check entirely, for example in offline CI.
hf update📚 Documentation: CLI guide — Updating
✏️ Global output formatting for every command
The --format, --json, and -q / --quiet flags are now handled globally by the CLI framework instead of being declared individually on each command. This means every hf command automatically accepts them — no more per-command --format boilerplate, and the flags are properly documented in a dedicated "Formatting options" section in every --help page. --format auto (the default) picks human for interactive terminals and agent when invoked by an AI agent, making CLI output automatically suitable for both people and tools.
# JSON output for scripting
hf models ls --search bert --limit 2 --json | jq '.[].id'
# IDs only, one per line
hf collections ls --owner nvidia -q📚 Documentation: CLI guide — Output formatting
🔗 Centralized hf:// URI parsing
A new parse_hf_uri function and HfUri dataclass provide a single source of truth for parsing hf://... strings across the library. Whether you reference a model, dataset, space, bucket, or file inside a repo, the parser handles all valid URI shapes — type prefixes, revisions, and paths — and rejects invalid ones with clear error messages. A companion parse_hf_mount / HfMount handles volume mount specifications (hf://...:/mnt:ro). Both are pure string parsers (no network calls) and round-trippable via .to_uri().
from huggingface_hub import parse_hf_uri, parse_hf_mount
parse_hf_uri("hf://datasets/namespace/my-dataset@refs/pr/3/train.json")
# HfUri(type='dataset', id='namespace/my-dataset', revision='refs/pr/3', path_in_repo='train.json')
parse_hf_mount("hf://buckets/my-org/my-bucket/sub/dir:/mnt:ro")
# HfMount(source=HfUri(type='bucket', id='my-org/my-bucket', ...), mount_path='/mnt', read_only=True)📚 Documentation: HF URIs reference
🚀 Bucket transport for Jobs script upload
Local scripts uploaded by hf jobs uv run are now stored in a {namespace}/jobs-artifacts bucket and mounted into the job container at /data instead of being base64-encoded into an environment variable. The old bash -c + xargs + base64 -d pipeline was fragile and required manual shell quoting. Bucket transport is simpler, easier to debug, and supports write-back: jobs can persist output artifacts to /data/ since the mount is read-write. The base64 transport path has been fully removed with no fallback.
- Add bucket+mount transport for Jobs script upload by @davanstrien in #4025
🖥️ CLI
🤖 Inference
- [Inference Providers] Add DeepInfra support by @hanouticelina in #4114
- Support list[str] inputs in feature_extraction by @SJeffZhang in #4115
📖 Documentation
- [CLI] Add benchmark dataset filter examples by @hanouticelina in #4156
🐛 Bug and typo fixes
- [BUG FIX]: hf_hub_download crashes when stderr lacks a real file descriptor by @tobocop2 in #4065
- [CLI] Fix datasets list table rendering by @hanouticelina in #4157
- [CLI] Fix installation method detection for curl-installed hf with Homebrew Python by @Wauplin in #4142
- Avoid reuploading preuploaded LFS files in upload-large-folder by @Dev-Jahn in #4165
🏗️ Internal
- [Release] Make release-notes job fail loudly on bad model/empty output by @Wauplin in #4138
- [Release] Fix bucket URL in social posts Slack notification by @Wauplin in #4139
- Post-release: bump version to 1.13.0.dev0 by @huggingface-hub-bot[bot] in #4140
- [CI] Fix two flaky Windows tests (root causes, not skips) by @Wauplin in #4141
- [Quality] Fix uvx ty check src errors by @Wauplin in #4159
- [Release] Mark minor releases as "latest" on GitHub by @Wauplin in #4167
[v1.12.2] Add DeepInfra support for Inference Providers
- [Inference Providers] Add DeepInfra support in #4114 by @hanouticelina
Full Changelog: v1.12.1...v1.12.2