From dca045f8eb6b885587d30c5329d26b255bfb9b62 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:19:38 +0000 Subject: [PATCH 01/13] docu: readme with notes about API Key --- README.Rmd | 6 ++++-- README.md | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/README.Rmd b/README.Rmd index bdb4e31..35802dd 100644 --- a/README.Rmd +++ b/README.Rmd @@ -70,10 +70,12 @@ ds <- zhapir::create_dataset( title = "Prod Datensatz", organisation_id = 14, description = "In PROD erstellt", - use_dev = FALSE # 👉 PROD statt DEV + use_dev = FALSE # 👉 PROD statt DEV --> zeigt auf "https://dev.mdv.statistik.zh.ch" ) ``` +> [!NOTE] Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der PROD API-Key angezogen wird. + ## ✨ Beispiele ### Datensatz erstellen @@ -120,7 +122,7 @@ dist <- zhapir::create_distribution( 🟢 Lizenztypen (license_id) | ID | Bedeutung | Entspricht | -|-------------|---------------------------------------------|--------------| +|------------------|------------------------------------|------------------| | 1 | kommerzielle & nicht-kommerzielle Nutzung **mit Quellenangabe** | ≈ CC BY 4.0 | | 2 | kommerzielle & nicht-kommerzielle Nutzung **ohne Quellenangabe** | ≈ CC0 1.0 Public Domain | diff --git a/README.md b/README.md index 8534a4c..06c9a97 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,19 @@ ds <- zhapir::create_dataset( title = "Prod Datensatz", organisation_id = 14, description = "In PROD erstellt", - use_dev = FALSE # 👉 PROD statt DEV + use_dev = FALSE # 👉 PROD statt DEV --> zeigt auf "https://dev.mdv.statistik.zh.ch" ) ``` +> \[!NOTE\] Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll +> (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der +> DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen +> wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem +> `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die +> Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche +> API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der +> PROD API-Key angezogen wird. + ## ✨ Beispiele ### Datensatz erstellen From c95a92c3e504c52e760afb16f32ed6d9c12f10e2 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:20:02 +0000 Subject: [PATCH 02/13] fix: add api key arguments and use_dev to functions --- R/create_dataset.R | 10 +-- R/create_distribution.R | 8 +-- R/helpers.R | 16 +++-- R/text_arguments_parser.R | 135 ++++++++++++++++++++++---------------- R/update_dataset.R | 10 +-- R/update_distribution.R | 8 +-- 6 files changed, 108 insertions(+), 79 deletions(-) diff --git a/R/create_dataset.R b/R/create_dataset.R index 50636ab..deda0e7 100644 --- a/R/create_dataset.R +++ b/R/create_dataset.R @@ -66,11 +66,11 @@ create_dataset <- function( # resolve all lookups up front - keyword_ids_api <- if (is.character(keyword_ids)) convert_keywords_to_id(keyword_ids) else keyword_ids - zh_web_catalog_ids_api <- if (is.character(zh_web_datacatalog_ids)) convert_zh_web_catalog_to_id(zh_web_datacatalog_ids) else zh_web_datacatalog_ids - theme_ids_api <- if (is.character(theme_ids)) convert_themes_to_id(theme_ids) else theme_ids - periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id) else periodicity_id - see_also_ids_api <- if (is.character(see_also_ids)) convert_datasets_to_id(see_also_ids) else see_also_ids + keyword_ids_api <- if (is.character(keyword_ids)) convert_keywords_to_id(keyword_ids, use_dev = use_dev, api_key = api_key) else keyword_ids + zh_web_catalog_ids_api <- if (is.character(zh_web_datacatalog_ids)) convert_zh_web_catalog_to_id(zh_web_datacatalog_ids, use_dev = use_dev, api_key = api_key) else zh_web_datacatalog_ids + theme_ids_api <- if (is.character(theme_ids)) convert_themes_to_id(theme_ids, use_dev = use_dev, api_key = api_key) else theme_ids + periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id, use_dev = use_dev, api_key = api_key) else periodicity_id + see_also_ids_api <- if (is.character(see_also_ids)) convert_datasets_to_id(see_also_ids, use_dev = use_dev, api_key = api_key) else see_also_ids diff --git a/R/create_distribution.R b/R/create_distribution.R index f031c28..31c11e4 100644 --- a/R/create_distribution.R +++ b/R/create_distribution.R @@ -91,10 +91,10 @@ create_distribution <- function( } # Resolve all lookups up front - status_id_api <- if (is.character(status_id)) convert_statuses_to_id(status_id) else status_id - license_id_api <- if (is.character(license_id)) convert_licenses_to_id(license_id) else license_id - file_format_id_api <- if (is.character(file_format_id)) convert_formats_to_id(file_format_id) else file_format_id - periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id) else periodicity_id + status_id_api <- if (is.character(status_id)) convert_statuses_to_id(status_id, use_dev = use_dev, api_key = api_key) else status_id + license_id_api <- if (is.character(license_id)) convert_licenses_to_id(license_id, use_dev = use_dev, api_key = api_key) else license_id + file_format_id_api <- if (is.character(file_format_id)) convert_formats_to_id(file_format_id, use_dev = use_dev, api_key = api_key) else file_format_id + periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id, use_dev = use_dev, api_key = api_key) else periodicity_id # Build pure Distribution (no HTTP here) dist <- Distribution( diff --git a/R/helpers.R b/R/helpers.R index 14f767d..28dee91 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -20,14 +20,15 @@ get_base_url <- function(use_dev = FALSE) { #' #' Attempts to fetch the API key from (in order): #' 1. Provided argument -#' 2. Environment variable `MDV_API_KEY` +#' 2. Environment variable `ZHAPIR_API_KEY` #' 3. Interactive prompt (RStudio or askpass) #' #' @param key Optional plain API key. #' @return API key string. #' @export get_api_key <- function(key = NULL) { - # 1. Direct argument + + # 1. Direct argument wins if (!is.null(key) && nzchar(key)) { return(key) } @@ -38,13 +39,17 @@ get_api_key <- function(key = NULL) { return(env_key) } - # 3. Interactive prompt (last resort) - prompt_key <- "" # create empty + # 3. Interactive prompt (last resort, and only if really interactive) if (interactive()) { prompt_key <- askpass::askpass("Please enter your ZHAPIR_API_KEY key") + + # askpass() kann NULL liefern (Abbruch) → robust abfangen + if (!is.null(prompt_key) && nzchar(prompt_key)) { + return(prompt_key) + } } - if (nzchar(prompt_key)) return(prompt_key) + # 4. Nichts gefunden → Fehler stop( "No API key found. Supply via argument or set ZHAPIR_API_KEY environment variable.", call. = FALSE @@ -52,7 +57,6 @@ get_api_key <- function(key = NULL) { } - #' Convert an S7 object into a JSON-ready payload list #' #' This helper extracts all properties, formats dates, and removes empty diff --git a/R/text_arguments_parser.R b/R/text_arguments_parser.R index 5c51f58..f102cf7 100644 --- a/R/text_arguments_parser.R +++ b/R/text_arguments_parser.R @@ -3,6 +3,8 @@ #' Retrieves a tibble of all organisations and their IDs. Optionally includes sub-units. #' #' @param show_organisation_units Logical; if TRUE, include sub-units. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with columns: #' - `organisation_id` (numeric) #' - `organisation` (character) @@ -16,11 +18,13 @@ #' get_organisations(FALSE) #' } #' @export -get_organisations <- function(show_organisation_units = TRUE) { +get_organisations <- function(show_organisation_units = TRUE, use_dev = FALSE, api_key = NULL) { + if (is.null(api_key)) api_key <- get_api_key() req <- api_request( method = "GET", endpoint = "/api/v1/organisations", - api_key = get_api_key(), + api_key = api_key, + use_dev = use_dev, object_label = "Organisation" ) @@ -49,6 +53,8 @@ get_organisations <- function(show_organisation_units = TRUE) { #' Retrieves a tibble of all keywords and their IDs. Optionally filters by name or ID. #' #' @param input Optional character vector of keyword names or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with two columns: #' - `keyword` (character): the keyword label #' - `id` (numeric): the keyword ID @@ -64,20 +70,20 @@ get_organisations <- function(show_organisation_units = TRUE) { #' get_keywords(578) #' } #' @export -get_keywords <- function(input = NULL) { - df <- req_to_df("keywords") +get_keywords <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("keywords", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } - #' Convert keyword names to IDs #' @param name Character vector of keyword names. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return Numeric vector of IDs. #' @keywords internal -convert_keywords_to_id <- function(name) { +convert_keywords_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - - df <- get_keywords() + df <- get_keywords(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } @@ -87,6 +93,8 @@ convert_keywords_to_id <- function(name) { #' Retrieves a tibble of datasets (title and id), with optional filtering. #' #' @param input Optional character vector of dataset titles or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with columns: #' - `dataset` (character): dataset title #' - `id` (numeric): dataset ID @@ -102,22 +110,19 @@ convert_keywords_to_id <- function(name) { #' get_datasets(10) #' } #' -get_datasets <- function(input = NULL) { +get_datasets <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + if (is.null(api_key)) api_key <- get_api_key() req <- api_request( method = "GET", endpoint = "/api/v1/datasets", - api_key = get_api_key(), + api_key = api_key, + use_dev = use_dev, object_label = "Dataset" ) df <- purrr::map_df(req$items, function(x) { - tibble::tibble( - dataset = x$title, - id = x$id - ) + tibble::tibble(dataset = x$title, id = x$id) }) - if (!is.null(input)) { - df <- converter(df, input, internal = FALSE) - } + if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } @@ -126,6 +131,8 @@ get_datasets <- function(input = NULL) { #' Retrieves a tibble of all zh-web-catalog entries and their IDs. Optionally filters by label or ID. #' #' @param input Optional character vector of catalog labels or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with two columns: #' - `zh_web_catalog` (character): the catalog label #' - `id` (numeric): the catalog ID @@ -141,17 +148,19 @@ get_datasets <- function(input = NULL) { #' get_zh_web_catalog(13) #' } #' @export -get_zh_web_catalog <- function(input = NULL) { - df <- req_to_df("zh-web-datacatalogs") +get_zh_web_catalog <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("zh-web-datacatalogs", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert zh-web-catalog names to IDs #' @keywords keywords internal -convert_zh_web_catalog_to_id <- function(name) { +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV +convert_zh_web_catalog_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_zh_web_catalog() + df <- get_zh_web_catalog(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } @@ -160,6 +169,8 @@ convert_zh_web_catalog_to_id <- function(name) { #' Retrieves a tibble of all themes and their IDs. Optionally filters by name or ID. #' #' @param input Optional character vector of theme names or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with two columns: #' - `theme` (character): the theme label #' - `id` (numeric): the theme ID @@ -175,17 +186,19 @@ convert_zh_web_catalog_to_id <- function(name) { #' get_themes(41) #' } #' @export -get_themes <- function(input = NULL) { - df <- req_to_df("themes") +get_themes <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("themes", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert theme names to IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords keywords internal -convert_themes_to_id <- function(name) { +convert_themes_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_themes() + df <- get_themes(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } @@ -194,6 +207,8 @@ convert_themes_to_id <- function(name) { #' Retrieves a tibble of all periodicities and their IDs. Optionally filters by name or ID. #' #' @param input Optional character vector of periodicity names or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with two columns: #' - `periodicity` (character): the periodicity label #' - `id` (numeric): the periodicity ID @@ -209,17 +224,19 @@ convert_themes_to_id <- function(name) { #' get_periodicities(42) #' } #' @export -get_periodicities <- function(input = NULL) { - df <- req_to_df("periodicities") +get_periodicities <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("periodicities", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert periodicity names to IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -convert_periodicities_to_id <- function(name) { +convert_periodicities_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_periodicities() + df <- get_periodicities(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } @@ -229,6 +246,8 @@ convert_periodicities_to_id <- function(name) { #' Retrieves a tibble of all statuses and their IDs. Optionally filters by name or ID. #' #' @param input Optional character vector of status names or numeric IDs. +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @return A tibble with two columns: #' - `status` (character): the status label #' - `id` (numeric): the status ID @@ -244,68 +263,68 @@ convert_periodicities_to_id <- function(name) { #' get_statuses(3) #' } #' @export -get_statuses <- function(input = NULL) { - df <- req_to_df("statuses") +get_statuses <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("statuses", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert status names to IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -convert_statuses_to_id <- function(name) { +convert_statuses_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_statuses() + df <- get_statuses(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } #' Get All Licenses and Their IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -get_licenses <- function(input = NULL) { - df <- req_to_df("licenses") +get_licenses <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("licenses", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert license names to IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -convert_licenses_to_id <- function(name) { +convert_licenses_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_licenses() + df <- get_licenses(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } #' Get All Formats and Their IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -get_formats <- function(input = NULL) { - df <- req_to_df("file-formats") +get_formats <- function(input = NULL, use_dev = FALSE, api_key = NULL) { + df <- req_to_df("file-formats", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) df } #' Convert format names to IDs +#' @param use_dev boolean FALSE = developemtent version of MDV +#' @param api_key optional API key for MDV #' @keywords internal -convert_formats_to_id <- function(name) { +convert_formats_to_id <- function(name, use_dev = FALSE, api_key = NULL) { if (inherits(name, "S7_missing")) return(S7::class_missing) - df <- get_formats() + df <- get_formats(use_dev = use_dev, api_key = api_key) get_id(df, name, internal = TRUE) } #' Retrieve a Data Frame from API Endpoint -#' -#' Generic helper to fetch entries with labels and ids. -#' #' @param endpoint One of: "keywords", "themes", etc. -#' @return A tibble with columns `` and `id`. +#' @param use_dev Logical; if TRUE, use the dev API base URL (default FALSE). +#' @param api_key Optional API key; falls back to get_api_key(). #' @keywords internal -#' Retrieve a Data Frame from API Endpoint -#' -#' Generic helper to fetch entries with labels and ids. -#' -#' @param endpoint One of: "keywords", "themes", etc. -#' @return A tibble with columns `` and `id`. -#' @keywords internal -req_to_df <- function(endpoint) { - +req_to_df <- function(endpoint, use_dev = FALSE, api_key = NULL) { label <- switch( endpoint, "keywords" = "Keyword", @@ -317,12 +336,18 @@ req_to_df <- function(endpoint) { "file-formats" = "FileFormat", stop("Unknown endpoint: ", endpoint) ) + + if (is.null(api_key)) { + api_key <- get_api_key() + } req <- api_request( method = "GET", endpoint = paste0("/api/v1/", endpoint), - api_key = get_api_key(), + api_key = api_key, + use_dev = use_dev, object_label = label ) + purrr::map_df(req, function(x) { tibble::tibble( !!endpoint := x$label, diff --git a/R/update_dataset.R b/R/update_dataset.R index 68405f5..4718221 100644 --- a/R/update_dataset.R +++ b/R/update_dataset.R @@ -67,11 +67,11 @@ update_dataset <- function( } # resolve all lookups up front - keyword_ids_api <- if (is.character(keyword_ids)) convert_keywords_to_id(keyword_ids) else keyword_ids - zh_web_catalog_ids_api <- if (is.character(zh_web_datacatalog_ids)) convert_zh_web_catalog_to_id(zh_web_datacatalog_ids) else zh_web_datacatalog_ids - theme_ids_api <- if (is.character(theme_ids)) convert_themes_to_id(theme_ids) else theme_ids - periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id) else periodicity_id - see_also_ids_api <- if (is.character(see_also_ids)) convert_datasets_to_id(see_also_ids) else see_also_ids + keyword_ids_api <- if (is.character(keyword_ids)) convert_keywords_to_id(keyword_ids, use_dev = use_dev, api_key = api_key) else keyword_ids + zh_web_catalog_ids_api <- if (is.character(zh_web_datacatalog_ids)) convert_zh_web_catalog_to_id(zh_web_datacatalog_ids, use_dev = use_dev, api_key = api_key) else zh_web_datacatalog_ids + theme_ids_api <- if (is.character(theme_ids)) convert_themes_to_id(theme_ids, use_dev = use_dev, api_key = api_key) else theme_ids + periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id, use_dev = use_dev, api_key = api_key) else periodicity_id + see_also_ids_api <- if (is.character(see_also_ids)) convert_datasets_to_id(see_also_ids, use_dev = use_dev, api_key = api_key) else see_also_ids # Build pure Dataset (no API calls here) with numeric IDs ds <- Dataset( diff --git a/R/update_distribution.R b/R/update_distribution.R index e62b8d4..ebb7878 100644 --- a/R/update_distribution.R +++ b/R/update_distribution.R @@ -76,10 +76,10 @@ update_distribution <- function( file_upload_id <- NULL } - status_id_api <- if (is.character(status_id)) convert_statuses_to_id(status_id) else status_id - license_id_api <- if (is.character(license_id)) convert_licenses_to_id(license_id) else license_id - file_format_id_api <- if (is.character(file_format_id)) convert_formats_to_id(file_format_id) else file_format_id - periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id) else periodicity_id + status_id_api <- if (is.character(status_id)) convert_statuses_to_id(status_id, use_dev = use_dev, api_key = api_key) else status_id + license_id_api <- if (is.character(license_id)) convert_licenses_to_id(license_id, use_dev = use_dev, api_key = api_key) else license_id + file_format_id_api <- if (is.character(file_format_id)) convert_formats_to_id(file_format_id, use_dev = use_dev, api_key = api_key) else file_format_id + periodicity_id_api <- if (is.character(periodicity_id)) convert_periodicities_to_id(periodicity_id, use_dev = use_dev, api_key = api_key) else periodicity_id # Create the Distribution object from arguments From efbc9bae93ef2011fcaef694f2c6ae90261b73b3 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:20:15 +0000 Subject: [PATCH 03/13] docu: auto generated roxygen docu --- man/convert_formats_to_id.Rd | 7 ++++++- man/convert_keywords_to_id.Rd | 6 +++++- man/convert_licenses_to_id.Rd | 7 ++++++- man/convert_periodicities_to_id.Rd | 7 ++++++- man/convert_statuses_to_id.Rd | 7 ++++++- man/convert_themes_to_id.Rd | 7 ++++++- man/convert_zh_web_catalog_to_id.Rd | 7 ++++++- man/get_api_key.Rd | 2 +- man/get_datasets.Rd | 6 +++++- man/get_formats.Rd | 7 ++++++- man/get_keywords.Rd | 6 +++++- man/get_licenses.Rd | 7 ++++++- man/get_organisations.Rd | 10 +++++++++- man/get_periodicities.Rd | 6 +++++- man/get_statuses.Rd | 6 +++++- man/get_themes.Rd | 6 +++++- man/get_zh_web_catalog.Rd | 6 +++++- man/req_to_df.Rd | 28 +++++----------------------- 18 files changed, 98 insertions(+), 40 deletions(-) diff --git a/man/convert_formats_to_id.Rd b/man/convert_formats_to_id.Rd index ef23728..ae29af0 100644 --- a/man/convert_formats_to_id.Rd +++ b/man/convert_formats_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_formats_to_id} \title{Convert format names to IDs} \usage{ -convert_formats_to_id(name) +convert_formats_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert format names to IDs diff --git a/man/convert_keywords_to_id.Rd b/man/convert_keywords_to_id.Rd index a4d08e9..baa6aea 100644 --- a/man/convert_keywords_to_id.Rd +++ b/man/convert_keywords_to_id.Rd @@ -4,10 +4,14 @@ \alias{convert_keywords_to_id} \title{Convert keyword names to IDs} \usage{ -convert_keywords_to_id(name) +convert_keywords_to_id(name, use_dev = FALSE, api_key = NULL) } \arguments{ \item{name}{Character vector of keyword names.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ Numeric vector of IDs. diff --git a/man/convert_licenses_to_id.Rd b/man/convert_licenses_to_id.Rd index 1bedbd3..69209f9 100644 --- a/man/convert_licenses_to_id.Rd +++ b/man/convert_licenses_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_licenses_to_id} \title{Convert license names to IDs} \usage{ -convert_licenses_to_id(name) +convert_licenses_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert license names to IDs diff --git a/man/convert_periodicities_to_id.Rd b/man/convert_periodicities_to_id.Rd index daa7582..0c83fed 100644 --- a/man/convert_periodicities_to_id.Rd +++ b/man/convert_periodicities_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_periodicities_to_id} \title{Convert periodicity names to IDs} \usage{ -convert_periodicities_to_id(name) +convert_periodicities_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert periodicity names to IDs diff --git a/man/convert_statuses_to_id.Rd b/man/convert_statuses_to_id.Rd index 43a59b4..d3f3569 100644 --- a/man/convert_statuses_to_id.Rd +++ b/man/convert_statuses_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_statuses_to_id} \title{Convert status names to IDs} \usage{ -convert_statuses_to_id(name) +convert_statuses_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert status names to IDs diff --git a/man/convert_themes_to_id.Rd b/man/convert_themes_to_id.Rd index e0ce000..1673b6d 100644 --- a/man/convert_themes_to_id.Rd +++ b/man/convert_themes_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_themes_to_id} \title{Convert theme names to IDs} \usage{ -convert_themes_to_id(name) +convert_themes_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert theme names to IDs diff --git a/man/convert_zh_web_catalog_to_id.Rd b/man/convert_zh_web_catalog_to_id.Rd index 1065c63..324ee09 100644 --- a/man/convert_zh_web_catalog_to_id.Rd +++ b/man/convert_zh_web_catalog_to_id.Rd @@ -4,7 +4,12 @@ \alias{convert_zh_web_catalog_to_id} \title{Convert zh-web-catalog names to IDs} \usage{ -convert_zh_web_catalog_to_id(name) +convert_zh_web_catalog_to_id(name, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Convert zh-web-catalog names to IDs diff --git a/man/get_api_key.Rd b/man/get_api_key.Rd index a26698c..faad042 100644 --- a/man/get_api_key.Rd +++ b/man/get_api_key.Rd @@ -16,7 +16,7 @@ API key string. Attempts to fetch the API key from (in order): \enumerate{ \item Provided argument -\item Environment variable \code{MDV_API_KEY} +\item Environment variable \code{ZHAPIR_API_KEY} \item Interactive prompt (RStudio or askpass) } } diff --git a/man/get_datasets.Rd b/man/get_datasets.Rd index 1be3e28..cb57549 100644 --- a/man/get_datasets.Rd +++ b/man/get_datasets.Rd @@ -4,10 +4,14 @@ \alias{get_datasets} \title{Get All Datasets and Their IDs} \usage{ -get_datasets(input = NULL) +get_datasets(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of dataset titles or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with columns: diff --git a/man/get_formats.Rd b/man/get_formats.Rd index 2e1d64e..e401cf0 100644 --- a/man/get_formats.Rd +++ b/man/get_formats.Rd @@ -4,7 +4,12 @@ \alias{get_formats} \title{Get All Formats and Their IDs} \usage{ -get_formats(input = NULL) +get_formats(input = NULL, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Get All Formats and Their IDs diff --git a/man/get_keywords.Rd b/man/get_keywords.Rd index d568c69..b980145 100644 --- a/man/get_keywords.Rd +++ b/man/get_keywords.Rd @@ -4,10 +4,14 @@ \alias{get_keywords} \title{Get All Keywords and Their IDs} \usage{ -get_keywords(input = NULL) +get_keywords(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of keyword names or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with two columns: diff --git a/man/get_licenses.Rd b/man/get_licenses.Rd index 208933b..f5751fb 100644 --- a/man/get_licenses.Rd +++ b/man/get_licenses.Rd @@ -4,7 +4,12 @@ \alias{get_licenses} \title{Get All Licenses and Their IDs} \usage{ -get_licenses(input = NULL) +get_licenses(input = NULL, use_dev = FALSE, api_key = NULL) +} +\arguments{ +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \description{ Get All Licenses and Their IDs diff --git a/man/get_organisations.Rd b/man/get_organisations.Rd index e6a3876..89089aa 100644 --- a/man/get_organisations.Rd +++ b/man/get_organisations.Rd @@ -4,10 +4,18 @@ \alias{get_organisations} \title{Get All Organisations and Their IDs} \usage{ -get_organisations(show_organisation_units = TRUE) +get_organisations( + show_organisation_units = TRUE, + use_dev = FALSE, + api_key = NULL +) } \arguments{ \item{show_organisation_units}{Logical; if TRUE, include sub-units.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with columns: diff --git a/man/get_periodicities.Rd b/man/get_periodicities.Rd index b81b6fb..bb91233 100644 --- a/man/get_periodicities.Rd +++ b/man/get_periodicities.Rd @@ -4,10 +4,14 @@ \alias{get_periodicities} \title{Get All Periodicities and Their IDs} \usage{ -get_periodicities(input = NULL) +get_periodicities(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of periodicity names or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with two columns: diff --git a/man/get_statuses.Rd b/man/get_statuses.Rd index 579cd87..e8677ae 100644 --- a/man/get_statuses.Rd +++ b/man/get_statuses.Rd @@ -4,10 +4,14 @@ \alias{get_statuses} \title{Get All Statuses and Their IDs} \usage{ -get_statuses(input = NULL) +get_statuses(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of status names or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with two columns: diff --git a/man/get_themes.Rd b/man/get_themes.Rd index 9039567..b55581f 100644 --- a/man/get_themes.Rd +++ b/man/get_themes.Rd @@ -4,10 +4,14 @@ \alias{get_themes} \title{Get All Themes and Their IDs} \usage{ -get_themes(input = NULL) +get_themes(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of theme names or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with two columns: diff --git a/man/get_zh_web_catalog.Rd b/man/get_zh_web_catalog.Rd index af63015..dc32ec4 100644 --- a/man/get_zh_web_catalog.Rd +++ b/man/get_zh_web_catalog.Rd @@ -4,10 +4,14 @@ \alias{get_zh_web_catalog} \title{Get All zh-web-catalog Keywords and Their IDs} \usage{ -get_zh_web_catalog(input = NULL) +get_zh_web_catalog(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ \item{input}{Optional character vector of catalog labels or numeric IDs.} + +\item{use_dev}{boolean FALSE = developemtent version of MDV} + +\item{api_key}{optional API key for MDV} } \value{ A tibble with two columns: diff --git a/man/req_to_df.Rd b/man/req_to_df.Rd index 528b9a5..5cd7f0d 100644 --- a/man/req_to_df.Rd +++ b/man/req_to_df.Rd @@ -4,34 +4,16 @@ \alias{req_to_df} \title{Retrieve a Data Frame from API Endpoint} \usage{ -req_to_df(endpoint) +req_to_df(endpoint, use_dev = FALSE, api_key = NULL) } \arguments{ \item{endpoint}{One of: "keywords", "themes", etc.} -} -\value{ -A tibble with columns \verb{} and \code{id}. -A tibble with columns \verb{} and \code{id}. +\item{use_dev}{Logical; if TRUE, use the dev API base URL (default FALSE).} + +\item{api_key}{Optional API key; falls back to get_api_key().} } \description{ -Generic helper to fetch \if{html}{\out{}} entries with labels and ids. +Retrieve a Data Frame from API Endpoint } -\keyword{} -\keyword{API} -\keyword{Data} -\keyword{Endpoint} -\keyword{Frame} -\keyword{Generic} -\keyword{Retrieve} -\keyword{a} -\keyword{and} -\keyword{entries} -\keyword{fetch} -\keyword{from} -\keyword{helper} -\keyword{ids.} \keyword{internal} -\keyword{labels} -\keyword{to} -\keyword{with} From 20ec9d949cc99b29e992603df731bf34c42bce51 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:20:45 +0000 Subject: [PATCH 04/13] fix: adapt test suite to handle use_dev and api_key --- tests/testthat/helper-integration.R | 22 ++--- tests/testthat/test-create_dataset.R | 4 +- tests/testthat/test-create_distribution.R | 3 - tests/testthat/test-e2e-user-flows.R | 96 ++++++++++++++-------- tests/testthat/test-integration-api.R | 18 ++-- tests/testthat/test-text_argument_parser.R | 9 +- tests/testthat/test-update_dataset.R | 28 ++++--- tests/testthat/test-utils-and-helpers.R | 10 +-- 8 files changed, 96 insertions(+), 94 deletions(-) diff --git a/tests/testthat/helper-integration.R b/tests/testthat/helper-integration.R index 4ac17db..dc9f5cd 100644 --- a/tests/testthat/helper-integration.R +++ b/tests/testthat/helper-integration.R @@ -1,21 +1,11 @@ -# Opt-in only: never run e2e unless the user explicitly asks for it. -skip_if_not_e2e <- function() { - # Hard stop on CI - testthat::skip_on_ci() +# tests/testthat/helper-integration - # Explicit opt-in switch - if (Sys.getenv("ZHAPIR_RUN_E2E") != "1") { - testthat::skip("Set ZHAPIR_RUN_E2E=1 in .Renviron file to run end-to-end integration tests (local only).") - } +skip_if_ci <- function() { + testthat::skip_on_ci() +} - # Require key +skip_if_no_dev_token <- function() { if (!nzchar(Sys.getenv("MDV_DEV_API_TOKEN_TEST"))) { - testthat::skip("ZHAPIR_API_KEY missing; cannot run end-to-end tests.") + testthat::skip("MDV_DEV_API_TOKEN_TEST missing; cannot run dev API tests.") } } - - -skip_if_no_api_key <- function() { - if (nzchar(Sys.getenv("MDV_DEV_API_TOKEN_TEST")) == FALSE) - skip("no ZHAPIR_API_KEY; skipping integration tests") -} diff --git a/tests/testthat/test-create_dataset.R b/tests/testthat/test-create_dataset.R index dcb31dc..993e7fe 100644 --- a/tests/testthat/test-create_dataset.R +++ b/tests/testthat/test-create_dataset.R @@ -6,7 +6,7 @@ test_that("dataset object is correctly created by the create_dataset function", testthat::local_mocked_bindings( - convert_themes_to_id = function(x) { + convert_themes_to_id = function(x, ...) { if (identical(x, c("Energie", "Gesundheit"))) { return(c(42, 43)) } else { @@ -47,7 +47,7 @@ test_that("an error is returned if no title is set", { ) testthat::local_mocked_bindings( - convert_themes_to_id = function(x) { + convert_themes_to_id = function(x, ...) { if (identical(x, c("Energie", "Gesundheit"))) { return(c(42, 43)) } else { diff --git a/tests/testthat/test-create_distribution.R b/tests/testthat/test-create_distribution.R index 07682f5..b2c0003 100644 --- a/tests/testthat/test-create_distribution.R +++ b/tests/testthat/test-create_distribution.R @@ -1,7 +1,4 @@ test_that("create_distribution(preview=TRUE) returns a Distribution S7 object with correct slots", { - testthat::local_mocked_bindings( - get_api_key = function(...) "DUMMY" - ) dist <- create_distribution( title = "Preview Dist", diff --git a/tests/testthat/test-e2e-user-flows.R b/tests/testthat/test-e2e-user-flows.R index 8efd16d..d4b06d1 100644 --- a/tests/testthat/test-e2e-user-flows.R +++ b/tests/testthat/test-e2e-user-flows.R @@ -1,15 +1,9 @@ -testthat::local_mocked_bindings( - get_api_key = function(key = NULL) { - tok <- base::Sys.getenv("MDV_DEV_API_TOKEN_TEST") - if (!base::nzchar(tok)) base::stop("MDV_DEV_API_TOKEN_TEST not set") - tok - }, - .package = "zhapir" -) - test_that("E2E: distribution cannot exceed dataset status", { - skip_if_not_e2e() + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") # Datensatz anlegen (bleibt im Default-Status, z. B. 'Entwurf') ds <- zhapir::create_dataset( title = paste0("E2E DS baseline ", format(Sys.time(), "%Y-%m-%d %H:%M:%S")), @@ -18,7 +12,8 @@ test_that("E2E: distribution cannot exceed dataset status", { contact_email = "team@example.org", keyword_ids = c("abfall"), theme_ids = c("Energie"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key ) ds_id <- ds$id @@ -36,7 +31,8 @@ test_that("E2E: distribution cannot exceed dataset status", { file_path = tf, license_id = 1, file_format_id = "CSV", - status_id = 2 + status_id = 2, + api_key = dev_key ), # Gruppiert, case-insensitive. Deckt alte und neue Backend-Message ab. regexp = "(?i)(Request failed \\(400\\).*(ogd_flag|zwingend erforderlich|required|Status der Distribution darf nicht .* gesetzt werden als ihr Datensatz))" @@ -46,7 +42,10 @@ test_that("E2E: distribution cannot exceed dataset status", { # test if with ogd flag the status change is allowed test_that("E2E: status change succeeds after setting ogd_flag", { - skip_if_not_e2e() + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") ds <- create_dataset( title = paste0("E2E DS with OGD ", format(Sys.time(), "%Y-%m-%d %H:%M:%S")), @@ -55,7 +54,8 @@ test_that("E2E: status change succeeds after setting ogd_flag", { contact_email = "team@example.org", keyword_ids = c("abfall"), theme_ids = c("Energie"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key ) ds_id <- ds$id @@ -69,14 +69,16 @@ test_that("E2E: status change succeeds after setting ogd_flag", { file_path = tf, license_id = 1, file_format_id = "CSV", - status_id = 1 + status_id = 1, + api_key = dev_key ) # Make the distribution eligible (set ogd_flag) res_upd <- update_distribution( id = dist$id, dataset_id = ds_id, - ogd_flag = TRUE + ogd_flag = TRUE, + api_key = dev_key ) expect_true(is.list(res_upd)) }) @@ -84,8 +86,11 @@ test_that("E2E: status change succeeds after setting ogd_flag", { # tests update + bump end_date test_that("E2E: update distribution, bump dataset end_date, and advance status with ogd_flag", { - skip_if_not_e2e() + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") ds <- create_dataset( title = paste0("E2E DS for Update ", format(Sys.time(), "%H:%M:%S")), organisation_id = 14, @@ -93,7 +98,8 @@ test_that("E2E: update distribution, bump dataset end_date, and advance status w contact_email = "update-test@example.org", keyword_ids = c("agglomeration"), theme_ids = c("Bevölkerung und Gesellschaft"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key ) ds_id <- ds$id @@ -107,6 +113,7 @@ test_that("E2E: update distribution, bump dataset end_date, and advance status w file_path = tf, license_id = 2, file_format_id = "CSV", + api_key = dev_key ) dist_id <- dist$id expect_true(dist_id > 0) @@ -117,7 +124,8 @@ test_that("E2E: update distribution, bump dataset end_date, and advance status w dataset_id = ds_id, description = "Updated description", end_date = format(Sys.Date(), "%Y-%m-%d"), - ogd_flag = TRUE + ogd_flag = TRUE, + api_key = dev_key ) expect_true(is.list(res_upd)) }) @@ -127,9 +135,10 @@ test_that("E2E: update distribution, bump dataset end_date, and advance status w test_that("E2E: dataset ohne start_date ist nicht valid für nächsten Status", { - skip_if_not_e2e() - + skip_if_ci() + skip_if_no_dev_token() + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") # Minimaler Datensatz OHNE start_date (bewusst invalid für Publish) ds <- create_dataset( title = paste0("E2E DS missing start_date ", format(Sys.time(), "%Y-%m-%d %H:%M:%S")), @@ -138,7 +147,8 @@ test_that("E2E: dataset ohne start_date ist nicht valid für nächsten Status", contact_email = "team@example.org", keyword_ids = c("abfall"), theme_ids = c("Energie"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key # start_date absichtlich weggelassen ) ds_id <- ds$id @@ -153,7 +163,8 @@ test_that("E2E: dataset ohne start_date ist nicht valid für nächsten Status", id = ds_id, use_dev = TRUE, verbosity = 0, - fail_on_invalid = FALSE + fail_on_invalid = FALSE, + api_key = dev_key ) }, regexp = "nicht valid", # German snippet is stable enough @@ -167,8 +178,11 @@ test_that("E2E: dataset ohne start_date ist nicht valid für nächsten Status", test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer gültigen Distribution", { - skip_if_not_e2e() + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") # Create dataset WITH start_date ds <- create_dataset( title = paste0("E2E DS valid path ", format(Sys.time(), "%Y-%m-%d %H:%M:%S")), @@ -178,7 +192,8 @@ test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer start_date = format(Sys.Date() - 365, "%Y-%m-%d"), keyword_ids = c("abfall"), theme_ids = c("Energie"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key ) ds_id <- ds$id expect_true(ds_id > 0) @@ -195,7 +210,8 @@ test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer file_path = tf, license_id = 1, file_format_id = "CSV", - status_id = 1 + status_id = 1, + api_key = dev_key ) expect_true(is.list(dist)) expect_true(dist$id > 0) @@ -207,7 +223,8 @@ test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer id = ds_id, use_dev = TRUE, verbosity = 0, - fail_on_invalid = FALSE + fail_on_invalid = FALSE, + api_key = dev_key ) }, regexp = "ist .*valid", @@ -220,7 +237,8 @@ test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer id = ds_id, use_dev = TRUE, verbosity = 0, - fail_on_invalid = FALSE + fail_on_invalid = FALSE, + api_key = dev_key ) ) expect_false(grepl("nicht valid", msg_ok, perl = TRUE)) @@ -228,8 +246,11 @@ test_that("E2E: dataset wird valid nach Setzen von start_date und Anlegen einer test_that("E2E: update_dataset setzt start_date nachträglich; mit Distribution wird Dataset valid", { - skip_if_not_e2e() + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") # Start invalid (no start_date) ds <- create_dataset( title = paste0("E2E DS to fix via update ", format(Sys.time(), "%Y-%m-%d %H:%M:%S")), @@ -238,7 +259,8 @@ test_that("E2E: update_dataset setzt start_date nachträglich; mit Distribution contact_email = "team@example.org", keyword_ids = c("abfall"), theme_ids = c("Energie"), - periodicity_id = "Jährlich" + periodicity_id = "Jährlich", + api_key = dev_key # start_date intentionally omitted ) ds_id <- ds$id @@ -247,7 +269,8 @@ test_that("E2E: update_dataset setzt start_date nachträglich; mit Distribution # Fix: set start_date upd <- update_dataset( id = ds_id, - start_date = format(Sys.Date() - 30, "%Y-%m-%d") + start_date = format(Sys.Date() - 30, "%Y-%m-%d"), + api_key = dev_key ) expect_true(is.list(upd)) @@ -262,7 +285,8 @@ test_that("E2E: update_dataset setzt start_date nachträglich; mit Distribution file_path = tf, license_id = 1, file_format_id = "CSV", - status_id = 1 + status_id = 1, + api_key = dev_key ) expect_true(is.list(dist)) expect_true(dist$id > 0) @@ -274,11 +298,11 @@ test_that("E2E: update_dataset setzt start_date nachträglich; mit Distribution id = ds_id, use_dev = TRUE, verbosity = 0, - fail_on_invalid = FALSE + fail_on_invalid = FALSE, + api_key = dev_key ) }, - regexp = "ist .*valid", - perl = TRUE - ) + regexp = "ist .*valid" + ) expect_true(isTRUE(resp_ok2$is_valid)) }) diff --git a/tests/testthat/test-integration-api.R b/tests/testthat/test-integration-api.R index 64ae450..b44c2a3 100644 --- a/tests/testthat/test-integration-api.R +++ b/tests/testthat/test-integration-api.R @@ -1,16 +1,12 @@ -testthat::local_mocked_bindings( - get_api_key = function(key = NULL) { - tok <- base::Sys.getenv("MDV_DEV_API_TOKEN_TEST") - if (!base::nzchar(tok)) base::stop("MDV_DEV_API_TOKEN_TEST not set") - tok - }, - .package = "zhapir" -) - test_that("convert_keywords_to_id actually finds known keywords", { - skip_if_not_e2e() + + skip_if_ci() + skip_if_no_dev_token() + + dev_key <- Sys.getenv("MDV_DEV_API_TOKEN_TEST") + # This will do a real GET /keywords - ids <- convert_keywords_to_id(c("abfall", "volksschule")) + ids <- convert_keywords_to_id(c("abfall", "volksschule"), use_dev = TRUE, api_key = dev_key) expect_type(ids, "double") expect_true(all(ids > 0)) }) diff --git a/tests/testthat/test-text_argument_parser.R b/tests/testthat/test-text_argument_parser.R index 5272480..5b26885 100644 --- a/tests/testthat/test-text_argument_parser.R +++ b/tests/testthat/test-text_argument_parser.R @@ -34,10 +34,9 @@ testthat::test_that("req_to_df builds correct tibbles and errors on unknown endp ) ) - mock_api_request <- function(method, endpoint, api_key, object_label) { + mock_api_request <- function(method, endpoint, ...) { # endpoints look like "/api/v1/" ep <- sub("^/api/v1/", "", endpoint) - # special for datasets and organisations (tested later), otherwise return list if (!is.null(fake_db[[ep]])) { return(fake_db[[ep]]) } @@ -183,7 +182,7 @@ testthat::test_that("get_organisations returns base and units correctly", { ) ) - mock_api_request <- function(method, endpoint, api_key, object_label) { + mock_api_request <- function(method, endpoint, ...) { ep <- sub("^/api/v1/", "", endpoint) if (ep == "organisations") return(org_payload) stop("Unexpected endpoint in mock: ", ep) @@ -243,7 +242,7 @@ testthat::test_that("req_to_df-backed getters and converters behave (with datase ) ) - mock_api_request <- function(method, endpoint, api_key, object_label) { + mock_api_request <- function(method, endpoint, ...) { ep <- sub("^/api/v1/", "", endpoint) if (ep == "datasets") return(fake_db[["datasets"]]) if (!is.null(fake_db[[ep]])) return(fake_db[[ep]]) @@ -262,7 +261,7 @@ testthat::test_that("req_to_df-backed getters and converters behave (with datase testthat::expect_identical(unname(m["fun_name"]), "get_datasets()") # keywords (passthrough) - all_kw <- zhapir::get_keywords() + all_kw <- zhapir::get_keywords(use_dev = TRUE) testthat::expect_identical(names(all_kw), c("keywords", "id")) testthat::expect_identical(nrow(all_kw), 3L) diff --git a/tests/testthat/test-update_dataset.R b/tests/testthat/test-update_dataset.R index 8329832..6b80105 100644 --- a/tests/testthat/test-update_dataset.R +++ b/tests/testthat/test-update_dataset.R @@ -2,7 +2,6 @@ test_that("update_dataset(preview=TRUE) preserves existing organisation_id and t calls <- list() testthat::local_mocked_bindings( - get_api_key = function(...) "DUMMY", get_dataset = function(id, api_key, use_dev) { calls$fetch <<- TRUE list( @@ -12,23 +11,23 @@ test_that("update_dataset(preview=TRUE) preserves existing organisation_id and t ) }, # Avoid accidental conversions that could hit the network - convert_keywords_to_id = function(x) x, - convert_zh_web_catalog_to_id = function(x) x, - convert_themes_to_id = function(x) x, - convert_periodicities_to_id = function(x) x, + convert_keywords_to_id = function(x, ...) x, + convert_zh_web_catalog_to_id = function(x, ...) x, + convert_themes_to_id = function(x, ...) x, + convert_periodicities_to_id = function(x, ...) x, .env = asNamespace("zhapir") ) ds <- update_dataset( id = 999L, - # intentionally omit title and organisation_id to trigger fetch description = "New description", theme_ids = c(41L, 42L), - preview = TRUE + preview = TRUE, + api_key = "DUMMY" # <--- hier der Trick ) - expect_true(isTRUE(calls$fetch)) # fetch happened - expect_true(inherits(ds, "zhapir::Dataset")) # S7 class check + expect_true(isTRUE(calls$fetch)) # fetch happened + expect_true(inherits(ds, "zhapir::Dataset")) # S7 class check expect_equal(ds@id, 999L) expect_equal(ds@title, "Existing Title") expect_equal(ds@organisation_id, 55L) @@ -40,8 +39,10 @@ test_that("update_dataset(preview=TRUE) uses provided title/org if supplied (no calls <- list(fetch = FALSE) testthat::local_mocked_bindings( - get_api_key = function(...) "DUMMY", - get_dataset = function(...) { calls$fetch <<- TRUE; stop("should not be called") }, + get_dataset = function(...) { + calls$fetch <<- TRUE + stop("get_dataset should NOT be called") + }, .env = asNamespace("zhapir") ) @@ -50,10 +51,11 @@ test_that("update_dataset(preview=TRUE) uses provided title/org if supplied (no title = "New Title", organisation_id = 77L, description = "Keep as provided", - preview = TRUE + preview = TRUE, + api_key = "DUMMY" # <--- wieder explizit ) - expect_false(isTRUE(calls$fetch)) # shouldn't have fetched + expect_false(isTRUE(calls$fetch)) # shouldn't have fetched expect_true(inherits(ds, "zhapir::Dataset")) expect_equal(ds@id, 1001L) expect_equal(ds@title, "New Title") diff --git a/tests/testthat/test-utils-and-helpers.R b/tests/testthat/test-utils-and-helpers.R index c7e6547..0e41057 100644 --- a/tests/testthat/test-utils-and-helpers.R +++ b/tests/testthat/test-utils-and-helpers.R @@ -1,38 +1,32 @@ + test_that("get_base_url returns correct endpoints", { expect_equal(get_base_url(TRUE), "https://dev.mdv.statistik.zh.ch") expect_equal(get_base_url(FALSE), "https://mdv.statistik.zh.ch") }) test_that("get_api_key uses explicit argument over env var", { - skip_if_not_e2e() withr::local_envvar(c(ZHAPIR_API_KEY = "FROM_ENV")) expect_equal(get_api_key("FROM_ARG"), "FROM_ARG") }) test_that("get_api_key falls back to env var", { - skip_if_not_e2e() withr::local_envvar(c(ZHAPIR_API_KEY = "FROM_ENV")) expect_equal(get_api_key(NULL), "FROM_ENV") }) test_that("get_api_key errors when neither arg nor env nor prompt are available", { - skip_if_not_e2e() withr::local_envvar(c(ZHAPIR_API_KEY = "")) expect_error( get_api_key(NULL), - "No API key found\\. Supply via argument or set ZHAPIR_API_KEY environment variable\\.", - fixed = FALSE + "No API key found\\. Supply via argument or set ZHAPIR_API_KEY environment variable\\." ) }) test_that("object_to_payload formats dates and drops empty fields", { - testthat::local_mocked_bindings( - get_api_key = function(...) "DUMMY" - ) # Build a Dataset with a mix of values ds <- Dataset( From ff0dc7630f924bc60da0406593972c550b980abb Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:26:36 +0000 Subject: [PATCH 05/13] docu: change note rendering --- README.Rmd | 3 ++- README.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index 35802dd..4e3cd51 100644 --- a/README.Rmd +++ b/README.Rmd @@ -74,7 +74,8 @@ ds <- zhapir::create_dataset( ) ``` -> [!NOTE] Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der PROD API-Key angezogen wird. +> [!NOTE] +> Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der PROD API-Key angezogen wird. ## ✨ Beispiele diff --git a/README.md b/README.md index 06c9a97..451e4ed 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ ds <- zhapir::create_dataset( ) ``` -> \[!NOTE\] Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll +> [!NOTE] +> Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll > (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der > DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen > wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem From f3a5eba0be5e46d073fd767d610a9ca0b63df247 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:28:52 +0000 Subject: [PATCH 06/13] docu: small note fix --- README.Rmd | 2 +- README.md | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.Rmd b/README.Rmd index 4e3cd51..94f2e8a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -75,7 +75,7 @@ ds <- zhapir::create_dataset( ``` > [!NOTE] -> Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der PROD API-Key angezogen wird. +> Wenn mit der DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = TRUE` und der PROD API-Key angezogen wird. ## ✨ Beispiele diff --git a/README.md b/README.md index 451e4ed..19a65c5 100644 --- a/README.md +++ b/README.md @@ -71,14 +71,13 @@ ds <- zhapir::create_dataset( ) ``` -> [!NOTE] -> Wenn mit dem DEV-Umgebung des MDV gearbeitet werden soll -> (z.B. um Änderungen zu an Dataset/Distribution zu testen), muss der +> [!NOTE] Wenn mit der DEV-Umgebung des MDV gearbeitet werden soll +> (z.B. um Änderungen an Dataset/Distribution zu testen), muss der > DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen > wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem > `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die > Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche -> API-Keys. Dies führt zu einem Fehler, wenn `use_dev = FALSE` und der +> API-Keys. Dies führt zu einem Fehler, wenn `use_dev = TRUE` und der > PROD API-Key angezogen wird. ## ✨ Beispiele From aeca6ca6555bd24a09d929204d88bad57e73321b Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 08:30:14 +0000 Subject: [PATCH 07/13] docu: new line --- README.Rmd | 3 ++- README.md | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.Rmd b/README.Rmd index 94f2e8a..7739791 100644 --- a/README.Rmd +++ b/README.Rmd @@ -74,7 +74,8 @@ ds <- zhapir::create_dataset( ) ``` -> [!NOTE] +> [!NOTE] + > Wenn mit der DEV-Umgebung des MDV gearbeitet werden soll (z.B. um Änderungen an Dataset/Distribution zu testen), muss der DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche API-Keys. Dies führt zu einem Fehler, wenn `use_dev = TRUE` und der PROD API-Key angezogen wird. ## ✨ Beispiele diff --git a/README.md b/README.md index 19a65c5..dc456c6 100644 --- a/README.md +++ b/README.md @@ -71,10 +71,11 @@ ds <- zhapir::create_dataset( ) ``` -> [!NOTE] Wenn mit der DEV-Umgebung des MDV gearbeitet werden soll -> (z.B. um Änderungen an Dataset/Distribution zu testen), muss der -> DEV-API Key explizit mitgegeben werden. Wenn `api_key` leer gelassen -> wird, versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem +> [!NOTE] +> Wenn mit der DEV-Umgebung des MDV gearbeitet werden soll (z.B. um +> Änderungen an Dataset/Distribution zu testen), muss der DEV-API Key +> explizit mitgegeben werden. Wenn `api_key` leer gelassen wird, +> versucht die Funktion im Hintergrund `ZHAPIR_API_KEY` aus dem > `.Renviron` zu lesen. Hier empfehlen wir den API-Key für die > Produktivumgebung abzulegen. DEV und PROD haben unterschiedliche > API-Keys. Dies führt zu einem Fehler, wenn `use_dev = TRUE` und der From 7ce9d1e77a3ec1592122595c137759695a957592 Mon Sep 17 00:00:00 2001 From: philbosch Date: Fri, 14 Nov 2025 09:16:32 +0000 Subject: [PATCH 08/13] fix: adapt test to run on CI --- tests/testthat/test-create_distribution.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testthat/test-create_distribution.R b/tests/testthat/test-create_distribution.R index b2c0003..8d93ea6 100644 --- a/tests/testthat/test-create_distribution.R +++ b/tests/testthat/test-create_distribution.R @@ -1,5 +1,6 @@ test_that("create_distribution(preview=TRUE) returns a Distribution S7 object with correct slots", { + dist <- create_distribution( title = "Preview Dist", dataset_id = 42, @@ -16,6 +17,7 @@ test_that("create_distribution(preview=TRUE) returns a Distribution S7 object wi file_path = "/tmp/should/not/upload.csv", start_date = "2025-08-01", end_date = "2025-08-31", + api_key = "PREVIEW", preview = TRUE ) From 66ab7928ba58682807e2f9287946a980e824a307 Mon Sep 17 00:00:00 2001 From: philbosch Date: Tue, 18 Nov 2025 15:50:46 +0000 Subject: [PATCH 09/13] feat: export get functions --- NAMESPACE | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index fd0f0cc..33f1ce0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,7 +8,9 @@ export(create_file) export(dataset_is_valid_for_status) export(get_api_key) export(get_dataset) +export(get_formats) export(get_keywords) +export(get_licenses) export(get_organisations) export(get_periodicities) export(get_statuses) From 311791559918082347c7f6741fe67e35e919f1ae Mon Sep 17 00:00:00 2001 From: philbosch Date: Tue, 18 Nov 2025 15:51:09 +0000 Subject: [PATCH 10/13] feat: edit roxygen docu --- R/create_dataset.R | 12 ++++++++++++ R/create_distribution.R | 31 +++++++++++++++++++++++++++++++ R/generics.R | 9 --------- R/text_arguments_parser.R | 6 ++++-- R/update_dataset.R | 12 ++++++++++++ R/update_distribution.R | 31 +++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/R/create_dataset.R b/R/create_dataset.R index deda0e7..ade321b 100644 --- a/R/create_dataset.R +++ b/R/create_dataset.R @@ -13,6 +13,18 @@ #' @param relation_ids Optional integer vector #' @param theme_ids Optional character vector #' @param periodicity_id Optional character +#' `1` = "Jährlich", +#' `21` = "Kontinuierlich", +#' `42` = "Zweijährlich", +#' `43` = "Halbjährlich", +#' `45` = "Vierteljährlich", +#' `47` = "Monatlich", +#' `49` = "Alle zwei Wochen", +#' `51` = "Wöchentlich", +#' `52` = "Halbwöchentlich", +#' `54` = "Täglich", +#' `55` = "Unregelmässig", +#' `56` = "Niemals" #' @param see_also_ids Optional integer vector #' @param api_key API key (optional; falls back to env var) #' @param use_dev Logical; use development base URL diff --git a/R/create_distribution.R b/R/create_distribution.R index 31c11e4..fd43d94 100644 --- a/R/create_distribution.R +++ b/R/create_distribution.R @@ -9,10 +9,41 @@ #' @param access_url Optional URL to access the distribution (must start with http:// or https://). #' @param byte_size Optional file size in bytes (must be a positive number). #' @param status_id Optional character; status ID (will be set via follow-up PATCH). +#' `0` = "verworfen, +#' `1` = "✍️ Entwurf ", +#' `2` = "🔍 in Prüfung", +#' `3` = "📜 publiziert", #' @param license_id integer; license ID. #' Use `1` = "CC BY 4.0 (Attribution required)" or `2` = "CC0 (No attribution required)". #' @param file_format_id Optional file format ID. +#' Häufige Formate: +#' `3` = "CSV" +#' `20` = "PDF" +#' `33` = "XLSX" +#' `12` = "JSON" +#' `29` = "TXT" +#' `34` = "XML" +#' `32` = "XLS" +#' `35` = "ZIP" +#' `8` = "HTML" +#' `13` = "JSONLD" +#' `5` = "DOCX" +#' `40` = "GPKG" +#' `11` = "JS" +#' `25` = "RTF" #' @param periodicity_id Optional character periodicity ID. +#' `1` = "Jährlich", +#' `21` = "Kontinuierlich", +#' `42` = "Zweijährlich", +#' `43` = "Halbjährlich", +#' `45` = "Vierteljährlich", +#' `47` = "Monatlich", +#' `49` = "Alle zwei Wochen", +#' `51` = "Wöchentlich", +#' `52` = "Halbwöchentlich", +#' `54` = "Täglich", +#' `55` = "Unregelmässig", +#' `56` = "Niemals" #' @param file_path Optional local file path; if provided, the file will be uploaded and linked. #' @param start_date POSIXct or ISO datetime string; new start (optional) #' @param end_date POSIXct or ISO datetime string; new end (optional) diff --git a/R/generics.R b/R/generics.R index df7ad26..7409b15 100644 --- a/R/generics.R +++ b/R/generics.R @@ -4,8 +4,6 @@ #' Generic method to create a new object in the data catalog via the API. #' #' @param object The object to create (Dataset or Distribution) -#' @param api_key Authentication information from login_to_api() -#' @param use_dev Whether to use the development environment #' #' @return The created object with updated information from the API response #' @keywords internal @@ -19,9 +17,6 @@ create <- S7::new_generic("create", "object") #' Generic method to update an existing object in the data catalog via the API. #' #' @param object The object to update -#' @param id ID of the object to update -#' @param api_key Authentication information from login_to_api() -#' @param use_dev Whether to use the development environment #' #' @return The updated object with updated information from the API response #' @keywords internal @@ -31,10 +26,6 @@ update <- S7::new_generic("update", "object") #' Set the status of a Dataset or Distribution via the "/set-status" endpoint #' #' @param object A `Dataset` or `Distribution` S7 object with `@id` and `@status_id` set -#' @param api_key API key string for authentication (optional) -#' @param use_dev Logical; use the development API endpoint (default `TRUE`) -#' @param verbosity Integer; httr2 verbosity level (default `0`) -#' #' @return Invisibly returns parsed response as a list. #' @keywords internal set_status <- S7::new_generic("set_status", "object") diff --git a/R/text_arguments_parser.R b/R/text_arguments_parser.R index f102cf7..be8079a 100644 --- a/R/text_arguments_parser.R +++ b/R/text_arguments_parser.R @@ -280,9 +280,10 @@ convert_statuses_to_id <- function(name, use_dev = FALSE, api_key = NULL) { } #' Get All Licenses and Their IDs +#' @param input a set of licenses to retrieve. Empty = all #' @param use_dev boolean FALSE = developemtent version of MDV #' @param api_key optional API key for MDV -#' @keywords internal +#' @export get_licenses <- function(input = NULL, use_dev = FALSE, api_key = NULL) { df <- req_to_df("licenses", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) @@ -300,9 +301,10 @@ convert_licenses_to_id <- function(name, use_dev = FALSE, api_key = NULL) { } #' Get All Formats and Their IDs +#' @param input a set of formats to retrieve. Empty = all #' @param use_dev boolean FALSE = developemtent version of MDV #' @param api_key optional API key for MDV -#' @keywords internal +#' @export get_formats <- function(input = NULL, use_dev = FALSE, api_key = NULL) { df <- req_to_df("file-formats", use_dev = use_dev, api_key = api_key) if (!is.null(input)) df <- converter(df, input, internal = FALSE) diff --git a/R/update_dataset.R b/R/update_dataset.R index 4718221..ae6c4b5 100644 --- a/R/update_dataset.R +++ b/R/update_dataset.R @@ -18,6 +18,18 @@ #' @param relation_ids integer vector; new relation IDs (optional) #' @param theme_ids integer vector; new theme IDs (optional) #' @param periodicity_id numeric; new periodicity ID (optional) +#' `1` = "Jährlich", +#' `21` = "Kontinuierlich", +#' `42` = "Zweijährlich", +#' `43` = "Halbjährlich", +#' `45` = "Vierteljährlich", +#' `47` = "Monatlich", +#' `49` = "Alle zwei Wochen", +#' `51` = "Wöchentlich", +#' `52` = "Halbwöchentlich", +#' `54` = "Täglich", +#' `55` = "Unregelmässig", +#' `56` = "Niemals" #' @param see_also_ids integer vector; new see-also IDs (optional) #' @param api_key API key (optional; falls back to env var) #' @param use_dev Logical; use development base URL (default TRUE) diff --git a/R/update_distribution.R b/R/update_distribution.R index ebb7878..2bce8a7 100644 --- a/R/update_distribution.R +++ b/R/update_distribution.R @@ -10,10 +10,41 @@ #' @param access_url Optional URL to access the distribution (must start with http:// or https://). #' @param byte_size Optional file size in bytes (must be a positive number). #' @param status_id Optional status ID (applied via PATCH after update). +#' `0` = "verworfen, +#' `1` = "✍️ Entwurf ", +#' `2` = "🔍 in Prüfung", +#' `3` = "📜 publiziert", #' @param license_id Optional license ID. #' Use `1` = "CC BY 4.0 (Attribution required)" or `2` = "CC0 (No attribution required)". #' @param file_format_id Optional file format ID. +#' Häufige Formate: +#' `3` = "CSV" +#' `20` = "PDF" +#' `33` = "XLSX" +#' `12` = "JSON" +#' `29` = "TXT" +#' `34` = "XML" +#' `32` = "XLS" +#' `35` = "ZIP" +#' `8` = "HTML" +#' `13` = "JSONLD" +#' `5` = "DOCX" +#' `40` = "GPKG" +#' `11` = "JS" +#' `25` = "RTF" #' @param periodicity_id Optional update frequency ID. +#' `1` = "Jährlich", +#' `21` = "Kontinuierlich", +#' `42` = "Zweijährlich", +#' `43` = "Halbjährlich", +#' `45` = "Vierteljährlich", +#' `47` = "Monatlich", +#' `49` = "Alle zwei Wochen", +#' `51` = "Wöchentlich", +#' `52` = "Halbwöchentlich", +#' `54` = "Täglich", +#' `55` = "Unregelmässig", +#' `56` = "Niemals" #' @param file_path Optional local file path; if provided, the file will be uploaded and linked. #' @param start_date POSIXct or ISO datetime string; new start of Dataset(optional) #' @param end_date POSIXct or ISO datetime string; new end of Dataset (optional) From a09d60650268a308d2c09cac531a1eca63f9b531 Mon Sep 17 00:00:00 2001 From: philbosch Date: Tue, 18 Nov 2025 15:51:23 +0000 Subject: [PATCH 11/13] docu: auto-generated roxygen docu --- man/create.Rd | 4 ---- man/create_dataset.Rd | 14 +++++++++++++- man/create_distribution.Rd | 39 ++++++++++++++++++++++++++++++++++---- man/get_formats.Rd | 3 ++- man/get_licenses.Rd | 3 ++- man/set_status.Rd | 6 ------ man/update.Rd | 6 ------ man/update_dataset.Rd | 14 +++++++++++++- man/update_distribution.Rd | 37 +++++++++++++++++++++++++++++++++--- 9 files changed, 99 insertions(+), 27 deletions(-) diff --git a/man/create.Rd b/man/create.Rd index ca2696d..0dbd389 100644 --- a/man/create.Rd +++ b/man/create.Rd @@ -8,10 +8,6 @@ create(object, ...) } \arguments{ \item{object}{The object to create (Dataset or Distribution)} - -\item{api_key}{Authentication information from login_to_api()} - -\item{use_dev}{Whether to use the development environment} } \value{ The created object with updated information from the API response diff --git a/man/create_dataset.Rd b/man/create_dataset.Rd index 5985b88..cc72571 100644 --- a/man/create_dataset.Rd +++ b/man/create_dataset.Rd @@ -50,7 +50,19 @@ create_dataset( \item{theme_ids}{Optional character vector} -\item{periodicity_id}{Optional character} +\item{periodicity_id}{Optional character +\code{1} = "Jährlich", +\code{21} = "Kontinuierlich", +\code{42} = "Zweijährlich", +\code{43} = "Halbjährlich", +\code{45} = "Vierteljährlich", +\code{47} = "Monatlich", +\code{49} = "Alle zwei Wochen", +\code{51} = "Wöchentlich", +\code{52} = "Halbwöchentlich", +\code{54} = "Täglich", +\code{55} = "Unregelmässig", +\code{56} = "Niemals"} \item{see_also_ids}{Optional integer vector} diff --git a/man/create_distribution.Rd b/man/create_distribution.Rd index f8526f1..de610db 100644 --- a/man/create_distribution.Rd +++ b/man/create_distribution.Rd @@ -44,14 +44,45 @@ create_distribution( \item{byte_size}{Optional file size in bytes (must be a positive number).} -\item{status_id}{Optional character; status ID (will be set via follow-up PATCH).} +\item{status_id}{Optional character; status ID (will be set via follow-up PATCH). +\code{0} = "verworfen, +\code{1} = "✍️ Entwurf ", +\code{2} = "🔍 in Prüfung", +\code{3} = "📜 publiziert",} \item{license_id}{integer; license ID. Use \code{1} = "CC BY 4.0 (Attribution required)" or \code{2} = "CC0 (No attribution required)".} -\item{file_format_id}{Optional file format ID.} - -\item{periodicity_id}{Optional character periodicity ID.} +\item{file_format_id}{Optional file format ID. +Häufige Formate: +\code{3} = "CSV" +\code{20} = "PDF" +\code{33} = "XLSX" +\code{12} = "JSON" +\code{29} = "TXT" +\code{34} = "XML" +\code{32} = "XLS" +\code{35} = "ZIP" +\code{8} = "HTML" +\code{13} = "JSONLD" +\code{5} = "DOCX" +\code{40} = "GPKG" +\code{11} = "JS" +\code{25} = "RTF"} + +\item{periodicity_id}{Optional character periodicity ID. +\code{1} = "Jährlich", +\code{21} = "Kontinuierlich", +\code{42} = "Zweijährlich", +\code{43} = "Halbjährlich", +\code{45} = "Vierteljährlich", +\code{47} = "Monatlich", +\code{49} = "Alle zwei Wochen", +\code{51} = "Wöchentlich", +\code{52} = "Halbwöchentlich", +\code{54} = "Täglich", +\code{55} = "Unregelmässig", +\code{56} = "Niemals"} \item{file_path}{Optional local file path; if provided, the file will be uploaded and linked.} diff --git a/man/get_formats.Rd b/man/get_formats.Rd index e401cf0..3cda272 100644 --- a/man/get_formats.Rd +++ b/man/get_formats.Rd @@ -7,6 +7,8 @@ get_formats(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ +\item{input}{a set of formats to retrieve. Empty = all} + \item{use_dev}{boolean FALSE = developemtent version of MDV} \item{api_key}{optional API key for MDV} @@ -14,4 +16,3 @@ get_formats(input = NULL, use_dev = FALSE, api_key = NULL) \description{ Get All Formats and Their IDs } -\keyword{internal} diff --git a/man/get_licenses.Rd b/man/get_licenses.Rd index f5751fb..c14e978 100644 --- a/man/get_licenses.Rd +++ b/man/get_licenses.Rd @@ -7,6 +7,8 @@ get_licenses(input = NULL, use_dev = FALSE, api_key = NULL) } \arguments{ +\item{input}{a set of licenses to retrieve. Empty = all} + \item{use_dev}{boolean FALSE = developemtent version of MDV} \item{api_key}{optional API key for MDV} @@ -14,4 +16,3 @@ get_licenses(input = NULL, use_dev = FALSE, api_key = NULL) \description{ Get All Licenses and Their IDs } -\keyword{internal} diff --git a/man/set_status.Rd b/man/set_status.Rd index af60f62..591c732 100644 --- a/man/set_status.Rd +++ b/man/set_status.Rd @@ -8,12 +8,6 @@ set_status(object, ...) } \arguments{ \item{object}{A \code{Dataset} or \code{Distribution} S7 object with \verb{@id} and \verb{@status_id} set} - -\item{api_key}{API key string for authentication (optional)} - -\item{use_dev}{Logical; use the development API endpoint (default \code{TRUE})} - -\item{verbosity}{Integer; httr2 verbosity level (default \code{0})} } \value{ Invisibly returns parsed response as a list. diff --git a/man/update.Rd b/man/update.Rd index 124dcd9..c527dce 100644 --- a/man/update.Rd +++ b/man/update.Rd @@ -8,12 +8,6 @@ update(object, ...) } \arguments{ \item{object}{The object to update} - -\item{id}{ID of the object to update} - -\item{api_key}{Authentication information from login_to_api()} - -\item{use_dev}{Whether to use the development environment} } \value{ The updated object with updated information from the API response diff --git a/man/update_dataset.Rd b/man/update_dataset.Rd index 17ea698..98e7762 100644 --- a/man/update_dataset.Rd +++ b/man/update_dataset.Rd @@ -53,7 +53,19 @@ update_dataset( \item{theme_ids}{integer vector; new theme IDs (optional)} -\item{periodicity_id}{numeric; new periodicity ID (optional)} +\item{periodicity_id}{numeric; new periodicity ID (optional) +\code{1} = "Jährlich", +\code{21} = "Kontinuierlich", +\code{42} = "Zweijährlich", +\code{43} = "Halbjährlich", +\code{45} = "Vierteljährlich", +\code{47} = "Monatlich", +\code{49} = "Alle zwei Wochen", +\code{51} = "Wöchentlich", +\code{52} = "Halbwöchentlich", +\code{54} = "Täglich", +\code{55} = "Unregelmässig", +\code{56} = "Niemals"} \item{see_also_ids}{integer vector; new see-also IDs (optional)} diff --git a/man/update_distribution.Rd b/man/update_distribution.Rd index 26fc623..0906451 100644 --- a/man/update_distribution.Rd +++ b/man/update_distribution.Rd @@ -45,16 +45,47 @@ update_distribution( \item{byte_size}{Optional file size in bytes (must be a positive number).} -\item{status_id}{Optional status ID (applied via PATCH after update).} +\item{status_id}{Optional status ID (applied via PATCH after update). +\code{0} = "verworfen, +\code{1} = "✍️ Entwurf ", +\code{2} = "🔍 in Prüfung", +\code{3} = "📜 publiziert",} \item{license_id}{Optional license ID. Use \code{1} = "CC BY 4.0 (Attribution required)" or \code{2} = "CC0 (No attribution required)".} -\item{file_format_id}{Optional file format ID.} +\item{file_format_id}{Optional file format ID. +Häufige Formate: +\code{3} = "CSV" +\code{20} = "PDF" +\code{33} = "XLSX" +\code{12} = "JSON" +\code{29} = "TXT" +\code{34} = "XML" +\code{32} = "XLS" +\code{35} = "ZIP" +\code{8} = "HTML" +\code{13} = "JSONLD" +\code{5} = "DOCX" +\code{40} = "GPKG" +\code{11} = "JS" +\code{25} = "RTF"} \item{dataset_id}{ID of the dataset to which this distribution belongs (optional).} -\item{periodicity_id}{Optional update frequency ID.} +\item{periodicity_id}{Optional update frequency ID. +\code{1} = "Jährlich", +\code{21} = "Kontinuierlich", +\code{42} = "Zweijährlich", +\code{43} = "Halbjährlich", +\code{45} = "Vierteljährlich", +\code{47} = "Monatlich", +\code{49} = "Alle zwei Wochen", +\code{51} = "Wöchentlich", +\code{52} = "Halbwöchentlich", +\code{54} = "Täglich", +\code{55} = "Unregelmässig", +\code{56} = "Niemals"} \item{file_path}{Optional local file path; if provided, the file will be uploaded and linked.} From e3ae14c78973b5dcdbafa81689a5650109201a05 Mon Sep 17 00:00:00 2001 From: philbosch Date: Tue, 18 Nov 2025 15:53:24 +0000 Subject: [PATCH 12/13] Increment version number to 1.0.1 --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 4244e9c..3c7540a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: zhapir Title: Wrapper around the API of the Datacatalogue of the cantonal administration -Version: 1.0.0 +Version: 1.0.1 Authors@R: c( person("Philipp", "Bosch", , "philipp.bosch@statistik.ji.zh.ch", role = c("aut", "cre")), person("Tabea", "Eggler", , "tabea.eggler@statistik.ji.zh.ch", role = "aut"), diff --git a/NEWS.md b/NEWS.md index d6c0510..481c86f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +# zhapir 1.0.1 + # zhapir 1.0.0 * Added a `NEWS.md` file to track changes to the package. From 908bb9fd83ba1775267665c019caf92b2d6caa59 Mon Sep 17 00:00:00 2001 From: philbosch Date: Tue, 18 Nov 2025 15:58:35 +0000 Subject: [PATCH 13/13] docu: add new functionality to news.md --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index 481c86f..cc1bdd3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,10 @@ # zhapir 1.0.1 +## Minor improvements and bug fixes + +* Exporting all `get`-functions +* All exported functions have an explicit `api_key` & `use_dev` argument. + # zhapir 1.0.0 * Added a `NEWS.md` file to track changes to the package.