Skip to content

Releases: huggingface/huggingface_hub

[v1.19.0] Trusted Publishers, hf:// URIs, and expose-ports for Jobs

11 Jun 10:07

Choose a tag to compare

🔐 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 .

📚 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
  • [CLI] Support hf:// URIs in hf upload and hf download by @Wauplin in #4297

📚 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])
  • [Jobs] Add --expose option to expose job ports through the jobs proxy by @XciD in #4316

📚 Documentation: Jobs guide

🖥️ CLI

⚡ 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 #4323get_token() now checks HF_TOKEN/HUGGING_FACE_HUB_TOKEN and the on-disk token file before the Colab secrets vault, so an explicit login() 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-harnesses instead 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_TYPE import from dataclasses module by @xsuchy in #4322 — fixes ImportError on Python 3.15 where dataclasses._MISSING_TYPE was removed upstream.
  • Fix ignored-pattern warning grammar in download CLI by @wunianze666-netizen in #4337 — corrects "have being" to "have been" in hf download warning output.
  • [fix] Transient location error due to CDN by @Wauplin in #4339 — fixes flaky test_get_hf_file_metadata_from_a_lfs_file by accepting cdn.hf.co in addition to xethub.hf.co in 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

05 Jun 09:26

Choose a tag to compare

🖥️ 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

  • [CLI] Add unified hf cp command (aliased as hf repos cp and hf buckets cp) by @Wauplin in #4295

🥚 Easter egg:explore your storage usage

image
  • [CLI] Easter egg: city skyline in hf repos ls by @Wauplin in #4287

🔗 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

  • [URIs] Parse web URLs in parse_hf_uri + add HfUri.to_url by @Wauplin in #4296

🚨 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.

  • [Fix] Make concurrent downloads safe even when file locking is broken by @Wauplin in #4306

🖥️ CLI

🐛 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

28 May 15:08

Choose a tag to compare

📋 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

📚 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"
  • [Jobs] Decouple Job hardware from Spaces, auto-sync enums with Hub API by @Wauplin in #4266

📚 Documentation: Jobs guide

💔 Breaking Change

Note: The second item changes hf jobs ps and hf jobs scheduled ps to use --format auto|human|agent|json|quiet (removing --format table and -q). JSON output for hf jobs ps now flattens command to a string and status to a stage string.

🖥️ CLI

  • [CLI] Migrate extensions, lfs-enable-largefiles, version to out singleton by @hanouticelina in #4284
  • [CLI] Fix parent aliases leaking into subcommand headers in CLI reference by @Wauplin in #4253

📊 Jobs

📚 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 click as 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

🏗️ 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.py by @hanouticelina in #4285

[v1.16.4] hot fix: Fix `typer>=0.26.0` compatibility

26 May 17:07

Choose a tag to compare

  • [CI] Cap typer below 0.26.0 (CLI incompatibility) #4272

  • [CI] Add click as explicit dependency #4270

Full Changelog: v1.16.1...v1.16.4

[v1.16.1] [Hot-fix] [Inference] Remove Together ASR task to drop urllib3 dependency

21 May 18:43

Choose a tag to compare

  • [Hot-fix] [Inference] Remove Together ASR task to drop urllib3 dependency by @Wauplin in #4248

Full Changelog: v1.16.0...v1.16.1

[v1.16.0] Together goes multimodal on Inference Providers, CLI improvements, and token security

21 May 10:38

Choose a tag to compare

⚡ Together goes multimodal on Inference Providers

Together now supports five additional task types beyond chat and text-to-image on Inference Providers:

  • feature_extraction
  • text_to_speech
  • automatic_speech_recognition EDIT: hot-fix v1.16.1 removed this task (see #4248) to fix a dependency issue. We will add it back in a future release.
  • image_to_image
  • text_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.

  • [Core] Migrate hf:// URI parsing to centralized parse_hf_uri by @Wauplin in #4189

📚 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

📚 Documentation: CLI guide

Miscellaneous

🔒 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.

  • [Auth] Harden HF_TOKEN_PATH and HF_STORED_TOKENS_PATH to 0o600 / 0o700 by @JAE0Y2N in #4234

📊 Jobs

🐛 Bug and typo fixes

  • [Download] Fix snapshot bar inflation on http_get retry by @popfido in #4209

📖 Documentation

  • [Docs] Refresh contributing guide and README by @Wauplin in #4237

🏗️ 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 ty invalid-type-form on WebhooksServer annotations 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

15 May 11:19

Choose a tag to compare

🌍 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
  • [Bucket/Repo] Support 'region' option in create_bucket and create_repo by @Wauplin in #4194

🧩 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] Pretty-print --help with ANSI styling by @Wauplin in #4192

🖥️ CLI

  • [CLI] Check Homebrew registry for updates when installed via brew by @Wauplin in #4204hf update no longer suggests a version that isn't on brew yet 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=1 for 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

[v1.14.0] Handle Spaces secrets & variables from CLI and other improvements

06 May 14:00

Choose a tag to compare

🖥️ 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 update by @hanouticelina in #4176hf skills upgrade no longer exists; use hf skills update instead.
  • [CLI] Add out.status() by @hanouticelina in #4171 — status updates (spinners/progress) on hf extensions install and hf spaces dev-mode are now suppressed when using --format json, --quiet, or --format agent.

🖥️ CLI

🐛 Bug and typo fixes

🏗️ 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

30 Apr 11:48

Choose a tag to compare

🖥️ 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

🚀 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

🔃 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

  • [CLI] Add hf update + drop interactive update prompt by @Wauplin in #4131

✏️ 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.

🖥️ CLI

  • [CLI] Print help when leaf command with required args is called without args by @Wauplin in #4135

🤖 Inference

📖 Documentation

🐛 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

29 Apr 09:49

Choose a tag to compare

Full Changelog: v1.12.1...v1.12.2