Skip to content

Commit d724916

Browse files
BastienGimbertgithub-actions[bot]hanouticelina
authored
Add client support for the organization overview endpoint (#3436)
* feat: add organization overview endpoint support - extend Organization dataclass with overview metadata returned by the Hub - expose get_organization_overview on HfApi and top-level package exports - cover the new endpoint with a production UserApi test * Apply style fixes * refactor: remove optional id field from Organization class * Update src/huggingface_hub/hf_api.py --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: célina <hanouticelina@gmail.com>
1 parent 9e46a06 commit d724916

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

src/huggingface_hub/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
"GitRefs",
160160
"HfApi",
161161
"ModelInfo",
162+
"Organization",
162163
"RepoUrl",
163164
"SpaceInfo",
164165
"User",
@@ -212,6 +213,7 @@
212213
"get_full_repo_name",
213214
"get_inference_endpoint",
214215
"get_model_tags",
216+
"get_organization_overview",
215217
"get_paths_info",
216218
"get_repo_discussions",
217219
"get_safetensors_metadata",
@@ -699,6 +701,7 @@
699701
"ObjectDetectionInput",
700702
"ObjectDetectionOutputElement",
701703
"ObjectDetectionParameters",
704+
"Organization",
702705
"PYTORCH_WEIGHTS_NAME",
703706
"Padding",
704707
"PyTorchModelHubMixin",
@@ -870,6 +873,7 @@
870873
"get_hf_file_metadata",
871874
"get_inference_endpoint",
872875
"get_model_tags",
876+
"get_organization_overview",
873877
"get_paths_info",
874878
"get_repo_discussions",
875879
"get_safetensors_metadata",
@@ -1179,6 +1183,7 @@ def __dir__():
11791183
GitRefs, # noqa: F401
11801184
HfApi, # noqa: F401
11811185
ModelInfo, # noqa: F401
1186+
Organization, # noqa: F401
11821187
RepoUrl, # noqa: F401
11831188
SpaceInfo, # noqa: F401
11841189
User, # noqa: F401
@@ -1232,6 +1237,7 @@ def __dir__():
12321237
get_full_repo_name, # noqa: F401
12331238
get_inference_endpoint, # noqa: F401
12341239
get_model_tags, # noqa: F401
1240+
get_organization_overview, # noqa: F401
12351241
get_paths_info, # noqa: F401
12361242
get_repo_discussions, # noqa: F401
12371243
get_safetensors_metadata, # noqa: F401

src/huggingface_hub/hf_api.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,16 +1404,48 @@ class Organization:
14041404
Name of the organization on the Hub (unique).
14051405
fullname (`str`):
14061406
Organization's full name.
1407+
details (`str`, *optional*):
1408+
Organization's description.
1409+
is_verified (`bool`, *optional*):
1410+
Whether the organization is verified.
1411+
is_following (`bool`, *optional*):
1412+
Whether the authenticated user follows this organization.
1413+
num_users (`int`, *optional*):
1414+
Number of members in the organization.
1415+
num_models (`int`, *optional*):
1416+
Number of models owned by the organization.
1417+
num_spaces (`int`, *optional*):
1418+
Number of Spaces owned by the organization.
1419+
num_datasets (`int`, *optional*):
1420+
Number of datasets owned by the organization.
1421+
num_followers (`int`, *optional*):
1422+
Number of followers of the organization.
14071423
"""
14081424

14091425
avatar_url: str
14101426
name: str
14111427
fullname: str
1428+
details: Optional[str] = None
1429+
is_verified: Optional[bool] = None
1430+
is_following: Optional[bool] = None
1431+
num_users: Optional[int] = None
1432+
num_models: Optional[int] = None
1433+
num_spaces: Optional[int] = None
1434+
num_datasets: Optional[int] = None
1435+
num_followers: Optional[int] = None
14121436

14131437
def __init__(self, **kwargs) -> None:
14141438
self.avatar_url = kwargs.pop("avatarUrl", "")
14151439
self.name = kwargs.pop("name", "")
14161440
self.fullname = kwargs.pop("fullname", "")
1441+
self.details = kwargs.pop("details", None)
1442+
self.is_verified = kwargs.pop("isVerified", None)
1443+
self.is_following = kwargs.pop("isFollowing", None)
1444+
self.num_users = kwargs.pop("numUsers", None)
1445+
self.num_models = kwargs.pop("numModels", None)
1446+
self.num_spaces = kwargs.pop("numSpaces", None)
1447+
self.num_datasets = kwargs.pop("numDatasets", None)
1448+
self.num_followers = kwargs.pop("numFollowers", None)
14171449

14181450
# forward compatibility
14191451
self.__dict__.update(**kwargs)
@@ -9663,6 +9695,33 @@ def get_user_overview(self, username: str, token: Union[bool, str, None] = None)
96639695
hf_raise_for_status(r)
96649696
return User(**r.json())
96659697

9698+
@validate_hf_hub_args
9699+
def get_organization_overview(self, organization: str, token: Union[bool, str, None] = None) -> Organization:
9700+
"""
9701+
Get an overview of an organization on the Hub.
9702+
9703+
Args:
9704+
organization (`str`):
9705+
Name of the organization to get an overview of.
9706+
token (`bool` or `str`, *optional*):
9707+
A valid user access token (string). Defaults to the locally saved token, which is the recommended method
9708+
for authentication (see https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
9709+
To disable authentication, pass `False`.
9710+
9711+
Returns:
9712+
`Organization`: An [`Organization`] object with the organization's overview.
9713+
9714+
Raises:
9715+
[`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError):
9716+
HTTP 404 If the organization does not exist on the Hub.
9717+
"""
9718+
r = get_session().get(
9719+
f"{constants.ENDPOINT}/api/organizations/{organization}/overview",
9720+
headers=self._build_hf_headers(token=token),
9721+
)
9722+
hf_raise_for_status(r)
9723+
return Organization(**r.json())
9724+
96669725
def list_organization_members(self, organization: str, token: Union[bool, str, None] = None) -> Iterable[User]:
96679726
"""
96689727
List of members of an organization on the Hub.
@@ -10956,6 +11015,7 @@ def _parse_revision_from_pr_url(pr_url: str) -> str:
1095611015

1095711016
# User API
1095811017
get_user_overview = api.get_user_overview
11018+
get_organization_overview = api.get_organization_overview
1095911019
list_organization_members = api.list_organization_members
1096011020
list_user_followers = api.list_user_followers
1096111021
list_user_following = api.list_user_following

tests/test_hf_api.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,6 +4282,15 @@ def test_user_overview(self) -> None:
42824282
assert overview.num_following > 300
42834283
assert overview.num_followers > 1000
42844284

4285+
def test_organization_overview(self) -> None:
4286+
overview = self.api.get_organization_overview("huggingface")
4287+
assert overview.name == "huggingface"
4288+
assert overview.fullname == "Hugging Face"
4289+
assert overview.avatar_url.startswith("https://")
4290+
assert overview.num_users is None or overview.num_users > 10
4291+
assert overview.num_models is None or overview.num_models > 10
4292+
assert overview.num_followers is None or overview.num_followers > 1000
4293+
42854294
def test_organization_members(self) -> None:
42864295
members = self.api.list_organization_members("huggingface")
42874296
assert len(list(members)) > 1

0 commit comments

Comments
 (0)