From fbd23f23856d634ad1573e13b7c23df2c7436775 Mon Sep 17 00:00:00 2001 From: Sebastian Fischer Date: Tue, 9 Jan 2024 10:54:41 +0100 Subject: [PATCH 1/2] update server address --- R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index ac957a4..af23aef 100644 --- a/R/utils.R +++ b/R/utils.R @@ -20,7 +20,7 @@ get_desc_downloader = function(type) { } get_server = function(test_server) { - if (test_server) "https://test.openml.org/api/v1" else "https://www.openml.org/api/v1" + if (test_server) "https://test.openml.org/api/v1" else "https://www.test.openml.org/py" } catf_estimation_procedure = function(estimation_procedure) { From d4115b8d9e6f8252d88a04fa844809cdd453184e Mon Sep 17 00:00:00 2001 From: Sebastian Fischer Date: Wed, 17 Jan 2024 11:22:21 +0100 Subject: [PATCH 2/2] some progress --- R/OMLTask.R | 4 +-- R/download_data_features.R | 2 +- R/download_data_qualities.R | 2 +- R/download_desc_collection.R | 4 +-- R/download_desc_data.R | 26 +++++++++++----- R/download_desc_flow.R | 10 ++---- R/download_desc_run.R | 2 +- R/download_desc_task.R | 11 +++---- R/helper.R | 26 +++++++++++----- R/list_oml_data.R | 2 +- R/list_oml_flows.R | 2 +- R/list_oml_measures.R | 2 +- R/list_oml_runs.R | 2 +- R/list_oml_setups.R | 2 +- R/list_oml_tasks.R | 2 +- R/magic_numbers.R | 1 + R/utils.R | 2 +- inst/old/odata61.rds | Bin 0 -> 5927 bytes inst/old/otask61.rds | Bin 0 -> 76744 bytes inst/testthat/helper_expectation.R | 13 ++++++++ old_objects.R | 48 +++++++++++++++++++++++++++++ tests/testthat/test_OMLData.R | 2 -- 22 files changed, 121 insertions(+), 44 deletions(-) create mode 100644 inst/old/odata61.rds create mode 100644 inst/old/otask61.rds create mode 100644 old_objects.R diff --git a/R/OMLTask.R b/R/OMLTask.R index 4bdd2b6..1345025 100644 --- a/R/OMLTask.R +++ b/R/OMLTask.R @@ -100,7 +100,7 @@ OMLTask = R6Class("OMLTask", #' @field name (`character(1)`)\cr #' Name of the task, extracted from the task description. name = function() { - self$desc$task_name + self$desc$name }, #' @field task_type (`character(1)`)\cr #' The OpenML task type. @@ -156,7 +156,7 @@ OMLTask = R6Class("OMLTask", #' @field data_name (`character()`)\cr #' Name of the dataset (inferred from the task name). data_name = function() { - strsplit(self$desc$task_name, split = " ")[[1]][[3]] + strsplit(self$desc$name, split = " ")[[1]][[3]] } ), private = list( diff --git a/R/download_data_features.R b/R/download_data_features.R index 19b891e..84d7e58 100644 --- a/R/download_data_features.R +++ b/R/download_data_features.R @@ -1,5 +1,5 @@ download_data_features = function(data_id, server, desc = download_desc_data(data_id, server)) { - features = get_json(paste0(server, "/json/data/features/%i"), data_id, server = server)[[1L]][[1L]] + features = get_json(paste0(server, "/datasets/features/%i"), data_id, server = server) features$index = as.integer(features$index) features$name = make.names(features$name) diff --git a/R/download_data_qualities.R b/R/download_data_qualities.R index b1eb5a3..72b756f 100644 --- a/R/download_data_qualities.R +++ b/R/download_data_qualities.R @@ -1,5 +1,5 @@ download_data_qualities = function(data_id, server) { - qualities = get_json(paste0(server, "/json/data/qualities/%i"), data_id, server = server)[[1L]][[1L]] # nolint + qualities = get_json(paste0(server, "/datasets/qualities/%i"), data_id, server = server) qualities$value = as.numeric(qualities$value) setDT(qualities, key = "name")[] diff --git a/R/download_desc_collection.R b/R/download_desc_collection.R index f8add40..63f43bd 100644 --- a/R/download_desc_collection.R +++ b/R/download_desc_collection.R @@ -1,7 +1,5 @@ download_desc_collection = function(collection_id, server) { - desc = get_json(paste0(server, "/json/study/%i"), collection_id, - simplify_data_frame = FALSE, server = server - )[[1L]] + desc = get_json(paste0(server, "/studies/%i"), collection_id, simplify_data_frame = FALSE, server = server) parse_desc_collection(desc) } diff --git a/R/download_desc_data.R b/R/download_desc_data.R index 8047400..a0b8c9e 100644 --- a/R/download_desc_data.R +++ b/R/download_desc_data.R @@ -1,6 +1,5 @@ download_desc_data = function(data_id, server) { - desc = get_json(paste0(server, "/json/data/%i"), data_id, simplify_data_frame = FALSE, - server = server)[[1L]] + desc = get_json(paste0(server, "/datasets/%i"), data_id, simplify_data_frame = FALSE, server = server) parse_desc_data(desc) } @@ -10,16 +9,29 @@ parse_desc_data = function(desc) { stopf("Unsupported data format: %s", desc$format) } - desc$id = as.integer(desc$id) - desc$version = as.integer(desc$version) + # default_target_attribute, row_id_attribute and ignore_attribute have reutrn type arrau in the json + # schema. In the empty case, jsonlite returns these as a `list()` so we have to convert them to characters + + # When accessing a dataset where make.names() does not return unique names on the features, an error is thrown + # at another part in the code, so we can change the name of the target column here without risk desc$default_target_attribute = make.names(desc$default_target_attribute) - desc$upload_date = strptime(desc$upload_date, format = "%Y-%m-%dT%H:%M:%S", tz = "UTC") - desc$processing_date = strptime(desc$processing_date, format = "%Y-%m-%d %H:%M:%S", tz = "UTC") + desc$row_id_attribute = as.character(desc$row_id_attribute) # OpenML (sometimes) uploaded the ignore_attributes comma-seperated ignore_attribute = map(desc$ignore_attribute, function(x) strsplit(x, ",")[[1L]]) - desc$ignore_attribute = make.unique(make.names(unlist(ignore_attribute))) + desc$ignore_attribute = make.names(as.character(ignore_attribute)) + if (anyDuplicated(desc$ignore_attribute)) { stopf("No unique names after conversion. This happened because ignore attribute names are not valid R names and had to be converted, which created duplicates.") # nolint } + + desc$upload_date = strptime(desc$upload_date, format = "%Y-%m-%dT%H:%M:%S", tz = "UTC") + desc$processing_date = strptime(desc$processing_date, format = "%Y-%m-%dT%H:%M:%S", tz = "UTC") + + desc$creator = as.character(desc$creator) + desc$contributor = as.character(desc$contributor) + desc$paper_url = as.character(desc$paper_url) + desc$tag = as.character(desc$tag) + return(desc) } + diff --git a/R/download_desc_flow.R b/R/download_desc_flow.R index 42645d1..5d711e3 100644 --- a/R/download_desc_flow.R +++ b/R/download_desc_flow.R @@ -1,18 +1,14 @@ download_desc_flow = function(flow_id, server) { - desc = get_json(paste0(server, "/json/flow/%i"), flow_id, server = server)[[1L]] + desc = get_json(paste0(server, "/flows/%i"), flow_id, server = server) desc = parse_desc_flow(desc) return(desc) } parse_desc_flow = function(desc) { - desc$id = as.integer(desc$id) desc$upload_date = as.POSIXct(desc$upload_date, format = "%Y-%m-%dT%H:%M:%S", tz = "UTC") - desc$version = as.integer(desc$version) - desc$uploader = as.integer(desc$uploader) - desc$id = as.integer(desc$id) - desc$parameter = - if (is.null(desc$parameter)) { + browser() + if (!length(desc$parameter)) { desc$parameter = data.table( name = character(0), data_type = character(0), diff --git a/R/download_desc_run.R b/R/download_desc_run.R index 43908f3..9686552 100644 --- a/R/download_desc_run.R +++ b/R/download_desc_run.R @@ -1,5 +1,5 @@ download_desc_run = function(run_id, server) { - desc = get_json(paste0(server, "/json/run/%i"), run_id, server = server)[[1L]] + desc = get_json(paste0(server, "/runs/%i"), run_id, server = server) desc = parse_desc_run(desc) return(desc) } diff --git a/R/download_desc_task.R b/R/download_desc_task.R index 08dc209..bc2efc3 100644 --- a/R/download_desc_task.R +++ b/R/download_desc_task.R @@ -1,17 +1,16 @@ download_desc_task = function(task_id, server) { - desc = get_json(paste0(server, "/json/task/%i"), task_id, + desc = get_json(paste0(server, "/tasks/%i"), task_id, simplify_data_frame = FALSE, server = server - )[[1L]] + ) desc = parse_desc_task(desc) return(desc) } parse_desc_task = function(desc) { - desc$task_id = as.integer(desc$task_id) - desc$task_type_id = as.integer(desc$task_type_id) - desc$input = set_names(map(desc$input, function(x) x[[2L]]), map_chr(desc$input, "name")) - desc$input$source_data$data_set_id = as.integer(desc$input$source_data$data_set_id) + desc$input = set_names(imap(desc$input, function(x, nm) x[[1]]), map_chr(desc$input, "name")) + desc$output = set_names(imap(desc$output, function(x, nm) x[[1]]), map_chr(desc$output, "name")) + est_params = desc$input$estimation_procedure$parameter ep_names = map(est_params, "name") ep_values = map(est_params, "value") diff --git a/R/helper.R b/R/helper.R index e734659..4982c72 100644 --- a/R/helper.R +++ b/R/helper.R @@ -101,17 +101,20 @@ get_json = function(url, ..., simplify_vector = TRUE, simplify_data_frame = TRUE for (retry in seq_len(retries)) { response = download_file(url, path, api_key = api_key) + browser() if (response$ok) { json = jsonlite::fromJSON(path, simplifyVector = simplify_vector, simplifyDataFrame = simplify_data_frame) return(json) } else if (retry < retries) { - if (response$oml_code %in% c(107L)) { - delay = max(rnorm(1L, mean = 10), 0) - lg$debug("Server busy, retrying in %.2f seconds", delay, try = retry) - Sys.sleep(delay) - } else { - break - } + break + # FIXME: + #if (isTRUE(response$oml_code %in% c(107L))) { + # delay = max(rnorm(1L, mean = 10), 0) + # lg$debug("Server busy, retrying in %.2f seconds", delay, try = retry) + # Sys.sleep(delay) + #} else { + # break + #} } } @@ -134,6 +137,15 @@ get_paginated_table = function(query_type, ..., limit, server) { query = build_filter_query(query_type, dots, server) response = get_json(query, error_on_fail = FALSE, server = server) + + response = httr::POST( + url = sprintf("%s/task", get_server(test_server)), + body = list( + description = httr::upload_file(desc_path) + ), + query = list(api_key = api_key) + ) + if (inherits(response, "server_response")) { if (response$oml_code %in% magic_numbers$oml_no_more_results) { # no more results diff --git a/R/list_oml_data.R b/R/list_oml_data.R index 2e684e3..5278ea1 100644 --- a/R/list_oml_data.R +++ b/R/list_oml_data.R @@ -53,7 +53,7 @@ list_oml_data = function(data_id = NULL, data_name = NULL, number_instances = NU number_classes = NULL, number_missing_values = NULL, tag = NULL, limit = limit_default(), test_server = test_server_default(), ...) { - tab = get_paginated_table("data", + tab = get_paginated_table("datasets", data_id = data_id, data_name = data_name, number_instances = number_instances, diff --git a/R/list_oml_flows.R b/R/list_oml_flows.R index dc172b9..5c5186a 100644 --- a/R/list_oml_flows.R +++ b/R/list_oml_flows.R @@ -4,7 +4,7 @@ #' @export list_oml_flows = function(uploader = NULL, tag = NULL, limit = limit_default(), test_server = test_server_default(), ...) { - tab = get_paginated_table("flow", + tab = get_paginated_table("flows", uploader = uploader, tag = tag, limit = limit, diff --git a/R/list_oml_measures.R b/R/list_oml_measures.R index 9897af4..51161ab 100644 --- a/R/list_oml_measures.R +++ b/R/list_oml_measures.R @@ -2,7 +2,7 @@ #' @export list_oml_measures = function(test_server = test_server_default()) { server = get_server(test_server) - measures = get_json(sprintf("%s/json/evaluationmeasure/list", server), + measures = get_json(sprintf("%s/py/evaluationmeasure/list", server), server = server)[[c(1L, 1L, 1L)]] data.table(measure = measures) } diff --git a/R/list_oml_runs.R b/R/list_oml_runs.R index 7fb7aa2..6f3bec5 100644 --- a/R/list_oml_runs.R +++ b/R/list_oml_runs.R @@ -4,7 +4,7 @@ #' @export list_oml_runs = function(run_id = NULL, task_id = NULL, tag = NULL, flow_id = NULL, limit = limit_default(), test_server = test_server_default(), ...) { - tab = get_paginated_table("run", + tab = get_paginated_table("runs", run = run_id, task = task_id, tag = tag, diff --git a/R/list_oml_setups.R b/R/list_oml_setups.R index 6c8d693..a01f4c5 100644 --- a/R/list_oml_setups.R +++ b/R/list_oml_setups.R @@ -6,7 +6,7 @@ #' @export list_oml_setups = function(flow_id = NULL, setup_id = NULL, tag = NULL, limit = limit_default(), test_server = test_server_default(), ...) { - tab = get_paginated_table("setup", + tab = get_paginated_table("setups", flow = flow_id, setup = setup_id, tag = tag, diff --git a/R/list_oml_tasks.R b/R/list_oml_tasks.R index 809a227..fa4c016 100644 --- a/R/list_oml_tasks.R +++ b/R/list_oml_tasks.R @@ -16,7 +16,7 @@ list_oml_tasks = function(task_id = NULL, data_id = NULL, number_instances = NUL clust = "5" ) } - tab = get_paginated_table("task", + tab = get_paginated_table("tasks", task_id = task_id, data_id = data_id, number_instances = number_instances, diff --git a/R/magic_numbers.R b/R/magic_numbers.R index 2eb58fb..8f5400a 100644 --- a/R/magic_numbers.R +++ b/R/magic_numbers.R @@ -1,4 +1,5 @@ magic_numbers = list( + # FIXME: These will not be be needed anymore / will change oml_no_more_results = c( data_set = 372L, task = 482L, diff --git a/R/utils.R b/R/utils.R index af23aef..5b01136 100644 --- a/R/utils.R +++ b/R/utils.R @@ -20,7 +20,7 @@ get_desc_downloader = function(type) { } get_server = function(test_server) { - if (test_server) "https://test.openml.org/api/v1" else "https://www.test.openml.org/py" + if (test_server) "https://test.openml.org/api/v1" else "https://test.openml.org/py" } catf_estimation_procedure = function(estimation_procedure) { diff --git a/inst/old/odata61.rds b/inst/old/odata61.rds new file mode 100644 index 0000000000000000000000000000000000000000..2086b2991d12e9e0abeeff3a90ead4c94ce89629 GIT binary patch literal 5927 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 literal 0 HcmV?d00001 diff --git a/inst/testthat/helper_expectation.R b/inst/testthat/helper_expectation.R index e95cd6b..86b8883 100644 --- a/inst/testthat/helper_expectation.R +++ b/inst/testthat/helper_expectation.R @@ -53,6 +53,13 @@ expect_oml_data = function(data) { expect_names(data$feature_names, "strict") expect_subset(data$feature_names, colnames(data$data)) expect_disjunct(data$target_names, data$feature_names) + expect_character(data$desc$default_target_attribute, null.ok = TRUE) + expect_character(data$desc$row_id_attribute, null.ok = TRUE) + expect_character(data$desc$ignore_attribute, null.ok = TRUE) + expect_character(data$desc$creator, null.ok = TRUE) + expect_character(data$desc$contributor, null.ok = TRUE) + expect_character(data$desc$paper_url, null.ok = TRUE) + expect_character(data$desc$tag, null.ok = TRUE) # can't do this because after OpenML's parquet transition some features seem to be missing # expect_set_equal(names(data$data), c(data$feature_names, data$target_names)) expect_count(data$nrow) @@ -65,6 +72,12 @@ expect_oml_data = function(data) { } expect_flag(data$parquet) backend = as_data_backend(data) + if (length(data$desc$default_target_attribute)) { + expect_choice(data$desc$default_target_attribute, backend$colnames) + } + if (length(data$desc$ignore_attribute)) { + expect_choice(data$desc$ignore_attribute, backend$colnames) + } expect_r6(backend, paste0("DataBackend")) } diff --git a/old_objects.R b/old_objects.R new file mode 100644 index 0000000..2e43c68 --- /dev/null +++ b/old_objects.R @@ -0,0 +1,48 @@ +library(mlr3oml) + +odata = odt(61) +odata$download() +saveRDS(odata, file.path("./inst/old/odata61.rds")) + +otask = otsk(61) +otask$download() +saveRDS(otask, file.path("./inst/old/otask61.rds")) + +oflow = oflw(1) +oflow$download() +saveRDS(oflow, file.path(".inst/old/l")) + + +test_that("new api works for OMLData", { + old = readRDS(system.file("old", "odata61.rds", package = "mlr3oml")) + new = odt(61, test_server = TRUE) + all.equal(old, new) + + fields = unique(c(names(old$desc), names(new$desc))) + + for (field in fields) { + if (!isTRUE(all.equal(old$desc[[field]], new$desc[[field]]))) { + print(field) + print("old:") + print(old$desc[[field]]) + print("new:") + print(new$desc[[field]]) + } + } +}) + +test_that("new api works for OMLTask", { + oldtask = readRDS(system.file("old", "otask61.rds", package = "mlr3oml")) + download_desc_task(61, get_server(FALSE)) + newdesc = get_json(paste0(get_server(FALSE), "/tasks/61"), + simplify_data_frame = FALSE, server = get_server(FALSE) + ) + path = tempfile() + response = download_file(paste0(get_server(FALSE), "/tasks/61"), path, server = get_server(FALSE)) + x = readLines(path) + olddesc = oldtask$desc + oldtask$desc + newdesc + all.equal(old, new) + +}) diff --git a/tests/testthat/test_OMLData.R b/tests/testthat/test_OMLData.R index abffaab..8097706 100644 --- a/tests/testthat/test_OMLData.R +++ b/tests/testthat/test_OMLData.R @@ -183,5 +183,3 @@ test_that("download runs without error", { # expect_data_table(odata$data) # #expect_class(odata$data[["Timestamp"]], "POSIXct") #}) - -