From 5083a37e84ceb9664324a3030c1e3131d595b717 Mon Sep 17 00:00:00 2001 From: narugo1992 Date: Tue, 16 Dec 2025 13:05:54 +0800 Subject: [PATCH 1/5] dev(narugo): update test --- .github/workflows/release.yml | 1 + .github/workflows/release_test.yml | 1 + .github/workflows/test.yml | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d99c3e740a..6a667c563f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,6 +55,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'ci skip')" strategy: fail-fast: false + max-parallel: 1 matrix: os: - 'ubuntu-22.04' diff --git a/.github/workflows/release_test.yml b/.github/workflows/release_test.yml index 83203ebe00..244b9e3456 100644 --- a/.github/workflows/release_test.yml +++ b/.github/workflows/release_test.yml @@ -49,6 +49,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'ci skip')" strategy: fail-fast: false + max-parallel: 1 matrix: os: - 'ubuntu-22.04' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ea14d3f3a..41ae7671bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,11 +20,11 @@ jobs: - 'macos-latest' python-version: - '3.8' - - '3.9' - - '3.10' +# - '3.9' +# - '3.10' - '3.11' - - '3.12' - - '3.13' +# - '3.12' +# - '3.13' steps: - name: Get system version for Linux From 5e05e864b15d3a3509a4c6379f1869750c590f33 Mon Sep 17 00:00:00 2001 From: narugo1992 Date: Tue, 16 Dec 2025 13:32:46 +0800 Subject: [PATCH 2/5] dev(narugo): move configure_http_backend for huggingface_hub>=1 --- .github/workflows/release.yml | 2 +- .github/workflows/release_test.yml | 2 +- .github/workflows/test.yml | 4 ++-- hfutils/entry/download.py | 11 ++++++++--- hfutils/entry/duplicate.py | 12 +++++++++--- hfutils/entry/ils.py | 11 ++++++++--- hfutils/entry/index.py | 11 ++++++++--- hfutils/entry/ls.py | 11 ++++++++--- hfutils/entry/ls_repo.py | 11 ++++++++--- hfutils/entry/rollback.py | 10 +++++++++- hfutils/entry/squash.py | 12 +++++++++--- hfutils/entry/tree.py | 11 ++++++++--- hfutils/entry/upload.py | 11 ++++++++--- hfutils/entry/warmup.py | 11 ++++++++--- hfutils/entry/whoami.py | 11 ++++++++--- hfutils/utils/__init__.py | 1 + hfutils/utils/version.py | 4 ++++ test/entry/test_ls.py | 4 ++-- 18 files changed, 110 insertions(+), 40 deletions(-) create mode 100644 hfutils/utils/version.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a667c563f..2257628cb8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: os: - 'ubuntu-22.04' - 'windows-2022' - - 'macos-13' + - 'macos-14' python-version: - '3.8' diff --git a/.github/workflows/release_test.yml b/.github/workflows/release_test.yml index 244b9e3456..f2ccc03811 100644 --- a/.github/workflows/release_test.yml +++ b/.github/workflows/release_test.yml @@ -54,7 +54,7 @@ jobs: os: - 'ubuntu-22.04' - 'windows-2022' - - 'macos-13' + - 'macos-14' python-version: - '3.8' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41ae7671bb..39be99d874 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: if: ${{ !contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'test skip') }} strategy: fail-fast: false - max-parallel: 2 + max-parallel: 1 matrix: os: - 'ubuntu-latest' @@ -132,7 +132,7 @@ jobs: os: - 'ubuntu-22.04' - 'windows-2022' - - 'macos-13' + - 'macos-14' python-version: - '3.8' diff --git a/hfutils/entry/download.py b/hfutils/entry/download.py index 4b2e8b0824..d82ea8ddf2 100644 --- a/hfutils/entry/download.py +++ b/hfutils/entry/download.py @@ -15,12 +15,16 @@ from typing import Optional import click -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS, command_wrap, ClickErrorException from ..operate import download_file_to_file, download_archive_as_directory, download_directory_as_directory from ..operate.base import REPO_TYPES, RepoTypeTyping -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None class NoRemotePathAssignedWithDownload(ClickErrorException): @@ -122,7 +126,8 @@ def download( :raises NoRemotePathAssignedWithDownload: If no remote path in repository is assigned. """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) if tmpdir: os.environ['TMPDIR'] = tmpdir diff --git a/hfutils/entry/duplicate.py b/hfutils/entry/duplicate.py index 7d49cf7276..50fa9fab51 100644 --- a/hfutils/entry/duplicate.py +++ b/hfutils/entry/duplicate.py @@ -6,12 +6,16 @@ """ import click -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS, command_wrap from ..operate import hf_repo_duplicate from ..operate.base import REPO_TYPES, RepoTypeTyping -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None def _add_duplicate_subcommand(cli: click.Group) -> click.Group: @@ -59,7 +63,9 @@ def duplicate(src_repo_id: str, dst_repo_id: str, repo_type: RepoTypeTyping, pri :raises: Various exceptions from huggingface_hub based on operation status """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) + hf_repo_duplicate( src_repo_id=src_repo_id, dst_repo_id=dst_repo_id, diff --git a/hfutils/entry/ils.py b/hfutils/entry/ils.py index 38d8b6fb06..243f8420fc 100644 --- a/hfutils/entry/ils.py +++ b/hfutils/entry/ils.py @@ -26,14 +26,18 @@ import click from hbutils.scale import size_to_bytes_str from hbutils.string import plural_word, titleize -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS from ..index import hf_tar_get_index, hf_tar_validate from ..operate.base import REPO_TYPES -from ..utils import get_requests_session, get_file_type, FileItemType +from ..utils import get_requests_session, get_file_type, FileItemType, HF_IS_VERSION_0_X_X from ..utils.path import RepoTypeTyping, hf_normpath +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None + _FT_NAME_MAP = { FileItemType.IMAGE: 'image', FileItemType.ARCHIVE: 'archive/compressed', @@ -133,7 +137,8 @@ def ls(repo_id: str, idx_repo_id: Optional[str], repo_type: RepoTypeTyping, revi The function uses click styles to format the output for better readability in the terminal. """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) idx_info = hf_tar_get_index( repo_id=repo_id, diff --git a/hfutils/entry/index.py b/hfutils/entry/index.py index 68eb1e56da..e7a33956cc 100644 --- a/hfutils/entry/index.py +++ b/hfutils/entry/index.py @@ -18,7 +18,6 @@ import click from hbutils.string import plural_word -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS from ..cache import delete_detached_cache @@ -26,7 +25,12 @@ from ..operate import get_hf_fs, download_file_to_file, upload_directory_as_directory from ..operate.base import REPO_TYPES, RepoTypeTyping, get_hf_client from ..utils import tqdm, hf_fs_path, parse_hf_fs_path, TemporaryDirectory, hf_normpath, ColoredFormatter, \ - get_requests_session + get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None def _add_index_subcommand(cli: click.Group) -> click.Group: @@ -90,7 +94,8 @@ def index(repo_id: str, idx_repo_id: Optional[str], repo_type: RepoTypeTyping, r This function is typically invoked through the CLI interface, like: $ python script.py index -r my_repo -x my_index_repo -t dataset -R main --min_upload_interval 120 """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) logger = logging.getLogger() logger.setLevel(logging.INFO) diff --git a/hfutils/entry/ls.py b/hfutils/entry/ls.py index 13c9c92f7f..bb8cdaa607 100644 --- a/hfutils/entry/ls.py +++ b/hfutils/entry/ls.py @@ -4,12 +4,16 @@ import click import tzlocal -from huggingface_hub import configure_http_backend from huggingface_hub.hf_api import RepoFolder, RepoFile from .base import CONTEXT_SETTINGS from ..operate.base import REPO_TYPES, get_hf_client -from ..utils import get_requests_session, FileItemType, get_file_type +from ..utils import get_requests_session, FileItemType, get_file_type, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None class ListItem: @@ -73,7 +77,8 @@ def ls(repo_id: str, repo_type: str, dir_in_repo, revision: str, show_all: bool, :param show_detailed: Flag to indicate whether to show detailed file information. :type show_detailed: bool """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) hf_client = get_hf_client() items: List[ListItem] = [] diff --git a/hfutils/entry/ls_repo.py b/hfutils/entry/ls_repo.py index 856859b614..79af41e115 100644 --- a/hfutils/entry/ls_repo.py +++ b/hfutils/entry/ls_repo.py @@ -2,12 +2,16 @@ from typing import Optional import click -from huggingface_hub import configure_http_backend from huggingface_hub.utils import LocalTokenNotFoundError from .base import CONTEXT_SETTINGS, ClickErrorException from ..operate.base import REPO_TYPES, get_hf_client -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None class NoLocalAuthentication(ClickErrorException): @@ -48,7 +52,8 @@ def ls(author: Optional[str], repo_type: str, pattern: str): :param pattern: Pattern of the repository names. :type pattern: str """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) hf_client = get_hf_client() if not author: diff --git a/hfutils/entry/rollback.py b/hfutils/entry/rollback.py index e3319352f6..6b768e9ce3 100644 --- a/hfutils/entry/rollback.py +++ b/hfutils/entry/rollback.py @@ -5,7 +5,12 @@ from .base import CONTEXT_SETTINGS from ..operate.base import REPO_TYPES, RepoTypeTyping from ..repository import hf_hub_rollback -from ..utils import ColoredFormatter +from ..utils import ColoredFormatter, HF_IS_VERSION_0_X_X, get_requests_session + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None def _add_rollback_subcommand(cli: click.Group) -> click.Group: @@ -43,6 +48,9 @@ def rollback(repo_id: str, repo_type: RepoTypeTyping, revision: str, rollback_to :param revision: The revision of the repository to rollback. :param rollback_to_commit_id: The commit ID to rollback to. """ + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) + # Set up logging logger = logging.getLogger() logger.setLevel(logging.INFO) diff --git a/hfutils/entry/squash.py b/hfutils/entry/squash.py index f2d455b2bb..914031460b 100644 --- a/hfutils/entry/squash.py +++ b/hfutils/entry/squash.py @@ -8,11 +8,15 @@ from typing import Optional import click -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS, command_wrap from ..operate.base import REPO_TYPES, RepoTypeTyping, get_hf_client -from ..utils import get_requests_session, hf_fs_path +from ..utils import get_requests_session, hf_fs_path, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None def _add_squash_subcommand(cli: click.Group) -> click.Group: @@ -59,7 +63,9 @@ def squash(repo_id: str, repo_type: RepoTypeTyping, revision: str, message: Opti :param message: Optional commit message for the squash operation. :type message: Optional[str] """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) + hf_client = get_hf_client() hf_client.super_squash_history( repo_id=repo_id, diff --git a/hfutils/entry/tree.py b/hfutils/entry/tree.py index 700fa04203..f5dc6d4778 100644 --- a/hfutils/entry/tree.py +++ b/hfutils/entry/tree.py @@ -22,13 +22,17 @@ import click from hbutils.string import format_tree -from huggingface_hub import configure_http_backend from huggingface_hub.hf_api import RepoFile from natsort import natsorted from .base import CONTEXT_SETTINGS from ..operate.base import REPO_TYPES, list_files_in_repository, RepoTypeTyping, get_hf_client -from ..utils import get_requests_session, hf_normpath, get_file_type, hf_fs_path, FileItemType +from ..utils import get_requests_session, hf_normpath, get_file_type, hf_fs_path, FileItemType, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None @dataclasses.dataclass @@ -221,7 +225,8 @@ def tree(repo_id: str, repo_type: RepoTypeTyping, dir_in_repo, revision: str, sh :param show_all: Whether to show hidden files. :type show_all: bool """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) _tree = _get_tree( repo_id=repo_id, diff --git a/hfutils/entry/upload.py b/hfutils/entry/upload.py index 600f76dffb..781a294e38 100644 --- a/hfutils/entry/upload.py +++ b/hfutils/entry/upload.py @@ -15,12 +15,16 @@ from typing import Optional import click -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS, command_wrap, ClickErrorException from ..operate import upload_file_to_file, upload_directory_as_archive, upload_directory_as_directory from ..operate.base import REPO_TYPES, RepoTypeTyping, get_hf_client -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None class NoRemotePathAssignedWithUpload(ClickErrorException): @@ -123,7 +127,8 @@ def upload(repo_id: str, repo_type: RepoTypeTyping, :raises NoRemotePathAssignedWithUpload: If no upload mode is specified. :raises ValueError: If conflicting visibility settings are provided. """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) if not file_in_repo and not archive_in_repo and not dir_in_repo: raise NoRemotePathAssignedWithUpload('No remote path in repository assigned.\n' diff --git a/hfutils/entry/warmup.py b/hfutils/entry/warmup.py index 6ac38147bd..1fe99e9d7a 100644 --- a/hfutils/entry/warmup.py +++ b/hfutils/entry/warmup.py @@ -14,12 +14,16 @@ from typing import Optional import click -from huggingface_hub import configure_http_backend from .base import CONTEXT_SETTINGS, command_wrap, ClickErrorException from ..operate import hf_warmup_file, hf_warmup_directory from ..operate.base import REPO_TYPES, RepoTypeTyping -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None class NoRemotePathAssignedWithWarmup(ClickErrorException): @@ -100,7 +104,8 @@ def warmup( :raises NoRemotePathAssignedWithWarmup: If no remote path in repository is assigned. """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) if not file_in_repo and not dir_in_repo: raise NoRemotePathAssignedWithWarmup('No remote path in repository assigned.\n' diff --git a/hfutils/entry/whoami.py b/hfutils/entry/whoami.py index 3e2f0fda91..0549cfe7a4 100644 --- a/hfutils/entry/whoami.py +++ b/hfutils/entry/whoami.py @@ -1,12 +1,16 @@ import click from hbutils.string import plural_word -from huggingface_hub import configure_http_backend from huggingface_hub.utils import LocalTokenNotFoundError from .base import CONTEXT_SETTINGS from ..meta import hf_site_info from ..operate.base import get_hf_client -from ..utils import get_requests_session +from ..utils import get_requests_session, HF_IS_VERSION_0_X_X + +if HF_IS_VERSION_0_X_X: + from huggingface_hub import configure_http_backend +else: + configure_http_backend = None def _add_whoami_subcommand(cli: click.Group) -> click.Group: @@ -31,7 +35,8 @@ def whoami(): This function retrieves the current user's identification from the Hugging Face Hub API and displays it. """ - configure_http_backend(get_requests_session) + if HF_IS_VERSION_0_X_X: + configure_http_backend(get_requests_session) hf_client = get_hf_client() try: diff --git a/hfutils/utils/__init__.py b/hfutils/utils/__init__.py index 7e7ce90672..ce5eab18a8 100644 --- a/hfutils/utils/__init__.py +++ b/hfutils/utils/__init__.py @@ -13,4 +13,5 @@ from .temp import TemporaryDirectory from .tqdm_ import tqdm from .type_ import FileItemType, get_file_type +from .version import HF_IS_VERSION_0_X_X, HF_IS_VERSION_1_X_X from .walk import walk_files diff --git a/hfutils/utils/version.py b/hfutils/utils/version.py new file mode 100644 index 0000000000..144a67bed0 --- /dev/null +++ b/hfutils/utils/version.py @@ -0,0 +1,4 @@ +from hbutils.testing import vpip + +HF_IS_VERSION_1_X_X = (vpip('huggingface_hub') >= '1.0.0') +HF_IS_VERSION_0_X_X = (vpip('huggingface_hub') < '1.0.0') diff --git a/test/entry/test_ls.py b/test/entry/test_ls.py index 6dbcfd72ab..1e10bcf28c 100644 --- a/test/entry/test_ls.py +++ b/test/entry/test_ls.py @@ -30,7 +30,7 @@ def test_simple_ls_2(self): assert result.exitcode == 0 assert click.unstyle(result.stdout).splitlines(keepends=False) == [ 'arknights', 'azurlane', 'bluearchive', 'fgo', 'genshin', 'girlsfrontline', 'neuralcloud', 'nikke', - 'pathtonowhere', 'starrail'] + 'pathtonowhere', 'starrail', 'README.md'] def test_simple_ls_2_all(self): result = simulate_entry(hfutilscli, [ @@ -41,7 +41,7 @@ def test_simple_ls_2_all(self): assert result.exitcode == 0 assert click.unstyle(result.stdout).splitlines(keepends=False) == [ 'arknights', 'azurlane', 'bluearchive', 'fgo', 'genshin', 'girlsfrontline', 'neuralcloud', 'nikke', - 'pathtonowhere', 'starrail', '.gitattributes'] + 'pathtonowhere', 'starrail', '.gitattributes', 'README.md'] def test_simple_3(self): result = simulate_entry(hfutilscli, [ From c35b45a658b366b8306a5a7d5dcd59c35103a832 Mon Sep 17 00:00:00 2001 From: narugo1992 Date: Tue, 16 Dec 2025 13:49:38 +0800 Subject: [PATCH 3/5] dev(hansbug): update hf_transfer conflict check --- hfutils/index/fetch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hfutils/index/fetch.py b/hfutils/index/fetch.py index 17f37c007f..e1110f2955 100644 --- a/hfutils/index/fetch.py +++ b/hfutils/index/fetch.py @@ -17,7 +17,7 @@ from .hash import _f_sha256 from ..operate.base import RepoTypeTyping, get_hf_client -from ..utils import hf_normpath, BinaryProxyIO +from ..utils import hf_normpath, BinaryProxyIO, HF_IS_VERSION_0_X_X class ArchiveStandaloneFileIncompleteDownload(Exception): @@ -699,7 +699,7 @@ def _hf_tar_file_info_write(repo_id: str, archive_in_repo: str, file_in_archive: def _check_hf_transfer_conflict(): - if constants.HF_HUB_ENABLE_HF_TRANSFER and vpip('huggingface_hub') < '0.31': + if HF_IS_VERSION_0_X_X and constants.HF_HUB_ENABLE_HF_TRANSFER and vpip('huggingface_hub') < '0.31': warnings.warn(f"You are trying to use huggingface_hub=={huggingface_hub.__version__} " f"with hf_transfer enabled at the same time, this may cause unexpected error " f"(see: https://github.com/huggingface/huggingface_hub/issues/2978 for more details). " From c779d325b927d924119df4e134cc89caa68fac99 Mon Sep 17 00:00:00 2001 From: narugo1992 Date: Tue, 16 Dec 2025 14:13:51 +0800 Subject: [PATCH 4/5] dev(hansbug): migrate HF_TOKEN='' to support it, use token=False --- hfutils/entry/ls_repo.py | 3 +++ hfutils/entry/whoami.py | 3 +++ hfutils/operate/base.py | 6 +++--- hfutils/repository/clone.py | 4 +++- test/entry/test_whoami.py | 12 +++++++++--- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/hfutils/entry/ls_repo.py b/hfutils/entry/ls_repo.py index 79af41e115..2b8602f137 100644 --- a/hfutils/entry/ls_repo.py +++ b/hfutils/entry/ls_repo.py @@ -58,6 +58,9 @@ def ls(author: Optional[str], repo_type: str, pattern: str): hf_client = get_hf_client() if not author: try: + if not hf_client.token: + raise LocalTokenNotFoundError + info = hf_client.whoami() author = author or info['name'] except LocalTokenNotFoundError: diff --git a/hfutils/entry/whoami.py b/hfutils/entry/whoami.py index 0549cfe7a4..5e9996a565 100644 --- a/hfutils/entry/whoami.py +++ b/hfutils/entry/whoami.py @@ -40,6 +40,9 @@ def whoami(): hf_client = get_hf_client() try: + if not hf_client.token: + raise LocalTokenNotFoundError + info = hf_client.whoami() username = info['name'] click.echo(f'Hi, {click.style(f"@{username}", fg="green", bold=True)} ' diff --git a/hfutils/operate/base.py b/hfutils/operate/base.py index ace1b01d67..d7076a9d3e 100644 --- a/hfutils/operate/base.py +++ b/hfutils/operate/base.py @@ -70,7 +70,7 @@ def get_hf_client(hf_token: Optional[str] = None) -> HfApi: >>> # Use client to interact with Hugging Face API >>> models = client.list_models(limit=5) """ - return HfApi(token=hf_token or _get_hf_token()) + return HfApi(token=hf_token or _get_hf_token() or False) @lru_cache() @@ -96,7 +96,7 @@ def get_hf_fs(hf_token: Optional[str] = None) -> HfFileSystem: """ # use_listings_cache=False is necessary # or the result of glob and ls will be cached, the unittest will down - return HfFileSystem(token=hf_token or _get_hf_token(), use_listings_cache=False) + return HfFileSystem(token=hf_token or _get_hf_token() or False, use_listings_cache=False) def _fn_path_pattern_norm(pattern: Union[List[str], str]) -> Union[List[str], str]: @@ -436,4 +436,4 @@ def list_files_in_repository( raise_when_base_not_exist=raise_when_base_not_exist, hf_token=hf_token, ) - ] \ No newline at end of file + ] diff --git a/hfutils/repository/clone.py b/hfutils/repository/clone.py index 4b5e0ba5bf..e85d4129e3 100644 --- a/hfutils/repository/clone.py +++ b/hfutils/repository/clone.py @@ -54,6 +54,8 @@ def hf_hub_clone(repo_id: str, dst_dir: str, _git = _check_git(requires_lfs=not no_lfs) hf_client = get_hf_client(hf_token) try: + if not hf_client.token: + raise LocalTokenNotFoundError username = hf_client.whoami()['name'] except LocalTokenNotFoundError: username = None # anonymous mode @@ -63,7 +65,7 @@ def hf_hub_clone(repo_id: str, dst_dir: str, repo_type=repo_type, endpoint=endpoint, )) - if username: + if username and hf_client.token: clone_url = clone_url.with_username(username).with_password(hf_client.token) clone_url = str(clone_url) diff --git a/test/entry/test_whoami.py b/test/entry/test_whoami.py index 48e2ba0662..fb7c8d7223 100644 --- a/test/entry/test_whoami.py +++ b/test/entry/test_whoami.py @@ -12,7 +12,7 @@ @pytest.fixture() def no_hf_token(): def _get_hf_client(): - return HfApi(token='') + return HfApi(token=False) with patch('hfutils.entry.whoami.get_hf_client', _get_hf_client), \ patch.dict(os.environ, {'HF_TOKEN': ''}): @@ -25,7 +25,10 @@ def test_simple_whoami(self): result = simulate_entry(hfutilscli, [ 'hfutils', 'whoami', ]) - assert result.exitcode == 0 + assert result.exitcode == 0, (f'Exitcode: {result.exitcode!r}\n' + f'Error: {result.error!r}\n' + f'========= Stdout =========\n{result.stdout}\n' + f'========= Stderr =========\n{result.stderr}\n') text = click.unstyle(result.stdout) lines = text.splitlines(keepends=False) assert 'Hi, @narugo1992 (full name: Naomi Rue Golding).' in lines @@ -44,7 +47,10 @@ def test_whoami_guest(self, no_hf_token): result = simulate_entry(hfutilscli, [ 'hfutils', 'whoami', ]) - assert result.exitcode == 0 + assert result.exitcode == 0, (f'Exitcode: {result.exitcode!r}\n' + f'Error: {result.error!r}\n' + f'========= Stdout =========\n{result.stdout}\n' + f'========= Stderr =========\n{result.stderr}\n') text = click.unstyle(result.stdout) lines = text.splitlines(keepends=False) assert 'Hi, Guest (not authenticated).' in lines From 5019583abcba45e5f4dfe56c3c6a4b26255e872f Mon Sep 17 00:00:00 2001 From: narugo1992 Date: Tue, 16 Dec 2025 14:50:40 +0800 Subject: [PATCH 5/5] dev(narugo): use token=None --- hfutils/operate/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hfutils/operate/base.py b/hfutils/operate/base.py index d7076a9d3e..7fe2902cc2 100644 --- a/hfutils/operate/base.py +++ b/hfutils/operate/base.py @@ -70,7 +70,7 @@ def get_hf_client(hf_token: Optional[str] = None) -> HfApi: >>> # Use client to interact with Hugging Face API >>> models = client.list_models(limit=5) """ - return HfApi(token=hf_token or _get_hf_token() or False) + return HfApi(token=hf_token or _get_hf_token() or None) @lru_cache() @@ -96,7 +96,7 @@ def get_hf_fs(hf_token: Optional[str] = None) -> HfFileSystem: """ # use_listings_cache=False is necessary # or the result of glob and ls will be cached, the unittest will down - return HfFileSystem(token=hf_token or _get_hf_token() or False, use_listings_cache=False) + return HfFileSystem(token=hf_token or _get_hf_token() or None, use_listings_cache=False) def _fn_path_pattern_norm(pattern: Union[List[str], str]) -> Union[List[str], str]: