diff --git a/src/huggingface_hub/__init__.py b/src/huggingface_hub/__init__.py index 08ae398a1a..95c5323589 100644 --- a/src/huggingface_hub/__init__.py +++ b/src/huggingface_hub/__init__.py @@ -40,6 +40,7 @@ delete_repo, get_full_repo_name, list_datasets, + list_metrics, list_models, list_repo_files, list_repos_objs, diff --git a/src/huggingface_hub/hf_api.py b/src/huggingface_hub/hf_api.py index 582b3dd0cb..fdbdf0e05d 100644 --- a/src/huggingface_hub/hf_api.py +++ b/src/huggingface_hub/hf_api.py @@ -225,6 +225,39 @@ def __str__(self): return r +class MetricInfo: + """ + Info about a public metric accessible from huggingface.co + """ + + def __init__( + self, + id: Optional[str] = None, # id of metric + description: Optional[str] = None, + citation: Optional[str] = None, + **kwargs, + ): + self.id = id + self.description = description + self.citation = citation + # Legacy stuff, "key" is always returned with an empty string + # because of old versions of the datasets lib that need this field + kwargs.pop("key", None) + # Store all the other fields returned by the API + for k, v in kwargs.items(): + setattr(self, k, v) + + def __repr__(self): + s = f"{self.__class__.__name__}:" + " {" + for key, val in self.__dict__.items(): + s += f"\n\t{key}: {val}" + return s + "\n}" + + def __str__(self): + r = f"Metric Name: {self.id}" + return r + + def write_to_credential_store(username: str, password: str): with subprocess.Popen( "git credential-store store".split(), @@ -506,6 +539,17 @@ def list_datasets( d = r.json() return [DatasetInfo(**x) for x in d] + def list_metrics(self) -> List[MetricInfo]: + """ + Get the public list of all the metrics on huggingface.co + """ + path = "{}/api/metrics".format(self.endpoint) + params = {} + r = requests.get(path, params=params) + r.raise_for_status() + d = r.json() + return [MetricInfo(**x) for x in d] + def model_info( self, repo_id: str, @@ -1085,6 +1129,8 @@ def delete_token(cls): list_datasets = api.list_datasets dataset_info = api.dataset_info +list_metrics = api.list_metrics + create_repo = api.create_repo delete_repo = api.delete_repo update_repo_visibility = api.update_repo_visibility diff --git a/tests/test_hf_api.py b/tests/test_hf_api.py index a509d66d4f..7e7b937487 100644 --- a/tests/test_hf_api.py +++ b/tests/test_hf_api.py @@ -28,6 +28,7 @@ DatasetInfo, HfApi, HfFolder, + MetricInfo, ModelInfo, RepoObj, erase_from_credential_store, @@ -509,6 +510,18 @@ def test_dataset_info(self): self.assertIsInstance(dataset, DatasetInfo) self.assertEqual(dataset.sha, DUMMY_DATASET_ID_REVISION_ONE_SPECIFIC_COMMIT) + def test_staging_list_metrics(self): + _api = HfApi(endpoint=ENDPOINT_STAGING) + _ = _api.list_metrics() + + @with_production_testing + def test_list_metrics(self): + _api = HfApi() + metrics = _api.list_metrics() + self.assertGreater(len(metrics), 10) + self.assertIsInstance(metrics[0], MetricInfo) + self.assertTrue(any(metric.description for metric in metrics)) + class HfApiPrivateTest(HfApiCommonTestWithLogin): def setUp(self) -> None: