Skip to content

Commit

Permalink
[Feature] Add update_repo_settings function to HfApi #2447 (#2502)
Browse files Browse the repository at this point in the history
* [Feature] Update Repo Settings

* resolve merge conflicts

* fix merge issue

* merge issues

* Add `update_repo_settings` function to HfApi

* Add `update_repo_settings` function to HfApi

* Enhance HfApi with `update_repo_settings` function

* Enhance HfApi with `update_repo_settings` function

* Enhance HfApi with `update_repo_settings` function

* Enhance HfApi with `update_repo_settings` function

* Enhance HfApi with `update_repo_settings` function

* Apply suggestions from code review

---------

Co-authored-by: Lucain <lucain@huggingface.co>
Co-authored-by: Lucain Pouget <lucainp@gmail.com>
  • Loading branch information
3 people authored Sep 12, 2024
1 parent 2f27522 commit 3cd3286
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 0 deletions.
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 @@ -252,6 +252,7 @@
"update_collection_item",
"update_collection_metadata",
"update_inference_endpoint",
"update_repo_settings",
"update_repo_visibility",
"update_webhook",
"upload_file",
Expand Down Expand Up @@ -761,6 +762,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
57 changes: 57 additions & 0 deletions src/huggingface_hub/hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3564,6 +3564,62 @@ def update_repo_visibility(
hf_raise_for_status(r)
return r.json()

@validate_hf_hub_args
def update_repo_settings(
self,
repo_id: str,
*,
gated: Literal["auto", "manual", False] = False,
token: Union[str, bool, None] = None,
repo_type: Optional[str] = None,
) -> None:
"""
Update the gated settings of a repository.
To give more control over how repos are used, the Hub allows repo authors to enable **access requests** for their repos.
Args:
repo_id (`str`):
A namespace (user or an organization) and a repo name separated by a /.
gated (`Literal["auto", "manual", False]`, *optional*):
The gated release status for the repository.
* "auto": The repository is gated, and access requests are automatically approved or denied based on predefined criteria.
* "manual": The repository is gated, and access requests require manual approval.
* False (default): The repository is not gated, and anyone can access it.
token (`Union[str, bool, None]`, *optional*):
A valid user access token (string). Defaults to the locally saved token,
which is the recommended method for authentication (see
https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
To disable authentication, pass False.
repo_type (`str`, *optional*):
The type of the repository to update settings from (`"model"`, `"dataset"` or `"space"`.
Defaults to `"model"`.
Raises:
[`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
If gated is not one of "auto", "manual", or False.
[`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
If repo_type is not one of the values in constants.REPO_TYPES.
[`~utils.HfHubHTTPError`]:
If the request to the Hugging Face Hub API fails.
"""
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(
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 @@ -9678,6 +9734,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
19 changes: 19 additions & 0 deletions tests/test_hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,25 @@ 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
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


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

0 comments on commit 3cd3286

Please sign in to comment.