Skip to content

Commit fe58eb0

Browse files
EmanAbdelhaleemsatvshrgeetu040fkiralySimonBlanke
authored
[ENH] V1 → V2 API Migration - evaluation measures (#1603)
Fixes #1593 Depends on #1576 Related to #1575 #### Details This PR implements `EvaluationMeasures` resource, and refactor its existing functions --------- Co-authored-by: Satvik Mishra <112589278+satvshr@users.noreply.github.com> Co-authored-by: geetu040 <raoarmaghanshakir040@gmail.com> Co-authored-by: Franz Király <fkiraly@gcos.ai> Co-authored-by: Simon Blanke <simon.blanke@yahoo.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Matthias Feurer <lists@matthiasfeurer.de> Co-authored-by: Pieter Gijsbers <p.gijsbers@tue.nl>
1 parent 8ff14eb commit fe58eb0

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
@@ -28,6 +28,9 @@ class EvaluationMeasureAPI(ResourceAPI):
2828

2929
resource_type: ResourceType = ResourceType.EVALUATION_MEASURE
3030

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

3235
class EstimationProcedureAPI(ResourceAPI):
3336
"""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
@@ -154,17 +154,7 @@ def list_evaluation_measures() -> list[str]:
154154
list
155155
156156
"""
157-
api_call = "evaluationmeasure/list"
158-
xml_string = openml._api_calls._perform_api_call(api_call, "get")
159-
qualities = xmltodict.parse(xml_string, force_list=("oml:measures"))
160-
# Minimalistic check if the XML is useful
161-
if "oml:evaluation_measures" not in qualities:
162-
raise ValueError('Error in return XML, does not contain "oml:evaluation_measures"')
163-
164-
if not isinstance(qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"], list):
165-
raise TypeError('Error in return XML, does not contain "oml:measure" as a list')
166-
167-
return qualities["oml:evaluation_measures"]["oml:measures"][0]["oml:measure"]
157+
return openml._backend.evaluation_measure.list()
168158

169159

170160
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)