Skip to content

Commit 2425d80

Browse files
authored
Merge branch 'main' into estimation-procedures-mig
2 parents 5653eca + fe58eb0 commit 2425d80

4 files changed

Lines changed: 93 additions & 13 deletions

File tree

openml/_api/resources/base/resources.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class EvaluationMeasureAPI(ResourceAPI):
2929

3030
resource_type: ResourceType = ResourceType.EVALUATION_MEASURE
3131

32+
@abstractmethod
33+
def list(self) -> list[str]: ...
34+
3235

3336
class EstimationProcedureAPI(ResourceAPI):
3437
"""Abstract API interface for estimation procedure resources."""
Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,60 @@
11
from __future__ import annotations
22

3+
import xmltodict
4+
35
from .base import EvaluationMeasureAPI, ResourceV1API, ResourceV2API
46

57

68
class EvaluationMeasureV1API(ResourceV1API, EvaluationMeasureAPI):
7-
"""Version 1 API implementation for evaluation measure resources."""
9+
"""V1 API implementation for evaluation measures.
10+
11+
Fetches evaluation measures from the v1 XML API endpoint.
12+
"""
13+
14+
def list(self) -> list[str]:
15+
"""List all evaluation measures available on OpenML.
16+
17+
Returns
18+
-------
19+
list[str]
20+
A list of evaluation measure names.
21+
"""
22+
path = "evaluationmeasure/list"
23+
response = self._http.get(path)
24+
xml_content = response.text
25+
26+
qualities = xmltodict.parse(xml_content, force_list=("oml:measures"))
27+
# Minimalistic check if the XML is useful
28+
if "oml:evaluation_measures" not in qualities:
29+
raise ValueError('Error in return XML, does not contain "oml:evaluation_measures"')
30+
31+
if not isinstance(
32+
qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"], list
33+
):
34+
raise TypeError('Error in return XML, does not contain "oml:measure" as a list')
35+
36+
return qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"]
837

938

1039
class EvaluationMeasureV2API(ResourceV2API, EvaluationMeasureAPI):
11-
"""Version 2 API implementation for evaluation measure resources."""
40+
"""V2 API implementation for evaluation measures.
41+
42+
Fetches evaluation measures from the v2 JSON API endpoint.
43+
"""
44+
45+
def list(self) -> list[str]:
46+
"""List all evaluation measures available on OpenML.
47+
48+
Returns
49+
-------
50+
list[str]
51+
A list of evaluation measure names.
52+
"""
53+
path = "evaluationmeasure/list"
54+
response = self._http.get(path)
55+
data = response.json()
56+
57+
if not isinstance(data, list):
58+
raise ValueError(f"Expected list, got {type(data)}")
59+
60+
return data

openml/evaluations/functions.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,7 @@ def list_evaluation_measures() -> list[str]:
153153
list
154154
155155
"""
156-
api_call = "evaluationmeasure/list"
157-
xml_string = openml._api_calls._perform_api_call(api_call, "get")
158-
qualities = xmltodict.parse(xml_string, force_list=("oml:measures"))
159-
# Minimalistic check if the XML is useful
160-
if "oml:evaluation_measures" not in qualities:
161-
raise ValueError('Error in return XML, does not contain "oml:evaluation_measures"')
162-
163-
if not isinstance(qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"], list):
164-
raise TypeError('Error in return XML, does not contain "oml:measure" as a list')
165-
166-
return qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"]
156+
return openml._backend.evaluation_measure.list()
167157

168158

169159
def list_estimation_procedures() -> list[str]:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# License: BSD 3-Clause
2+
from __future__ import annotations
3+
4+
import pytest
5+
from openml._api import EvaluationMeasureV1API, EvaluationMeasureV2API
6+
7+
8+
@pytest.fixture
9+
def evaluation_measure_v1(http_client_v1, minio_client) -> EvaluationMeasureV1API:
10+
return EvaluationMeasureV1API(http=http_client_v1, minio=minio_client)
11+
12+
13+
@pytest.fixture
14+
def evaluation_measure_v2(http_client_v2, minio_client) -> EvaluationMeasureV2API:
15+
return EvaluationMeasureV2API(http=http_client_v2, minio=minio_client)
16+
17+
18+
@pytest.mark.test_server()
19+
def test_v1_list(evaluation_measure_v1):
20+
measures = evaluation_measure_v1.list()
21+
assert isinstance(measures, list)
22+
assert all(isinstance(s, str) for s in measures)
23+
24+
25+
@pytest.mark.test_server()
26+
def test_v2_list(evaluation_measure_v2):
27+
measures = evaluation_measure_v2.list()
28+
assert isinstance(measures, list)
29+
assert all(isinstance(s, str) for s in measures)
30+
31+
32+
@pytest.mark.test_server()
33+
def test_list_matches(evaluation_measure_v1,evaluation_measure_v2):
34+
output_v1 = evaluation_measure_v1.list()
35+
output_v2 = evaluation_measure_v2.list()
36+
37+
assert type(output_v1) == type(output_v2)
38+
assert output_v1 == output_v2

0 commit comments

Comments
 (0)