huggingface-hub 0.36.0rc0__py3-none-any.whl → 1.0.0__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.
Potentially problematic release.
This version of huggingface-hub might be problematic. Click here for more details.
- huggingface_hub/__init__.py +33 -45
- huggingface_hub/_commit_api.py +39 -43
- huggingface_hub/_commit_scheduler.py +11 -8
- huggingface_hub/_inference_endpoints.py +8 -8
- huggingface_hub/_jobs_api.py +20 -20
- huggingface_hub/_login.py +17 -43
- huggingface_hub/_oauth.py +8 -8
- huggingface_hub/_snapshot_download.py +135 -50
- huggingface_hub/_space_api.py +4 -4
- huggingface_hub/_tensorboard_logger.py +5 -5
- huggingface_hub/_upload_large_folder.py +18 -32
- huggingface_hub/_webhooks_payload.py +3 -3
- huggingface_hub/_webhooks_server.py +2 -2
- huggingface_hub/cli/__init__.py +0 -14
- huggingface_hub/cli/_cli_utils.py +143 -39
- huggingface_hub/cli/auth.py +105 -171
- huggingface_hub/cli/cache.py +594 -361
- huggingface_hub/cli/download.py +120 -112
- huggingface_hub/cli/hf.py +38 -41
- huggingface_hub/cli/jobs.py +689 -1017
- huggingface_hub/cli/lfs.py +120 -143
- huggingface_hub/cli/repo.py +282 -216
- huggingface_hub/cli/repo_files.py +50 -84
- huggingface_hub/cli/system.py +6 -25
- huggingface_hub/cli/upload.py +198 -220
- huggingface_hub/cli/upload_large_folder.py +91 -106
- huggingface_hub/community.py +5 -5
- huggingface_hub/constants.py +17 -52
- huggingface_hub/dataclasses.py +135 -21
- huggingface_hub/errors.py +47 -30
- huggingface_hub/fastai_utils.py +8 -9
- huggingface_hub/file_download.py +351 -303
- huggingface_hub/hf_api.py +398 -570
- huggingface_hub/hf_file_system.py +101 -66
- huggingface_hub/hub_mixin.py +32 -54
- huggingface_hub/inference/_client.py +177 -162
- huggingface_hub/inference/_common.py +38 -54
- huggingface_hub/inference/_generated/_async_client.py +218 -258
- 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 +16 -16
- 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/sentence_similarity.py +3 -3
- huggingface_hub/inference/_generated/types/summarization.py +2 -2
- huggingface_hub/inference/_generated/types/table_question_answering.py +4 -4
- 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/agent.py +3 -3
- huggingface_hub/inference/_mcp/constants.py +1 -2
- huggingface_hub/inference/_mcp/mcp_client.py +33 -22
- huggingface_hub/inference/_mcp/types.py +10 -10
- huggingface_hub/inference/_mcp/utils.py +4 -4
- huggingface_hub/inference/_providers/__init__.py +12 -4
- huggingface_hub/inference/_providers/_common.py +62 -24
- huggingface_hub/inference/_providers/black_forest_labs.py +6 -6
- huggingface_hub/inference/_providers/cohere.py +3 -3
- huggingface_hub/inference/_providers/fal_ai.py +25 -25
- huggingface_hub/inference/_providers/featherless_ai.py +4 -4
- huggingface_hub/inference/_providers/fireworks_ai.py +3 -3
- huggingface_hub/inference/_providers/hf_inference.py +13 -13
- huggingface_hub/inference/_providers/hyperbolic.py +4 -4
- huggingface_hub/inference/_providers/nebius.py +10 -10
- huggingface_hub/inference/_providers/novita.py +5 -5
- huggingface_hub/inference/_providers/nscale.py +4 -4
- huggingface_hub/inference/_providers/replicate.py +15 -15
- huggingface_hub/inference/_providers/sambanova.py +6 -6
- huggingface_hub/inference/_providers/together.py +7 -7
- huggingface_hub/lfs.py +21 -94
- huggingface_hub/repocard.py +15 -16
- huggingface_hub/repocard_data.py +57 -57
- huggingface_hub/serialization/__init__.py +0 -1
- huggingface_hub/serialization/_base.py +9 -9
- huggingface_hub/serialization/_dduf.py +7 -7
- huggingface_hub/serialization/_torch.py +28 -28
- huggingface_hub/utils/__init__.py +11 -6
- huggingface_hub/utils/_auth.py +5 -5
- huggingface_hub/utils/_cache_manager.py +49 -74
- huggingface_hub/utils/_deprecation.py +1 -1
- huggingface_hub/utils/_dotenv.py +3 -3
- huggingface_hub/utils/_fixes.py +0 -10
- huggingface_hub/utils/_git_credential.py +3 -3
- huggingface_hub/utils/_headers.py +7 -29
- huggingface_hub/utils/_http.py +371 -208
- 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 +59 -23
- huggingface_hub/utils/_safetensors.py +21 -21
- huggingface_hub/utils/_subprocess.py +9 -9
- huggingface_hub/utils/_telemetry.py +3 -3
- huggingface_hub/{commands/_cli_utils.py → utils/_terminal.py} +4 -9
- huggingface_hub/utils/_typing.py +3 -3
- huggingface_hub/utils/_validators.py +53 -72
- huggingface_hub/utils/_xet.py +16 -16
- huggingface_hub/utils/_xet_progress_reporting.py +1 -1
- huggingface_hub/utils/insecure_hashlib.py +3 -9
- huggingface_hub/utils/tqdm.py +3 -3
- {huggingface_hub-0.36.0rc0.dist-info → huggingface_hub-1.0.0.dist-info}/METADATA +16 -35
- huggingface_hub-1.0.0.dist-info/RECORD +152 -0
- {huggingface_hub-0.36.0rc0.dist-info → huggingface_hub-1.0.0.dist-info}/entry_points.txt +0 -1
- huggingface_hub/commands/__init__.py +0 -27
- huggingface_hub/commands/delete_cache.py +0 -476
- huggingface_hub/commands/download.py +0 -204
- huggingface_hub/commands/env.py +0 -39
- huggingface_hub/commands/huggingface_cli.py +0 -65
- huggingface_hub/commands/lfs.py +0 -200
- huggingface_hub/commands/repo.py +0 -151
- huggingface_hub/commands/repo_files.py +0 -132
- huggingface_hub/commands/scan_cache.py +0 -183
- huggingface_hub/commands/tag.py +0 -161
- huggingface_hub/commands/upload.py +0 -318
- huggingface_hub/commands/upload_large_folder.py +0 -131
- huggingface_hub/commands/user.py +0 -208
- huggingface_hub/commands/version.py +0 -40
- huggingface_hub/inference_api.py +0 -217
- huggingface_hub/keras_mixin.py +0 -497
- huggingface_hub/repository.py +0 -1471
- huggingface_hub/serialization/_tensorflow.py +0 -92
- huggingface_hub/utils/_hf_folder.py +0 -68
- huggingface_hub-0.36.0rc0.dist-info/RECORD +0 -170
- {huggingface_hub-0.36.0rc0.dist-info → huggingface_hub-1.0.0.dist-info}/LICENSE +0 -0
- {huggingface_hub-0.36.0rc0.dist-info → huggingface_hub-1.0.0.dist-info}/WHEEL +0 -0
- {huggingface_hub-0.36.0rc0.dist-info → huggingface_hub-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -34,95 +34,61 @@ Usage:
|
|
|
34
34
|
hf repo-files delete <repo_id> file.txt --revision=refs/pr/1 --repo-type=dataset
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
|
-
from
|
|
38
|
-
|
|
37
|
+
from typing import Annotated, Optional
|
|
38
|
+
|
|
39
|
+
import typer
|
|
39
40
|
|
|
40
41
|
from huggingface_hub import logging
|
|
41
|
-
|
|
42
|
-
from
|
|
42
|
+
|
|
43
|
+
from ._cli_utils import RepoIdArg, RepoType, RepoTypeOpt, RevisionOpt, TokenOpt, get_hf_api, typer_factory
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
logger = logging.get_logger(__name__)
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
self.commit_description: Optional[str] = args.commit_description
|
|
58
|
-
self.create_pr: bool = args.create_pr
|
|
59
|
-
self.token: Optional[str] = args.token
|
|
60
|
-
|
|
61
|
-
def run(self) -> None:
|
|
62
|
-
logging.set_verbosity_info()
|
|
63
|
-
url = self.api.delete_files(
|
|
64
|
-
delete_patterns=self.patterns,
|
|
65
|
-
repo_id=self.repo_id,
|
|
66
|
-
repo_type=self.repo_type,
|
|
67
|
-
revision=self.revision,
|
|
68
|
-
commit_message=self.commit_message,
|
|
69
|
-
commit_description=self.commit_description,
|
|
70
|
-
create_pr=self.create_pr,
|
|
71
|
-
)
|
|
72
|
-
print(f"Files correctly deleted from repo. Commit: {url}.")
|
|
73
|
-
logging.set_verbosity_warning()
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class RepoFilesCommand(BaseHuggingfaceCLICommand):
|
|
77
|
-
@staticmethod
|
|
78
|
-
def register_subcommand(parser: _SubParsersAction):
|
|
79
|
-
repo_files_parser = parser.add_parser("repo-files", help="Manage files in a repo on the Hub.")
|
|
80
|
-
repo_files_subparsers = repo_files_parser.add_subparsers(
|
|
81
|
-
help="Action to execute against the files.",
|
|
82
|
-
required=True,
|
|
83
|
-
)
|
|
84
|
-
delete_subparser = repo_files_subparsers.add_parser(
|
|
85
|
-
"delete",
|
|
86
|
-
help="Delete files from a repo on the Hub",
|
|
87
|
-
)
|
|
88
|
-
delete_subparser.set_defaults(func=lambda args: DeleteFilesSubCommand(args))
|
|
89
|
-
delete_subparser.add_argument(
|
|
90
|
-
"repo_id", type=str, help="The ID of the repo to manage (e.g. `username/repo-name`)."
|
|
91
|
-
)
|
|
92
|
-
delete_subparser.add_argument(
|
|
93
|
-
"patterns",
|
|
94
|
-
nargs="+",
|
|
95
|
-
type=str,
|
|
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(
|
|
96
58
|
help="Glob patterns to match files to delete.",
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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()
|
huggingface_hub/cli/system.py
CHANGED
|
@@ -18,35 +18,16 @@ Usage:
|
|
|
18
18
|
hf version
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
from argparse import _SubParsersAction
|
|
22
|
-
|
|
23
21
|
from huggingface_hub import __version__
|
|
24
22
|
|
|
25
23
|
from ..utils import dump_environment_info
|
|
26
|
-
from . import BaseHuggingfaceCLICommand
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class EnvironmentCommand(BaseHuggingfaceCLICommand):
|
|
30
|
-
def __init__(self, args):
|
|
31
|
-
self.args = args
|
|
32
|
-
|
|
33
|
-
@staticmethod
|
|
34
|
-
def register_subcommand(parser: _SubParsersAction):
|
|
35
|
-
env_parser = parser.add_parser("env", help="Print information about the environment.")
|
|
36
|
-
env_parser.set_defaults(func=EnvironmentCommand)
|
|
37
|
-
|
|
38
|
-
def run(self) -> None:
|
|
39
|
-
dump_environment_info()
|
|
40
24
|
|
|
41
25
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
def env() -> None:
|
|
27
|
+
"""Print information about the environment."""
|
|
28
|
+
dump_environment_info()
|
|
45
29
|
|
|
46
|
-
@staticmethod
|
|
47
|
-
def register_subcommand(parser: _SubParsersAction):
|
|
48
|
-
version_parser = parser.add_parser("version", help="Print information about the hf version.")
|
|
49
|
-
version_parser.set_defaults(func=VersionCommand)
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
31
|
+
def version() -> None:
|
|
32
|
+
"""Print CLI version."""
|
|
33
|
+
print(__version__)
|
huggingface_hub/cli/upload.py
CHANGED
|
@@ -49,215 +49,151 @@ Usage:
|
|
|
49
49
|
import os
|
|
50
50
|
import time
|
|
51
51
|
import warnings
|
|
52
|
-
from
|
|
53
|
-
|
|
52
|
+
from typing import Annotated, Optional
|
|
53
|
+
|
|
54
|
+
import typer
|
|
54
55
|
|
|
55
56
|
from huggingface_hub import logging
|
|
56
57
|
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
58
|
from huggingface_hub.errors import RevisionNotFoundError
|
|
60
|
-
from huggingface_hub.hf_api import HfApi
|
|
61
59
|
from huggingface_hub.utils import disable_progress_bars, enable_progress_bars
|
|
62
|
-
|
|
60
|
+
|
|
61
|
+
from ._cli_utils import PrivateOpt, RepoIdArg, RepoType, RepoTypeOpt, RevisionOpt, TokenOpt, get_hf_api
|
|
63
62
|
|
|
64
63
|
|
|
65
64
|
logger = logging.get_logger(__name__)
|
|
66
65
|
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
74
|
-
upload_parser.add_argument(
|
|
75
|
-
"repo_id", type=str, help="The ID of the repo to upload to (e.g. `username/repo-name`)."
|
|
76
|
-
)
|
|
77
|
-
upload_parser.add_argument(
|
|
78
|
-
"local_path",
|
|
79
|
-
nargs="?",
|
|
67
|
+
def upload(
|
|
68
|
+
repo_id: RepoIdArg,
|
|
69
|
+
local_path: Annotated[
|
|
70
|
+
Optional[str],
|
|
71
|
+
typer.Argument(
|
|
80
72
|
help="Local path to the file or folder to upload. Wildcard patterns are supported. Defaults to current directory.",
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
),
|
|
74
|
+
] = None,
|
|
75
|
+
path_in_repo: Annotated[
|
|
76
|
+
Optional[str],
|
|
77
|
+
typer.Argument(
|
|
85
78
|
help="Path of the file or folder in the repo. Defaults to the relative path of the file or folder.",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
" exists."
|
|
107
|
-
),
|
|
108
|
-
)
|
|
109
|
-
upload_parser.add_argument("--include", nargs="*", type=str, help="Glob patterns to match files to upload.")
|
|
110
|
-
upload_parser.add_argument(
|
|
111
|
-
"--exclude", nargs="*", type=str, help="Glob patterns to exclude from files to upload."
|
|
112
|
-
)
|
|
113
|
-
upload_parser.add_argument(
|
|
114
|
-
"--delete",
|
|
115
|
-
nargs="*",
|
|
116
|
-
type=str,
|
|
79
|
+
),
|
|
80
|
+
] = None,
|
|
81
|
+
repo_type: RepoTypeOpt = RepoType.model,
|
|
82
|
+
revision: RevisionOpt = None,
|
|
83
|
+
private: PrivateOpt = False,
|
|
84
|
+
include: Annotated[
|
|
85
|
+
Optional[list[str]],
|
|
86
|
+
typer.Option(
|
|
87
|
+
help="Glob patterns to match files to upload.",
|
|
88
|
+
),
|
|
89
|
+
] = None,
|
|
90
|
+
exclude: Annotated[
|
|
91
|
+
Optional[list[str]],
|
|
92
|
+
typer.Option(
|
|
93
|
+
help="Glob patterns to exclude from files to upload.",
|
|
94
|
+
),
|
|
95
|
+
] = None,
|
|
96
|
+
delete: Annotated[
|
|
97
|
+
Optional[list[str]],
|
|
98
|
+
typer.Option(
|
|
117
99
|
help="Glob patterns for file to be deleted from the repo while committing.",
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
help="
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if
|
|
168
|
-
if
|
|
169
|
-
|
|
170
|
-
if
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
self.path_in_repo = "."
|
|
175
|
-
elif args.local_path is None and os.path.isfile(repo_name):
|
|
176
|
-
# Implicit case 1: user provided only a repo_id which happen to be a local file as well => upload it with same name
|
|
177
|
-
self.local_path = repo_name
|
|
178
|
-
self.path_in_repo = repo_name
|
|
179
|
-
elif args.local_path is None and os.path.isdir(repo_name):
|
|
180
|
-
# Implicit case 2: user provided only a repo_id which happen to be a local folder as well => upload it at root
|
|
181
|
-
self.local_path = repo_name
|
|
182
|
-
self.path_in_repo = "."
|
|
183
|
-
elif args.local_path is None:
|
|
184
|
-
# Implicit case 3: user provided only a repo_id that does not match a local file or folder
|
|
185
|
-
# => the user must explicitly provide a local_path => raise exception
|
|
186
|
-
raise ValueError(f"'{repo_name}' is not a local file or folder. Please set `local_path` explicitly.")
|
|
187
|
-
elif args.path_in_repo is None and os.path.isfile(args.local_path):
|
|
188
|
-
# Explicit local path to file, no path in repo => upload it at root with same name
|
|
189
|
-
self.local_path = args.local_path
|
|
190
|
-
self.path_in_repo = os.path.basename(args.local_path)
|
|
191
|
-
elif args.path_in_repo is None:
|
|
192
|
-
# Explicit local path to folder, no path in repo => upload at root
|
|
193
|
-
self.local_path = args.local_path
|
|
194
|
-
self.path_in_repo = "."
|
|
195
|
-
else:
|
|
196
|
-
# Finally, if both paths are explicit
|
|
197
|
-
self.local_path = args.local_path
|
|
198
|
-
self.path_in_repo = args.path_in_repo
|
|
199
|
-
|
|
200
|
-
def run(self) -> None:
|
|
201
|
-
if self.quiet:
|
|
202
|
-
disable_progress_bars()
|
|
203
|
-
with warnings.catch_warnings():
|
|
204
|
-
warnings.simplefilter("ignore")
|
|
205
|
-
print(self._upload())
|
|
206
|
-
enable_progress_bars()
|
|
207
|
-
else:
|
|
208
|
-
logging.set_verbosity_info()
|
|
209
|
-
print(self._upload())
|
|
210
|
-
logging.set_verbosity_warning()
|
|
211
|
-
|
|
212
|
-
def _upload(self) -> str:
|
|
213
|
-
if os.path.isfile(self.local_path):
|
|
214
|
-
if self.include is not None and len(self.include) > 0:
|
|
215
|
-
warnings.warn("Ignoring `--include` since a single file is uploaded.")
|
|
216
|
-
if self.exclude is not None and len(self.exclude) > 0:
|
|
217
|
-
warnings.warn("Ignoring `--exclude` since a single file is uploaded.")
|
|
218
|
-
if self.delete is not None and len(self.delete) > 0:
|
|
219
|
-
warnings.warn("Ignoring `--delete` since a single file is uploaded.")
|
|
220
|
-
|
|
221
|
-
if not is_xet_available() and not HF_HUB_ENABLE_HF_TRANSFER:
|
|
222
|
-
logger.info(
|
|
223
|
-
"Consider using `hf_transfer` for faster uploads. This solution comes with some limitations. See"
|
|
224
|
-
" https://huggingface.co/docs/huggingface_hub/hf_transfer for more details."
|
|
225
|
-
)
|
|
100
|
+
),
|
|
101
|
+
] = None,
|
|
102
|
+
commit_message: Annotated[
|
|
103
|
+
Optional[str],
|
|
104
|
+
typer.Option(
|
|
105
|
+
help="The summary / title / first line of the generated commit.",
|
|
106
|
+
),
|
|
107
|
+
] = None,
|
|
108
|
+
commit_description: Annotated[
|
|
109
|
+
Optional[str],
|
|
110
|
+
typer.Option(
|
|
111
|
+
help="The description of the generated commit.",
|
|
112
|
+
),
|
|
113
|
+
] = None,
|
|
114
|
+
create_pr: Annotated[
|
|
115
|
+
bool,
|
|
116
|
+
typer.Option(
|
|
117
|
+
help="Whether to upload content as a new Pull Request.",
|
|
118
|
+
),
|
|
119
|
+
] = False,
|
|
120
|
+
every: Annotated[
|
|
121
|
+
Optional[float],
|
|
122
|
+
typer.Option(
|
|
123
|
+
help="f set, a background job is scheduled to create commits every `every` minutes.",
|
|
124
|
+
),
|
|
125
|
+
] = None,
|
|
126
|
+
token: TokenOpt = None,
|
|
127
|
+
quiet: Annotated[
|
|
128
|
+
bool,
|
|
129
|
+
typer.Option(
|
|
130
|
+
help="Disable progress bars and warnings; print only the returned path.",
|
|
131
|
+
),
|
|
132
|
+
] = False,
|
|
133
|
+
) -> None:
|
|
134
|
+
"""Upload a file or a folder to the Hub. Recommended for single-commit uploads."""
|
|
135
|
+
|
|
136
|
+
if every is not None and every <= 0:
|
|
137
|
+
raise typer.BadParameter("--every must be a positive value", param_hint="every")
|
|
138
|
+
|
|
139
|
+
repo_type_str = repo_type.value
|
|
140
|
+
|
|
141
|
+
api = get_hf_api(token=token)
|
|
142
|
+
|
|
143
|
+
# Resolve local_path and path_in_repo based on implicit/explicit rules
|
|
144
|
+
resolved_local_path, resolved_path_in_repo, resolved_include = _resolve_upload_paths(
|
|
145
|
+
repo_id=repo_id, local_path=local_path, path_in_repo=path_in_repo, include=include
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def run_upload() -> str:
|
|
149
|
+
if os.path.isfile(resolved_local_path):
|
|
150
|
+
if resolved_include is not None and len(resolved_include) > 0 and isinstance(resolved_include, list):
|
|
151
|
+
warnings.warn("Ignoring --include since a single file is uploaded.")
|
|
152
|
+
if exclude is not None and len(exclude) > 0:
|
|
153
|
+
warnings.warn("Ignoring --exclude since a single file is uploaded.")
|
|
154
|
+
if delete is not None and len(delete) > 0:
|
|
155
|
+
warnings.warn("Ignoring --delete since a single file is uploaded.")
|
|
226
156
|
|
|
227
157
|
# Schedule commits if `every` is set
|
|
228
|
-
if
|
|
229
|
-
if os.path.isfile(
|
|
158
|
+
if every is not None:
|
|
159
|
+
if os.path.isfile(resolved_local_path):
|
|
230
160
|
# If file => watch entire folder + use allow_patterns
|
|
231
|
-
folder_path = os.path.dirname(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if
|
|
235
|
-
else
|
|
161
|
+
folder_path = os.path.dirname(resolved_local_path)
|
|
162
|
+
pi = (
|
|
163
|
+
resolved_path_in_repo[: -len(resolved_local_path)]
|
|
164
|
+
if resolved_path_in_repo.endswith(resolved_local_path)
|
|
165
|
+
else resolved_path_in_repo
|
|
236
166
|
)
|
|
237
|
-
allow_patterns = [
|
|
238
|
-
ignore_patterns = []
|
|
167
|
+
allow_patterns = [resolved_local_path]
|
|
168
|
+
ignore_patterns: Optional[list[str]] = []
|
|
239
169
|
else:
|
|
240
|
-
folder_path =
|
|
241
|
-
|
|
242
|
-
allow_patterns =
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
170
|
+
folder_path = resolved_local_path
|
|
171
|
+
pi = resolved_path_in_repo
|
|
172
|
+
allow_patterns = (
|
|
173
|
+
resolved_include or []
|
|
174
|
+
if isinstance(resolved_include, list)
|
|
175
|
+
else [resolved_include]
|
|
176
|
+
if isinstance(resolved_include, str)
|
|
177
|
+
else []
|
|
178
|
+
)
|
|
179
|
+
ignore_patterns = exclude or []
|
|
180
|
+
if delete is not None and len(delete) > 0:
|
|
181
|
+
warnings.warn("Ignoring --delete when uploading with scheduled commits.")
|
|
246
182
|
|
|
247
183
|
scheduler = CommitScheduler(
|
|
248
184
|
folder_path=folder_path,
|
|
249
|
-
repo_id=
|
|
250
|
-
repo_type=
|
|
251
|
-
revision=
|
|
185
|
+
repo_id=repo_id,
|
|
186
|
+
repo_type=repo_type_str,
|
|
187
|
+
revision=revision,
|
|
252
188
|
allow_patterns=allow_patterns,
|
|
253
189
|
ignore_patterns=ignore_patterns,
|
|
254
|
-
path_in_repo=
|
|
255
|
-
private=
|
|
256
|
-
every=
|
|
257
|
-
hf_api=
|
|
190
|
+
path_in_repo=pi,
|
|
191
|
+
private=private,
|
|
192
|
+
every=every,
|
|
193
|
+
hf_api=api,
|
|
258
194
|
)
|
|
259
|
-
print(f"Scheduling commits every {
|
|
260
|
-
try:
|
|
195
|
+
print(f"Scheduling commits every {every} minutes to {scheduler.repo_id}.")
|
|
196
|
+
try:
|
|
261
197
|
while True:
|
|
262
198
|
time.sleep(100)
|
|
263
199
|
except KeyboardInterrupt:
|
|
@@ -265,52 +201,94 @@ class UploadCommand(BaseHuggingfaceCLICommand):
|
|
|
265
201
|
return "Stopped scheduled commits."
|
|
266
202
|
|
|
267
203
|
# Otherwise, create repo and proceed with the upload
|
|
268
|
-
if not os.path.isfile(
|
|
269
|
-
raise FileNotFoundError(f"No such file or directory: '{
|
|
270
|
-
|
|
271
|
-
repo_id=
|
|
272
|
-
repo_type=
|
|
204
|
+
if not os.path.isfile(resolved_local_path) and not os.path.isdir(resolved_local_path):
|
|
205
|
+
raise FileNotFoundError(f"No such file or directory: '{resolved_local_path}'.")
|
|
206
|
+
created = api.create_repo(
|
|
207
|
+
repo_id=repo_id,
|
|
208
|
+
repo_type=repo_type_str,
|
|
273
209
|
exist_ok=True,
|
|
274
|
-
private=
|
|
275
|
-
space_sdk="gradio" if
|
|
210
|
+
private=private,
|
|
211
|
+
space_sdk="gradio" if repo_type_str == "space" else None,
|
|
276
212
|
# ^ We don't want it to fail when uploading to a Space => let's set Gradio by default.
|
|
277
213
|
# ^ I'd rather not add CLI args to set it explicitly as we already have `hf repo create` for that.
|
|
278
214
|
).repo_id
|
|
279
215
|
|
|
280
216
|
# Check if branch already exists and if not, create it
|
|
281
|
-
if
|
|
217
|
+
if revision is not None and not create_pr:
|
|
282
218
|
try:
|
|
283
|
-
|
|
219
|
+
api.repo_info(repo_id=created, repo_type=repo_type_str, revision=revision)
|
|
284
220
|
except RevisionNotFoundError:
|
|
285
|
-
logger.info(f"Branch '{
|
|
286
|
-
|
|
221
|
+
logger.info(f"Branch '{revision}' not found. Creating it...")
|
|
222
|
+
api.create_branch(repo_id=created, repo_type=repo_type_str, branch=revision, exist_ok=True)
|
|
287
223
|
# ^ `exist_ok=True` to avoid race concurrency issues
|
|
288
224
|
|
|
289
225
|
# File-based upload
|
|
290
|
-
if os.path.isfile(
|
|
291
|
-
return
|
|
292
|
-
path_or_fileobj=
|
|
293
|
-
path_in_repo=
|
|
294
|
-
repo_id=
|
|
295
|
-
repo_type=
|
|
296
|
-
revision=
|
|
297
|
-
commit_message=
|
|
298
|
-
commit_description=
|
|
299
|
-
create_pr=
|
|
226
|
+
if os.path.isfile(resolved_local_path):
|
|
227
|
+
return api.upload_file(
|
|
228
|
+
path_or_fileobj=resolved_local_path,
|
|
229
|
+
path_in_repo=resolved_path_in_repo,
|
|
230
|
+
repo_id=created,
|
|
231
|
+
repo_type=repo_type_str,
|
|
232
|
+
revision=revision,
|
|
233
|
+
commit_message=commit_message,
|
|
234
|
+
commit_description=commit_description,
|
|
235
|
+
create_pr=create_pr,
|
|
300
236
|
)
|
|
301
237
|
|
|
302
238
|
# Folder-based upload
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
239
|
+
return api.upload_folder(
|
|
240
|
+
folder_path=resolved_local_path,
|
|
241
|
+
path_in_repo=resolved_path_in_repo,
|
|
242
|
+
repo_id=created,
|
|
243
|
+
repo_type=repo_type_str,
|
|
244
|
+
revision=revision,
|
|
245
|
+
commit_message=commit_message,
|
|
246
|
+
commit_description=commit_description,
|
|
247
|
+
create_pr=create_pr,
|
|
248
|
+
allow_patterns=(
|
|
249
|
+
resolved_include
|
|
250
|
+
if isinstance(resolved_include, list)
|
|
251
|
+
else [resolved_include]
|
|
252
|
+
if isinstance(resolved_include, str)
|
|
253
|
+
else None
|
|
254
|
+
),
|
|
255
|
+
ignore_patterns=exclude,
|
|
256
|
+
delete_patterns=delete,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
if quiet:
|
|
260
|
+
disable_progress_bars()
|
|
261
|
+
with warnings.catch_warnings():
|
|
262
|
+
warnings.simplefilter("ignore")
|
|
263
|
+
print(run_upload())
|
|
264
|
+
enable_progress_bars()
|
|
265
|
+
else:
|
|
266
|
+
print(run_upload())
|
|
267
|
+
logging.set_verbosity_warning()
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _resolve_upload_paths(
|
|
271
|
+
*, repo_id: str, local_path: Optional[str], path_in_repo: Optional[str], include: Optional[list[str]]
|
|
272
|
+
) -> tuple[str, str, Optional[list[str]]]:
|
|
273
|
+
repo_name = repo_id.split("/")[-1]
|
|
274
|
+
resolved_include = include
|
|
275
|
+
|
|
276
|
+
if local_path is not None and any(c in local_path for c in ["*", "?", "["]):
|
|
277
|
+
if include is not None:
|
|
278
|
+
raise ValueError("Cannot set --include when local_path contains a wildcard.")
|
|
279
|
+
if path_in_repo is not None and path_in_repo != ".":
|
|
280
|
+
raise ValueError("Cannot set path_in_repo when local_path contains a wildcard.")
|
|
281
|
+
return ".", local_path, ["."] # will be adjusted below; placeholder for type
|
|
282
|
+
|
|
283
|
+
if local_path is None and os.path.isfile(repo_name):
|
|
284
|
+
return repo_name, repo_name, resolved_include
|
|
285
|
+
if local_path is None and os.path.isdir(repo_name):
|
|
286
|
+
return repo_name, ".", resolved_include
|
|
287
|
+
if local_path is None:
|
|
288
|
+
raise ValueError(f"'{repo_name}' is not a local file or folder. Please set local_path explicitly.")
|
|
289
|
+
|
|
290
|
+
if path_in_repo is None and os.path.isfile(local_path):
|
|
291
|
+
return local_path, os.path.basename(local_path), resolved_include
|
|
292
|
+
if path_in_repo is None:
|
|
293
|
+
return local_path, ".", resolved_include
|
|
294
|
+
return local_path, path_in_repo, resolved_include
|