Skip to content

Commit 685c19a

Browse files
committed
added tests
Signed-off-by: Omswastik-11 <omswastikpanda11@gmail.com>
1 parent 95fc75f commit 685c19a

6 files changed

Lines changed: 103 additions & 229 deletions

File tree

openml/_api/clients/http.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,14 @@ def _parse_exception_response(
151151
if "json" in content_type:
152152
server_exception = response.json()
153153
server_error = server_exception["detail"]
154-
code = server_error.get("code")
155-
message = server_error.get("message")
156-
additional_information = server_error.get("additional_information")
154+
if isinstance(server_error, dict):
155+
code = server_error.get("code")
156+
message = server_error.get("message")
157+
additional_information = server_error.get("additional_information")
158+
else:
159+
code = None
160+
message = str(server_error)
161+
additional_information = None
157162
else:
158163
server_exception = xmltodict.parse(response.text)
159164
server_error = server_exception["oml:error"]

openml/_api/resources/base/resources.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def list(
5454
) -> pd.DataFrame: ...
5555

5656
@abstractmethod
57-
def create(self, flow: OpenMLFlow) -> OpenMLFlow | tuple[OpenMLFlow, Response]: ...
57+
def publish(self, flow: OpenMLFlow) -> OpenMLFlow | tuple[OpenMLFlow, Response]: ... # type: ignore[override]
5858

5959
@abstractmethod
6060
def delete(self, flow_id: int) -> bool: ...

openml/_api/resources/flows.py

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from typing import Any
44

55
import pandas as pd
6-
import requests
76
import xmltodict
87

98
from openml._api.resources.base import FlowsAPI
10-
from openml.exceptions import OpenMLServerException
9+
from openml.exceptions import OpenMLServerError, OpenMLServerException
1110
from openml.flows.flow import OpenMLFlow
1211

1312

@@ -55,17 +54,7 @@ def exists(self, name: str, external_version: str) -> int | bool:
5554
raise ValueError("Argument 'version' should be a non-empty string")
5655

5756
data = {"name": name, "external_version": external_version, "api_key": self._http.api_key}
58-
# Avoid duplicating base_url when server already contains the API path
59-
server = self._http.server
60-
base = self._http.base_url
61-
if base and base.strip("/") in server:
62-
url = server.rstrip("/") + "/flow/exists"
63-
response = requests.post(
64-
url, data=data, headers=self._http.headers, timeout=self._http.timeout
65-
)
66-
xml_response = response.text
67-
else:
68-
xml_response = self._http.post("flow/exists", data=data).text
57+
xml_response = self._http.post("flow/exists", data=data).text
6958
result_dict = xmltodict.parse(xml_response)
7059
# Detect error payloads and raise
7160
if "oml:error" in result_dict:
@@ -116,20 +105,8 @@ def list(
116105
if uploader is not None:
117106
api_call += f"/uploader/{uploader}"
118107

119-
server = self._http.server
120-
base = self._http.base_url
121-
if base and base.strip("/") in server:
122-
url = server.rstrip("/") + "/" + api_call
123-
response = requests.get(
124-
url,
125-
headers=self._http.headers,
126-
params={"api_key": self._http.api_key},
127-
timeout=self._http.timeout,
128-
)
129-
xml_string = response.text
130-
else:
131-
response = self._http.get(api_call, use_api_key=True)
132-
xml_string = response.text
108+
response = self._http.get(api_call, use_api_key=True)
109+
xml_string = response.text
133110
flows_dict = xmltodict.parse(xml_string, force_list=("oml:flow",))
134111

135112
if "oml:error" in flows_dict:
@@ -158,7 +135,7 @@ def list(
158135

159136
return pd.DataFrame.from_dict(flows, orient="index")
160137

161-
def create(self, flow: OpenMLFlow) -> OpenMLFlow:
138+
def publish(self, flow: OpenMLFlow) -> OpenMLFlow: # type: ignore[override]
162139
"""Create a new flow on the OpenML server.
163140
164141
under development , not fully functional yet
@@ -187,16 +164,7 @@ def create(self, flow: OpenMLFlow) -> OpenMLFlow:
187164
# POST to server (multipart/files). Ensure api_key is sent in the form data.
188165
files = file_elements
189166
data = {"api_key": self._http.api_key}
190-
# If server already contains base path, post directly with requests to avoid double base_url
191-
server = self._http.server
192-
base = self._http.base_url
193-
if base and base.strip("/") in server:
194-
url = server.rstrip("/") + "/flow"
195-
response = requests.post(
196-
url, files=files, data=data, headers=self._http.headers, timeout=self._http.timeout
197-
)
198-
else:
199-
response = self._http.post("flow", files=files, data=data)
167+
response = self._http.post("flow", files=files, data=data)
200168

201169
parsed = xmltodict.parse(response.text)
202170
if "oml:error" in parsed:
@@ -222,9 +190,6 @@ def delete(self, flow_id: int) -> bool:
222190
self._http.delete(f"flow/{flow_id}")
223191
return True
224192

225-
def publish(self) -> None:
226-
pass
227-
228193

229194
class FlowsV2(FlowsAPI):
230195
def get(
@@ -277,8 +242,8 @@ def exists(self, name: str, external_version: str) -> int | bool:
277242
result = response.json()
278243
flow_id: int | bool = result.get("flow_id", False)
279244
return flow_id
280-
except (requests.exceptions.HTTPError, KeyError):
281-
# v2 returns 404 when flow doesn't exist
245+
except (OpenMLServerError, KeyError):
246+
# v2 returns 404 when flow doesn't exist, which raises OpenMLServerError
282247
return False
283248

284249
def list(
@@ -291,15 +256,12 @@ def list(
291256
) -> pd.DataFrame:
292257
raise NotImplementedError("flows (list) not yet implemented in v2 server")
293258

294-
def create(self, flow: OpenMLFlow) -> OpenMLFlow:
259+
def publish(self, flow: OpenMLFlow) -> OpenMLFlow: # type: ignore[override]
295260
raise NotImplementedError("POST /flows (create) not yet implemented in v2 server")
296261

297262
def delete(self, flow_id: int) -> bool:
298263
raise NotImplementedError("DELETE /flows/{id} not yet implemented in v2 server")
299264

300-
def publish(self) -> None:
301-
raise NotImplementedError("publish not implemented in v2 server")
302-
303265
@staticmethod
304266
def _convert_v2_to_v1_format(v2_json: dict[str, Any]) -> dict[str, dict]:
305267
"""Convert v2 JSON response to v1 XML-dict format for OpenMLFlow._from_dict().

openml/base.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,15 @@ def publish(self) -> OpenMLBase:
128128
"""Publish the object on the OpenML server."""
129129
from openml._api import api_context
130130

131-
# 1. Resolve the correct resource manager (e.g., Flows, Runs)
132131
resource_manager = api_context.backend.get_resource_for_entity(self)
133132

134-
# 2. Delegate creation to the backend (Handles V1/V2 switching internally)
135-
# The backend returns the updated entity (with ID) or the ID itself.
136-
published_entity = resource_manager.create(self) # type: ignore
133+
published_entity = resource_manager.publish(self) # type: ignore
137134

138-
# 3. Update self with ID if not already done (V2 response handling)
139-
if self.id is None and published_entity.id is not None:
135+
if (
136+
published_entity is not None
137+
and hasattr(published_entity, "id")
138+
and published_entity.id is not None
139+
):
140140
self.id = published_entity.id # type: ignore
141141

142142
return self

openml/flows/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def _get_cached_flow(fid: int) -> OpenMLFlow:
6969
raise OpenMLCacheException(f"Flow file for fid {fid} not cached") from e
7070

7171

72-
@openml.utils.thread_safe_if_oslo_installed
72+
# @openml.utils.thread_safe_if_oslo_installed
7373
def get_flow(flow_id: int, reinstantiate: bool = False, strict_version: bool = True) -> OpenMLFlow: # noqa: FBT002
7474
"""Download the OpenML flow for a given flow ID.
7575
@@ -192,7 +192,7 @@ def flow_exists(name: str, external_version: str) -> int | bool:
192192
"""
193193
if not (isinstance(name, str) and len(name) > 0):
194194
raise ValueError("Argument 'name' should be a non-empty string")
195-
if not (isinstance(name, str) and len(external_version) > 0):
195+
if not (isinstance(external_version, str) and len(external_version) > 0):
196196
raise ValueError("Argument 'version' should be a non-empty string")
197197

198198
from openml._api import api_context

0 commit comments

Comments
 (0)