Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 21 additions & 3 deletions src/huggingface_hub/hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8535,7 +8535,13 @@ def accept_access_request(

@validate_hf_hub_args
def reject_access_request(
self, repo_id: str, user: str, *, repo_type: Optional[str] = None, token: Union[bool, str, None] = None
self,
repo_id: str,
user: str,
*,
repo_type: Optional[str] = None,
rejection_reason: Optional[str],
token: Union[bool, str, None] = None,
) -> None:
"""
Reject an access request from a user for a given gated repo.
Expand All @@ -8554,6 +8560,8 @@ def reject_access_request(
repo_type (`str`, *optional*):
The type of the repo to reject access request for. Must be one of `model`, `dataset` or `space`.
Defaults to `model`.
rejection_reason (`str`, *optional*):
Optional rejection reason that will be sent to the user (max 200 characters).
token (Union[bool, str, None], optional):
A valid user access token (string). Defaults to the locally saved
token, which is the recommended method for authentication (see
Expand All @@ -8573,7 +8581,9 @@ def reject_access_request(
[`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError):
HTTP 404 if the user access request is already in the rejected list.
"""
self._handle_access_request(repo_id, user, "rejected", repo_type=repo_type, token=token)
self._handle_access_request(
repo_id, user, "rejected", repo_type=repo_type, rejection_reason=rejection_reason, token=token
)

@validate_hf_hub_args
def _handle_access_request(
Expand All @@ -8582,17 +8592,25 @@ def _handle_access_request(
user: str,
status: Literal["accepted", "rejected", "pending"],
repo_type: Optional[str] = None,
rejection_reason: Optional[str] = None,
token: Union[bool, str, None] = None,
) -> None:
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

payload = {"user": user, "status": status}

if rejection_reason is not None:
if status != "rejected":
raise ValueError("`rejection_reason` can only be passed when rejecting an access request.")
payload["rejectionReason"] = rejection_reason

response = get_session().post(
f"{constants.ENDPOINT}/api/{repo_type}s/{repo_id}/user-access-request/handle",
headers=self._build_hf_headers(token=token),
json={"user": user, "status": status},
json=payload,
)
hf_raise_for_status(response)

Expand Down
6 changes: 3 additions & 3 deletions tests/test_hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4124,7 +4124,7 @@ def test_access_requests_normal_usage(self) -> None:
assert requests[0].username == OTHER_USER

# Reject access
self._api.reject_access_request(self.repo_id, OTHER_USER)
self._api.reject_access_request(self.repo_id, OTHER_USER, rejection_reason="This is a rejection reason")
requests = self._api.list_pending_access_requests(self.repo_id)
assert len(requests) == 0 # not pending anymore
requests = self._api.list_rejected_access_requests(self.repo_id)
Expand All @@ -4150,9 +4150,9 @@ def test_access_request_error(self):
self._api.accept_access_request(self.repo_id, OTHER_USER)

# Cannot reject to already rejected
self._api.reject_access_request(self.repo_id, OTHER_USER)
self._api.reject_access_request(self.repo_id, OTHER_USER, rejection_reason="This is a rejection reason")
with self.assertRaises(HTTPError):
self._api.reject_access_request(self.repo_id, OTHER_USER)
self._api.reject_access_request(self.repo_id, OTHER_USER, rejection_reason="This is a rejection reason")

# Cannot cancel to already cancelled
self._api.cancel_access_request(self.repo_id, OTHER_USER)
Expand Down
Loading