Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add update_repo_settings function to HfApi #2447 #2502

Merged
merged 25 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
91042af
[Feature] Update Repo Settings
WizKnight Sep 2, 2024
451baf1
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 2, 2024
f256710
Merge branch 'main' into feature/update-repo-settings
Wauplin Sep 3, 2024
409baa5
resolve merge conflicts
Wauplin Sep 3, 2024
f773f77
fix merge issue
Wauplin Sep 3, 2024
92c9531
merge issues
Wauplin Sep 3, 2024
fb7cfd1
Merge branch 'huggingface:main' into feature/update-repo-settings
WizKnight Sep 3, 2024
cf3c78c
Add `update_repo_settings` function to HfApi
WizKnight Sep 3, 2024
6e81211
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 4, 2024
2544898
Add `update_repo_settings` function to HfApi
WizKnight Sep 4, 2024
22952bf
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 4, 2024
609ea61
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 5, 2024
3e507a9
Enhance HfApi with `update_repo_settings` function
WizKnight Sep 5, 2024
761a33d
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 6, 2024
6d57808
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 10, 2024
401502f
Merge branch 'main' into feature/update-repo-settings
Wauplin Sep 10, 2024
244e4b2
Merge branch 'main' of https://github.com/WizKnight/huggingface_hub i…
WizKnight Sep 10, 2024
12e0eb5
Merge branch 'feature/update-repo-settings' of https://github.com/Wiz…
WizKnight Sep 10, 2024
8e6f9cf
Enhance HfApi with `update_repo_settings` function
WizKnight Sep 10, 2024
59c05a5
Enhance HfApi with `update_repo_settings` function
WizKnight Sep 10, 2024
8bf6f82
Merge branch 'main' of https://github.com/WizKnight/huggingface_hub i…
WizKnight Sep 11, 2024
2bd4767
Enhance HfApi with `update_repo_settings` function
WizKnight Sep 11, 2024
fbe8cbe
Enhance HfApi with `update_repo_settings` function
WizKnight Sep 11, 2024
772837d
Merge branch 'main' into feature/update-repo-settings
WizKnight Sep 12, 2024
ef61fbb
Apply suggestions from code review
Wauplin Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/source/en/guides/repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ A repository can be public or private. A private repository is only visible to y
>>> update_repo_visibility(repo_id=repo_id, private=True)
```

### Setup gated access

To give more control over how repos are used, the Hub allows repo authors to enable **access requests** for their repos. User must agree to share their contact information (username and email address) with the repo authors to access the files when enabled. A repo with access requests enabled is called a **gated repo**.

You can set a repo as gated using [`update_repo_settings`]:

```py
>>> from huggingface_hub import HfApi

>>> api = HfApi()
>>> api.update_repo_settings(repo_id=repo_id, gated="auto") # Set automatic gating for a model
```

### Rename your repository

You can rename your repository on the Hub using [`move_repo`]. Using this method, you can also move the repo from a user to
Expand Down
2 changes: 2 additions & 0 deletions src/huggingface_hub/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@
"update_collection_item",
"update_collection_metadata",
"update_inference_endpoint",
"update_repo_settings",
"update_repo_visibility",
"update_webhook",
"upload_file",
Expand Down Expand Up @@ -759,6 +760,7 @@ def __dir__():
update_collection_item, # noqa: F401
update_collection_metadata, # noqa: F401
update_inference_endpoint, # noqa: F401
update_repo_settings, # noqa: F401
update_repo_visibility, # noqa: F401
update_webhook, # noqa: F401
upload_file, # noqa: F401
Expand Down
28 changes: 28 additions & 0 deletions src/huggingface_hub/hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3574,6 +3574,33 @@ def update_repo_visibility(
hf_raise_for_status(r)
return r.json()

@validate_hf_hub_args
def update_repo_settings(
Wauplin marked this conversation as resolved.
Show resolved Hide resolved
self,
repo_id: str,
*,
gated: Literal["auto", "manual", False] = False,
token: Union[str, bool, None] = None,
repo_type: Optional[str] = None,
) -> None:
if gated not in ["auto", "manual", False]:
raise ValueError(f"Invalid gated status, must be one of 'auto', 'manual', or False. Got '{gated}'.")

if repo_type not in constants.REPO_TYPES:
raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}")
if repo_type is None:
repo_type = constants.REPO_TYPE_MODEL # default repo type

# Build headers
headers = self._build_hf_headers(token=token)

r = get_session().put(
Wauplin marked this conversation as resolved.
Show resolved Hide resolved
url=f"{self.endpoint}/api/{repo_type}s/{repo_id}/settings",
headers=headers,
json={"gated": gated},
)
hf_raise_for_status(r)

def move_repo(
self,
from_id: str,
Expand Down Expand Up @@ -9624,6 +9651,7 @@ def _parse_revision_from_pr_url(pr_url: str) -> str:
create_repo = api.create_repo
delete_repo = api.delete_repo
update_repo_visibility = api.update_repo_visibility
update_repo_settings = api.update_repo_settings
super_squash_history = api.super_squash_history
move_repo = api.move_repo
upload_file = api.upload_file
Expand Down
27 changes: 27 additions & 0 deletions tests/test_hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,33 @@ def test_move_repo_invalid_repo_id(self) -> None:
with pytest.raises(ValueError, match=r"Invalid repo_id*"):
self._api.move_repo(from_id="invalid_repo_id", to_id="namespace/repo_name")

@use_tmp_repo(repo_type="model")
def test_update_repo_settings(self, repo_url: RepoUrl):
repo_id = repo_url.repo_id

for gated_value in ["auto", "manual", False]:
self._api.update_repo_settings(repo_id=repo_id, gated=gated_value)
info = self._api.model_info(repo_id, expand="gated")
assert info.gated == gated_value

@use_tmp_repo(repo_type="dataset")
def test_update_dataset_repo_settings(self, repo_url: RepoUrl):
repo_id = repo_url.repo_id

for gated_value in ["auto", "manual", False]:
self._api.update_repo_settings(repo_id=repo_id, gated=gated_value)
info = self._api.dataset_info(repo_id, expand="gated")
assert info.gated == gated_value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test was failing with a Bad Request error because repo_type was not specified here. This works fine for model repos, as they are the default repo type. For dataset repos, we need to explicitly provide the repo_type.

Suggested change
def test_update_dataset_repo_settings(self, repo_url: RepoUrl):
repo_id = repo_url.repo_id
for gated_value in ["auto", "manual", False]:
self._api.update_repo_settings(repo_id=repo_id, gated=gated_value)
info = self._api.dataset_info(repo_id, expand="gated")
assert info.gated == gated_value
def test_update_dataset_repo_settings(self, repo_url: RepoUrl):
repo_id = repo_url.repo_id
repo_type = repo_url.repo_type
for gated_value in ["auto", "manual", False]:
self._api.update_repo_settings(repo_id=repo_id, repo_type=repo_type, gated=gated_value)
info = self._api.dataset_info(repo_id, expand="gated")
assert info.gated == gated_value


@use_tmp_repo(repo_type="space")
def test_update_space_repo_settings(self, repo_url: RepoUrl):
repo_id = repo_url.repo_id

for gated_value in ["auto", "manual", False]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above, we need to explicitly provide repo_type. Also, you probably got a BadRequestError here, because the concept of "gated" repositories does not apply to spaces. Only models and datasets can be gated. For spaces, the only valid value for the gated parameter is False

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can drop the test for Space repo_type then, thanks for looking into it @hanouticelina :) Testing on model and dataset is already more than enough 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay then @Wauplin :) , I'll remove the space_repo_type test and commit again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @hanouticelina, thanks for taking a look at the space_repo_settings test. I removed it in the latest commit, as @Wauplin recommended. Also, I added repo_type to dataset_repo_settings based on your suggestion.

self._api.update_repo_settings(repo_id=repo_id, gated=gated_value)
info = self._api.space_info(repo_id, expand="gated")
assert info.gated == gated_value


class CommitApiTest(HfApiCommonTest):
def setUp(self) -> None:
Expand Down
Loading