Repository: huggingface/huggingface_hub
Pull request #1225 (2022-11-25 12:52:20)

Add custom `GatedRepoError` when trying to access gated repo
Related to discussions happening around gated repo (example : https://github.com/huggingface/huggingface_hub/issues/1198#issuecomment-1325030852). Follow [server-side PR](https://github.com/huggingface/moon-landing/pull/4627) (internal link).

This PR takes advantage of the new "GatedRepo" error code that is returned by server when a user tries to access a repo that is gated (and user is not in authorized list). It raises a  `GatedRepoError` in python (cc @sgugger).

Note: `GatedRepoError` inherits from `RepositoryNotFoundError` to avoid breaking changes.

HuggingFaceDocBuilderDev: The docs for this PR live [here](https://moon-ci-docs.huggingface.co/docs/huggingface_hub/pr_1225). All of your documentation changes will be reflected on that endpoint.
codecov[bot]: # [Codecov](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface) Report
Base: **84.27**% // Head: **84.29**% // Increases project coverage by **`+0.01%`** :tada:
> Coverage data is based on head [(`35089c5`)](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface) compared to base [(`b4ca199`)](https://codecov.io/gh/huggingface/huggingface_hub/commit/b4ca199e6f5ac42dfc4e9194a3bd86c35d5db76d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1225      +/-   ##
==========================================
+ Coverage   84.27%   84.29%   +0.01%     
==========================================
  Files          44       44              
  Lines        4338     4342       +4     
==========================================
+ Hits         3656     3660       +4     
  Misses        682      682              
```


| [Impacted Files](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface) | Coverage Δ | |
|---|---|---|
| [src/huggingface\_hub/utils/\_\_init\_\_.py](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface#diff-c3JjL2h1Z2dpbmdmYWNlX2h1Yi91dGlscy9fX2luaXRfXy5weQ==) | `100.00% <ø> (ø)` | |
| [src/huggingface\_hub/utils/\_errors.py](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface#diff-c3JjL2h1Z2dpbmdmYWNlX2h1Yi91dGlscy9fZXJyb3JzLnB5) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/huggingface/huggingface_hub/pull/1225?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=huggingface).


Patch:
diff --git a/docs/source/package_reference/utilities.mdx b/docs/source/package_reference/utilities.mdx
index 0ef50639..7162d8d4 100644
--- a/docs/source/package_reference/utilities.mdx
+++ b/docs/source/package_reference/utilities.mdx
@@ -94,6 +94,10 @@ user as possible.
 
 [[autodoc]] huggingface_hub.utils.RepositoryNotFoundError
 
+#### GatedRepoError
+
+[[autodoc]] huggingface_hub.utils.GatedRepoError
+
 #### RevisionNotFoundError
 
 [[autodoc]] huggingface_hub.utils.RevisionNotFoundError
diff --git a/src/huggingface_hub/utils/__init__.py b/src/huggingface_hub/utils/__init__.py
index 8d2ddd7c..5d9fd387 100644
--- a/src/huggingface_hub/utils/__init__.py
+++ b/src/huggingface_hub/utils/__init__.py
@@ -32,6 +32,7 @@ from ._datetime import parse_datetime
 from ._errors import (
     BadRequestError,
     EntryNotFoundError,
+    GatedRepoError,
     HfHubHTTPError,
     LocalEntryNotFoundError,
     RepositoryNotFoundError,
diff --git a/src/huggingface_hub/utils/_errors.py b/src/huggingface_hub/utils/_errors.py
index b6af5ebc..766cff76 100644
--- a/src/huggingface_hub/utils/_errors.py
+++ b/src/huggingface_hub/utils/_errors.py
@@ -108,6 +108,28 @@ class RepositoryNotFoundError(HfHubHTTPError):
     """
 
 
+class GatedRepoError(RepositoryNotFoundError):
+    """
+    Raised when trying to access a gated repository for which the user is not on the
+    authorized list.
+
+    Note: derives from `RepositoryNotFoundError` to ensure backward compatibility.
+
+    Example:
+
+    ```py
+    >>> from huggingface_hub import model_info
+    >>> model_info("<gated_repository>")
+    (...)
+    huggingface_hub.utils._errors.GatedRepoError: 403 Client Error. (Request ID: ViT1Bf7O_026LGSQuVqfa)
+
+    Cannot access gated repo for url https://huggingface.co/api/models/ardent-figment/gated-model.
+    Access to model ardent-figment/gated-model is restricted and you are not in the authorized list.
+    Visit https://huggingface.co/ardent-figment/gated-model to ask for access.
+    ```
+    """
+
+
 class RevisionNotFoundError(HfHubHTTPError):
     """
     Raised when trying to access a hf.co URL with a valid repository but an invalid
@@ -223,6 +245,9 @@ def hf_raise_for_status(
             If the repository to download from cannot be found. This may be because it
             doesn't exist, because `repo_type` is not set correctly, or because the repo
             is `private` and you do not have access.
+        - [`~utils.GatedRepoError`]
+            If the repository exists but is gated and the user is not on the authorized
+            list.
         - [`~utils.RevisionNotFoundError`]
             If the repository exists but the revision couldn't be find.
         - [`~utils.EntryNotFoundError`]
@@ -256,6 +281,14 @@ def hf_raise_for_status(
             )
             raise EntryNotFoundError(message, response) from e
 
+        elif error_code == "GatedRepo":
+            message = (
+                f"{response.status_code} Client Error."
+                + "\n\n"
+                + f"Cannot access gated repo for url {response.url}."
+            )
+            raise GatedRepoError(message, response) from e
+
         elif error_code == "RepoNotFound" or response.status_code == 401:
             # 401 is misleading as it is returned for:
             #    - private and gated repos if user is not authenticated


Test patch:
diff --git a/tests/test_file_download.py b/tests/test_file_download.py
index 515645ce..fe8b19a9 100644
--- a/tests/test_file_download.py
+++ b/tests/test_file_download.py
@@ -37,7 +37,7 @@ from huggingface_hub.file_download import (
 )
 from huggingface_hub.utils import (
     EntryNotFoundError,
-    HfHubHTTPError,
+    GatedRepoError,
     LocalEntryNotFoundError,
     RepositoryNotFoundError,
     RevisionNotFoundError,
@@ -416,7 +416,7 @@ class StagingCachedDownloadTest(unittest.TestCase):
         """
         with TemporaryDirectory() as tmpdir:
             with self.assertRaisesRegex(
-                HfHubHTTPError,
+                GatedRepoError,
                 "Access to model .* is restricted and you are not in the authorized"
                 " list",
             ):