Skip to content

Commit 5e894d4

Browse files
authored
Merge branch 'main' into repr_openmlsplit
2 parents f33beac + 7feb2a3 commit 5e894d4

15 files changed

Lines changed: 130 additions & 181 deletions

File tree

openml/_api_calls.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
from . import config
2323
from .__version__ import __version__
2424
from .exceptions import (
25+
OpenMLAuthenticationError,
2526
OpenMLHashException,
26-
OpenMLNotAuthorizedError,
2727
OpenMLServerError,
2828
OpenMLServerException,
2929
OpenMLServerNoResult,
@@ -515,11 +515,7 @@ def __parse_server_exception(
515515
400, # run/42 delete
516516
460, # task/42 delete
517517
]:
518-
msg = (
519-
f"The API call {url} requires authentication via an API key.\nPlease configure "
520-
"OpenML-Python to use your API as described in this example:"
521-
"\nhttps://openml.github.io/openml-python/latest/examples/Basics/introduction_tutorial/#authentication"
522-
)
523-
return OpenMLNotAuthorizedError(message=msg)
518+
msg = f"The API call {url} requires authentication via an API key."
519+
return OpenMLAuthenticationError(message=msg)
524520

525521
return OpenMLServerException(code=code, message=full_message, url=url)

openml/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def check_server(server: str) -> str:
109109

110110
def replace_shorthand(server: str) -> str:
111111
if server == "test":
112-
return "https://test.openml.org/api/v1/xml"
112+
return f"{config.TEST_SERVER_URL}/api/v1/xml"
113113
if server == "production_server":
114114
return "https://www.openml.org/api/v1/xml"
115115
return server

openml/config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
OPENML_TEST_SERVER_ADMIN_KEY_ENV_VAR = "OPENML_TEST_SERVER_ADMIN_KEY"
2929
_TEST_SERVER_NORMAL_USER_KEY = "normaluser"
3030

31+
TEST_SERVER_URL = "https://test.openml.org"
32+
3133

3234
class _Config(TypedDict):
3335
apikey: str
@@ -214,7 +216,7 @@ class ConfigurationForExamples:
214216
_last_used_server = None
215217
_last_used_key = None
216218
_start_last_called = False
217-
_test_server = "https://test.openml.org/api/v1/xml"
219+
_test_server = f"{TEST_SERVER_URL}/api/v1/xml"
218220
_test_apikey = _TEST_SERVER_NORMAL_USER_KEY
219221

220222
@classmethod
@@ -470,7 +472,8 @@ def get_cache_directory() -> str:
470472
471473
"""
472474
url_suffix = urlparse(server).netloc
473-
reversed_url_suffix = os.sep.join(url_suffix.split(".")[::-1]) # noqa: PTH118
475+
url_parts = url_suffix.replace(":", "_").split(".")[::-1]
476+
reversed_url_suffix = os.sep.join(url_parts) # noqa: PTH118
474477
return os.path.join(_root_cache_directory, reversed_url_suffix) # noqa: PTH118
475478

476479

openml/exceptions.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,28 @@ class OpenMLNotAuthorizedError(OpenMLServerError):
6363
"""Indicates an authenticated user is not authorized to execute the requested action."""
6464

6565

66+
class OpenMLAuthenticationError(OpenMLServerError):
67+
"""Exception raised when API authentication fails.
68+
69+
This typically occurs when:
70+
- No API key is configured
71+
- The API key is invalid or expired
72+
- The API key format is incorrect
73+
74+
This is different from authorization (OpenMLNotAuthorizedError), which occurs
75+
when a valid API key lacks permissions for the requested operation.
76+
"""
77+
78+
def __init__(self, message: str):
79+
help_text = (
80+
"\n\nTo fix this:\n"
81+
"1. Get your API key from https://www.openml.org/\n"
82+
" (you'll need to register for a free account if you don't have one)\n"
83+
"2. Configure your API key by following the authentication guide:\n"
84+
" https://openml.github.io/openml-python/latest/examples/Basics/introduction_tutorial/#authentication"
85+
)
86+
super().__init__(message + help_text)
87+
88+
6689
class ObjectNotPublishedError(PyOpenMLError):
6790
"""Indicates an object has not been published yet."""

openml/tasks/functions.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,24 +415,28 @@ def get_task(
415415
if not isinstance(task_id, int):
416416
raise TypeError(f"Task id should be integer, is {type(task_id)}")
417417

418-
cache_key_dir = openml.utils._create_cache_directory_for_id(TASKS_CACHE_DIR_NAME, task_id)
419-
tid_cache_dir = cache_key_dir / str(task_id)
420-
tid_cache_dir_existed = tid_cache_dir.exists()
418+
task_cache_directory = openml.utils._create_cache_directory_for_id(
419+
TASKS_CACHE_DIR_NAME, task_id
420+
)
421+
task_cache_directory_existed = task_cache_directory.exists()
421422
try:
422423
task = _get_task_description(task_id)
423424
dataset = get_dataset(task.dataset_id, **get_dataset_kwargs)
424425
# List of class labels available in dataset description
425426
# Including class labels as part of task meta data handles
426427
# the case where data download was initially disabled
427428
if isinstance(task, (OpenMLClassificationTask, OpenMLLearningCurveTask)):
429+
assert task.target_name is not None, (
430+
"Supervised tasks must define a target feature before retrieving class labels."
431+
)
428432
task.class_labels = dataset.retrieve_class_labels(task.target_name)
429433
# Clustering tasks do not have class labels
430434
# and do not offer download_split
431435
if download_splits and isinstance(task, OpenMLSupervisedTask):
432436
task.download_split()
433437
except Exception as e:
434-
if not tid_cache_dir_existed:
435-
openml.utils._remove_cache_dir_for_id(TASKS_CACHE_DIR_NAME, tid_cache_dir)
438+
if not task_cache_directory_existed:
439+
openml.utils._remove_cache_dir_for_id(TASKS_CACHE_DIR_NAME, task_cache_directory)
436440
raise e
437441

438442
return task
@@ -598,6 +602,7 @@ def create_task(
598602
)
599603

600604
return task_cls(
605+
task_id=None,
601606
task_type_id=task_type,
602607
task_type="None", # TODO: refactor to get task type string from ID.
603608
data_set_id=dataset_id,

0 commit comments

Comments
 (0)