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.
Files changed (150) hide show
  1. huggingface_hub/__init__.py +145 -46
  2. huggingface_hub/_commit_api.py +168 -119
  3. huggingface_hub/_commit_scheduler.py +15 -15
  4. huggingface_hub/_inference_endpoints.py +15 -12
  5. huggingface_hub/_jobs_api.py +301 -0
  6. huggingface_hub/_local_folder.py +18 -3
  7. huggingface_hub/_login.py +31 -63
  8. huggingface_hub/_oauth.py +460 -0
  9. huggingface_hub/_snapshot_download.py +239 -80
  10. huggingface_hub/_space_api.py +5 -5
  11. huggingface_hub/_tensorboard_logger.py +15 -19
  12. huggingface_hub/_upload_large_folder.py +172 -76
  13. huggingface_hub/_webhooks_payload.py +3 -3
  14. huggingface_hub/_webhooks_server.py +13 -25
  15. huggingface_hub/{commands → cli}/__init__.py +1 -15
  16. huggingface_hub/cli/_cli_utils.py +173 -0
  17. huggingface_hub/cli/auth.py +147 -0
  18. huggingface_hub/cli/cache.py +841 -0
  19. huggingface_hub/cli/download.py +189 -0
  20. huggingface_hub/cli/hf.py +60 -0
  21. huggingface_hub/cli/inference_endpoints.py +377 -0
  22. huggingface_hub/cli/jobs.py +772 -0
  23. huggingface_hub/cli/lfs.py +175 -0
  24. huggingface_hub/cli/repo.py +315 -0
  25. huggingface_hub/cli/repo_files.py +94 -0
  26. huggingface_hub/{commands/env.py → cli/system.py} +10 -13
  27. huggingface_hub/cli/upload.py +294 -0
  28. huggingface_hub/cli/upload_large_folder.py +117 -0
  29. huggingface_hub/community.py +20 -12
  30. huggingface_hub/constants.py +38 -53
  31. huggingface_hub/dataclasses.py +609 -0
  32. huggingface_hub/errors.py +80 -30
  33. huggingface_hub/fastai_utils.py +30 -41
  34. huggingface_hub/file_download.py +435 -351
  35. huggingface_hub/hf_api.py +2050 -1124
  36. huggingface_hub/hf_file_system.py +269 -152
  37. huggingface_hub/hub_mixin.py +43 -63
  38. huggingface_hub/inference/_client.py +347 -434
  39. huggingface_hub/inference/_common.py +133 -121
  40. huggingface_hub/inference/_generated/_async_client.py +397 -541
  41. huggingface_hub/inference/_generated/types/__init__.py +5 -1
  42. huggingface_hub/inference/_generated/types/automatic_speech_recognition.py +3 -3
  43. huggingface_hub/inference/_generated/types/base.py +10 -7
  44. huggingface_hub/inference/_generated/types/chat_completion.py +59 -23
  45. huggingface_hub/inference/_generated/types/depth_estimation.py +2 -2
  46. huggingface_hub/inference/_generated/types/document_question_answering.py +2 -2
  47. huggingface_hub/inference/_generated/types/feature_extraction.py +2 -2
  48. huggingface_hub/inference/_generated/types/fill_mask.py +2 -2
  49. huggingface_hub/inference/_generated/types/image_to_image.py +6 -2
  50. huggingface_hub/inference/_generated/types/image_to_video.py +60 -0
  51. huggingface_hub/inference/_generated/types/sentence_similarity.py +3 -3
  52. huggingface_hub/inference/_generated/types/summarization.py +2 -2
  53. huggingface_hub/inference/_generated/types/table_question_answering.py +5 -5
  54. huggingface_hub/inference/_generated/types/text2text_generation.py +2 -2
  55. huggingface_hub/inference/_generated/types/text_generation.py +10 -10
  56. huggingface_hub/inference/_generated/types/text_to_video.py +2 -2
  57. huggingface_hub/inference/_generated/types/token_classification.py +2 -2
  58. huggingface_hub/inference/_generated/types/translation.py +2 -2
  59. huggingface_hub/inference/_generated/types/zero_shot_classification.py +2 -2
  60. huggingface_hub/inference/_generated/types/zero_shot_image_classification.py +2 -2
  61. huggingface_hub/inference/_generated/types/zero_shot_object_detection.py +1 -3
  62. huggingface_hub/inference/_mcp/__init__.py +0 -0
  63. huggingface_hub/inference/_mcp/_cli_hacks.py +88 -0
  64. huggingface_hub/inference/_mcp/agent.py +100 -0
  65. huggingface_hub/inference/_mcp/cli.py +247 -0
  66. huggingface_hub/inference/_mcp/constants.py +81 -0
  67. huggingface_hub/inference/_mcp/mcp_client.py +395 -0
  68. huggingface_hub/inference/_mcp/types.py +45 -0
  69. huggingface_hub/inference/_mcp/utils.py +128 -0
  70. huggingface_hub/inference/_providers/__init__.py +82 -7
  71. huggingface_hub/inference/_providers/_common.py +129 -27
  72. huggingface_hub/inference/_providers/black_forest_labs.py +6 -6
  73. huggingface_hub/inference/_providers/cerebras.py +1 -1
  74. huggingface_hub/inference/_providers/clarifai.py +13 -0
  75. huggingface_hub/inference/_providers/cohere.py +20 -3
  76. huggingface_hub/inference/_providers/fal_ai.py +183 -56
  77. huggingface_hub/inference/_providers/featherless_ai.py +38 -0
  78. huggingface_hub/inference/_providers/fireworks_ai.py +18 -0
  79. huggingface_hub/inference/_providers/groq.py +9 -0
  80. huggingface_hub/inference/_providers/hf_inference.py +69 -30
  81. huggingface_hub/inference/_providers/hyperbolic.py +4 -4
  82. huggingface_hub/inference/_providers/nebius.py +33 -5
  83. huggingface_hub/inference/_providers/novita.py +5 -5
  84. huggingface_hub/inference/_providers/nscale.py +44 -0
  85. huggingface_hub/inference/_providers/openai.py +3 -1
  86. huggingface_hub/inference/_providers/publicai.py +6 -0
  87. huggingface_hub/inference/_providers/replicate.py +31 -13
  88. huggingface_hub/inference/_providers/sambanova.py +18 -4
  89. huggingface_hub/inference/_providers/scaleway.py +28 -0
  90. huggingface_hub/inference/_providers/together.py +20 -5
  91. huggingface_hub/inference/_providers/wavespeed.py +138 -0
  92. huggingface_hub/inference/_providers/zai_org.py +17 -0
  93. huggingface_hub/lfs.py +33 -100
  94. huggingface_hub/repocard.py +34 -38
  95. huggingface_hub/repocard_data.py +57 -57
  96. huggingface_hub/serialization/__init__.py +0 -1
  97. huggingface_hub/serialization/_base.py +12 -15
  98. huggingface_hub/serialization/_dduf.py +8 -8
  99. huggingface_hub/serialization/_torch.py +69 -69
  100. huggingface_hub/utils/__init__.py +19 -8
  101. huggingface_hub/utils/_auth.py +7 -7
  102. huggingface_hub/utils/_cache_manager.py +92 -147
  103. huggingface_hub/utils/_chunk_utils.py +2 -3
  104. huggingface_hub/utils/_deprecation.py +1 -1
  105. huggingface_hub/utils/_dotenv.py +55 -0
  106. huggingface_hub/utils/_experimental.py +7 -5
  107. huggingface_hub/utils/_fixes.py +0 -10
  108. huggingface_hub/utils/_git_credential.py +5 -5
  109. huggingface_hub/utils/_headers.py +8 -30
  110. huggingface_hub/utils/_http.py +398 -239
  111. huggingface_hub/utils/_pagination.py +4 -4
  112. huggingface_hub/utils/_parsing.py +98 -0
  113. huggingface_hub/utils/_paths.py +5 -5
  114. huggingface_hub/utils/_runtime.py +61 -24
  115. huggingface_hub/utils/_safetensors.py +21 -21
  116. huggingface_hub/utils/_subprocess.py +9 -9
  117. huggingface_hub/utils/_telemetry.py +4 -4
  118. huggingface_hub/{commands/_cli_utils.py → utils/_terminal.py} +4 -4
  119. huggingface_hub/utils/_typing.py +25 -5
  120. huggingface_hub/utils/_validators.py +55 -74
  121. huggingface_hub/utils/_verification.py +167 -0
  122. huggingface_hub/utils/_xet.py +64 -17
  123. huggingface_hub/utils/_xet_progress_reporting.py +162 -0
  124. huggingface_hub/utils/insecure_hashlib.py +3 -5
  125. huggingface_hub/utils/logging.py +8 -11
  126. huggingface_hub/utils/tqdm.py +5 -4
  127. {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/METADATA +94 -85
  128. huggingface_hub-1.1.3.dist-info/RECORD +155 -0
  129. {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/WHEEL +1 -1
  130. huggingface_hub-1.1.3.dist-info/entry_points.txt +6 -0
  131. huggingface_hub/commands/delete_cache.py +0 -474
  132. huggingface_hub/commands/download.py +0 -200
  133. huggingface_hub/commands/huggingface_cli.py +0 -61
  134. huggingface_hub/commands/lfs.py +0 -200
  135. huggingface_hub/commands/repo_files.py +0 -128
  136. huggingface_hub/commands/scan_cache.py +0 -181
  137. huggingface_hub/commands/tag.py +0 -159
  138. huggingface_hub/commands/upload.py +0 -314
  139. huggingface_hub/commands/upload_large_folder.py +0 -129
  140. huggingface_hub/commands/user.py +0 -304
  141. huggingface_hub/commands/version.py +0 -37
  142. huggingface_hub/inference_api.py +0 -217
  143. huggingface_hub/keras_mixin.py +0 -500
  144. huggingface_hub/repository.py +0 -1477
  145. huggingface_hub/serialization/_tensorflow.py +0 -95
  146. huggingface_hub/utils/_hf_folder.py +0 -68
  147. huggingface_hub-0.31.0rc0.dist-info/RECORD +0 -135
  148. huggingface_hub-0.31.0rc0.dist-info/entry_points.txt +0 -6
  149. {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info/licenses}/LICENSE +0 -0
  150. {huggingface_hub-0.31.0rc0.dist-info → huggingface_hub-1.1.3.dist-info}/top_level.txt +0 -0
@@ -1,181 +0,0 @@
1
- # coding=utf-8
2
- # Copyright 2022-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
- """Contains command to scan the HF cache directory.
16
-
17
- Usage:
18
- huggingface-cli scan-cache
19
- huggingface-cli scan-cache -v
20
- huggingface-cli scan-cache -vvv
21
- huggingface-cli scan-cache --dir ~/.cache/huggingface/hub
22
- """
23
-
24
- import time
25
- from argparse import Namespace, _SubParsersAction
26
- from typing import Optional
27
-
28
- from ..utils import CacheNotFound, HFCacheInfo, scan_cache_dir
29
- from . import BaseHuggingfaceCLICommand
30
- from ._cli_utils import ANSI, tabulate
31
-
32
-
33
- class ScanCacheCommand(BaseHuggingfaceCLICommand):
34
- @staticmethod
35
- def register_subcommand(parser: _SubParsersAction):
36
- scan_cache_parser = parser.add_parser("scan-cache", help="Scan cache directory.")
37
-
38
- scan_cache_parser.add_argument(
39
- "--dir",
40
- type=str,
41
- default=None,
42
- help="cache directory to scan (optional). Default to the default HuggingFace cache.",
43
- )
44
- scan_cache_parser.add_argument(
45
- "-v",
46
- "--verbose",
47
- action="count",
48
- default=0,
49
- help="show a more verbose output",
50
- )
51
- scan_cache_parser.set_defaults(func=ScanCacheCommand)
52
-
53
- def __init__(self, args: Namespace) -> None:
54
- self.verbosity: int = args.verbose
55
- self.cache_dir: Optional[str] = args.dir
56
-
57
- def run(self):
58
- try:
59
- t0 = time.time()
60
- hf_cache_info = scan_cache_dir(self.cache_dir)
61
- t1 = time.time()
62
- except CacheNotFound as exc:
63
- cache_dir = exc.cache_dir
64
- print(f"Cache directory not found: {cache_dir}")
65
- return
66
-
67
- self._print_hf_cache_info_as_table(hf_cache_info)
68
-
69
- print(
70
- f"\nDone in {round(t1 - t0, 1)}s. Scanned {len(hf_cache_info.repos)} repo(s)"
71
- f" for a total of {ANSI.red(hf_cache_info.size_on_disk_str)}."
72
- )
73
- if len(hf_cache_info.warnings) > 0:
74
- message = f"Got {len(hf_cache_info.warnings)} warning(s) while scanning."
75
- if self.verbosity >= 3:
76
- print(ANSI.gray(message))
77
- for warning in hf_cache_info.warnings:
78
- print(ANSI.gray(warning))
79
- else:
80
- print(ANSI.gray(message + " Use -vvv to print details."))
81
-
82
- def _print_hf_cache_info_as_table(self, hf_cache_info: HFCacheInfo) -> None:
83
- print(get_table(hf_cache_info, verbosity=self.verbosity))
84
-
85
-
86
- def get_table(hf_cache_info: HFCacheInfo, *, verbosity: int = 0) -> str:
87
- """Generate a table from the [`HFCacheInfo`] object.
88
-
89
- Pass `verbosity=0` to get a table with a single row per repo, with columns
90
- "repo_id", "repo_type", "size_on_disk", "nb_files", "last_accessed", "last_modified", "refs", "local_path".
91
-
92
- Pass `verbosity=1` to get a table with a row per repo and revision (thus multiple rows can appear for a single repo), with columns
93
- "repo_id", "repo_type", "revision", "size_on_disk", "nb_files", "last_modified", "refs", "local_path".
94
-
95
- Example:
96
- ```py
97
- >>> from huggingface_hub.utils import scan_cache_dir
98
- >>> from huggingface_hub.commands.scan_cache import get_table
99
-
100
- >>> hf_cache_info = scan_cache_dir()
101
- HFCacheInfo(...)
102
-
103
- >>> print(get_table(hf_cache_info, verbosity=0))
104
- REPO ID REPO TYPE SIZE ON DISK NB FILES LAST_ACCESSED LAST_MODIFIED REFS LOCAL PATH
105
- --------------------------------------------------- --------- ------------ -------- ------------- ------------- ---- --------------------------------------------------------------------------------------------------
106
- roberta-base model 2.7M 5 1 day ago 1 week ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--roberta-base
107
- suno/bark model 8.8K 1 1 week ago 1 week ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--suno--bark
108
- t5-base model 893.8M 4 4 days ago 7 months ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--t5-base
109
- t5-large model 3.0G 4 5 weeks ago 5 months ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--t5-large
110
-
111
- >>> print(get_table(hf_cache_info, verbosity=1))
112
- REPO ID REPO TYPE REVISION SIZE ON DISK NB FILES LAST_MODIFIED REFS LOCAL PATH
113
- --------------------------------------------------- --------- ---------------------------------------- ------------ -------- ------------- ---- -----------------------------------------------------------------------------------------------------------------------------------------------------
114
- roberta-base model e2da8e2f811d1448a5b465c236feacd80ffbac7b 2.7M 5 1 week ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--roberta-base\\snapshots\\e2da8e2f811d1448a5b465c236feacd80ffbac7b
115
- suno/bark model 70a8a7d34168586dc5d028fa9666aceade177992 8.8K 1 1 week ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--suno--bark\\snapshots\\70a8a7d34168586dc5d028fa9666aceade177992
116
- t5-base model a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1 893.8M 4 7 months ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--t5-base\\snapshots\\a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1
117
- t5-large model 150ebc2c4b72291e770f58e6057481c8d2ed331a 3.0G 4 5 months ago main C:\\Users\\admin\\.cache\\huggingface\\hub\\models--t5-large\\snapshots\\150ebc2c4b72291e770f58e6057481c8d2ed331a ```
118
- ```
119
-
120
- Args:
121
- hf_cache_info ([`HFCacheInfo`]):
122
- The HFCacheInfo object to print.
123
- verbosity (`int`, *optional*):
124
- The verbosity level. Defaults to 0.
125
-
126
- Returns:
127
- `str`: The table as a string.
128
- """
129
- if verbosity == 0:
130
- return tabulate(
131
- rows=[
132
- [
133
- repo.repo_id,
134
- repo.repo_type,
135
- "{:>12}".format(repo.size_on_disk_str),
136
- repo.nb_files,
137
- repo.last_accessed_str,
138
- repo.last_modified_str,
139
- ", ".join(sorted(repo.refs)),
140
- str(repo.repo_path),
141
- ]
142
- for repo in sorted(hf_cache_info.repos, key=lambda repo: repo.repo_path)
143
- ],
144
- headers=[
145
- "REPO ID",
146
- "REPO TYPE",
147
- "SIZE ON DISK",
148
- "NB FILES",
149
- "LAST_ACCESSED",
150
- "LAST_MODIFIED",
151
- "REFS",
152
- "LOCAL PATH",
153
- ],
154
- )
155
- else:
156
- return tabulate(
157
- rows=[
158
- [
159
- repo.repo_id,
160
- repo.repo_type,
161
- revision.commit_hash,
162
- "{:>12}".format(revision.size_on_disk_str),
163
- revision.nb_files,
164
- revision.last_modified_str,
165
- ", ".join(sorted(revision.refs)),
166
- str(revision.snapshot_path),
167
- ]
168
- for repo in sorted(hf_cache_info.repos, key=lambda repo: repo.repo_path)
169
- for revision in sorted(repo.revisions, key=lambda revision: revision.commit_hash)
170
- ],
171
- headers=[
172
- "REPO ID",
173
- "REPO TYPE",
174
- "REVISION",
175
- "SIZE ON DISK",
176
- "NB FILES",
177
- "LAST_MODIFIED",
178
- "REFS",
179
- "LOCAL PATH",
180
- ],
181
- )
@@ -1,159 +0,0 @@
1
- # coding=utf-8
2
- # Copyright 2024-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
-
16
- """Contains commands to perform tag management with the CLI.
17
-
18
- Usage Examples:
19
- - Create a tag:
20
- $ huggingface-cli tag user/my-model 1.0 --message "First release"
21
- $ huggingface-cli tag user/my-model 1.0 -m "First release" --revision develop
22
- $ huggingface-cli tag user/my-dataset 1.0 -m "First release" --repo-type dataset
23
- $ huggingface-cli tag user/my-space 1.0
24
- - List all tags:
25
- $ huggingface-cli tag -l user/my-model
26
- $ huggingface-cli tag --list user/my-dataset --repo-type dataset
27
- - Delete a tag:
28
- $ huggingface-cli tag -d user/my-model 1.0
29
- $ huggingface-cli tag --delete user/my-dataset 1.0 --repo-type dataset
30
- $ huggingface-cli tag -d user/my-space 1.0 -y
31
- """
32
-
33
- from argparse import Namespace, _SubParsersAction
34
-
35
- from requests.exceptions import HTTPError
36
-
37
- from huggingface_hub.commands import BaseHuggingfaceCLICommand
38
- from huggingface_hub.constants import (
39
- REPO_TYPES,
40
- )
41
- from huggingface_hub.hf_api import HfApi
42
-
43
- from ..errors import HfHubHTTPError, RepositoryNotFoundError, RevisionNotFoundError
44
- from ._cli_utils import ANSI
45
-
46
-
47
- class TagCommands(BaseHuggingfaceCLICommand):
48
- @staticmethod
49
- def register_subcommand(parser: _SubParsersAction):
50
- tag_parser = parser.add_parser("tag", help="(create, list, delete) tags for a repo in the hub")
51
-
52
- tag_parser.add_argument("repo_id", type=str, help="The ID of the repo to tag (e.g. `username/repo-name`).")
53
- tag_parser.add_argument("tag", nargs="?", type=str, help="The name of the tag for creation or deletion.")
54
- tag_parser.add_argument("-m", "--message", type=str, help="The description of the tag to create.")
55
- tag_parser.add_argument("--revision", type=str, help="The git revision to tag.")
56
- tag_parser.add_argument(
57
- "--token", type=str, help="A User Access Token generated from https://huggingface.co/settings/tokens."
58
- )
59
- tag_parser.add_argument(
60
- "--repo-type",
61
- choices=["model", "dataset", "space"],
62
- default="model",
63
- help="Set the type of repository (model, dataset, or space).",
64
- )
65
- tag_parser.add_argument("-y", "--yes", action="store_true", help="Answer Yes to prompts automatically.")
66
-
67
- tag_parser.add_argument("-l", "--list", action="store_true", help="List tags for a repository.")
68
- tag_parser.add_argument("-d", "--delete", action="store_true", help="Delete a tag for a repository.")
69
-
70
- tag_parser.set_defaults(func=lambda args: handle_commands(args))
71
-
72
-
73
- def handle_commands(args: Namespace):
74
- if args.list:
75
- return TagListCommand(args)
76
- elif args.delete:
77
- return TagDeleteCommand(args)
78
- else:
79
- return TagCreateCommand(args)
80
-
81
-
82
- class TagCommand:
83
- def __init__(self, args: Namespace):
84
- self.args = args
85
- self.api = HfApi(token=self.args.token)
86
- self.repo_id = self.args.repo_id
87
- self.repo_type = self.args.repo_type
88
- if self.repo_type not in REPO_TYPES:
89
- print("Invalid repo --repo-type")
90
- exit(1)
91
-
92
-
93
- class TagCreateCommand(TagCommand):
94
- def run(self):
95
- print(f"You are about to create tag {ANSI.bold(self.args.tag)} on {self.repo_type} {ANSI.bold(self.repo_id)}")
96
-
97
- try:
98
- self.api.create_tag(
99
- repo_id=self.repo_id,
100
- tag=self.args.tag,
101
- tag_message=self.args.message,
102
- revision=self.args.revision,
103
- repo_type=self.repo_type,
104
- )
105
- except RepositoryNotFoundError:
106
- print(f"{self.repo_type.capitalize()} {ANSI.bold(self.repo_id)} not found.")
107
- exit(1)
108
- except RevisionNotFoundError:
109
- print(f"Revision {ANSI.bold(self.args.revision)} not found.")
110
- exit(1)
111
- except HfHubHTTPError as e:
112
- if e.response.status_code == 409:
113
- print(f"Tag {ANSI.bold(self.args.tag)} already exists on {ANSI.bold(self.repo_id)}")
114
- exit(1)
115
- raise e
116
-
117
- print(f"Tag {ANSI.bold(self.args.tag)} created on {ANSI.bold(self.repo_id)}")
118
-
119
-
120
- class TagListCommand(TagCommand):
121
- def run(self):
122
- try:
123
- refs = self.api.list_repo_refs(
124
- repo_id=self.repo_id,
125
- repo_type=self.repo_type,
126
- )
127
- except RepositoryNotFoundError:
128
- print(f"{self.repo_type.capitalize()} {ANSI.bold(self.repo_id)} not found.")
129
- exit(1)
130
- except HTTPError as e:
131
- print(e)
132
- print(ANSI.red(e.response.text))
133
- exit(1)
134
- if len(refs.tags) == 0:
135
- print("No tags found")
136
- exit(0)
137
- print(f"Tags for {self.repo_type} {ANSI.bold(self.repo_id)}:")
138
- for tag in refs.tags:
139
- print(tag.name)
140
-
141
-
142
- class TagDeleteCommand(TagCommand):
143
- def run(self):
144
- print(f"You are about to delete tag {ANSI.bold(self.args.tag)} on {self.repo_type} {ANSI.bold(self.repo_id)}")
145
-
146
- if not self.args.yes:
147
- choice = input("Proceed? [Y/n] ").lower()
148
- if choice not in ("", "y", "yes"):
149
- print("Abort")
150
- exit()
151
- try:
152
- self.api.delete_tag(repo_id=self.repo_id, tag=self.args.tag, repo_type=self.repo_type)
153
- except RepositoryNotFoundError:
154
- print(f"{self.repo_type.capitalize()} {ANSI.bold(self.repo_id)} not found.")
155
- exit(1)
156
- except RevisionNotFoundError:
157
- print(f"Tag {ANSI.bold(self.args.tag)} not found on {ANSI.bold(self.repo_id)}")
158
- exit(1)
159
- print(f"Tag {ANSI.bold(self.args.tag)} deleted on {ANSI.bold(self.repo_id)}")
@@ -1,314 +0,0 @@
1
- # coding=utf-8
2
- # Copyright 2023-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
- """Contains command to upload a repo or file with the CLI.
16
-
17
- Usage:
18
- # Upload file (implicit)
19
- huggingface-cli upload my-cool-model ./my-cool-model.safetensors
20
-
21
- # Upload file (explicit)
22
- huggingface-cli upload my-cool-model ./my-cool-model.safetensors model.safetensors
23
-
24
- # Upload directory (implicit). If `my-cool-model/` is a directory it will be uploaded, otherwise an exception is raised.
25
- huggingface-cli upload my-cool-model
26
-
27
- # Upload directory (explicit)
28
- huggingface-cli upload my-cool-model ./models/my-cool-model .
29
-
30
- # Upload filtered directory (example: tensorboard logs except for the last run)
31
- huggingface-cli upload my-cool-model ./model/training /logs --include "*.tfevents.*" --exclude "*20230905*"
32
-
33
- # Upload with wildcard
34
- huggingface-cli upload my-cool-model "./model/training/*.safetensors"
35
-
36
- # Upload private dataset
37
- huggingface-cli upload Wauplin/my-cool-dataset ./data . --repo-type=dataset --private
38
-
39
- # Upload with token
40
- huggingface-cli upload Wauplin/my-cool-model --token=hf_****
41
-
42
- # Sync local Space with Hub (upload new files, delete removed files)
43
- huggingface-cli upload Wauplin/space-example --repo-type=space --exclude="/logs/*" --delete="*" --commit-message="Sync local Space with Hub"
44
-
45
- # Schedule commits every 30 minutes
46
- huggingface-cli upload Wauplin/my-cool-model --every=30
47
- """
48
-
49
- import os
50
- import time
51
- import warnings
52
- from argparse import Namespace, _SubParsersAction
53
- from typing import List, Optional
54
-
55
- from huggingface_hub import logging
56
- from huggingface_hub._commit_scheduler import CommitScheduler
57
- from huggingface_hub.commands import BaseHuggingfaceCLICommand
58
- from huggingface_hub.constants import HF_HUB_ENABLE_HF_TRANSFER
59
- from huggingface_hub.errors import RevisionNotFoundError
60
- from huggingface_hub.hf_api import HfApi
61
- from huggingface_hub.utils import disable_progress_bars, enable_progress_bars
62
- from huggingface_hub.utils._runtime import is_xet_available
63
-
64
-
65
- logger = logging.get_logger(__name__)
66
-
67
-
68
- class UploadCommand(BaseHuggingfaceCLICommand):
69
- @staticmethod
70
- def register_subcommand(parser: _SubParsersAction):
71
- upload_parser = parser.add_parser("upload", help="Upload a file or a folder to a repo on the Hub")
72
- upload_parser.add_argument(
73
- "repo_id", type=str, help="The ID of the repo to upload to (e.g. `username/repo-name`)."
74
- )
75
- upload_parser.add_argument(
76
- "local_path",
77
- nargs="?",
78
- help="Local path to the file or folder to upload. Wildcard patterns are supported. Defaults to current directory.",
79
- )
80
- upload_parser.add_argument(
81
- "path_in_repo",
82
- nargs="?",
83
- help="Path of the file or folder in the repo. Defaults to the relative path of the file or folder.",
84
- )
85
- upload_parser.add_argument(
86
- "--repo-type",
87
- choices=["model", "dataset", "space"],
88
- default="model",
89
- help="Type of the repo to upload to (e.g. `dataset`).",
90
- )
91
- upload_parser.add_argument(
92
- "--revision",
93
- type=str,
94
- help=(
95
- "An optional Git revision to push to. It can be a branch name or a PR reference. If revision does not"
96
- " exist and `--create-pr` is not set, a branch will be automatically created."
97
- ),
98
- )
99
- upload_parser.add_argument(
100
- "--private",
101
- action="store_true",
102
- help=(
103
- "Whether to create a private repo if repo doesn't exist on the Hub. Ignored if the repo already"
104
- " exists."
105
- ),
106
- )
107
- upload_parser.add_argument("--include", nargs="*", type=str, help="Glob patterns to match files to upload.")
108
- upload_parser.add_argument(
109
- "--exclude", nargs="*", type=str, help="Glob patterns to exclude from files to upload."
110
- )
111
- upload_parser.add_argument(
112
- "--delete",
113
- nargs="*",
114
- type=str,
115
- help="Glob patterns for file to be deleted from the repo while committing.",
116
- )
117
- upload_parser.add_argument(
118
- "--commit-message", type=str, help="The summary / title / first line of the generated commit."
119
- )
120
- upload_parser.add_argument("--commit-description", type=str, help="The description of the generated commit.")
121
- upload_parser.add_argument(
122
- "--create-pr", action="store_true", help="Whether to upload content as a new Pull Request."
123
- )
124
- upload_parser.add_argument(
125
- "--every",
126
- type=float,
127
- help="If set, a background job is scheduled to create commits every `every` minutes.",
128
- )
129
- upload_parser.add_argument(
130
- "--token", type=str, help="A User Access Token generated from https://huggingface.co/settings/tokens"
131
- )
132
- upload_parser.add_argument(
133
- "--quiet",
134
- action="store_true",
135
- help="If True, progress bars are disabled and only the path to the uploaded files is printed.",
136
- )
137
- upload_parser.set_defaults(func=UploadCommand)
138
-
139
- def __init__(self, args: Namespace) -> None:
140
- self.repo_id: str = args.repo_id
141
- self.repo_type: Optional[str] = args.repo_type
142
- self.revision: Optional[str] = args.revision
143
- self.private: bool = args.private
144
-
145
- self.include: Optional[List[str]] = args.include
146
- self.exclude: Optional[List[str]] = args.exclude
147
- self.delete: Optional[List[str]] = args.delete
148
-
149
- self.commit_message: Optional[str] = args.commit_message
150
- self.commit_description: Optional[str] = args.commit_description
151
- self.create_pr: bool = args.create_pr
152
- self.api: HfApi = HfApi(token=args.token, library_name="huggingface-cli")
153
- self.quiet: bool = args.quiet # disable warnings and progress bars
154
-
155
- # Check `--every` is valid
156
- if args.every is not None and args.every <= 0:
157
- raise ValueError(f"`every` must be a positive value (got '{args.every}')")
158
- self.every: Optional[float] = args.every
159
-
160
- # Resolve `local_path` and `path_in_repo`
161
- repo_name: str = args.repo_id.split("/")[-1] # e.g. "Wauplin/my-cool-model" => "my-cool-model"
162
- self.local_path: str
163
- self.path_in_repo: str
164
-
165
- if args.local_path is not None and any(c in args.local_path for c in ["*", "?", "["]):
166
- if args.include is not None:
167
- raise ValueError("Cannot set `--include` when passing a `local_path` containing a wildcard.")
168
- if args.path_in_repo is not None and args.path_in_repo != ".":
169
- raise ValueError("Cannot set `path_in_repo` when passing a `local_path` containing a wildcard.")
170
- self.local_path = "."
171
- self.include = args.local_path
172
- self.path_in_repo = "."
173
- elif args.local_path is None and os.path.isfile(repo_name):
174
- # Implicit case 1: user provided only a repo_id which happen to be a local file as well => upload it with same name
175
- self.local_path = repo_name
176
- self.path_in_repo = repo_name
177
- elif args.local_path is None and os.path.isdir(repo_name):
178
- # Implicit case 2: user provided only a repo_id which happen to be a local folder as well => upload it at root
179
- self.local_path = repo_name
180
- self.path_in_repo = "."
181
- elif args.local_path is None:
182
- # Implicit case 3: user provided only a repo_id that does not match a local file or folder
183
- # => the user must explicitly provide a local_path => raise exception
184
- raise ValueError(f"'{repo_name}' is not a local file or folder. Please set `local_path` explicitly.")
185
- elif args.path_in_repo is None and os.path.isfile(args.local_path):
186
- # Explicit local path to file, no path in repo => upload it at root with same name
187
- self.local_path = args.local_path
188
- self.path_in_repo = os.path.basename(args.local_path)
189
- elif args.path_in_repo is None:
190
- # Explicit local path to folder, no path in repo => upload at root
191
- self.local_path = args.local_path
192
- self.path_in_repo = "."
193
- else:
194
- # Finally, if both paths are explicit
195
- self.local_path = args.local_path
196
- self.path_in_repo = args.path_in_repo
197
-
198
- def run(self) -> None:
199
- if self.quiet:
200
- disable_progress_bars()
201
- with warnings.catch_warnings():
202
- warnings.simplefilter("ignore")
203
- print(self._upload())
204
- enable_progress_bars()
205
- else:
206
- logging.set_verbosity_info()
207
- print(self._upload())
208
- logging.set_verbosity_warning()
209
-
210
- def _upload(self) -> str:
211
- if os.path.isfile(self.local_path):
212
- if self.include is not None and len(self.include) > 0:
213
- warnings.warn("Ignoring `--include` since a single file is uploaded.")
214
- if self.exclude is not None and len(self.exclude) > 0:
215
- warnings.warn("Ignoring `--exclude` since a single file is uploaded.")
216
- if self.delete is not None and len(self.delete) > 0:
217
- warnings.warn("Ignoring `--delete` since a single file is uploaded.")
218
-
219
- if not is_xet_available() and not HF_HUB_ENABLE_HF_TRANSFER:
220
- logger.info(
221
- "Consider using `hf_transfer` for faster uploads. This solution comes with some limitations. See"
222
- " https://huggingface.co/docs/huggingface_hub/hf_transfer for more details."
223
- )
224
-
225
- # Schedule commits if `every` is set
226
- if self.every is not None:
227
- if os.path.isfile(self.local_path):
228
- # If file => watch entire folder + use allow_patterns
229
- folder_path = os.path.dirname(self.local_path)
230
- path_in_repo = (
231
- self.path_in_repo[: -len(self.local_path)] # remove filename from path_in_repo
232
- if self.path_in_repo.endswith(self.local_path)
233
- else self.path_in_repo
234
- )
235
- allow_patterns = [self.local_path]
236
- ignore_patterns = []
237
- else:
238
- folder_path = self.local_path
239
- path_in_repo = self.path_in_repo
240
- allow_patterns = self.include or []
241
- ignore_patterns = self.exclude or []
242
- if self.delete is not None and len(self.delete) > 0:
243
- warnings.warn("Ignoring `--delete` when uploading with scheduled commits.")
244
-
245
- scheduler = CommitScheduler(
246
- folder_path=folder_path,
247
- repo_id=self.repo_id,
248
- repo_type=self.repo_type,
249
- revision=self.revision,
250
- allow_patterns=allow_patterns,
251
- ignore_patterns=ignore_patterns,
252
- path_in_repo=path_in_repo,
253
- private=self.private,
254
- every=self.every,
255
- hf_api=self.api,
256
- )
257
- print(f"Scheduling commits every {self.every} minutes to {scheduler.repo_id}.")
258
- try: # Block main thread until KeyboardInterrupt
259
- while True:
260
- time.sleep(100)
261
- except KeyboardInterrupt:
262
- scheduler.stop()
263
- return "Stopped scheduled commits."
264
-
265
- # Otherwise, create repo and proceed with the upload
266
- if not os.path.isfile(self.local_path) and not os.path.isdir(self.local_path):
267
- raise FileNotFoundError(f"No such file or directory: '{self.local_path}'.")
268
- repo_id = self.api.create_repo(
269
- repo_id=self.repo_id,
270
- repo_type=self.repo_type,
271
- exist_ok=True,
272
- private=self.private,
273
- space_sdk="gradio" if self.repo_type == "space" else None,
274
- # ^ We don't want it to fail when uploading to a Space => let's set Gradio by default.
275
- # ^ I'd rather not add CLI args to set it explicitly as we already have `huggingface-cli repo create` for that.
276
- ).repo_id
277
-
278
- # Check if branch already exists and if not, create it
279
- if self.revision is not None and not self.create_pr:
280
- try:
281
- self.api.repo_info(repo_id=repo_id, repo_type=self.repo_type, revision=self.revision)
282
- except RevisionNotFoundError:
283
- logger.info(f"Branch '{self.revision}' not found. Creating it...")
284
- self.api.create_branch(repo_id=repo_id, repo_type=self.repo_type, branch=self.revision, exist_ok=True)
285
- # ^ `exist_ok=True` to avoid race concurrency issues
286
-
287
- # File-based upload
288
- if os.path.isfile(self.local_path):
289
- return self.api.upload_file(
290
- path_or_fileobj=self.local_path,
291
- path_in_repo=self.path_in_repo,
292
- repo_id=repo_id,
293
- repo_type=self.repo_type,
294
- revision=self.revision,
295
- commit_message=self.commit_message,
296
- commit_description=self.commit_description,
297
- create_pr=self.create_pr,
298
- )
299
-
300
- # Folder-based upload
301
- else:
302
- return self.api.upload_folder(
303
- folder_path=self.local_path,
304
- path_in_repo=self.path_in_repo,
305
- repo_id=repo_id,
306
- repo_type=self.repo_type,
307
- revision=self.revision,
308
- commit_message=self.commit_message,
309
- commit_description=self.commit_description,
310
- create_pr=self.create_pr,
311
- allow_patterns=self.include,
312
- ignore_patterns=self.exclude,
313
- delete_patterns=self.delete,
314
- )