| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| """Contains commands to interact with repositories on the Hugging Face Hub. |
| |
| Usage: |
| # create a new dataset repo on the Hub |
| hf repo create my-cool-dataset --repo-type=dataset |
| |
| # create a private model repo on the Hub |
| hf repo create my-cool-model --private |
| """ |
|
|
| import enum |
| from typing import Annotated, Optional |
|
|
| import typer |
|
|
| from huggingface_hub.errors import HfHubHTTPError, RepositoryNotFoundError, RevisionNotFoundError |
| from huggingface_hub.utils import ANSI, logging |
|
|
| from ._cli_utils import ( |
| PrivateOpt, |
| RepoIdArg, |
| RepoType, |
| RepoTypeOpt, |
| RevisionOpt, |
| TokenOpt, |
| get_hf_api, |
| typer_factory, |
| ) |
|
|
|
|
| logger = logging.get_logger(__name__) |
|
|
| repo_cli = typer_factory(help="Manage repos on the Hub.") |
| tag_cli = typer_factory(help="Manage tags for a repo on the Hub.") |
| branch_cli = typer_factory(help="Manage branches for a repo on the Hub.") |
| repo_cli.add_typer(tag_cli, name="tag") |
| repo_cli.add_typer(branch_cli, name="branch") |
|
|
|
|
| class GatedChoices(str, enum.Enum): |
| auto = "auto" |
| manual = "manual" |
| false = "false" |
|
|
|
|
| @repo_cli.command("create", help="Create a new repo on the Hub.") |
| def repo_create( |
| repo_id: RepoIdArg, |
| repo_type: RepoTypeOpt = RepoType.model, |
| space_sdk: Annotated[ |
| Optional[str], |
| typer.Option( |
| help="Hugging Face Spaces SDK type. Required when --type is set to 'space'.", |
| ), |
| ] = None, |
| private: PrivateOpt = False, |
| token: TokenOpt = None, |
| exist_ok: Annotated[ |
| bool, |
| typer.Option( |
| help="Do not raise an error if repo already exists.", |
| ), |
| ] = False, |
| resource_group_id: Annotated[ |
| Optional[str], |
| typer.Option( |
| help="Resource group in which to create the repo. Resource groups is only available for Enterprise Hub organizations.", |
| ), |
| ] = None, |
| ) -> None: |
| api = get_hf_api(token=token) |
| repo_url = api.create_repo( |
| repo_id=repo_id, |
| repo_type=repo_type.value, |
| private=private, |
| token=token, |
| exist_ok=exist_ok, |
| resource_group_id=resource_group_id, |
| space_sdk=space_sdk, |
| ) |
| print(f"Successfully created {ANSI.bold(repo_url.repo_id)} on the Hub.") |
| print(f"Your repo is now available at {ANSI.bold(repo_url)}") |
|
|
|
|
| @repo_cli.command("delete", help="Delete a repo from the Hub. this is an irreversible operation.") |
| def repo_delete( |
| repo_id: RepoIdArg, |
| repo_type: RepoTypeOpt = RepoType.model, |
| token: TokenOpt = None, |
| missing_ok: Annotated[ |
| bool, |
| typer.Option( |
| help="If set to True, do not raise an error if repo does not exist.", |
| ), |
| ] = False, |
| ) -> None: |
| api = get_hf_api(token=token) |
| api.delete_repo( |
| repo_id=repo_id, |
| repo_type=repo_type.value, |
| missing_ok=missing_ok, |
| ) |
| print(f"Successfully deleted {ANSI.bold(repo_id)} on the Hub.") |
|
|
|
|
| @repo_cli.command("move", help="Move a repository from a namespace to another namespace.") |
| def repo_move( |
| from_id: RepoIdArg, |
| to_id: RepoIdArg, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| api = get_hf_api(token=token) |
| api.move_repo( |
| from_id=from_id, |
| to_id=to_id, |
| repo_type=repo_type.value, |
| ) |
| print(f"Successfully moved {ANSI.bold(from_id)} to {ANSI.bold(to_id)} on the Hub.") |
|
|
|
|
| @repo_cli.command("settings", help="Update the settings of a repository.") |
| def repo_settings( |
| repo_id: RepoIdArg, |
| gated: Annotated[ |
| Optional[GatedChoices], |
| typer.Option( |
| help="The gated status for the repository.", |
| ), |
| ] = None, |
| private: Annotated[ |
| Optional[bool], |
| typer.Option( |
| help="Whether the repository should be private.", |
| ), |
| ] = None, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| api = get_hf_api(token=token) |
| api.update_repo_settings( |
| repo_id=repo_id, |
| gated=(gated.value if gated else None), |
| private=private, |
| repo_type=repo_type.value, |
| ) |
| print(f"Successfully updated the settings of {ANSI.bold(repo_id)} on the Hub.") |
|
|
|
|
| @branch_cli.command("create", help="Create a new branch for a repo on the Hub.") |
| def branch_create( |
| repo_id: RepoIdArg, |
| branch: Annotated[ |
| str, |
| typer.Argument( |
| help="The name of the branch to create.", |
| ), |
| ], |
| revision: RevisionOpt = None, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| exist_ok: Annotated[ |
| bool, |
| typer.Option( |
| help="If set to True, do not raise an error if branch already exists.", |
| ), |
| ] = False, |
| ) -> None: |
| api = get_hf_api(token=token) |
| api.create_branch( |
| repo_id=repo_id, |
| branch=branch, |
| revision=revision, |
| repo_type=repo_type.value, |
| exist_ok=exist_ok, |
| ) |
| print(f"Successfully created {ANSI.bold(branch)} branch on {repo_type.value} {ANSI.bold(repo_id)}") |
|
|
|
|
| @branch_cli.command("delete", help="Delete a branch from a repo on the Hub.") |
| def branch_delete( |
| repo_id: RepoIdArg, |
| branch: Annotated[ |
| str, |
| typer.Argument( |
| help="The name of the branch to delete.", |
| ), |
| ], |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| api = get_hf_api(token=token) |
| api.delete_branch( |
| repo_id=repo_id, |
| branch=branch, |
| repo_type=repo_type.value, |
| ) |
| print(f"Successfully deleted {ANSI.bold(branch)} branch on {repo_type.value} {ANSI.bold(repo_id)}") |
|
|
|
|
| @tag_cli.command("create", help="Create a tag for a repo.") |
| def tag_create( |
| repo_id: RepoIdArg, |
| tag: Annotated[ |
| str, |
| typer.Argument( |
| help="The name of the tag to create.", |
| ), |
| ], |
| message: Annotated[ |
| Optional[str], |
| typer.Option( |
| "-m", |
| "--message", |
| help="The description of the tag to create.", |
| ), |
| ] = None, |
| revision: RevisionOpt = None, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| repo_type_str = repo_type.value |
| api = get_hf_api(token=token) |
| print(f"You are about to create tag {ANSI.bold(tag)} on {repo_type_str} {ANSI.bold(repo_id)}") |
| try: |
| api.create_tag(repo_id=repo_id, tag=tag, tag_message=message, revision=revision, repo_type=repo_type_str) |
| except RepositoryNotFoundError: |
| print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.") |
| raise typer.Exit(code=1) |
| except RevisionNotFoundError: |
| print(f"Revision {ANSI.bold(str(revision))} not found.") |
| raise typer.Exit(code=1) |
| except HfHubHTTPError as e: |
| if e.response.status_code == 409: |
| print(f"Tag {ANSI.bold(tag)} already exists on {ANSI.bold(repo_id)}") |
| raise typer.Exit(code=1) |
| raise e |
| print(f"Tag {ANSI.bold(tag)} created on {ANSI.bold(repo_id)}") |
|
|
|
|
| @tag_cli.command("list", help="List tags for a repo.") |
| def tag_list( |
| repo_id: RepoIdArg, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| repo_type_str = repo_type.value |
| api = get_hf_api(token=token) |
| try: |
| refs = api.list_repo_refs(repo_id=repo_id, repo_type=repo_type_str) |
| except RepositoryNotFoundError: |
| print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.") |
| raise typer.Exit(code=1) |
| except HfHubHTTPError as e: |
| print(e) |
| print(ANSI.red(e.response.text)) |
| raise typer.Exit(code=1) |
| if len(refs.tags) == 0: |
| print("No tags found") |
| raise typer.Exit(code=0) |
| print(f"Tags for {repo_type_str} {ANSI.bold(repo_id)}:") |
| for t in refs.tags: |
| print(t.name) |
|
|
|
|
| @tag_cli.command("delete", help="Delete a tag for a repo.") |
| def tag_delete( |
| repo_id: RepoIdArg, |
| tag: Annotated[ |
| str, |
| typer.Argument( |
| help="The name of the tag to delete.", |
| ), |
| ], |
| yes: Annotated[ |
| bool, |
| typer.Option( |
| "-y", |
| "--yes", |
| help="Answer Yes to prompt automatically", |
| ), |
| ] = False, |
| token: TokenOpt = None, |
| repo_type: RepoTypeOpt = RepoType.model, |
| ) -> None: |
| repo_type_str = repo_type.value |
| print(f"You are about to delete tag {ANSI.bold(tag)} on {repo_type_str} {ANSI.bold(repo_id)}") |
| if not yes: |
| choice = input("Proceed? [Y/n] ").lower() |
| if choice not in ("", "y", "yes"): |
| print("Abort") |
| raise typer.Exit() |
| api = get_hf_api(token=token) |
| try: |
| api.delete_tag(repo_id=repo_id, tag=tag, repo_type=repo_type_str) |
| except RepositoryNotFoundError: |
| print(f"{repo_type_str.capitalize()} {ANSI.bold(repo_id)} not found.") |
| raise typer.Exit(code=1) |
| except RevisionNotFoundError: |
| print(f"Tag {ANSI.bold(tag)} not found on {ANSI.bold(repo_id)}") |
| raise typer.Exit(code=1) |
| print(f"Tag {ANSI.bold(tag)} deleted on {ANSI.bold(repo_id)}") |
|
|