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
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Implementation of a custom transfer agent for the transfer type "multipart" for
|
|
3
|
+
git-lfs.
|
|
4
|
+
|
|
5
|
+
Inspired by:
|
|
6
|
+
github.com/cbartz/git-lfs-swift-transfer-agent/blob/master/git_lfs_swift_transfer.py
|
|
7
|
+
|
|
8
|
+
Spec is: github.com/git-lfs/git-lfs/blob/master/docs/custom-transfers.md
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
To launch debugger while developing:
|
|
12
|
+
|
|
13
|
+
``` [lfs "customtransfer.multipart"]
|
|
14
|
+
path = /path/to/huggingface_hub/.env/bin/python args = -m debugpy --listen 5678
|
|
15
|
+
--wait-for-client
|
|
16
|
+
/path/to/huggingface_hub/src/huggingface_hub/commands/huggingface_cli.py
|
|
17
|
+
lfs-multipart-upload ```"""
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import os
|
|
21
|
+
import subprocess
|
|
22
|
+
import sys
|
|
23
|
+
from typing import Annotated, Optional
|
|
24
|
+
|
|
25
|
+
import typer
|
|
26
|
+
|
|
27
|
+
from huggingface_hub.lfs import LFS_MULTIPART_UPLOAD_COMMAND
|
|
28
|
+
|
|
29
|
+
from ..utils import get_session, hf_raise_for_status, logging
|
|
30
|
+
from ..utils._lfs import SliceFileObj
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
logger = logging.get_logger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def lfs_enable_largefiles(
|
|
37
|
+
path: Annotated[
|
|
38
|
+
str,
|
|
39
|
+
typer.Argument(
|
|
40
|
+
help="Local path to repository you want to configure.",
|
|
41
|
+
),
|
|
42
|
+
],
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Configure a local git repository to use the multipart transfer agent for large files.
|
|
46
|
+
|
|
47
|
+
This command sets up git-lfs to use the custom multipart transfer agent
|
|
48
|
+
which enables efficient uploading of large files in chunks.
|
|
49
|
+
"""
|
|
50
|
+
local_path = os.path.abspath(path)
|
|
51
|
+
if not os.path.isdir(local_path):
|
|
52
|
+
print("This does not look like a valid git repo.")
|
|
53
|
+
raise typer.Exit(code=1)
|
|
54
|
+
subprocess.run(
|
|
55
|
+
"git config lfs.customtransfer.multipart.path hf".split(),
|
|
56
|
+
check=True,
|
|
57
|
+
cwd=local_path,
|
|
58
|
+
)
|
|
59
|
+
subprocess.run(
|
|
60
|
+
f"git config lfs.customtransfer.multipart.args {LFS_MULTIPART_UPLOAD_COMMAND}".split(),
|
|
61
|
+
check=True,
|
|
62
|
+
cwd=local_path,
|
|
63
|
+
)
|
|
64
|
+
print("Local repo set up for largefiles")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def write_msg(msg: dict):
|
|
68
|
+
"""Write out the message in Line delimited JSON."""
|
|
69
|
+
msg_str = json.dumps(msg) + "\n"
|
|
70
|
+
sys.stdout.write(msg_str)
|
|
71
|
+
sys.stdout.flush()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def read_msg() -> Optional[dict]:
|
|
75
|
+
"""Read Line delimited JSON from stdin."""
|
|
76
|
+
msg = json.loads(sys.stdin.readline().strip())
|
|
77
|
+
|
|
78
|
+
if "terminate" in (msg.get("type"), msg.get("event")):
|
|
79
|
+
# terminate message received
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
if msg.get("event") not in ("download", "upload"):
|
|
83
|
+
logger.critical("Received unexpected message")
|
|
84
|
+
sys.exit(1)
|
|
85
|
+
|
|
86
|
+
return msg
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def lfs_multipart_upload() -> None:
|
|
90
|
+
"""Internal git-lfs custom transfer agent for multipart uploads.
|
|
91
|
+
|
|
92
|
+
This function implements the custom transfer protocol for git-lfs multipart uploads.
|
|
93
|
+
Handles chunked uploads of large files to Hugging Face Hub.
|
|
94
|
+
"""
|
|
95
|
+
# Immediately after invoking a custom transfer process, git-lfs
|
|
96
|
+
# sends initiation data to the process over stdin.
|
|
97
|
+
# This tells the process useful information about the configuration.
|
|
98
|
+
init_msg = json.loads(sys.stdin.readline().strip())
|
|
99
|
+
if not (init_msg.get("event") == "init" and init_msg.get("operation") == "upload"):
|
|
100
|
+
write_msg({"error": {"code": 32, "message": "Wrong lfs init operation"}})
|
|
101
|
+
sys.exit(1)
|
|
102
|
+
|
|
103
|
+
# The transfer process should use the information it needs from the
|
|
104
|
+
# initiation structure, and also perform any one-off setup tasks it
|
|
105
|
+
# needs to do. It should then respond on stdout with a simple empty
|
|
106
|
+
# confirmation structure, as follows:
|
|
107
|
+
write_msg({})
|
|
108
|
+
|
|
109
|
+
# After the initiation exchange, git-lfs will send any number of
|
|
110
|
+
# transfer requests to the stdin of the transfer process, in a serial sequence.
|
|
111
|
+
while True:
|
|
112
|
+
msg = read_msg()
|
|
113
|
+
if msg is None:
|
|
114
|
+
# When all transfers have been processed, git-lfs will send
|
|
115
|
+
# a terminate event to the stdin of the transfer process.
|
|
116
|
+
# On receiving this message the transfer process should
|
|
117
|
+
# clean up and terminate. No response is expected.
|
|
118
|
+
sys.exit(0)
|
|
119
|
+
|
|
120
|
+
oid = msg["oid"]
|
|
121
|
+
filepath = msg["path"]
|
|
122
|
+
completion_url = msg["action"]["href"]
|
|
123
|
+
header = msg["action"]["header"]
|
|
124
|
+
chunk_size = int(header.pop("chunk_size"))
|
|
125
|
+
presigned_urls: list[str] = list(header.values())
|
|
126
|
+
|
|
127
|
+
# Send a "started" progress event to allow other workers to start.
|
|
128
|
+
# Otherwise they're delayed until first "progress" event is reported,
|
|
129
|
+
# i.e. after the first 5GB by default (!)
|
|
130
|
+
write_msg(
|
|
131
|
+
{
|
|
132
|
+
"event": "progress",
|
|
133
|
+
"oid": oid,
|
|
134
|
+
"bytesSoFar": 1,
|
|
135
|
+
"bytesSinceLast": 0,
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
parts = []
|
|
140
|
+
with open(filepath, "rb") as file:
|
|
141
|
+
for i, presigned_url in enumerate(presigned_urls):
|
|
142
|
+
with SliceFileObj(
|
|
143
|
+
file,
|
|
144
|
+
seek_from=i * chunk_size,
|
|
145
|
+
read_limit=chunk_size,
|
|
146
|
+
) as data:
|
|
147
|
+
r = get_session().put(presigned_url, data=data)
|
|
148
|
+
hf_raise_for_status(r)
|
|
149
|
+
parts.append(
|
|
150
|
+
{
|
|
151
|
+
"etag": r.headers.get("etag"),
|
|
152
|
+
"partNumber": i + 1,
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
# In order to support progress reporting while data is uploading / downloading,
|
|
156
|
+
# the transfer process should post messages to stdout
|
|
157
|
+
write_msg(
|
|
158
|
+
{
|
|
159
|
+
"event": "progress",
|
|
160
|
+
"oid": oid,
|
|
161
|
+
"bytesSoFar": (i + 1) * chunk_size,
|
|
162
|
+
"bytesSinceLast": chunk_size,
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
r = get_session().post(
|
|
167
|
+
completion_url,
|
|
168
|
+
json={
|
|
169
|
+
"oid": oid,
|
|
170
|
+
"parts": parts,
|
|
171
|
+
},
|
|
172
|
+
)
|
|
173
|
+
hf_raise_for_status(r)
|
|
174
|
+
|
|
175
|
+
write_msg({"event": "complete", "oid": oid})
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""Contains commands to interact with repositories on the Hugging Face Hub.
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
# create a new dataset repo on the Hub
|
|
18
|
+
hf repo create my-cool-dataset --repo-type=dataset
|
|
19
|
+
|
|
20
|
+
# create a private model repo on the Hub
|
|
21
|
+
hf repo create my-cool-model --private
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import enum
|
|
25
|
+
from typing import Annotated, Optional
|
|
26
|
+
|
|
27
|
+
import typer
|
|
28
|
+
|
|
29
|
+
from huggingface_hub.errors import HfHubHTTPError, RepositoryNotFoundError, RevisionNotFoundError
|
|
30
|
+
from huggingface_hub.utils import ANSI, logging
|
|
31
|
+
|
|
32
|
+
from ._cli_utils import (
|
|
33
|
+
PrivateOpt,
|
|
34
|
+
RepoIdArg,
|
|
35
|
+
RepoType,
|
|
36
|
+
RepoTypeOpt,
|
|
37
|
+
RevisionOpt,
|
|
38
|
+
TokenOpt,
|
|
39
|
+
get_hf_api,
|
|
40
|
+
typer_factory,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
logger = logging.get_logger(__name__)
|
|
45
|
+
|
|
46
|
+
repo_cli = typer_factory(help="Manage repos on the Hub.")
|
|
47
|
+
tag_cli = typer_factory(help="Manage tags for a repo on the Hub.")
|
|
48
|
+
branch_cli = typer_factory(help="Manage branches for a repo on the Hub.")
|
|
49
|
+
repo_cli.add_typer(tag_cli, name="tag")
|
|
50
|
+
repo_cli.add_typer(branch_cli, name="branch")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class GatedChoices(str, enum.Enum):
|
|
54
|
+
auto = "auto"
|
|
55
|
+
manual = "manual"
|
|
56
|
+
false = "false"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@repo_cli.command("create", help="Create a new repo on the Hub.")
|
|
60
|
+
def repo_create(
|
|
61
|
+
repo_id: RepoIdArg,
|
|
62
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
63
|
+
space_sdk: Annotated[
|
|
64
|
+
Optional[str],
|
|
65
|
+
typer.Option(
|
|
66
|
+
help="Hugging Face Spaces SDK type. Required when --type is set to 'space'.",
|
|
67
|
+
),
|
|
68
|
+
] = None,
|
|
69
|
+
private: PrivateOpt = False,
|
|
70
|
+
token: TokenOpt = None,
|
|
71
|
+
exist_ok: Annotated[
|
|
72
|
+
bool,
|
|
73
|
+
typer.Option(
|
|
74
|
+
help="Do not raise an error if repo already exists.",
|
|
75
|
+
),
|
|
76
|
+
] = False,
|
|
77
|
+
resource_group_id: Annotated[
|
|
78
|
+
Optional[str],
|
|
79
|
+
typer.Option(
|
|
80
|
+
help="Resource group in which to create the repo. Resource groups is only available for Enterprise Hub organizations.",
|
|
81
|
+
),
|
|
82
|
+
] = None,
|
|
83
|
+
) -> None:
|
|
84
|
+
api = get_hf_api(token=token)
|
|
85
|
+
repo_url = api.create_repo(
|
|
86
|
+
repo_id=repo_id,
|
|
87
|
+
repo_type=repo_type.value,
|
|
88
|
+
private=private,
|
|
89
|
+
token=token,
|
|
90
|
+
exist_ok=exist_ok,
|
|
91
|
+
resource_group_id=resource_group_id,
|
|
92
|
+
space_sdk=space_sdk,
|
|
93
|
+
)
|
|
94
|
+
print(f"Successfully created {ANSI.bold(repo_url.repo_id)} on the Hub.")
|
|
95
|
+
print(f"Your repo is now available at {ANSI.bold(repo_url)}")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@repo_cli.command("delete", help="Delete a repo from the Hub. this is an irreversible operation.")
|
|
99
|
+
def repo_delete(
|
|
100
|
+
repo_id: RepoIdArg,
|
|
101
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
102
|
+
token: TokenOpt = None,
|
|
103
|
+
missing_ok: Annotated[
|
|
104
|
+
bool,
|
|
105
|
+
typer.Option(
|
|
106
|
+
help="If set to True, do not raise an error if repo does not exist.",
|
|
107
|
+
),
|
|
108
|
+
] = False,
|
|
109
|
+
) -> None:
|
|
110
|
+
api = get_hf_api(token=token)
|
|
111
|
+
api.delete_repo(
|
|
112
|
+
repo_id=repo_id,
|
|
113
|
+
repo_type=repo_type.value,
|
|
114
|
+
missing_ok=missing_ok,
|
|
115
|
+
)
|
|
116
|
+
print(f"Successfully deleted {ANSI.bold(repo_id)} on the Hub.")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@repo_cli.command("move", help="Move a repository from a namespace to another namespace.")
|
|
120
|
+
def repo_move(
|
|
121
|
+
from_id: RepoIdArg,
|
|
122
|
+
to_id: RepoIdArg,
|
|
123
|
+
token: TokenOpt = None,
|
|
124
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
125
|
+
) -> None:
|
|
126
|
+
api = get_hf_api(token=token)
|
|
127
|
+
api.move_repo(
|
|
128
|
+
from_id=from_id,
|
|
129
|
+
to_id=to_id,
|
|
130
|
+
repo_type=repo_type.value,
|
|
131
|
+
)
|
|
132
|
+
print(f"Successfully moved {ANSI.bold(from_id)} to {ANSI.bold(to_id)} on the Hub.")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@repo_cli.command("settings", help="Update the settings of a repository.")
|
|
136
|
+
def repo_settings(
|
|
137
|
+
repo_id: RepoIdArg,
|
|
138
|
+
gated: Annotated[
|
|
139
|
+
Optional[GatedChoices],
|
|
140
|
+
typer.Option(
|
|
141
|
+
help="The gated status for the repository.",
|
|
142
|
+
),
|
|
143
|
+
] = None,
|
|
144
|
+
private: Annotated[
|
|
145
|
+
Optional[bool],
|
|
146
|
+
typer.Option(
|
|
147
|
+
help="Whether the repository should be private.",
|
|
148
|
+
),
|
|
149
|
+
] = None,
|
|
150
|
+
token: TokenOpt = None,
|
|
151
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
152
|
+
) -> None:
|
|
153
|
+
api = get_hf_api(token=token)
|
|
154
|
+
api.update_repo_settings(
|
|
155
|
+
repo_id=repo_id,
|
|
156
|
+
gated=(gated.value if gated else None), # type: ignore [arg-type]
|
|
157
|
+
private=private,
|
|
158
|
+
repo_type=repo_type.value,
|
|
159
|
+
)
|
|
160
|
+
print(f"Successfully updated the settings of {ANSI.bold(repo_id)} on the Hub.")
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@branch_cli.command("create", help="Create a new branch for a repo on the Hub.")
|
|
164
|
+
def branch_create(
|
|
165
|
+
repo_id: RepoIdArg,
|
|
166
|
+
branch: Annotated[
|
|
167
|
+
str,
|
|
168
|
+
typer.Argument(
|
|
169
|
+
help="The name of the branch to create.",
|
|
170
|
+
),
|
|
171
|
+
],
|
|
172
|
+
revision: RevisionOpt = None,
|
|
173
|
+
token: TokenOpt = None,
|
|
174
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
175
|
+
exist_ok: Annotated[
|
|
176
|
+
bool,
|
|
177
|
+
typer.Option(
|
|
178
|
+
help="If set to True, do not raise an error if branch already exists.",
|
|
179
|
+
),
|
|
180
|
+
] = False,
|
|
181
|
+
) -> None:
|
|
182
|
+
api = get_hf_api(token=token)
|
|
183
|
+
api.create_branch(
|
|
184
|
+
repo_id=repo_id,
|
|
185
|
+
branch=branch,
|
|
186
|
+
revision=revision,
|
|
187
|
+
repo_type=repo_type.value,
|
|
188
|
+
exist_ok=exist_ok,
|
|
189
|
+
)
|
|
190
|
+
print(f"Successfully created {ANSI.bold(branch)} branch on {repo_type.value} {ANSI.bold(repo_id)}")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@branch_cli.command("delete", help="Delete a branch from a repo on the Hub.")
|
|
194
|
+
def branch_delete(
|
|
195
|
+
repo_id: RepoIdArg,
|
|
196
|
+
branch: Annotated[
|
|
197
|
+
str,
|
|
198
|
+
typer.Argument(
|
|
199
|
+
help="The name of the branch to delete.",
|
|
200
|
+
),
|
|
201
|
+
],
|
|
202
|
+
token: TokenOpt = None,
|
|
203
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
204
|
+
) -> None:
|
|
205
|
+
api = get_hf_api(token=token)
|
|
206
|
+
api.delete_branch(
|
|
207
|
+
repo_id=repo_id,
|
|
208
|
+
branch=branch,
|
|
209
|
+
repo_type=repo_type.value,
|
|
210
|
+
)
|
|
211
|
+
print(f"Successfully deleted {ANSI.bold(branch)} branch on {repo_type.value} {ANSI.bold(repo_id)}")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@tag_cli.command("create", help="Create a tag for a repo.")
|
|
215
|
+
def tag_create(
|
|
216
|
+
repo_id: RepoIdArg,
|
|
217
|
+
tag: Annotated[
|
|
218
|
+
str,
|
|
219
|
+
typer.Argument(
|
|
220
|
+
help="The name of the tag to create.",
|
|
221
|
+
),
|
|
222
|
+
],
|
|
223
|
+
message: Annotated[
|
|
224
|
+
Optional[str],
|
|
225
|
+
typer.Option(
|
|
226
|
+
"-m",
|
|
227
|
+
"--message",
|
|
228
|
+
help="The description of the tag to create.",
|
|
229
|
+
),
|
|
230
|
+
] = None,
|
|
231
|
+
revision: RevisionOpt = None,
|
|
232
|
+
token: TokenOpt = None,
|
|
233
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
234
|
+
) -> None:
|
|
235
|
+
repo_type_str = repo_type.value
|
|
236
|
+
api = get_hf_api(token=token)
|
|
237
|
+
print(f"You are about to create tag {ANSI.bold(tag)} on {repo_type_str} {ANSI.bold(repo_id)}")
|
|
238
|
+
try:
|
|
239
|
+
api.create_tag(repo_id=repo_id, tag=tag, tag_message=message, revision=revision, repo_type=repo_type_str)
|
|
240
|
+
except RepositoryNotFoundError:
|
|
241
|
+
print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.")
|
|
242
|
+
raise typer.Exit(code=1)
|
|
243
|
+
except RevisionNotFoundError:
|
|
244
|
+
print(f"Revision {ANSI.bold(str(revision))} not found.")
|
|
245
|
+
raise typer.Exit(code=1)
|
|
246
|
+
except HfHubHTTPError as e:
|
|
247
|
+
if e.response.status_code == 409:
|
|
248
|
+
print(f"Tag {ANSI.bold(tag)} already exists on {ANSI.bold(repo_id)}")
|
|
249
|
+
raise typer.Exit(code=1)
|
|
250
|
+
raise e
|
|
251
|
+
print(f"Tag {ANSI.bold(tag)} created on {ANSI.bold(repo_id)}")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@tag_cli.command("list", help="List tags for a repo.")
|
|
255
|
+
def tag_list(
|
|
256
|
+
repo_id: RepoIdArg,
|
|
257
|
+
token: TokenOpt = None,
|
|
258
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
259
|
+
) -> None:
|
|
260
|
+
repo_type_str = repo_type.value
|
|
261
|
+
api = get_hf_api(token=token)
|
|
262
|
+
try:
|
|
263
|
+
refs = api.list_repo_refs(repo_id=repo_id, repo_type=repo_type_str)
|
|
264
|
+
except RepositoryNotFoundError:
|
|
265
|
+
print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.")
|
|
266
|
+
raise typer.Exit(code=1)
|
|
267
|
+
except HfHubHTTPError as e:
|
|
268
|
+
print(e)
|
|
269
|
+
print(ANSI.red(e.response.text))
|
|
270
|
+
raise typer.Exit(code=1)
|
|
271
|
+
if len(refs.tags) == 0:
|
|
272
|
+
print("No tags found")
|
|
273
|
+
raise typer.Exit(code=0)
|
|
274
|
+
print(f"Tags for {repo_type_str} {ANSI.bold(repo_id)}:")
|
|
275
|
+
for t in refs.tags:
|
|
276
|
+
print(t.name)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@tag_cli.command("delete", help="Delete a tag for a repo.")
|
|
280
|
+
def tag_delete(
|
|
281
|
+
repo_id: RepoIdArg,
|
|
282
|
+
tag: Annotated[
|
|
283
|
+
str,
|
|
284
|
+
typer.Argument(
|
|
285
|
+
help="The name of the tag to delete.",
|
|
286
|
+
),
|
|
287
|
+
],
|
|
288
|
+
yes: Annotated[
|
|
289
|
+
bool,
|
|
290
|
+
typer.Option(
|
|
291
|
+
"-y",
|
|
292
|
+
"--yes",
|
|
293
|
+
help="Answer Yes to prompt automatically",
|
|
294
|
+
),
|
|
295
|
+
] = False,
|
|
296
|
+
token: TokenOpt = None,
|
|
297
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
298
|
+
) -> None:
|
|
299
|
+
repo_type_str = repo_type.value
|
|
300
|
+
print(f"You are about to delete tag {ANSI.bold(tag)} on {repo_type_str} {ANSI.bold(repo_id)}")
|
|
301
|
+
if not yes:
|
|
302
|
+
choice = input("Proceed? [Y/n] ").lower()
|
|
303
|
+
if choice not in ("", "y", "yes"):
|
|
304
|
+
print("Abort")
|
|
305
|
+
raise typer.Exit()
|
|
306
|
+
api = get_hf_api(token=token)
|
|
307
|
+
try:
|
|
308
|
+
api.delete_tag(repo_id=repo_id, tag=tag, repo_type=repo_type_str)
|
|
309
|
+
except RepositoryNotFoundError:
|
|
310
|
+
print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.")
|
|
311
|
+
raise typer.Exit(code=1)
|
|
312
|
+
except RevisionNotFoundError:
|
|
313
|
+
print(f"Tag {ANSI.bold(tag)} not found on {ANSI.bold(repo_id)}")
|
|
314
|
+
raise typer.Exit(code=1)
|
|
315
|
+
print(f"Tag {ANSI.bold(tag)} deleted on {ANSI.bold(repo_id)}")
|
|
@@ -0,0 +1,94 @@
|
|
|
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 update or delete files in a repository using the CLI.
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
# delete all
|
|
19
|
+
hf repo-files delete <repo_id> "*"
|
|
20
|
+
|
|
21
|
+
# delete single file
|
|
22
|
+
hf repo-files delete <repo_id> file.txt
|
|
23
|
+
|
|
24
|
+
# delete single folder
|
|
25
|
+
hf repo-files delete <repo_id> folder/
|
|
26
|
+
|
|
27
|
+
# delete multiple
|
|
28
|
+
hf repo-files delete <repo_id> file.txt folder/ file2.txt
|
|
29
|
+
|
|
30
|
+
# delete multiple patterns
|
|
31
|
+
hf repo-files delete <repo_id> file.txt "*.json" "folder/*.parquet"
|
|
32
|
+
|
|
33
|
+
# delete from different revision / repo-type
|
|
34
|
+
hf repo-files delete <repo_id> file.txt --revision=refs/pr/1 --repo-type=dataset
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
from typing import Annotated, Optional
|
|
38
|
+
|
|
39
|
+
import typer
|
|
40
|
+
|
|
41
|
+
from huggingface_hub import logging
|
|
42
|
+
|
|
43
|
+
from ._cli_utils import RepoIdArg, RepoType, RepoTypeOpt, RevisionOpt, TokenOpt, get_hf_api, typer_factory
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
logger = logging.get_logger(__name__)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
repo_files_cli = typer_factory(help="Manage files in a repo on the Hub.")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@repo_files_cli.command("delete")
|
|
53
|
+
def repo_files_delete(
|
|
54
|
+
repo_id: RepoIdArg,
|
|
55
|
+
patterns: Annotated[
|
|
56
|
+
list[str],
|
|
57
|
+
typer.Argument(
|
|
58
|
+
help="Glob patterns to match files to delete.",
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
62
|
+
revision: RevisionOpt = None,
|
|
63
|
+
commit_message: Annotated[
|
|
64
|
+
Optional[str],
|
|
65
|
+
typer.Option(
|
|
66
|
+
help="The summary / title / first line of the generated commit.",
|
|
67
|
+
),
|
|
68
|
+
] = None,
|
|
69
|
+
commit_description: Annotated[
|
|
70
|
+
Optional[str],
|
|
71
|
+
typer.Option(
|
|
72
|
+
help="The description of the generated commit.",
|
|
73
|
+
),
|
|
74
|
+
] = None,
|
|
75
|
+
create_pr: Annotated[
|
|
76
|
+
bool,
|
|
77
|
+
typer.Option(
|
|
78
|
+
help="Whether to create a new Pull Request for these changes.",
|
|
79
|
+
),
|
|
80
|
+
] = False,
|
|
81
|
+
token: TokenOpt = None,
|
|
82
|
+
) -> None:
|
|
83
|
+
api = get_hf_api(token=token)
|
|
84
|
+
url = api.delete_files(
|
|
85
|
+
delete_patterns=patterns,
|
|
86
|
+
repo_id=repo_id,
|
|
87
|
+
repo_type=repo_type.value,
|
|
88
|
+
revision=revision,
|
|
89
|
+
commit_message=commit_message,
|
|
90
|
+
commit_description=commit_description,
|
|
91
|
+
create_pr=create_pr,
|
|
92
|
+
)
|
|
93
|
+
print(f"Files correctly deleted from repo. Commit: {url}.")
|
|
94
|
+
logging.set_verbosity_warning()
|
|
@@ -11,26 +11,23 @@
|
|
|
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 commands to print information about the environment and version.
|
|
15
15
|
|
|
16
16
|
Usage:
|
|
17
|
-
|
|
17
|
+
hf env
|
|
18
|
+
hf version
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
|
-
from
|
|
21
|
+
from huggingface_hub import __version__
|
|
21
22
|
|
|
22
23
|
from ..utils import dump_environment_info
|
|
23
|
-
from . import BaseHuggingfaceCLICommand
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
def env() -> None:
|
|
27
|
+
"""Print information about the environment."""
|
|
28
|
+
dump_environment_info()
|
|
29
29
|
|
|
30
|
-
@staticmethod
|
|
31
|
-
def register_subcommand(parser: _SubParsersAction):
|
|
32
|
-
env_parser = parser.add_parser("env", help="Print information about the environment.")
|
|
33
|
-
env_parser.set_defaults(func=EnvironmentCommand)
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
def version() -> None:
|
|
32
|
+
"""Print CLI version."""
|
|
33
|
+
print(__version__)
|