Skip to content

Commit 3c00d7b

Browse files
authored
Issue 1028: public delete functions for run, task, flow and database (#1060)
1 parent 24cbc5e commit 3c00d7b

36 files changed

+691
-36
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ target/
7777
# IDE
7878
.idea
7979
*.swp
80+
.vscode
8081

8182
# MYPY
8283
.mypy_cache

doc/api.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Dataset Functions
3838
attributes_arff_from_df
3939
check_datasets_active
4040
create_dataset
41+
delete_dataset
4142
get_dataset
4243
get_datasets
4344
list_datasets
@@ -103,6 +104,7 @@ Flow Functions
103104
:template: function.rst
104105

105106
assert_flows_equal
107+
delete_flow
106108
flow_exists
107109
get_flow
108110
list_flows
@@ -133,6 +135,7 @@ Run Functions
133135
:toctree: generated/
134136
:template: function.rst
135137

138+
delete_run
136139
get_run
137140
get_runs
138141
get_run_trace
@@ -251,6 +254,7 @@ Task Functions
251254
:template: function.rst
252255

253256
create_task
257+
delete_task
254258
get_task
255259
get_tasks
256260
list_tasks

doc/progress.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ Changelog
1010
~~~~~~
1111

1212
* Add new contributions here.
13-
* ADD#1144: Add locally computed results to the ``OpenMLRun`` object's representation.
13+
* ADD#1028: Add functions to delete runs, flows, datasets, and tasks (e.g., ``openml.datasets.delete_dataset``).
14+
* ADD#1144: Add locally computed results to the ``OpenMLRun`` object's representation if the run was created locally and not downloaded from the server.
1415
* FIX #1197 #559 #1131: Fix the order of ground truth and predictions in the ``OpenMLRun`` object and in ``format_prediction``.
1516
* FIX #1198: Support numpy 1.24 and higher.
16-
* ADD#1144: Add locally computed results to the ``OpenMLRun`` object's representation if the run was created locally and not downloaded from the server.
1717

1818
0.13.0
1919
~~~~~~

openml/_api_calls.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,12 @@ def _send_request(request_method, url, data, files=None, md5_checksum=None):
351351
xml.parsers.expat.ExpatError,
352352
OpenMLHashException,
353353
) as e:
354-
if isinstance(e, OpenMLServerException):
355-
if e.code not in [107]:
356-
# 107: database connection error
357-
raise
354+
if isinstance(e, OpenMLServerException) and e.code != 107:
355+
# Propagate all server errors to the calling functions, except
356+
# for 107 which represents a database connection error.
357+
# These are typically caused by high server load,
358+
# which means trying again might resolve the issue.
359+
raise
358360
elif isinstance(e, xml.parsers.expat.ExpatError):
359361
if request_method != "get" or retry_counter >= n_retries:
360362
raise OpenMLServerError(

openml/datasets/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
list_qualities,
1212
edit_dataset,
1313
fork_dataset,
14+
delete_dataset,
1415
)
1516
from .dataset import OpenMLDataset
1617
from .data_feature import OpenMLDataFeature
@@ -28,4 +29,5 @@
2829
"list_qualities",
2930
"edit_dataset",
3031
"fork_dataset",
32+
"delete_dataset",
3133
]

openml/datasets/functions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,3 +1271,22 @@ def _get_online_dataset_format(dataset_id):
12711271
dataset_xml = openml._api_calls._perform_api_call("data/%d" % dataset_id, "get")
12721272
# build a dict from the xml and get the format from the dataset description
12731273
return xmltodict.parse(dataset_xml)["oml:data_set_description"]["oml:format"].lower()
1274+
1275+
1276+
def delete_dataset(dataset_id: int) -> bool:
1277+
"""Delete dataset with id `dataset_id` from the OpenML server.
1278+
1279+
This can only be done if you are the owner of the dataset and
1280+
no tasks are attached to the dataset.
1281+
1282+
Parameters
1283+
----------
1284+
dataset_id : int
1285+
OpenML id of the dataset
1286+
1287+
Returns
1288+
-------
1289+
bool
1290+
True if the deletion was successful. False otherwise.
1291+
"""
1292+
return openml.utils._delete_entity("data", dataset_id)

openml/exceptions.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ class OpenMLServerError(PyOpenMLError):
1111
"""class for when something is really wrong on the server
1212
(result did not parse to dict), contains unparsed error."""
1313

14-
def __init__(self, message: str):
15-
super().__init__(message)
14+
pass
1615

1716

1817
class OpenMLServerException(OpenMLServerError):
1918
"""exception for when the result of the server was
2019
not 200 (e.g., listing call w/o results)."""
2120

22-
# Code needs to be optional to allow the exceptino to be picklable:
21+
# Code needs to be optional to allow the exception to be picklable:
2322
# https://stackoverflow.com/questions/16244923/how-to-make-a-custom-exception-class-with-multiple-init-args-pickleable # noqa: E501
2423
def __init__(self, message: str, code: int = None, url: str = None):
2524
self.message = message
@@ -28,24 +27,19 @@ def __init__(self, message: str, code: int = None, url: str = None):
2827
super().__init__(message)
2928

3029
def __str__(self):
31-
return "%s returned code %s: %s" % (
32-
self.url,
33-
self.code,
34-
self.message,
35-
)
30+
return f"{self.url} returned code {self.code}: {self.message}"
3631

3732

3833
class OpenMLServerNoResult(OpenMLServerException):
39-
"""exception for when the result of the server is empty."""
34+
"""Exception for when the result of the server is empty."""
4035

4136
pass
4237

4338

4439
class OpenMLCacheException(PyOpenMLError):
4540
"""Dataset / task etc not found in cache"""
4641

47-
def __init__(self, message: str):
48-
super().__init__(message)
42+
pass
4943

5044

5145
class OpenMLHashException(PyOpenMLError):
@@ -57,8 +51,7 @@ class OpenMLHashException(PyOpenMLError):
5751
class OpenMLPrivateDatasetError(PyOpenMLError):
5852
"""Exception thrown when the user has no rights to access the dataset."""
5953

60-
def __init__(self, message: str):
61-
super().__init__(message)
54+
pass
6255

6356

6457
class OpenMLRunsExistError(PyOpenMLError):
@@ -69,3 +62,9 @@ def __init__(self, run_ids: set, message: str):
6962
raise ValueError("Set of run ids must be non-empty.")
7063
self.run_ids = run_ids
7164
super().__init__(message)
65+
66+
67+
class OpenMLNotAuthorizedError(OpenMLServerError):
68+
"""Indicates an authenticated user is not authorized to execute the requested action."""
69+
70+
pass

openml/flows/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
from .flow import OpenMLFlow
44

5-
from .functions import get_flow, list_flows, flow_exists, get_flow_id, assert_flows_equal
5+
from .functions import (
6+
get_flow,
7+
list_flows,
8+
flow_exists,
9+
get_flow_id,
10+
assert_flows_equal,
11+
delete_flow,
12+
)
613

714
__all__ = [
815
"OpenMLFlow",
@@ -11,4 +18,5 @@
1118
"get_flow_id",
1219
"flow_exists",
1320
"assert_flows_equal",
21+
"delete_flow",
1422
]

openml/flows/functions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,22 @@ def _create_flow_from_xml(flow_xml: str) -> OpenMLFlow:
544544
"""
545545

546546
return OpenMLFlow._from_dict(xmltodict.parse(flow_xml))
547+
548+
549+
def delete_flow(flow_id: int) -> bool:
550+
"""Delete flow with id `flow_id` from the OpenML server.
551+
552+
You can only delete flows which you uploaded and which
553+
which are not linked to runs.
554+
555+
Parameters
556+
----------
557+
flow_id : int
558+
OpenML id of the flow
559+
560+
Returns
561+
-------
562+
bool
563+
True if the deletion was successful. False otherwise.
564+
"""
565+
return openml.utils._delete_entity("flow", flow_id)

openml/runs/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
run_exists,
1313
initialize_model_from_run,
1414
initialize_model_from_trace,
15+
delete_run,
1516
)
1617

1718
__all__ = [
@@ -27,4 +28,5 @@
2728
"run_exists",
2829
"initialize_model_from_run",
2930
"initialize_model_from_trace",
31+
"delete_run",
3032
]

0 commit comments

Comments
 (0)