huggingface-hub 1.0.0rc0__py3-none-any.whl → 1.0.0rc1__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 +4 -4
- huggingface_hub/cli/__init__.py +0 -14
- huggingface_hub/cli/_cli_utils.py +79 -2
- huggingface_hub/cli/auth.py +104 -149
- huggingface_hub/cli/cache.py +97 -121
- huggingface_hub/cli/download.py +93 -110
- huggingface_hub/cli/hf.py +37 -41
- huggingface_hub/cli/jobs.py +687 -1014
- huggingface_hub/cli/lfs.py +116 -139
- huggingface_hub/cli/repo.py +159 -215
- huggingface_hub/cli/repo_files.py +50 -84
- huggingface_hub/cli/system.py +6 -25
- huggingface_hub/cli/upload.py +198 -212
- huggingface_hub/cli/upload_large_folder.py +90 -105
- huggingface_hub/errors.py +1 -1
- huggingface_hub/utils/__init__.py +1 -1
- huggingface_hub/utils/_http.py +5 -5
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/METADATA +6 -1
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/RECORD +23 -23
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/LICENSE +0 -0
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/WHEEL +0 -0
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/entry_points.txt +0 -0
- {huggingface_hub-1.0.0rc0.dist-info → huggingface_hub-1.0.0rc1.dist-info}/top_level.txt +0 -0
huggingface_hub/__init__.py
CHANGED
|
@@ -46,7 +46,7 @@ import sys
|
|
|
46
46
|
from typing import TYPE_CHECKING
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
__version__ = "1.0.0.
|
|
49
|
+
__version__ = "1.0.0.rc1"
|
|
50
50
|
|
|
51
51
|
# Alphabetical order of definitions is ensured in tests
|
|
52
52
|
# WARNING: any comment added in this dictionary definition will be lost when
|
|
@@ -516,7 +516,7 @@ _SUBMOD_ATTRS = {
|
|
|
516
516
|
"HfHubAsyncTransport",
|
|
517
517
|
"HfHubTransport",
|
|
518
518
|
"cached_assets_path",
|
|
519
|
-
"
|
|
519
|
+
"close_session",
|
|
520
520
|
"dump_environment_info",
|
|
521
521
|
"get_async_session",
|
|
522
522
|
"get_session",
|
|
@@ -815,7 +815,7 @@ __all__ = [
|
|
|
815
815
|
"cancel_access_request",
|
|
816
816
|
"cancel_job",
|
|
817
817
|
"change_discussion_status",
|
|
818
|
-
"
|
|
818
|
+
"close_session",
|
|
819
819
|
"comment_discussion",
|
|
820
820
|
"create_branch",
|
|
821
821
|
"create_collection",
|
|
@@ -1518,7 +1518,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
1518
1518
|
HfHubAsyncTransport, # noqa: F401
|
|
1519
1519
|
HfHubTransport, # noqa: F401
|
|
1520
1520
|
cached_assets_path, # noqa: F401
|
|
1521
|
-
|
|
1521
|
+
close_session, # noqa: F401
|
|
1522
1522
|
dump_environment_info, # noqa: F401
|
|
1523
1523
|
get_async_session, # noqa: F401
|
|
1524
1524
|
get_session, # noqa: F401
|
huggingface_hub/cli/__init__.py
CHANGED
|
@@ -11,17 +11,3 @@
|
|
|
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
|
-
|
|
15
|
-
from abc import ABC, abstractmethod
|
|
16
|
-
from argparse import _SubParsersAction
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class BaseHuggingfaceCLICommand(ABC):
|
|
20
|
-
@staticmethod
|
|
21
|
-
@abstractmethod
|
|
22
|
-
def register_subcommand(parser: _SubParsersAction):
|
|
23
|
-
raise NotImplementedError()
|
|
24
|
-
|
|
25
|
-
@abstractmethod
|
|
26
|
-
def run(self):
|
|
27
|
-
raise NotImplementedError()
|
|
@@ -11,10 +11,17 @@
|
|
|
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 CLI utilities (styling, helpers)."""
|
|
15
15
|
|
|
16
16
|
import os
|
|
17
|
-
from
|
|
17
|
+
from enum import Enum
|
|
18
|
+
from typing import Annotated, Optional, Union
|
|
19
|
+
|
|
20
|
+
import click
|
|
21
|
+
import typer
|
|
22
|
+
|
|
23
|
+
from huggingface_hub import __version__
|
|
24
|
+
from huggingface_hub.hf_api import HfApi
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
class ANSI:
|
|
@@ -67,3 +74,73 @@ def tabulate(rows: list[list[Union[str, int]]], headers: list[str]) -> str:
|
|
|
67
74
|
for row in rows:
|
|
68
75
|
lines.append(row_format.format(*row))
|
|
69
76
|
return "\n".join(lines)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#### TYPER UTILS
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class AlphabeticalMixedGroup(typer.core.TyperGroup):
|
|
83
|
+
"""
|
|
84
|
+
Typer Group that lists commands and sub-apps mixed and alphabetically.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def list_commands(self, ctx: click.Context) -> list[str]: # type: ignore[name-defined]
|
|
88
|
+
# click.Group stores both commands and sub-groups in `self.commands`
|
|
89
|
+
return sorted(self.commands.keys())
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def typer_factory(help: str) -> typer.Typer:
|
|
93
|
+
return typer.Typer(
|
|
94
|
+
help=help,
|
|
95
|
+
add_completion=True,
|
|
96
|
+
rich_markup_mode=None,
|
|
97
|
+
no_args_is_help=True,
|
|
98
|
+
cls=AlphabeticalMixedGroup,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class RepoType(str, Enum):
|
|
103
|
+
model = "model"
|
|
104
|
+
dataset = "dataset"
|
|
105
|
+
space = "space"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
RepoIdArg = Annotated[
|
|
109
|
+
str,
|
|
110
|
+
typer.Argument(
|
|
111
|
+
help="The ID of the repo (e.g. `username/repo-name`).",
|
|
112
|
+
),
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
RepoTypeOpt = Annotated[
|
|
117
|
+
RepoType,
|
|
118
|
+
typer.Option(
|
|
119
|
+
help="The type of repository (model, dataset, or space).",
|
|
120
|
+
),
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
TokenOpt = Annotated[
|
|
124
|
+
Optional[str],
|
|
125
|
+
typer.Option(
|
|
126
|
+
help="A User Access Token generated from https://huggingface.co/settings/tokens.",
|
|
127
|
+
),
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
PrivateOpt = Annotated[
|
|
131
|
+
bool,
|
|
132
|
+
typer.Option(
|
|
133
|
+
help="Whether to create a private repo if repo doesn't exist on the Hub. Ignored if the repo already exists.",
|
|
134
|
+
),
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
RevisionOpt = Annotated[
|
|
138
|
+
Optional[str],
|
|
139
|
+
typer.Option(
|
|
140
|
+
help="Git revision id which can be a branch name, a tag, or a commit hash.",
|
|
141
|
+
),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_hf_api(token: Optional[str] = None) -> HfApi:
|
|
146
|
+
return HfApi(token=token, library_name="hf", library_version=__version__)
|
huggingface_hub/cli/auth.py
CHANGED
|
@@ -30,17 +30,17 @@ Usage:
|
|
|
30
30
|
hf auth whoami
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
from
|
|
34
|
-
|
|
33
|
+
from typing import Annotated, Optional
|
|
34
|
+
|
|
35
|
+
import typer
|
|
35
36
|
|
|
36
|
-
from huggingface_hub.commands import BaseHuggingfaceCLICommand
|
|
37
37
|
from huggingface_hub.constants import ENDPOINT
|
|
38
38
|
from huggingface_hub.errors import HfHubHTTPError
|
|
39
|
-
from huggingface_hub.hf_api import
|
|
39
|
+
from huggingface_hub.hf_api import whoami
|
|
40
40
|
|
|
41
41
|
from .._login import auth_list, auth_switch, login, logout
|
|
42
42
|
from ..utils import get_stored_tokens, get_token, logging
|
|
43
|
-
from ._cli_utils import ANSI
|
|
43
|
+
from ._cli_utils import ANSI, TokenOpt, typer_factory
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
logger = logging.get_logger(__name__)
|
|
@@ -54,125 +54,42 @@ except ImportError:
|
|
|
54
54
|
_inquirer_py_available = False
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
logout_parser = auth_subparsers.add_parser("logout", help="Log out")
|
|
85
|
-
logout_parser.add_argument(
|
|
86
|
-
"--token-name",
|
|
87
|
-
type=str,
|
|
88
|
-
help="Optional: Name of the access token to log out from.",
|
|
89
|
-
)
|
|
90
|
-
logout_parser.set_defaults(func=lambda args: AuthLogout(args))
|
|
91
|
-
|
|
92
|
-
# Add 'whoami' as a subcommand of 'auth'
|
|
93
|
-
whoami_parser = auth_subparsers.add_parser(
|
|
94
|
-
"whoami", help="Find out which huggingface.co account you are logged in as."
|
|
95
|
-
)
|
|
96
|
-
whoami_parser.set_defaults(func=lambda args: AuthWhoami(args))
|
|
97
|
-
|
|
98
|
-
# Existing subcommands
|
|
99
|
-
auth_switch_parser = auth_subparsers.add_parser("switch", help="Switch between access tokens")
|
|
100
|
-
auth_switch_parser.add_argument(
|
|
101
|
-
"--token-name",
|
|
102
|
-
type=str,
|
|
103
|
-
help="Optional: Name of the access token to switch to.",
|
|
104
|
-
)
|
|
105
|
-
auth_switch_parser.add_argument(
|
|
106
|
-
"--add-to-git-credential",
|
|
107
|
-
action="store_true",
|
|
108
|
-
help="Optional: Save token to git credential helper.",
|
|
109
|
-
)
|
|
110
|
-
auth_switch_parser.set_defaults(func=lambda args: AuthSwitch(args))
|
|
111
|
-
|
|
112
|
-
auth_list_parser = auth_subparsers.add_parser("list", help="List all stored access tokens")
|
|
113
|
-
auth_list_parser.set_defaults(func=lambda args: AuthList(args))
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
class BaseAuthCommand:
|
|
117
|
-
def __init__(self, args):
|
|
118
|
-
self.args = args
|
|
119
|
-
self._api = HfApi()
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
class AuthLogin(BaseAuthCommand):
|
|
123
|
-
def run(self):
|
|
124
|
-
logging.set_verbosity_info()
|
|
125
|
-
login(
|
|
126
|
-
token=self.args.token,
|
|
127
|
-
add_to_git_credential=self.args.add_to_git_credential,
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class AuthLogout(BaseAuthCommand):
|
|
132
|
-
def run(self):
|
|
133
|
-
logging.set_verbosity_info()
|
|
134
|
-
logout(token_name=self.args.token_name)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class AuthSwitch(BaseAuthCommand):
|
|
138
|
-
def run(self):
|
|
139
|
-
logging.set_verbosity_info()
|
|
140
|
-
token_name = self.args.token_name
|
|
141
|
-
if token_name is None:
|
|
142
|
-
token_name = self._select_token_name()
|
|
143
|
-
|
|
144
|
-
if token_name is None:
|
|
145
|
-
print("No token name provided. Aborting.")
|
|
146
|
-
exit()
|
|
147
|
-
auth_switch(token_name, add_to_git_credential=self.args.add_to_git_credential)
|
|
148
|
-
|
|
149
|
-
def _select_token_name(self) -> Optional[str]:
|
|
150
|
-
token_names = list(get_stored_tokens().keys())
|
|
151
|
-
|
|
152
|
-
if not token_names:
|
|
153
|
-
logger.error("No stored tokens found. Please login first.")
|
|
154
|
-
return None
|
|
57
|
+
auth_cli = typer_factory(help="Manage authentication (login, logout, etc.).")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@auth_cli.command("login", help="Login using a token from huggingface.co/settings/tokens")
|
|
61
|
+
def auth_login(
|
|
62
|
+
token: TokenOpt = None,
|
|
63
|
+
add_to_git_credential: Annotated[
|
|
64
|
+
bool,
|
|
65
|
+
typer.Option(
|
|
66
|
+
help="Save to git credential helper. Useful only if you plan to run git commands directly.",
|
|
67
|
+
),
|
|
68
|
+
] = False,
|
|
69
|
+
) -> None:
|
|
70
|
+
login(token=token, add_to_git_credential=add_to_git_credential)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@auth_cli.command("logout", help="Logout from a specific token")
|
|
74
|
+
def auth_logout(
|
|
75
|
+
token_name: Annotated[
|
|
76
|
+
Optional[str],
|
|
77
|
+
typer.Option(
|
|
78
|
+
help="Name of token to logout",
|
|
79
|
+
),
|
|
80
|
+
] = None,
|
|
81
|
+
) -> None:
|
|
82
|
+
logout(token_name=token_name)
|
|
83
|
+
|
|
155
84
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
choice = input("Enter the number of the token to switch to (or 'q' to quit): ")
|
|
165
|
-
if choice.lower() == "q":
|
|
166
|
-
return None
|
|
167
|
-
index = int(choice) - 1
|
|
168
|
-
if 0 <= index < len(token_names):
|
|
169
|
-
return token_names[index]
|
|
170
|
-
else:
|
|
171
|
-
print("Invalid selection. Please try again.")
|
|
172
|
-
except ValueError:
|
|
173
|
-
print("Invalid input. Please enter a number or 'q' to quit.")
|
|
174
|
-
|
|
175
|
-
def _select_token_name_tui(self, token_names: list[str]) -> Optional[str]:
|
|
85
|
+
def _select_token_name() -> Optional[str]:
|
|
86
|
+
token_names = list(get_stored_tokens().keys())
|
|
87
|
+
|
|
88
|
+
if not token_names:
|
|
89
|
+
logger.error("No stored tokens found. Please login first.")
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
if _inquirer_py_available:
|
|
176
93
|
choices = [Choice(token_name, name=token_name) for token_name in token_names]
|
|
177
94
|
try:
|
|
178
95
|
return inquirer.select(
|
|
@@ -183,30 +100,68 @@ class AuthSwitch(BaseAuthCommand):
|
|
|
183
100
|
except KeyboardInterrupt:
|
|
184
101
|
logger.info("Token selection cancelled.")
|
|
185
102
|
return None
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
auth_list()
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
class AuthWhoami(BaseAuthCommand):
|
|
195
|
-
def run(self):
|
|
196
|
-
token = get_token()
|
|
197
|
-
if token is None:
|
|
198
|
-
print("Not logged in")
|
|
199
|
-
exit()
|
|
103
|
+
# if inquirer is not available, use a simpler terminal UI
|
|
104
|
+
print("Available stored tokens:")
|
|
105
|
+
for i, token_name in enumerate(token_names, 1):
|
|
106
|
+
print(f"{i}. {token_name}")
|
|
107
|
+
while True:
|
|
200
108
|
try:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
print(
|
|
209
|
-
except
|
|
210
|
-
print(
|
|
211
|
-
|
|
212
|
-
|
|
109
|
+
choice = input("Enter the number of the token to switch to (or 'q' to quit): ")
|
|
110
|
+
if choice.lower() == "q":
|
|
111
|
+
return None
|
|
112
|
+
index = int(choice) - 1
|
|
113
|
+
if 0 <= index < len(token_names):
|
|
114
|
+
return token_names[index]
|
|
115
|
+
else:
|
|
116
|
+
print("Invalid selection. Please try again.")
|
|
117
|
+
except ValueError:
|
|
118
|
+
print("Invalid input. Please enter a number or 'q' to quit.")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@auth_cli.command("switch", help="Switch between access tokens")
|
|
122
|
+
def auth_switch_cmd(
|
|
123
|
+
token_name: Annotated[
|
|
124
|
+
Optional[str],
|
|
125
|
+
typer.Option(
|
|
126
|
+
help="Name of the token to switch to",
|
|
127
|
+
),
|
|
128
|
+
] = None,
|
|
129
|
+
add_to_git_credential: Annotated[
|
|
130
|
+
bool,
|
|
131
|
+
typer.Option(
|
|
132
|
+
help="Save to git credential helper. Useful only if you plan to run git commands directly.",
|
|
133
|
+
),
|
|
134
|
+
] = False,
|
|
135
|
+
) -> None:
|
|
136
|
+
if token_name is None:
|
|
137
|
+
token_name = _select_token_name()
|
|
138
|
+
if token_name is None:
|
|
139
|
+
print("No token name provided. Aborting.")
|
|
140
|
+
raise typer.Exit()
|
|
141
|
+
auth_switch(token_name, add_to_git_credential=add_to_git_credential)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@auth_cli.command("list", help="List all stored access tokens")
|
|
145
|
+
def auth_list_cmd() -> None:
|
|
146
|
+
auth_list()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@auth_cli.command("whoami", help="Find out which huggingface.co account you are logged in as.")
|
|
150
|
+
def auth_whoami() -> None:
|
|
151
|
+
token = get_token()
|
|
152
|
+
if token is None:
|
|
153
|
+
print("Not logged in")
|
|
154
|
+
raise typer.Exit()
|
|
155
|
+
try:
|
|
156
|
+
info = whoami(token)
|
|
157
|
+
print(ANSI.bold("user: "), info["name"])
|
|
158
|
+
orgs = [org["name"] for org in info["orgs"]]
|
|
159
|
+
if orgs:
|
|
160
|
+
print(ANSI.bold("orgs: "), ",".join(orgs))
|
|
161
|
+
|
|
162
|
+
if ENDPOINT != "https://huggingface.co":
|
|
163
|
+
print(f"Authenticated through private endpoint: {ENDPOINT}")
|
|
164
|
+
except HfHubHTTPError as e:
|
|
165
|
+
print(e)
|
|
166
|
+
print(ANSI.red(e.response.text))
|
|
167
|
+
raise typer.Exit(code=1)
|