huggingface-hub 0.31.0rc0__py3-none-any.whl → 1.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- huggingface_hub/__init__.py +145 -46
- huggingface_hub/_commit_api.py +168 -119
- huggingface_hub/_commit_scheduler.py +15 -15
- huggingface_hub/_inference_endpoints.py +15 -12
- huggingface_hub/_jobs_api.py +301 -0
- huggingface_hub/_local_folder.py +18 -3
- huggingface_hub/_login.py +31 -63
- huggingface_hub/_oauth.py +460 -0
- huggingface_hub/_snapshot_download.py +239 -80
- huggingface_hub/_space_api.py +5 -5
- huggingface_hub/_tensorboard_logger.py +15 -19
- huggingface_hub/_upload_large_folder.py +172 -76
- huggingface_hub/_webhooks_payload.py +3 -3
- huggingface_hub/_webhooks_server.py +13 -25
- huggingface_hub/{commands → cli}/__init__.py +1 -15
- huggingface_hub/cli/_cli_utils.py +173 -0
- huggingface_hub/cli/auth.py +147 -0
- huggingface_hub/cli/cache.py +841 -0
- huggingface_hub/cli/download.py +189 -0
- huggingface_hub/cli/hf.py +60 -0
- huggingface_hub/cli/inference_endpoints.py +377 -0
- huggingface_hub/cli/jobs.py +772 -0
- huggingface_hub/cli/lfs.py +175 -0
- huggingface_hub/cli/repo.py +315 -0
- huggingface_hub/cli/repo_files.py +94 -0
- huggingface_hub/{commands/env.py → cli/system.py} +10 -13
- huggingface_hub/cli/upload.py +294 -0
- huggingface_hub/cli/upload_large_folder.py +117 -0
- huggingface_hub/community.py +20 -12
- huggingface_hub/constants.py +38 -53
- huggingface_hub/dataclasses.py +609 -0
- huggingface_hub/errors.py +80 -30
- huggingface_hub/fastai_utils.py +30 -41
- huggingface_hub/file_download.py +435 -351
- huggingface_hub/hf_api.py +2050 -1124
- huggingface_hub/hf_file_system.py +269 -152
- huggingface_hub/hub_mixin.py +43 -63
- huggingface_hub/inference/_client.py +347 -434
- huggingface_hub/inference/_common.py +133 -121
- huggingface_hub/inference/_generated/_async_client.py +397 -541
- huggingface_hub/inference/_generated/types/__init__.py +5 -1
- huggingface_hub/inference/_generated/types/automatic_speech_recognition.py +3 -3
- huggingface_hub/inference/_generated/types/base.py +10 -7
- huggingface_hub/inference/_generated/types/chat_completion.py +59 -23
- huggingface_hub/inference/_generated/types/depth_estimation.py +2 -2
- huggingface_hub/inference/_generated/types/document_question_answering.py +2 -2
- huggingface_hub/inference/_generated/types/feature_extraction.py +2 -2
- huggingface_hub/inference/_generated/types/fill_mask.py +2 -2
- huggingface_hub/inference/_generated/types/image_to_image.py +6 -2
- huggingface_hub/inference/_generated/types/image_to_video.py +60 -0
- huggingface_hub/inference/_generated/types/sentence_similarity.py +3 -3
- huggingface_hub/inference/_generated/types/summarization.py +2 -2
- huggingface_hub/inference/_generated/types/table_question_answering.py +5 -5
- huggingface_hub/inference/_generated/types/text2text_generation.py +2 -2
- huggingface_hub/inference/_generated/types/text_generation.py +10 -10
- huggingface_hub/inference/_generated/types/text_to_video.py +2 -2
- huggingface_hub/inference/_generated/types/token_classification.py +2 -2
- huggingface_hub/inference/_generated/types/translation.py +2 -2
- huggingface_hub/inference/_generated/types/zero_shot_classification.py +2 -2
- huggingface_hub/inference/_generated/types/zero_shot_image_classification.py +2 -2
- huggingface_hub/inference/_generated/types/zero_shot_object_detection.py +1 -3
- huggingface_hub/inference/_mcp/__init__.py +0 -0
- huggingface_hub/inference/_mcp/_cli_hacks.py +88 -0
- huggingface_hub/inference/_mcp/agent.py +100 -0
- huggingface_hub/inference/_mcp/cli.py +247 -0
- huggingface_hub/inference/_mcp/constants.py +81 -0
- huggingface_hub/inference/_mcp/mcp_client.py +395 -0
- huggingface_hub/inference/_mcp/types.py +45 -0
- huggingface_hub/inference/_mcp/utils.py +128 -0
- huggingface_hub/inference/_providers/__init__.py +82 -7
- huggingface_hub/inference/_providers/_common.py +129 -27
- huggingface_hub/inference/_providers/black_forest_labs.py +6 -6
- huggingface_hub/inference/_providers/cerebras.py +1 -1
- huggingface_hub/inference/_providers/clarifai.py +13 -0
- huggingface_hub/inference/_providers/cohere.py +20 -3
- huggingface_hub/inference/_providers/fal_ai.py +183 -56
- huggingface_hub/inference/_providers/featherless_ai.py +38 -0
- huggingface_hub/inference/_providers/fireworks_ai.py +18 -0
- huggingface_hub/inference/_providers/groq.py +9 -0
- huggingface_hub/inference/_providers/hf_inference.py +69 -30
- huggingface_hub/inference/_providers/hyperbolic.py +4 -4
- huggingface_hub/inference/_providers/nebius.py +33 -5
- huggingface_hub/inference/_providers/novita.py +5 -5
- huggingface_hub/inference/_providers/nscale.py +44 -0
- huggingface_hub/inference/_providers/openai.py +3 -1
- huggingface_hub/inference/_providers/publicai.py +6 -0
- huggingface_hub/inference/_providers/replicate.py +31 -13
- huggingface_hub/inference/_providers/sambanova.py +18 -4
- huggingface_hub/inference/_providers/scaleway.py +28 -0
- huggingface_hub/inference/_providers/together.py +20 -5
- huggingface_hub/inference/_providers/wavespeed.py +138 -0
- huggingface_hub/inference/_providers/zai_org.py +17 -0
- huggingface_hub/lfs.py +33 -100
- huggingface_hub/repocard.py +34 -38
- huggingface_hub/repocard_data.py +57 -57
- huggingface_hub/serialization/__init__.py +0 -1
- huggingface_hub/serialization/_base.py +12 -15
- huggingface_hub/serialization/_dduf.py +8 -8
- huggingface_hub/serialization/_torch.py +69 -69
- huggingface_hub/utils/__init__.py +19 -8
- huggingface_hub/utils/_auth.py +7 -7
- huggingface_hub/utils/_cache_manager.py +92 -147
- huggingface_hub/utils/_chunk_utils.py +2 -3
- huggingface_hub/utils/_deprecation.py +1 -1
- huggingface_hub/utils/_dotenv.py +55 -0
- huggingface_hub/utils/_experimental.py +7 -5
- huggingface_hub/utils/_fixes.py +0 -10
- huggingface_hub/utils/_git_credential.py +5 -5
- huggingface_hub/utils/_headers.py +8 -30
- huggingface_hub/utils/_http.py +398 -239
- huggingface_hub/utils/_pagination.py +4 -4
- huggingface_hub/utils/_parsing.py +98 -0
- huggingface_hub/utils/_paths.py +5 -5
- huggingface_hub/utils/_runtime.py +61 -24
- huggingface_hub/utils/_safetensors.py +21 -21
- huggingface_hub/utils/_subprocess.py +9 -9
- huggingface_hub/utils/_telemetry.py +4 -4
- huggingface_hub/{commands/_cli_utils.py → utils/_terminal.py} +4 -4
- huggingface_hub/utils/_typing.py +25 -5
- huggingface_hub/utils/_validators.py +55 -74
- huggingface_hub/utils/_verification.py +167 -0
- huggingface_hub/utils/_xet.py +64 -17
- huggingface_hub/utils/_xet_progress_reporting.py +162 -0
- huggingface_hub/utils/insecure_hashlib.py +3 -5
- huggingface_hub/utils/logging.py +8 -11
- huggingface_hub/utils/tqdm.py +5 -4
- {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/METADATA +94 -85
- huggingface_hub-1.1.3.dist-info/RECORD +155 -0
- {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/WHEEL +1 -1
- huggingface_hub-1.1.3.dist-info/entry_points.txt +6 -0
- huggingface_hub/commands/delete_cache.py +0 -474
- huggingface_hub/commands/download.py +0 -200
- huggingface_hub/commands/huggingface_cli.py +0 -61
- huggingface_hub/commands/lfs.py +0 -200
- huggingface_hub/commands/repo_files.py +0 -128
- huggingface_hub/commands/scan_cache.py +0 -181
- huggingface_hub/commands/tag.py +0 -159
- huggingface_hub/commands/upload.py +0 -314
- huggingface_hub/commands/upload_large_folder.py +0 -129
- huggingface_hub/commands/user.py +0 -304
- huggingface_hub/commands/version.py +0 -37
- huggingface_hub/inference_api.py +0 -217
- huggingface_hub/keras_mixin.py +0 -500
- huggingface_hub/repository.py +0 -1477
- huggingface_hub/serialization/_tensorflow.py +0 -95
- huggingface_hub/utils/_hf_folder.py +0 -68
- huggingface_hub-0.31.0rc0.dist-info/RECORD +0 -135
- huggingface_hub-0.31.0rc0.dist-info/entry_points.txt +0 -6
- {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info/licenses}/LICENSE +0 -0
- {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/top_level.txt +0 -0
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""Contains utilities to handle pagination on Huggingface Hub."""
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Iterable, Optional
|
|
18
18
|
|
|
19
|
-
import
|
|
19
|
+
import httpx
|
|
20
20
|
|
|
21
21
|
from . import get_session, hf_raise_for_status, http_backoff, logging
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ from . import get_session, hf_raise_for_status, http_backoff, logging
|
|
|
24
24
|
logger = logging.get_logger(__name__)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def paginate(path: str, params:
|
|
27
|
+
def paginate(path: str, params: dict, headers: dict) -> Iterable:
|
|
28
28
|
"""Fetch a list of models/datasets/spaces and paginate through results.
|
|
29
29
|
|
|
30
30
|
This is using the same "Link" header format as GitHub.
|
|
@@ -48,5 +48,5 @@ def paginate(path: str, params: Dict, headers: Dict) -> Iterable:
|
|
|
48
48
|
next_page = _get_next_page(r)
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def _get_next_page(response:
|
|
51
|
+
def _get_next_page(response: httpx.Response) -> Optional[str]:
|
|
52
52
|
return response.links.get("next", {}).get("url")
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# Copyright 2025-present, the HuggingFace Inc. team.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
"""Parsing helpers shared across modules."""
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
import time
|
|
19
|
+
from typing import Dict
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
RE_NUMBER_WITH_UNIT = re.compile(r"(\d+)([a-z]+)", re.IGNORECASE)
|
|
23
|
+
|
|
24
|
+
BYTE_UNITS: Dict[str, int] = {
|
|
25
|
+
"k": 1_000,
|
|
26
|
+
"m": 1_000_000,
|
|
27
|
+
"g": 1_000_000_000,
|
|
28
|
+
"t": 1_000_000_000_000,
|
|
29
|
+
"p": 1_000_000_000_000_000,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
TIME_UNITS: Dict[str, int] = {
|
|
33
|
+
"s": 1,
|
|
34
|
+
"m": 60,
|
|
35
|
+
"h": 60 * 60,
|
|
36
|
+
"d": 24 * 60 * 60,
|
|
37
|
+
"w": 7 * 24 * 60 * 60,
|
|
38
|
+
"mo": 30 * 24 * 60 * 60,
|
|
39
|
+
"y": 365 * 24 * 60 * 60,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def parse_size(value: str) -> int:
|
|
44
|
+
"""Parse a size expressed as a string with digits and unit (like `"10MB"`) to an integer (in bytes)."""
|
|
45
|
+
return _parse_with_unit(value, BYTE_UNITS)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def parse_duration(value: str) -> int:
|
|
49
|
+
"""Parse a duration expressed as a string with digits and unit (like `"10s"`) to an integer (in seconds)."""
|
|
50
|
+
return _parse_with_unit(value, TIME_UNITS)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _parse_with_unit(value: str, units: Dict[str, int]) -> int:
|
|
54
|
+
"""Parse a numeric value with optional unit."""
|
|
55
|
+
stripped = value.strip()
|
|
56
|
+
if not stripped:
|
|
57
|
+
raise ValueError("Value cannot be empty.")
|
|
58
|
+
try:
|
|
59
|
+
return int(value)
|
|
60
|
+
except ValueError:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
match = RE_NUMBER_WITH_UNIT.fullmatch(stripped)
|
|
64
|
+
if not match:
|
|
65
|
+
raise ValueError(f"Invalid value '{value}'. Must match pattern '\\d+[a-z]+' or be a plain number.")
|
|
66
|
+
|
|
67
|
+
number = int(match.group(1))
|
|
68
|
+
unit = match.group(2).lower()
|
|
69
|
+
|
|
70
|
+
if unit not in units:
|
|
71
|
+
raise ValueError(f"Unknown unit '{unit}'. Must be one of {list(units.keys())}.")
|
|
72
|
+
|
|
73
|
+
return number * units[unit]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def format_timesince(ts: float) -> str:
|
|
77
|
+
"""Format timestamp in seconds into a human-readable string, relative to now.
|
|
78
|
+
|
|
79
|
+
Vaguely inspired by Django's `timesince` formatter.
|
|
80
|
+
"""
|
|
81
|
+
_TIMESINCE_CHUNKS = (
|
|
82
|
+
# Label, divider, max value
|
|
83
|
+
("second", 1, 60),
|
|
84
|
+
("minute", 60, 60),
|
|
85
|
+
("hour", 60 * 60, 24),
|
|
86
|
+
("day", 60 * 60 * 24, 6),
|
|
87
|
+
("week", 60 * 60 * 24 * 7, 6),
|
|
88
|
+
("month", 60 * 60 * 24 * 30, 11),
|
|
89
|
+
("year", 60 * 60 * 24 * 365, None),
|
|
90
|
+
)
|
|
91
|
+
delta = time.time() - ts
|
|
92
|
+
if delta < 20:
|
|
93
|
+
return "a few seconds ago"
|
|
94
|
+
for label, divider, max_value in _TIMESINCE_CHUNKS: # noqa: B007
|
|
95
|
+
value = round(delta / divider)
|
|
96
|
+
if max_value is not None and value <= max_value:
|
|
97
|
+
break
|
|
98
|
+
return f"{value} {label}{'s' if value > 1 else ''} ago"
|
huggingface_hub/utils/_paths.py
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from fnmatch import fnmatch
|
|
18
18
|
from pathlib import Path
|
|
19
|
-
from typing import Callable, Generator, Iterable,
|
|
19
|
+
from typing import Callable, Generator, Iterable, Optional, TypeVar, Union
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
T = TypeVar("T")
|
|
@@ -39,8 +39,8 @@ FORBIDDEN_FOLDERS = [".git", ".cache"]
|
|
|
39
39
|
def filter_repo_objects(
|
|
40
40
|
items: Iterable[T],
|
|
41
41
|
*,
|
|
42
|
-
allow_patterns: Optional[Union[
|
|
43
|
-
ignore_patterns: Optional[Union[
|
|
42
|
+
allow_patterns: Optional[Union[list[str], str]] = None,
|
|
43
|
+
ignore_patterns: Optional[Union[list[str], str]] = None,
|
|
44
44
|
key: Optional[Callable[[T], str]] = None,
|
|
45
45
|
) -> Generator[T, None, None]:
|
|
46
46
|
"""Filter repo objects based on an allowlist and a denylist.
|
|
@@ -55,10 +55,10 @@ def filter_repo_objects(
|
|
|
55
55
|
Args:
|
|
56
56
|
items (`Iterable`):
|
|
57
57
|
List of items to filter.
|
|
58
|
-
allow_patterns (`str` or `
|
|
58
|
+
allow_patterns (`str` or `list[str]`, *optional*):
|
|
59
59
|
Patterns constituting the allowlist. If provided, item paths must match at
|
|
60
60
|
least one pattern from the allowlist.
|
|
61
|
-
ignore_patterns (`str` or `
|
|
61
|
+
ignore_patterns (`str` or `list[str]`, *optional*):
|
|
62
62
|
Patterns constituting the denylist. If provided, item paths must not match
|
|
63
63
|
any patterns from the denylist.
|
|
64
64
|
key (`Callable[[T], str]`, *optional*):
|
|
@@ -19,7 +19,8 @@ import os
|
|
|
19
19
|
import platform
|
|
20
20
|
import sys
|
|
21
21
|
import warnings
|
|
22
|
-
from
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Any, Literal
|
|
23
24
|
|
|
24
25
|
from .. import __version__, constants
|
|
25
26
|
|
|
@@ -35,9 +36,9 @@ _CANDIDATES = {
|
|
|
35
36
|
"fastcore": {"fastcore"},
|
|
36
37
|
"gradio": {"gradio"},
|
|
37
38
|
"graphviz": {"graphviz"},
|
|
38
|
-
"hf_transfer": {"hf_transfer"},
|
|
39
39
|
"hf_xet": {"hf_xet"},
|
|
40
40
|
"jinja": {"Jinja2"},
|
|
41
|
+
"httpx": {"httpx"},
|
|
41
42
|
"keras": {"keras"},
|
|
42
43
|
"numpy": {"numpy"},
|
|
43
44
|
"pillow": {"Pillow"},
|
|
@@ -143,19 +144,19 @@ def get_graphviz_version() -> str:
|
|
|
143
144
|
return _get_version("graphviz")
|
|
144
145
|
|
|
145
146
|
|
|
146
|
-
#
|
|
147
|
-
def
|
|
148
|
-
return is_package_available("
|
|
147
|
+
# httpx
|
|
148
|
+
def is_httpx_available() -> bool:
|
|
149
|
+
return is_package_available("httpx")
|
|
149
150
|
|
|
150
151
|
|
|
151
|
-
def
|
|
152
|
-
return _get_version("
|
|
152
|
+
def get_httpx_version() -> str:
|
|
153
|
+
return _get_version("httpx")
|
|
153
154
|
|
|
154
155
|
|
|
155
156
|
# xet
|
|
156
157
|
def is_xet_available() -> bool:
|
|
157
158
|
# since hf_xet is automatically used if available, allow explicit disabling via environment variable
|
|
158
|
-
if constants.
|
|
159
|
+
if constants.HF_HUB_DISABLE_XET:
|
|
159
160
|
return False
|
|
160
161
|
|
|
161
162
|
return is_package_available("hf_xet")
|
|
@@ -312,7 +313,50 @@ def is_colab_enterprise() -> bool:
|
|
|
312
313
|
return os.environ.get("VERTEX_PRODUCT") == "COLAB_ENTERPRISE"
|
|
313
314
|
|
|
314
315
|
|
|
315
|
-
|
|
316
|
+
# Check how huggingface_hub has been installed
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def installation_method() -> Literal["brew", "hf_installer", "unknown"]:
|
|
320
|
+
"""Return the installation method of the current environment.
|
|
321
|
+
|
|
322
|
+
- "hf_installer" if installed via the official installer script
|
|
323
|
+
- "brew" if installed via Homebrew
|
|
324
|
+
- "unknown" otherwise
|
|
325
|
+
"""
|
|
326
|
+
if _is_brew_installation():
|
|
327
|
+
return "brew"
|
|
328
|
+
elif _is_hf_installer_installation():
|
|
329
|
+
return "hf_installer"
|
|
330
|
+
else:
|
|
331
|
+
return "unknown"
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _is_brew_installation() -> bool:
|
|
335
|
+
"""Check if running from a Homebrew installation.
|
|
336
|
+
|
|
337
|
+
Note: AI-generated by Claude.
|
|
338
|
+
"""
|
|
339
|
+
exe_path = Path(sys.executable).resolve()
|
|
340
|
+
exe_str = str(exe_path)
|
|
341
|
+
|
|
342
|
+
# Check common Homebrew paths
|
|
343
|
+
# /opt/homebrew (Apple Silicon), /usr/local (Intel)
|
|
344
|
+
return "/Cellar/" in exe_str or "/opt/homebrew/" in exe_str or exe_str.startswith("/usr/local/Cellar/")
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def _is_hf_installer_installation() -> bool:
|
|
348
|
+
"""Return `True` if the current environment was set up via the official hf installer script.
|
|
349
|
+
|
|
350
|
+
i.e. using one of
|
|
351
|
+
curl -LsSf https://hf.co/cli/install.sh | bash
|
|
352
|
+
powershell -ExecutionPolicy ByPass -c "irm https://hf.co/cli/install.ps1 | iex"
|
|
353
|
+
"""
|
|
354
|
+
venv = sys.prefix # points to venv root if active
|
|
355
|
+
marker = Path(venv) / ".hf_installer_marker"
|
|
356
|
+
return marker.exists()
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def dump_environment_info() -> dict[str, Any]:
|
|
316
360
|
"""Dump information about the machine to help debugging issues.
|
|
317
361
|
|
|
318
362
|
Similar helper exist in:
|
|
@@ -326,7 +370,7 @@ def dump_environment_info() -> Dict[str, Any]:
|
|
|
326
370
|
token = get_token()
|
|
327
371
|
|
|
328
372
|
# Generic machine info
|
|
329
|
-
info:
|
|
373
|
+
info: dict[str, Any] = {
|
|
330
374
|
"huggingface_hub version": get_hf_hub_version(),
|
|
331
375
|
"Platform": platform.platform(),
|
|
332
376
|
"Python version": get_python_version(),
|
|
@@ -356,22 +400,14 @@ def dump_environment_info() -> Dict[str, Any]:
|
|
|
356
400
|
except Exception:
|
|
357
401
|
pass
|
|
358
402
|
|
|
403
|
+
# How huggingface_hub has been installed?
|
|
404
|
+
info["Installation method"] = installation_method()
|
|
405
|
+
|
|
359
406
|
# Installed dependencies
|
|
360
|
-
info["
|
|
361
|
-
info["
|
|
362
|
-
info["Torch"] = get_torch_version()
|
|
363
|
-
info["Jinja2"] = get_jinja_version()
|
|
364
|
-
info["Graphviz"] = get_graphviz_version()
|
|
365
|
-
info["keras"] = get_keras_version()
|
|
366
|
-
info["Pydot"] = get_pydot_version()
|
|
367
|
-
info["Pillow"] = get_pillow_version()
|
|
368
|
-
info["hf_transfer"] = get_hf_transfer_version()
|
|
407
|
+
info["httpx"] = get_httpx_version()
|
|
408
|
+
info["hf_xet"] = get_xet_version()
|
|
369
409
|
info["gradio"] = get_gradio_version()
|
|
370
410
|
info["tensorboard"] = get_tensorboard_version()
|
|
371
|
-
info["numpy"] = get_numpy_version()
|
|
372
|
-
info["pydantic"] = get_pydantic_version()
|
|
373
|
-
info["aiohttp"] = get_aiohttp_version()
|
|
374
|
-
info["hf_xet"] = get_xet_version()
|
|
375
411
|
|
|
376
412
|
# Environment variables
|
|
377
413
|
info["ENDPOINT"] = constants.ENDPOINT
|
|
@@ -385,9 +421,10 @@ def dump_environment_info() -> Dict[str, Any]:
|
|
|
385
421
|
info["HF_HUB_DISABLE_SYMLINKS_WARNING"] = constants.HF_HUB_DISABLE_SYMLINKS_WARNING
|
|
386
422
|
info["HF_HUB_DISABLE_EXPERIMENTAL_WARNING"] = constants.HF_HUB_DISABLE_EXPERIMENTAL_WARNING
|
|
387
423
|
info["HF_HUB_DISABLE_IMPLICIT_TOKEN"] = constants.HF_HUB_DISABLE_IMPLICIT_TOKEN
|
|
388
|
-
info["
|
|
424
|
+
info["HF_HUB_DISABLE_XET"] = constants.HF_HUB_DISABLE_XET
|
|
389
425
|
info["HF_HUB_ETAG_TIMEOUT"] = constants.HF_HUB_ETAG_TIMEOUT
|
|
390
426
|
info["HF_HUB_DOWNLOAD_TIMEOUT"] = constants.HF_HUB_DOWNLOAD_TIMEOUT
|
|
427
|
+
info["HF_XET_HIGH_PERFORMANCE"] = constants.HF_XET_HIGH_PERFORMANCE
|
|
391
428
|
|
|
392
429
|
print("\nCopy-and-paste the text below in your GitHub issue.\n")
|
|
393
430
|
print("\n".join([f"- {prop}: {val}" for prop, val in info.items()]) + "\n")
|
|
@@ -2,7 +2,7 @@ import functools
|
|
|
2
2
|
import operator
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Literal, Optional
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
FILENAME_T = str
|
|
@@ -19,17 +19,17 @@ class TensorInfo:
|
|
|
19
19
|
Attributes:
|
|
20
20
|
dtype (`str`):
|
|
21
21
|
The data type of the tensor ("F64", "F32", "F16", "BF16", "I64", "I32", "I16", "I8", "U8", "BOOL").
|
|
22
|
-
shape (`
|
|
22
|
+
shape (`list[int]`):
|
|
23
23
|
The shape of the tensor.
|
|
24
|
-
data_offsets (`
|
|
24
|
+
data_offsets (`tuple[int, int]`):
|
|
25
25
|
The offsets of the data in the file as a tuple `[BEGIN, END]`.
|
|
26
26
|
parameter_count (`int`):
|
|
27
27
|
The number of parameters in the tensor.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
dtype: DTYPE_T
|
|
31
|
-
shape:
|
|
32
|
-
data_offsets:
|
|
31
|
+
shape: list[int]
|
|
32
|
+
data_offsets: tuple[int, int]
|
|
33
33
|
parameter_count: int = field(init=False)
|
|
34
34
|
|
|
35
35
|
def __post_init__(self) -> None:
|
|
@@ -49,22 +49,22 @@ class SafetensorsFileMetadata:
|
|
|
49
49
|
For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format.
|
|
50
50
|
|
|
51
51
|
Attributes:
|
|
52
|
-
metadata (`
|
|
52
|
+
metadata (`dict`):
|
|
53
53
|
The metadata contained in the file.
|
|
54
|
-
tensors (`
|
|
54
|
+
tensors (`dict[str, TensorInfo]`):
|
|
55
55
|
A map of all tensors. Keys are tensor names and values are information about the corresponding tensor, as a
|
|
56
56
|
[`TensorInfo`] object.
|
|
57
|
-
parameter_count (`
|
|
57
|
+
parameter_count (`dict[str, int]`):
|
|
58
58
|
A map of the number of parameters per data type. Keys are data types and values are the number of parameters
|
|
59
59
|
of that data type.
|
|
60
60
|
"""
|
|
61
61
|
|
|
62
|
-
metadata:
|
|
63
|
-
tensors:
|
|
64
|
-
parameter_count:
|
|
62
|
+
metadata: dict[str, str]
|
|
63
|
+
tensors: dict[TENSOR_NAME_T, TensorInfo]
|
|
64
|
+
parameter_count: dict[DTYPE_T, int] = field(init=False)
|
|
65
65
|
|
|
66
66
|
def __post_init__(self) -> None:
|
|
67
|
-
parameter_count:
|
|
67
|
+
parameter_count: dict[DTYPE_T, int] = defaultdict(int)
|
|
68
68
|
for tensor in self.tensors.values():
|
|
69
69
|
parameter_count[tensor.dtype] += tensor.parameter_count
|
|
70
70
|
self.parameter_count = dict(parameter_count)
|
|
@@ -82,29 +82,29 @@ class SafetensorsRepoMetadata:
|
|
|
82
82
|
For more details regarding the safetensors format, check out https://huggingface.co/docs/safetensors/index#format.
|
|
83
83
|
|
|
84
84
|
Attributes:
|
|
85
|
-
metadata (`
|
|
85
|
+
metadata (`dict`, *optional*):
|
|
86
86
|
The metadata contained in the 'model.safetensors.index.json' file, if it exists. Only populated for sharded
|
|
87
87
|
models.
|
|
88
88
|
sharded (`bool`):
|
|
89
89
|
Whether the repo contains a sharded model or not.
|
|
90
|
-
weight_map (`
|
|
90
|
+
weight_map (`dict[str, str]`):
|
|
91
91
|
A map of all weights. Keys are tensor names and values are filenames of the files containing the tensors.
|
|
92
|
-
files_metadata (`
|
|
92
|
+
files_metadata (`dict[str, SafetensorsFileMetadata]`):
|
|
93
93
|
A map of all files metadata. Keys are filenames and values are the metadata of the corresponding file, as
|
|
94
94
|
a [`SafetensorsFileMetadata`] object.
|
|
95
|
-
parameter_count (`
|
|
95
|
+
parameter_count (`dict[str, int]`):
|
|
96
96
|
A map of the number of parameters per data type. Keys are data types and values are the number of parameters
|
|
97
97
|
of that data type.
|
|
98
98
|
"""
|
|
99
99
|
|
|
100
|
-
metadata: Optional[
|
|
100
|
+
metadata: Optional[dict]
|
|
101
101
|
sharded: bool
|
|
102
|
-
weight_map:
|
|
103
|
-
files_metadata:
|
|
104
|
-
parameter_count:
|
|
102
|
+
weight_map: dict[TENSOR_NAME_T, FILENAME_T] # tensor name -> filename
|
|
103
|
+
files_metadata: dict[FILENAME_T, SafetensorsFileMetadata] # filename -> metadata
|
|
104
|
+
parameter_count: dict[DTYPE_T, int] = field(init=False)
|
|
105
105
|
|
|
106
106
|
def __post_init__(self) -> None:
|
|
107
|
-
parameter_count:
|
|
107
|
+
parameter_count: dict[DTYPE_T, int] = defaultdict(int)
|
|
108
108
|
for file_metadata in self.files_metadata.values():
|
|
109
109
|
for dtype, nb_parameters_ in file_metadata.parameter_count.items():
|
|
110
110
|
parameter_count[dtype] += nb_parameters_
|
|
@@ -20,7 +20,7 @@ import sys
|
|
|
20
20
|
from contextlib import contextmanager
|
|
21
21
|
from io import StringIO
|
|
22
22
|
from pathlib import Path
|
|
23
|
-
from typing import IO, Generator,
|
|
23
|
+
from typing import IO, Generator, Optional, Union
|
|
24
24
|
|
|
25
25
|
from .logging import get_logger
|
|
26
26
|
|
|
@@ -51,7 +51,7 @@ def capture_output() -> Generator[StringIO, None, None]:
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def run_subprocess(
|
|
54
|
-
command: Union[str,
|
|
54
|
+
command: Union[str, list[str]],
|
|
55
55
|
folder: Optional[Union[str, Path]] = None,
|
|
56
56
|
check=True,
|
|
57
57
|
**kwargs,
|
|
@@ -62,7 +62,7 @@ def run_subprocess(
|
|
|
62
62
|
be captured.
|
|
63
63
|
|
|
64
64
|
Args:
|
|
65
|
-
command (`str` or `
|
|
65
|
+
command (`str` or `list[str]`):
|
|
66
66
|
The command to execute as a string or list of strings.
|
|
67
67
|
folder (`str`, *optional*):
|
|
68
68
|
The folder in which to run the command. Defaults to current working
|
|
@@ -70,7 +70,7 @@ def run_subprocess(
|
|
|
70
70
|
check (`bool`, *optional*, defaults to `True`):
|
|
71
71
|
Setting `check` to `True` will raise a `subprocess.CalledProcessError`
|
|
72
72
|
when the subprocess has a non-zero exit code.
|
|
73
|
-
kwargs (`
|
|
73
|
+
kwargs (`dict[str]`):
|
|
74
74
|
Keyword arguments to be passed to the `subprocess.run` underlying command.
|
|
75
75
|
|
|
76
76
|
Returns:
|
|
@@ -96,23 +96,23 @@ def run_subprocess(
|
|
|
96
96
|
|
|
97
97
|
@contextmanager
|
|
98
98
|
def run_interactive_subprocess(
|
|
99
|
-
command: Union[str,
|
|
99
|
+
command: Union[str, list[str]],
|
|
100
100
|
folder: Optional[Union[str, Path]] = None,
|
|
101
101
|
**kwargs,
|
|
102
|
-
) -> Generator[
|
|
102
|
+
) -> Generator[tuple[IO[str], IO[str]], None, None]:
|
|
103
103
|
"""Run a subprocess in an interactive mode in a context manager.
|
|
104
104
|
|
|
105
105
|
Args:
|
|
106
|
-
command (`str` or `
|
|
106
|
+
command (`str` or `list[str]`):
|
|
107
107
|
The command to execute as a string or list of strings.
|
|
108
108
|
folder (`str`, *optional*):
|
|
109
109
|
The folder in which to run the command. Defaults to current working
|
|
110
110
|
directory (from `os.getcwd()`).
|
|
111
|
-
kwargs (`
|
|
111
|
+
kwargs (`dict[str]`):
|
|
112
112
|
Keyword arguments to be passed to the `subprocess.run` underlying command.
|
|
113
113
|
|
|
114
114
|
Returns:
|
|
115
|
-
`
|
|
115
|
+
`tuple[IO[str], IO[str]]`: A tuple with `stdin` and `stdout` to interact
|
|
116
116
|
with the process (input and output are utf-8 encoded).
|
|
117
117
|
|
|
118
118
|
Example:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from queue import Queue
|
|
2
2
|
from threading import Lock, Thread
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import Optional, Union
|
|
4
4
|
from urllib.parse import quote
|
|
5
5
|
|
|
6
6
|
from .. import constants, logging
|
|
@@ -22,10 +22,10 @@ def send_telemetry(
|
|
|
22
22
|
*,
|
|
23
23
|
library_name: Optional[str] = None,
|
|
24
24
|
library_version: Optional[str] = None,
|
|
25
|
-
user_agent: Union[
|
|
25
|
+
user_agent: Union[dict, str, None] = None,
|
|
26
26
|
) -> None:
|
|
27
27
|
"""
|
|
28
|
-
Sends telemetry that helps
|
|
28
|
+
Sends telemetry that helps track usage of different HF libraries.
|
|
29
29
|
|
|
30
30
|
This usage data helps us debug issues and prioritize new features. However, we understand that not everyone wants
|
|
31
31
|
to share additional information, and we respect your privacy. You can disable telemetry collection by setting the
|
|
@@ -98,7 +98,7 @@ def _send_telemetry_in_thread(
|
|
|
98
98
|
*,
|
|
99
99
|
library_name: Optional[str] = None,
|
|
100
100
|
library_version: Optional[str] = None,
|
|
101
|
-
user_agent: Union[
|
|
101
|
+
user_agent: Union[dict, str, None] = None,
|
|
102
102
|
) -> None:
|
|
103
103
|
"""Contains the actual data sending data to the Hub.
|
|
104
104
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
"""Contains
|
|
14
|
+
"""Contains utilities to print stuff to the terminal (styling, helpers)."""
|
|
15
15
|
|
|
16
16
|
import os
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Union
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class ANSI:
|
|
@@ -52,7 +52,7 @@ class ANSI:
|
|
|
52
52
|
return f"{code}{s}{cls._reset}"
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
def tabulate(rows:
|
|
55
|
+
def tabulate(rows: list[list[Union[str, int]]], headers: list[str]) -> str:
|
|
56
56
|
"""
|
|
57
57
|
Inspired by:
|
|
58
58
|
|
huggingface_hub/utils/_typing.py
CHANGED
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"""Handle typing imports based on system compatibility."""
|
|
16
16
|
|
|
17
17
|
import sys
|
|
18
|
-
from typing import Any, Callable,
|
|
18
|
+
from typing import Any, Callable, Literal, Optional, Type, TypeVar, Union, get_args, get_origin
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
UNION_TYPES:
|
|
21
|
+
UNION_TYPES: list[Any] = [Union]
|
|
22
22
|
if sys.version_info >= (3, 10):
|
|
23
23
|
from types import UnionType
|
|
24
24
|
|
|
@@ -33,7 +33,7 @@ CallableT = TypeVar("CallableT", bound=Callable)
|
|
|
33
33
|
_JSON_SERIALIZABLE_TYPES = (int, float, str, bool, type(None))
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def is_jsonable(obj: Any) -> bool:
|
|
36
|
+
def is_jsonable(obj: Any, _visited: Optional[set[int]] = None) -> bool:
|
|
37
37
|
"""Check if an object is JSON serializable.
|
|
38
38
|
|
|
39
39
|
This is a weak check, as it does not check for the actual JSON serialization, but only for the types of the object.
|
|
@@ -43,19 +43,39 @@ def is_jsonable(obj: Any) -> bool:
|
|
|
43
43
|
- it is an instance of int, float, str, bool, or NoneType
|
|
44
44
|
- it is a list or tuple and all its items are json serializable
|
|
45
45
|
- it is a dict and all its keys are strings and all its values are json serializable
|
|
46
|
+
|
|
47
|
+
Uses a visited set to avoid infinite recursion on circular references. If object has already been visited, it is
|
|
48
|
+
considered not json serializable.
|
|
46
49
|
"""
|
|
50
|
+
# Initialize visited set to track object ids and detect circular references
|
|
51
|
+
if _visited is None:
|
|
52
|
+
_visited = set()
|
|
53
|
+
|
|
54
|
+
# Detect circular reference
|
|
55
|
+
obj_id = id(obj)
|
|
56
|
+
if obj_id in _visited:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
# Add current object to visited before recursive checks
|
|
60
|
+
_visited.add(obj_id)
|
|
47
61
|
try:
|
|
48
62
|
if isinstance(obj, _JSON_SERIALIZABLE_TYPES):
|
|
49
63
|
return True
|
|
50
64
|
if isinstance(obj, (list, tuple)):
|
|
51
|
-
return all(is_jsonable(item) for item in obj)
|
|
65
|
+
return all(is_jsonable(item, _visited) for item in obj)
|
|
52
66
|
if isinstance(obj, dict):
|
|
53
|
-
return all(
|
|
67
|
+
return all(
|
|
68
|
+
isinstance(key, _JSON_SERIALIZABLE_TYPES) and is_jsonable(value, _visited)
|
|
69
|
+
for key, value in obj.items()
|
|
70
|
+
)
|
|
54
71
|
if hasattr(obj, "__json__"):
|
|
55
72
|
return True
|
|
56
73
|
return False
|
|
57
74
|
except RecursionError:
|
|
58
75
|
return False
|
|
76
|
+
finally:
|
|
77
|
+
# Remove the object id from visited to avoid side‑effects for other branches
|
|
78
|
+
_visited.discard(obj_id)
|
|
59
79
|
|
|
60
80
|
|
|
61
81
|
def is_simple_optional_type(type_: Type) -> bool:
|