diff --git a/NAMESPACE b/NAMESPACE index 0e3046d2..7a065558 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,6 +20,7 @@ export(spq) export(spq_add) export(spq_arrange) export(spq_assemble) +export(spq_control_request) export(spq_count) export(spq_filter) export(spq_group_by) diff --git a/R/build_sparql.R b/R/build_sparql.R index 49e72b90..957b3eb8 100644 --- a/R/build_sparql.R +++ b/R/build_sparql.R @@ -1,6 +1,5 @@ #' Assemble query parts into a proper SPARQL query #' @param .query a list with elements of the query -#' @param endpoint SPARQL endpoint to send the query to #' @param strict whether to perform some linting on the query, #' and error in case a problem is detected. #' @return A query object @@ -12,9 +11,9 @@ #' spq_add("?city wdt:P1082 ?pop") %>% #' spq_assemble() %>% #' cat() -spq_assemble = function(.query, - endpoint = "Wikidata", - strict = TRUE) { +spq_assemble = function(.query, strict = TRUE) { + + endpoint = .query[["endpoint"]] .query = spq_prefix(.query, auto = TRUE, prefixes = NULL) diff --git a/R/send_sparql.R b/R/send_sparql.R index 73dbecd9..ccc0ad5a 100644 --- a/R/send_sparql.R +++ b/R/send_sparql.R @@ -1,79 +1,128 @@ #' Send SPARQL query to endpoint and get tibble as a result -#' @param .query a string corresponding to a SPARQL query +#' @param query_string a string corresponding to a SPARQL query #' @param endpoint a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata" -#' @param user_agent a string indicating the user agent to send with the query. -#' @inheritParams httr2::req_retry -#' @param timeout maximum number of seconds to wait (`httr2::req_timeout()`). -#' @param request_type a string indicating how the query should be sent: in the +#' @param user_agent `r lifecycle::badge('deprecated')` a string indicating the user agent to send with the query. +#' @param max_tries,max_seconds `r lifecycle::badge('deprecated')` Cap the maximal number of +#' attemps with `max_tries` or the total elapsed time from the first request with `max_seconds`. +#' @param timeout `r lifecycle::badge('deprecated')` maximum number of seconds to wait (`httr2::req_timeout()`). +#' @param request_type `r lifecycle::badge('deprecated')` a string indicating how the query should be sent: in the #' URL (`url`, default, most common) or as a body form (`body-form`). #' @param dry_run Boolean indicating whether to return the output of `httr2::req_dry_run()` -#' rather than of `httr2::req_perform`. Useful for debugging. +#' rather than of `httr2::req_perform()`. Useful for debugging. +#' @inheritParams spq_init #' @examples -#'metro_query='SELECT ?item ?itemLabel ?coords -#'{ -#' ?item wdt:P361 wd:Q1552; -#' wdt:P625 ?coords. -#' OPTIONAL{?item wdt:P1619 ?date.} -#' SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . } -#'} ORDER BY ?itemLabel -#'' -#'send_sparql(metro_query) +#' \dontrun{ +#' query_string = spq_init() %>% +#' spq_add("?city wdt:P31/wdt:P279* wd:Q486972") %>% +#' spq_label(city) %>% +#' spq_mutate(coords = wdt::P625(city), +#' .within_distance=list(center=c(long=4.84,lat=45.76), +#' radius=5)) %>% +#' spq_assemble() +#' send_sparql(query_string) +#' } +#' @details +#' +#' Control the way the query is performed via the `control_request` +#' argument of `spq_init()`. +#' This way you can create a basic spq object with all the correct options +#' corresponding to the SPARQL service you are using, and then use it as +#' the basis of all your subsequent glitter pipelines. +#' +#' #' @export -send_sparql = function(.query, - endpoint = "Wikidata", - user_agent = getOption("glitter.ua", "glitter R package (https://github.com/lvaudor/glitter)"), - max_tries = getOption("glitter.max_tries", 3L), - max_seconds = getOption("glitter.max_seconds", 120L), - timeout = getOption("glitter.timeout", 1000L), - request_type = c("url", "body-form"), - dry_run = FALSE) { - - if (!inherits(user_agent, "character")) { - cli::cli_abort("{.field user_agent} must be a string.") +send_sparql = function(query_string, + endpoint = NULL, + user_agent = lifecycle::deprecated(), + max_tries = lifecycle::deprecated(), + max_seconds = lifecycle::deprecated(), + timeout = lifecycle::deprecated(), + request_type = lifecycle::deprecated(), + dry_run = FALSE, + request_control = NULL) { + + if (lifecycle::is_present(user_agent)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(user_agent)", + "spq_request_control(user_agent)", + details = control_explanation() + ) + } else { + user_agent = request_control[["user_agent"]] } - if (!inherits(max_tries, "integer")) { - cli::cli_abort("{.field max_tries} must be a integer") + if (lifecycle::is_present(max_tries)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(max_tries)", + "spq_request_control(max_tries)", + details = control_explanation() + ) + } else { + max_tries = request_control[["max_tries"]] } - if (!inherits(max_seconds, "integer")) { - cli::cli_abort("{.field max_seconds} must be a integer") + if (lifecycle::is_present(max_seconds)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(max_seconds)", + "spq_request_control(max_seconds)", + details = control_explanation() + ) + } else { + max_seconds = request_control[["max_seconds"]] } - if (!inherits(timeout, "integer")) { - cli::cli_abort("{.field timeout} must be a integer") + if (lifecycle::is_present(timeout)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(timeout)", + "spq_request_control(timeout)", + details = control_explanation() + ) + } else { + timeout = request_control[["timeout"]] } - request_type <- rlang::arg_match(request_type, c("url", "body-form")) - - endpoint = tolower(endpoint) + if (lifecycle::is_present(request_type)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(request_type)", + "spq_request_control(request_type)", + details = control_explanation() + ) + } else { + request_type = request_control[["request_type"]] + } # if endpoint wikidata, use WikidataQueryServiceR::query_wikidata() - if (endpoint == "wikidata") { - return(purrr::quietly(WikidataQueryServiceR::query_wikidata)(.query)$result) + if (endpoint == "https://query.wikidata.org/") { + return(purrr::quietly(WikidataQueryServiceR::query_wikidata)(query_string)$result) } # else, use httr2 - # if endpoint passed as name, get url - usual_endpoint_info = usual_endpoints %>% - dplyr::filter(.data$name == endpoint) - url = if (nrow(usual_endpoint_info) > 0) { - dplyr::pull(usual_endpoint_info, .data$url) - } else { - endpoint - } - - initial_request = httr2::request(url) %>% + initial_request = httr2::request(endpoint) %>% httr2::req_method("POST") %>% httr2::req_headers(Accept = "application/sparql-results+json") %>% httr2::req_user_agent(user_agent) %>% httr2::req_retry(max_tries = max_tries, max_seconds = max_seconds) %>% httr2::req_timeout(timeout) - request <- if (request_type == "url") { - httr2::req_url_query(initial_request, query = .query) + rate = request_control[["rate"]] + if (!is.null(rate)) { + realm = request_control[["realm"]] + initial_request = httr2::req_throttle( + initial_request, + rate = rate, + realm = realm + ) + } + + request = if (request_type == "url") { + httr2::req_url_query(initial_request, query = query_string) } else { - httr2::req_body_form(initial_request, query = .query) + httr2::req_body_form(initial_request, query = query_string) } if (dry_run) { @@ -82,13 +131,13 @@ send_sparql = function(.query, resp <- httr2::req_perform(request) - httr2::resp_check_status(resp) + httr2::resp_check_status(resp) - if (httr2::resp_content_type(resp) != "application/sparql-results+json") { - rlang::abort("Not right response type") #TODO:better message, more flexibility - } + if (httr2::resp_content_type(resp) != "application/sparql-results+json") { + rlang::abort("Not right response type") #TODO:better message, more flexibility + } - content = httr2::resp_body_json(resp) + content = httr2::resp_body_json(resp) # Adapted from https://github.com/wikimedia/WikidataQueryServiceR/blob/accff89a06ad4ac4af1bef369f589175c92837b6/R/query.R#L56 if (length(content$results$bindings) > 0) { @@ -103,7 +152,7 @@ send_sparql = function(.query, type, character = x, # easier for now as dbpedia can return different things with the same name - integer = ifelse(endpoint == "dbpedia", x, as.integer(x)), + integer = ifelse(endpoint == "https://dbpedia.org/sparql", x, as.integer(x)), datetime = anytime::anytime(x), x ) diff --git a/R/spq_control_request.R b/R/spq_control_request.R new file mode 100644 index 00000000..7cd6638b --- /dev/null +++ b/R/spq_control_request.R @@ -0,0 +1,74 @@ +#' Create the request control object for `spq_init()` +#' +#' @param user_agent a string indicating the user agent to send with the query. +#' @param max_tries,max_seconds Cap the maximal number of +#' attemps with `max_tries` or the total elapsed time from the first request +#' with `max_seconds`. +#' @param timeout maximum number of seconds to wait (`httr2::req_timeout()`). +#' @param request_type a string indicating how the query should be sent: in the +#' URL (`url`, default, most common) or as a body form (`body-form`). +#' @inheritParams httr2::req_throttle +#' +#' @return A list to be used in `spq_init()`'s `request_control` argument. +#' @export +#' +#' @examples +#' # Defaults +#' spq_control_request() +#' # Tweaking values +#' spq_control_request( +#' user_agent = "Jane Doe https://example.com", +#' max_tries = 1L, +#' max_seconds = 10L, +#' timeout = 10L, +#' request_type = "url" +#' ) +spq_control_request <- function(user_agent = getOption("glitter.ua", "glitter R package (https://github.com/lvaudor/glitter)"), + max_tries = getOption("glitter.max_tries", 3L), + max_seconds = getOption("glitter.max_seconds", 120L), + timeout = getOption("glitter.timeout", 1000L), + request_type = c("url", "body-form"), + rate = NULL, + realm = NULL) { + + + if (!is.character(user_agent)) { + cli::cli_abort("Must provide a character as {.arg user_agent}.") + } + + if (!is.integer(max_tries)) { + cli::cli_abort(c( + "Must provide an integer as {.arg max_tries}.", + i = "You provided a {.val {typeof(max_tries)}}." + )) + } + + if (!is.integer(max_seconds)) { + cli::cli_abort(c( + "Must provide an integer as {.arg max_seconds}.", + i = "You provided a {.val {typeof(max_seconds)}}." + )) + } + + if (!is.integer(timeout)) { + cli::cli_abort(c( + "Must provide an integer as {.arg timeout}.", + i = "You provided a {.val {typeof(timeout)}}." + )) + } + + request_type = rlang::arg_match(request_type, c("url", "body-form")) + structure( + list( + user_agent = user_agent, + max_tries = max_tries, + max_seconds = max_seconds, + timeout = timeout, + request_type = request_type, + rate = rate, + realm = realm + ), + class = "glitter_request_control" + ) + +} diff --git a/R/spq_init.R b/R/spq_init.R index 5b6bc61b..187aea6f 100644 --- a/R/spq_init.R +++ b/R/spq_init.R @@ -1,4 +1,9 @@ #' Initialize a query object. +#' +#' @param endpoint Endpoint, either name if it is in `usual_endpoints`, +#' or an URL +#' @param request_control An object as returned by [`spq_control_request()`] +#' #' @return A query object #' @export #' @section Printing: @@ -15,7 +20,30 @@ #' You can also turn off the cli behavior by setting the environment variable #' `"GLITTER.NOCLI"` to any non-empty string. #' That's what we do in glitter snapshot tests. -spq_init = function(){ +spq_init = function( + endpoint = "wikidata", + request_control = spq_control_request( + user_agent = getOption("glitter.ua", "glitter R package (https://github.com/lvaudor/glitter)"), + max_tries = getOption("glitter.max_tries", 3L), + max_seconds = getOption("glitter.max_seconds", 120L), + timeout = getOption("glitter.timeout", 1000L), + request_type = c("url", "body-form") + ) + ) { + if (!inherits(request_control, "glitter_request_control")) { + cli::cli_abort("{.arg request_control} must be created by {.fun spq_control_request}.") + } + + # if endpoint passed as name, get url + endpoint = tolower(endpoint) + usual_endpoint_info = usual_endpoints %>% + dplyr::filter(.data$name == endpoint) + endpoint = if (nrow(usual_endpoint_info) > 0) { + dplyr::pull(usual_endpoint_info, .data$url) + } else { + endpoint + } + query = list( prefixes_provided = tibble::tibble(name = NULL, url = NULL), prefixes_used = NULL, @@ -27,7 +55,9 @@ spq_init = function(){ limit = NULL, group_by = NULL, order_by = NULL, - offset = NULL + offset = NULL, + endpoint = endpoint, + request_control = request_control ) structure(query, class = c("sparqle_query", "list")) diff --git a/R/spq_perform.R b/R/spq_perform.R index 75b5db7e..29da69ff 100644 --- a/R/spq_perform.R +++ b/R/spq_perform.R @@ -1,6 +1,6 @@ #' Assemble query parts into a sparql query and send it to endpoint to get a tibble as a result. #' @param .query a list with elements of the query -#' @param endpoint a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata" +#' @param endpoint `r lifecycle::badge('deprecated')` a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata" #' @param replace_prefixes Boolean indicating whether to replace used prefixes in the results table, #' for instance making, for instance "http://www.wikidata.org/entity/" "wd:". #' @inheritParams send_sparql @@ -16,15 +16,27 @@ #' spq_perform() #' } spq_perform = function(.query, - endpoint = "Wikidata", - user_agent = getOption("glitter.ua", "glitter R package (https://github.com/lvaudor/glitter)"), - max_tries = getOption("glitter.max_tries", 3L), - max_seconds = getOption("glitter.max_seconds", 120L), - timeout = getOption("glitter.timeout", 1000L), - request_type = c("url", "body-form"), + endpoint = lifecycle::deprecated(), + user_agent = lifecycle::deprecated(), + max_tries = lifecycle::deprecated(), + max_seconds = lifecycle::deprecated(), + timeout = lifecycle::deprecated(), + request_type = lifecycle::deprecated(), dry_run = FALSE, replace_prefixes = FALSE){ - sparql_query = spq_assemble(.query = .query, endpoint = endpoint) + + if (lifecycle::is_present(endpoint)) { + lifecycle::deprecate_warn( + "0.3.0", + "spq_perform(endpoint)", + "spq_init(endpoint)" + ) + } else { + endpoint = .query[["endpoint"]] + } + + + sparql_query = spq_assemble(.query = .query) results = send_sparql( sparql_query, @@ -34,7 +46,8 @@ spq_perform = function(.query, max_seconds = max_seconds, timeout = timeout, request_type = request_type, - dry_run = FALSE + dry_run = dry_run, + request_control = .query[["request_control"]] ) if (replace_prefixes) { @@ -62,3 +75,8 @@ replace_prefix = function(prefix, results, .query) { ) ) } + +control_explanation <- function() { + "Parameters controlling how the request is made have to be + passed to `spq_init()`'s `request_control` argument." +} diff --git a/data-raw/glitter_for_SyMoGih.Rmd b/data-raw/glitter_for_SyMoGih.Rmd index 6bceddbb..6953063e 100644 --- a/data-raw/glitter_for_SyMoGih.Rmd +++ b/data-raw/glitter_for_SyMoGih.Rmd @@ -29,7 +29,7 @@ library(glitter) - KUTy a pour étiquette KUTyLabel ```{r ressources_maths} -tib=spq_init() %>% +tib=spq_init(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?r sym:associatesObject syr:AbOb213") %>% @@ -39,7 +39,7 @@ tib=spq_init() %>% spq_add(". sym:hasKnowledgeUnitType ?KUTy") %>% spq_label(KUTy, .languages = NULL) %>% spq_head(n=10) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() knitr::kable(tib) ``` @@ -47,7 +47,7 @@ knitr::kable(tib) ## Structure de la partie abstraite de l'ontologie ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?s a ?cl") %>% @@ -57,7 +57,7 @@ tib=spq_init() %>% spq_head(n=10) %>% spq_summarise(effectif = n("*")) %>% spq_arrange(desc(effectif)) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() knitr::kable(tib) ``` @@ -65,7 +65,7 @@ knitr::kable(tib) ## Structure de la partie instanciée de l'ontologie ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?s sym:hasKnowledgeUnitType ?tyin") %>% @@ -75,14 +75,14 @@ tib=spq_init() %>% spq_summarise(effectif = n("*")) %>% spq_arrange(tyin,tyro,desc(effectif)) %>% spq_head(n=10) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() ``` ## Types d'informations et types de rôles, avec effectifs ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?s sym:hasKnowledgeUnitType ?tyin") %>% @@ -92,7 +92,7 @@ tib=spq_init() %>% spq_summarise(effectif = n("*")) %>% spq_arrange(tyin, tyro, effectif) %>% spq_head(n=10) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() knitr::kable(tib) ``` @@ -100,7 +100,7 @@ knitr::kable(tib) ## Le parcours biographique de Gaston,Louis, Henry May (1849 - 1940) ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?tyro rdfs:label ?TyRoLabel") %>% @@ -113,7 +113,7 @@ tib=spq_init() %>% spq_add(". sym:hasKnowledgeUnitType ?tyin") %>% spq_arrange(infoStandardDate) %>% spq_head(n=10) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() knitr::kable(tib) ``` diff --git a/man/send_sparql.Rd b/man/send_sparql.Rd index 67c401ef..081a7e74 100644 --- a/man/send_sparql.Rd +++ b/man/send_sparql.Rd @@ -5,48 +5,56 @@ \title{Send SPARQL query to endpoint and get tibble as a result} \usage{ send_sparql( - .query, - endpoint = "Wikidata", - user_agent = getOption("glitter.ua", - "glitter R package (https://github.com/lvaudor/glitter)"), - max_tries = getOption("glitter.max_tries", 3L), - max_seconds = getOption("glitter.max_seconds", 120L), - timeout = getOption("glitter.timeout", 1000L), - request_type = c("url", "body-form"), - dry_run = FALSE + query_string, + endpoint = NULL, + user_agent = lifecycle::deprecated(), + max_tries = lifecycle::deprecated(), + max_seconds = lifecycle::deprecated(), + timeout = lifecycle::deprecated(), + request_type = lifecycle::deprecated(), + dry_run = FALSE, + request_control = NULL ) } \arguments{ -\item{.query}{a string corresponding to a SPARQL query} +\item{query_string}{a string corresponding to a SPARQL query} \item{endpoint}{a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata"} -\item{user_agent}{a string indicating the user agent to send with the query.} +\item{user_agent}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} a string indicating the user agent to send with the query.} -\item{max_tries, max_seconds}{Cap the maximum number of attempts with -\code{max_tries} or the total elapsed time from the first request with -\code{max_seconds}. If neither option is supplied (the default), \code{\link[httr2:req_perform]{req_perform()}} -will not retry.} +\item{max_tries, max_seconds}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Cap the maximal number of +attemps with \code{max_tries} or the total elapsed time from the first request with \code{max_seconds}.} -\item{timeout}{maximum number of seconds to wait (\code{httr2::req_timeout()}).} +\item{timeout}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} maximum number of seconds to wait (\code{httr2::req_timeout()}).} -\item{request_type}{a string indicating how the query should be sent: in the +\item{request_type}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} a string indicating how the query should be sent: in the URL (\code{url}, default, most common) or as a body form (\code{body-form}).} \item{dry_run}{Boolean indicating whether to return the output of \code{httr2::req_dry_run()} -rather than of \code{httr2::req_perform}. Useful for debugging.} +rather than of \code{httr2::req_perform()}. Useful for debugging.} + +\item{request_control}{An object as returned by \code{\link[=spq_control_request]{spq_control_request()}}} } \description{ Send SPARQL query to endpoint and get tibble as a result } +\details{ +Control the way the query is performed via the \code{control_request} +argument of \code{spq_init()}. +This way you can create a basic spq object with all the correct options +corresponding to the SPARQL service you are using, and then use it as +the basis of all your subsequent glitter pipelines. +} \examples{ -metro_query='SELECT ?item ?itemLabel ?coords -{ - ?item wdt:P361 wd:Q1552; - wdt:P625 ?coords. - OPTIONAL{?item wdt:P1619 ?date.} - SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . } -} ORDER BY ?itemLabel -' -send_sparql(metro_query) +\dontrun{ +query_string = spq_init() \%>\% + spq_add("?city wdt:P31/wdt:P279* wd:Q486972") \%>\% + spq_label(city) \%>\% + spq_mutate(coords = wdt::P625(city), + .within_distance=list(center=c(long=4.84,lat=45.76), + radius=5)) \%>\% + spq_assemble() + send_sparql(query_string) + } } diff --git a/man/spq_assemble.Rd b/man/spq_assemble.Rd index 7e94b0d9..91e5235a 100644 --- a/man/spq_assemble.Rd +++ b/man/spq_assemble.Rd @@ -4,13 +4,11 @@ \alias{spq_assemble} \title{Assemble query parts into a proper SPARQL query} \usage{ -spq_assemble(.query, endpoint = "Wikidata", strict = TRUE) +spq_assemble(.query, strict = TRUE) } \arguments{ \item{.query}{a list with elements of the query} -\item{endpoint}{SPARQL endpoint to send the query to} - \item{strict}{whether to perform some linting on the query, and error in case a problem is detected.} } diff --git a/man/spq_control_request.Rd b/man/spq_control_request.Rd new file mode 100644 index 00000000..d5514960 --- /dev/null +++ b/man/spq_control_request.Rd @@ -0,0 +1,55 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/spq_control_request.R +\name{spq_control_request} +\alias{spq_control_request} +\title{Create the request control object for \code{spq_init()}} +\usage{ +spq_control_request( + user_agent = getOption("glitter.ua", + "glitter R package (https://github.com/lvaudor/glitter)"), + max_tries = getOption("glitter.max_tries", 3L), + max_seconds = getOption("glitter.max_seconds", 120L), + timeout = getOption("glitter.timeout", 1000L), + request_type = c("url", "body-form"), + rate = NULL, + realm = NULL +) +} +\arguments{ +\item{user_agent}{a string indicating the user agent to send with the query.} + +\item{max_tries, max_seconds}{Cap the maximal number of +attemps with \code{max_tries} or the total elapsed time from the first request +with \code{max_seconds}.} + +\item{timeout}{maximum number of seconds to wait (\code{httr2::req_timeout()}).} + +\item{request_type}{a string indicating how the query should be sent: in the +URL (\code{url}, default, most common) or as a body form (\code{body-form}).} + +\item{rate}{Maximum rate, i.e. maximum number of requests per second. +Usually easiest expressed as a fraction, +\code{number_of_requests / number_of_seconds}, e.g. 15 requests per minute +is \code{15 / 60}.} + +\item{realm}{An unique identifier that for throttle pool. If not supplied, +defaults to the hostname of the request.} +} +\value{ +A list to be used in \code{spq_init()}'s \code{request_control} argument. +} +\description{ +Create the request control object for \code{spq_init()} +} +\examples{ +# Defaults +spq_control_request() +# Tweaking values +spq_control_request( + user_agent = "Jane Doe https://example.com", + max_tries = 1L, + max_seconds = 10L, + timeout = 10L, + request_type = "url" +) +} diff --git a/man/spq_init.Rd b/man/spq_init.Rd index ac12b507..f0870847 100644 --- a/man/spq_init.Rd +++ b/man/spq_init.Rd @@ -4,7 +4,20 @@ \alias{spq_init} \title{Initialize a query object.} \usage{ -spq_init() +spq_init( + endpoint = "wikidata", + request_control = spq_control_request(user_agent = getOption("glitter.ua", + "glitter R package (https://github.com/lvaudor/glitter)"), max_tries = + getOption("glitter.max_tries", 3L), max_seconds = getOption("glitter.max_seconds", + 120L), timeout = getOption("glitter.timeout", 1000L), request_type = c("url", + "body-form")) +) +} +\arguments{ +\item{endpoint}{Endpoint, either name if it is in \code{usual_endpoints}, +or an URL} + +\item{request_control}{An object as returned by \code{\link[=spq_control_request]{spq_control_request()}}} } \value{ A query object diff --git a/man/spq_perform.Rd b/man/spq_perform.Rd index a28dec3b..c745cc5b 100644 --- a/man/spq_perform.Rd +++ b/man/spq_perform.Rd @@ -6,13 +6,12 @@ \usage{ spq_perform( .query, - endpoint = "Wikidata", - user_agent = getOption("glitter.ua", - "glitter R package (https://github.com/lvaudor/glitter)"), - max_tries = getOption("glitter.max_tries", 3L), - max_seconds = getOption("glitter.max_seconds", 120L), - timeout = getOption("glitter.timeout", 1000L), - request_type = c("url", "body-form"), + endpoint = lifecycle::deprecated(), + user_agent = lifecycle::deprecated(), + max_tries = lifecycle::deprecated(), + max_seconds = lifecycle::deprecated(), + timeout = lifecycle::deprecated(), + request_type = lifecycle::deprecated(), dry_run = FALSE, replace_prefixes = FALSE ) @@ -20,22 +19,20 @@ spq_perform( \arguments{ \item{.query}{a list with elements of the query} -\item{endpoint}{a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata"} +\item{endpoint}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} a string or url corresponding to a SPARQL endpoint. Defaults to "Wikidata"} -\item{user_agent}{a string indicating the user agent to send with the query.} +\item{user_agent}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} a string indicating the user agent to send with the query.} -\item{max_tries, max_seconds}{Cap the maximum number of attempts with -\code{max_tries} or the total elapsed time from the first request with -\code{max_seconds}. If neither option is supplied (the default), \code{\link[httr2:req_perform]{req_perform()}} -will not retry.} +\item{max_tries, max_seconds}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Cap the maximal number of +attemps with \code{max_tries} or the total elapsed time from the first request with \code{max_seconds}.} -\item{timeout}{maximum number of seconds to wait (\code{httr2::req_timeout()}).} +\item{timeout}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} maximum number of seconds to wait (\code{httr2::req_timeout()}).} -\item{request_type}{a string indicating how the query should be sent: in the +\item{request_type}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} a string indicating how the query should be sent: in the URL (\code{url}, default, most common) or as a body form (\code{body-form}).} \item{dry_run}{Boolean indicating whether to return the output of \code{httr2::req_dry_run()} -rather than of \code{httr2::req_perform}. Useful for debugging.} +rather than of \code{httr2::req_perform()}. Useful for debugging.} \item{replace_prefixes}{Boolean indicating whether to replace used prefixes in the results table, for instance making, for instance "http://www.wikidata.org/entity/" "wd:".} diff --git a/tests/testthat/_snaps/send_sparql.md b/tests/testthat/_snaps/send_sparql.md deleted file mode 100644 index 5c5967c2..00000000 --- a/tests/testthat/_snaps/send_sparql.md +++ /dev/null @@ -1,35 +0,0 @@ -# httr2 options error - - Code - send_sparql(.query = spq_init() %>% spq_assemble(), timeout = "ahahah") - Error - timeout must be a integer - ---- - - Code - send_sparql(.query = spq_init() %>% spq_assemble(), max_tries = "ahahah") - Error - max_tries must be a integer - ---- - - Code - send_sparql(.query = spq_init() %>% spq_assemble(), max_seconds = "ahahah") - Error - max_seconds must be a integer - ---- - - Code - send_sparql(.query = spq_init() %>% spq_assemble(), request_type = "ahahah") - Error - `request_type` must be one of "url" or "body-form", not "ahahah". - ---- - - Code - send_sparql(.query = spq_init() %>% spq_assemble(), user_agent = 42) - Error - user_agent must be a string. - diff --git a/tests/testthat/_snaps/spq_control_request.md b/tests/testthat/_snaps/spq_control_request.md new file mode 100644 index 00000000..bc6d6e7a --- /dev/null +++ b/tests/testthat/_snaps/spq_control_request.md @@ -0,0 +1,38 @@ +# httr2 options error + + Code + spq_control_request(timeout = "ahahah") + Error + Must provide an integer as `timeout`. + i You provided a "character". + +--- + + Code + spq_control_request(max_tries = "ahahah") + Error + Must provide an integer as `max_tries`. + i You provided a "character". + +--- + + Code + spq_control_request(max_seconds = "ahahah") + Error + Must provide an integer as `max_seconds`. + i You provided a "character". + +--- + + Code + spq_control_request(request_type = "ahahah") + Error + `request_type` must be one of "url" or "body-form", not "ahahah". + +--- + + Code + spq_control_request(user_agent = 42) + Error + Must provide a character as `user_agent`. + diff --git a/tests/testthat/_snaps/spq_init.md b/tests/testthat/_snaps/spq_init.md index 6154ccfc..cd63d358 100644 --- a/tests/testthat/_snaps/spq_init.md +++ b/tests/testthat/_snaps/spq_init.md @@ -26,3 +26,10 @@ GROUP BY ?narrative_location_label ORDER BY DESC(?n_films) +# spq_init() errors for DIY request control + + Code + spq_init(request_control = list(max_tries = 1L)) + Error + `request_control` must be created by `spq_control_request()`. + diff --git a/tests/testthat/fixtures/auteurs/data.bnf.fr/sparql-754d02-POST.R b/tests/testthat/fixtures/auteurs/data.bnf.fr/sparql-754d02-POST.R index eadd8e5c..665cfebc 100644 --- a/tests/testthat/fixtures/auteurs/data.bnf.fr/sparql-754d02-POST.R +++ b/tests/testthat/fixtures/auteurs/data.bnf.fr/sparql-754d02-POST.R @@ -1,5 +1,5 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%20foaf%3A%20%3Chttp%3A%2F%2Fxmlns.com%2Ffoaf%2F0.1%2F%3E%0APREFIX%20bio%3A%20%3Chttp%3A%2F%2Fvocab.org%2Fbio%2F0.1%2F%3E%0ASELECT%20%3Fauteur%20%3Fdate1%20%3Fdate2%20%3Fjour%20%3Fnom%0AWHERE%20%7B%0A%0A%3Fauteur%20foaf%3Abirthday%20%3Fjour.%0A%3Fauteur%20bio%3Abirth%20%3Fdate1.%0A%3Fauteur%20bio%3Adeath%20%3Fdate2.%0AOPTIONAL%20%7B%3Fauteur%20foaf%3Aname%20%3Fnom.%7D%0A%0A%7D%0AORDER%20BY%20%3Fjour%0ALIMIT%2010", - status_code = 200L, headers = structure(list(Date = "Thu, 07 Sep 2023 10:05:19 GMT", + status_code = 200L, headers = structure(list(Date = "Thu, 14 Sep 2023 11:09:08 GMT", Server = "Virtuoso/07.20.3229 (Linux) x86_64-generic_glibc25-linux-gnu", `Accept-Ranges` = "bytes", `Content-Type` = "application/sparql-results+json", `Content-Encoding` = "gzip", `Access-Control-Allow-Origin` = "*", diff --git a/tests/testthat/fixtures/auteurset/data.bnf.fr/sparql-629846-POST.R b/tests/testthat/fixtures/auteurset/data.bnf.fr/sparql-629846-POST.R index b668bdf7..288e4737 100644 --- a/tests/testthat/fixtures/auteurset/data.bnf.fr/sparql-629846-POST.R +++ b/tests/testthat/fixtures/auteurset/data.bnf.fr/sparql-629846-POST.R @@ -1,5 +1,5 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%20foaf%3A%20%3Chttp%3A%2F%2Fxmlns.com%2Ffoaf%2F0.1%2F%3E%0APREFIX%20bio%3A%20%3Chttp%3A%2F%2Fvocab.org%2Fbio%2F0.1%2F%3E%0ASELECT%20%3Fanniv%20%3Fauteur%20%3Fdate1%20%3Fdate2%20%3Fjour%20%3Fnom%0AWHERE%20%7B%0A%0A%3Fauteur%20%3Fanniv%20%3Fjour.%0A%3Fauteur%20bio%3Abirth%20%3Fdate1.%0A%3Fauteur%20bio%3Adeath%20%3Fdate2.%0AOPTIONAL%20%7B%3Fauteur%20foaf%3Aname%20%3Fnom.%7D%0AVALUES%20%3Fanniv%20%7Bfoaf%3Abirthday%7D%0A%0A%7D%0AORDER%20BY%20%3Fjour%0ALIMIT%2010", - status_code = 200L, headers = structure(list(Date = "Thu, 07 Sep 2023 10:05:26 GMT", + status_code = 200L, headers = structure(list(Date = "Thu, 14 Sep 2023 11:19:19 GMT", Server = "Virtuoso/07.20.3229 (Linux) x86_64-generic_glibc25-linux-gnu", `Accept-Ranges` = "bytes", `Content-Type` = "application/sparql-results+json", `Content-Encoding` = "gzip", `Access-Control-Allow-Origin` = "*", @@ -75,30 +75,107 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, - 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x30, 0x35, 0x39, - 0x30, 0x34, 0x32, 0x38, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, + 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x31, 0x30, 0x38, + 0x32, 0x32, 0x33, 0x66, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x39, 0x35, + 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x36, 0x31, - 0x2d, 0x30, 0x33, 0x2d, 0x32, 0x31, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, - 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, + 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x2e, 0x2e, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, + 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, + 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x41, 0x6d, 0x5c, 0x75, 0x30, 0x30, + 0x45, 0x39, 0x64, 0x5c, 0x75, 0x30, 0x30, 0x45, 0x39, 0x65, + 0x20, 0x43, 0x68, 0x69, 0x76, 0x6f, 0x74, 0x22, 0x20, 0x7d, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, + 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, + 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x66, 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, + 0x2f, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, + 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, + 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, + 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, + 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x31, 0x31, 0x32, 0x38, + 0x31, 0x36, 0x6b, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, + 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x38, 0x33, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, + 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x34, 0x35, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, + 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, + 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, + 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x48, 0x72, 0x69, 0x73, 0x74, 0x6f, 0x20, + 0x4b, 0x61, 0x6c, 0x66, 0x6f, 0x76, 0x22, 0x20, 0x7d, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, + 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, + 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x66, 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, 0x2f, + 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x20, + 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, 0x75, + 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, - 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, - 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x44, 0x61, 0x6e, 0x6e, 0x79, 0x20, 0x46, 0x72, 0x75, 0x73, - 0x68, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, + 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, + 0x2f, 0x63, 0x62, 0x31, 0x37, 0x31, 0x31, 0x34, 0x37, 0x37, + 0x31, 0x78, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, + 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, + 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x35, 0x32, 0x22, 0x20, + 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, + 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x32, 0x39, 0x2d, 0x30, + 0x36, 0x2d, 0x31, 0x31, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, + 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, + 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, + 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, + 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x52, 0x6f, + 0x62, 0x65, 0x72, 0x74, 0x20, 0x44, 0x65, 0x6e, 0x6d, 0x61, + 0x6e, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, @@ -113,19 +190,19 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, - 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x32, - 0x32, 0x34, 0x34, 0x31, 0x30, 0x36, 0x78, 0x23, 0x61, 0x62, + 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, + 0x31, 0x30, 0x32, 0x33, 0x33, 0x33, 0x6b, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x35, 0x36, 0x30, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, + 0x38, 0x36, 0x30, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x36, 0x32, 0x38, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, + 0x39, 0x32, 0x39, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, @@ -134,9 +211,86 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x69, 0x63, 0x6f, 0x20, 0x44, 0x65, 0x6c, 0x6c, - 0x61, 0x20, 0x43, 0x61, 0x73, 0x61, 0x22, 0x20, 0x7d, 0x7d, + 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x4b, 0x61, 0x72, + 0x6c, 0x20, 0x48, 0x6f, 0x70, 0x70, 0x65, 0x22, 0x20, 0x7d, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, + 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, + 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x66, 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, + 0x2f, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, + 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, + 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, + 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, + 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x31, 0x30, 0x33, 0x34, + 0x34, 0x37, 0x73, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, + 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x38, 0x34, 0x22, + 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, + 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x35, 0x32, 0x2d, + 0x30, 0x38, 0x2d, 0x30, 0x32, 0x22, 0x20, 0x7d, 0x09, 0x2c, + 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, + 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, + 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, + 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x48, + 0x65, 0x6c, 0x65, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x67, 0x61, + 0x72, 0x65, 0x74, 0x68, 0x20, 0x4b, 0x65, 0x6c, 0x6c, 0x79, + 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, + 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6f, 0x61, 0x66, 0x2f, + 0x30, 0x2e, 0x31, 0x2f, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, + 0x61, 0x79, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x61, + 0x75, 0x74, 0x65, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, + 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, + 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, + 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x37, + 0x39, 0x33, 0x33, 0x35, 0x30, 0x39, 0x23, 0x61, 0x62, 0x6f, + 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, + 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, + 0x37, 0x34, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, + 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, + 0x34, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x31, 0x38, 0x22, 0x20, + 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, + 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, + 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, + 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, + 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, + 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x41, 0x2e, 0x20, 0x43, 0x2e, 0x20, 0x43, 0x2e, + 0x20, 0x48, 0x6f, 0x6c, 0x74, 0x7a, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, @@ -152,139 +306,31 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, - 0x2f, 0x63, 0x62, 0x31, 0x33, 0x37, 0x35, 0x36, 0x36, 0x33, - 0x37, 0x38, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, + 0x2f, 0x63, 0x62, 0x31, 0x37, 0x37, 0x39, 0x34, 0x33, 0x34, + 0x34, 0x6d, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x3a, 0x20, 0x22, 0x31, 0x34, 0x35, 0x30, 0x22, 0x20, + 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x38, 0x36, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x3a, 0x20, 0x22, 0x31, 0x34, 0x39, 0x34, 0x2d, 0x30, - 0x32, 0x2d, 0x30, 0x34, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, + 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x32, 0x37, 0x2d, 0x31, + 0x30, 0x2d, 0x30, 0x33, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, - 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, - 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, - 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, - 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, 0x2f, 0x62, 0x69, - 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, 0x75, 0x72, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, - 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, - 0x62, 0x31, 0x37, 0x30, 0x37, 0x30, 0x31, 0x35, 0x34, 0x73, - 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x38, 0x39, 0x36, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x39, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, - 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, - 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, - 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, - 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x47, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x73, 0x20, 0x56, 0x65, - 0x72, 0x67, 0x65, 0x72, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, - 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, - 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, - 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, 0x2f, 0x62, 0x69, - 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, 0x75, 0x72, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, - 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, - 0x62, 0x31, 0x37, 0x30, 0x37, 0x31, 0x37, 0x34, 0x31, 0x62, - 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x39, 0x30, 0x35, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x39, 0x32, 0x38, 0x2d, 0x30, 0x34, 0x2d, - 0x32, 0x35, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, - 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, - 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, - 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, - 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, - 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x48, 0x65, 0x6e, 0x72, - 0x69, 0x65, 0x74, 0x74, 0x65, 0x20, 0x47, 0x61, 0x72, 0x64, - 0x65, 0x6c, 0x6c, 0x65, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, - 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, - 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, - 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, 0x2f, 0x62, 0x69, - 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, 0x75, 0x72, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, - 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, - 0x62, 0x31, 0x37, 0x30, 0x37, 0x35, 0x30, 0x32, 0x32, 0x33, - 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x39, 0x30, 0x30, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, - 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, - 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, - 0x20, 0x22, 0x31, 0x39, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, - 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, - 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, - 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, - 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, - 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, - 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x47, 0x6c, 0x61, 0x64, 0x79, 0x73, 0x20, 0x4a, 0x6f, 0x65, - 0x6c, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x2e, 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, + 0x22, 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x46, 0x72, + 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x52, 0x6f, + 0x71, 0x75, 0x65, 0x20, 0x53, 0x65, 0x72, 0x72, 0x61, 0x6e, + 0x6f, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, @@ -300,57 +346,18 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, - 0x30, 0x37, 0x35, 0x31, 0x35, 0x39, 0x71, 0x23, 0x61, 0x62, + 0x38, 0x31, 0x33, 0x35, 0x33, 0x35, 0x67, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x38, 0x35, 0x37, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, + 0x39, 0x31, 0x30, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x39, 0x33, 0x33, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x31, 0x22, - 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, - 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, - 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, - 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, 0x22, - 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, - 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x45, 0x75, 0x67, 0x65, 0x6e, 0x65, 0x20, - 0x43, 0x6f, 0x72, 0x72, 0x69, 0x22, 0x20, 0x7d, 0x7d, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, - 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, - 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x66, 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, 0x31, 0x2f, 0x62, - 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x20, 0x7d, - 0x09, 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, 0x65, 0x75, 0x72, - 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, - 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, - 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, - 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, - 0x63, 0x62, 0x31, 0x37, 0x30, 0x37, 0x37, 0x31, 0x39, 0x31, - 0x70, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, - 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, - 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x31, 0x38, 0x38, 0x32, 0x22, 0x20, 0x7d, - 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, - 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x31, 0x39, 0x33, 0x34, 0x2d, 0x30, 0x35, - 0x2d, 0x31, 0x34, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, + 0x39, 0x39, 0x31, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, @@ -359,45 +366,45 @@ structure(list(method = "POST", url = "https://data.bnf.fr/sparql?query=PREFIX%2 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x4e, 0x6f, 0x72, - 0x6d, 0x61, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x70, 0x68, 0x61, - 0x6d, 0x22, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x7b, 0x20, 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, - 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6f, 0x61, 0x66, - 0x2f, 0x30, 0x2e, 0x31, 0x2f, 0x62, 0x69, 0x72, 0x74, 0x68, - 0x64, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, - 0x61, 0x75, 0x74, 0x65, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, + 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x48, 0x69, 0x6c, + 0x64, 0x61, 0x20, 0x53, 0x68, 0x61, 0x72, 0x70, 0x22, 0x20, + 0x7d, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, + 0x22, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, - 0x66, 0x2e, 0x66, 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, - 0x31, 0x32, 0x31, 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, - 0x30, 0x37, 0x38, 0x36, 0x31, 0x37, 0x77, 0x23, 0x61, 0x62, - 0x6f, 0x75, 0x74, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, - 0x64, 0x61, 0x74, 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, - 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, - 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x38, 0x38, 0x31, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, - 0x64, 0x61, 0x74, 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, - 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, - 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, - 0x39, 0x33, 0x37, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, - 0x6a, 0x6f, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, - 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, - 0x2d, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, - 0x6e, 0x6f, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, - 0x65, 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x50, 0x61, 0x72, - 0x6d, 0x65, 0x6c, 0x79, 0x20, 0x48, 0x65, 0x72, 0x72, 0x69, - 0x63, 0x6b, 0x22, 0x20, 0x7d, 0x7d, 0x20, 0x5d, 0x20, 0x7d, - 0x20, 0x7d))), class = "httr2_response") + 0x3a, 0x2f, 0x2f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x66, 0x6f, 0x61, 0x66, 0x2f, 0x30, 0x2e, + 0x31, 0x2f, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x61, 0x75, 0x74, + 0x65, 0x75, 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, + 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x62, 0x6e, 0x66, 0x2e, 0x66, + 0x72, 0x2f, 0x61, 0x72, 0x6b, 0x3a, 0x2f, 0x31, 0x32, 0x31, + 0x34, 0x38, 0x2f, 0x63, 0x62, 0x31, 0x37, 0x38, 0x31, 0x36, + 0x33, 0x34, 0x33, 0x38, 0x23, 0x61, 0x62, 0x6f, 0x75, 0x74, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, + 0x65, 0x31, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x38, 0x39, 0x34, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, + 0x65, 0x32, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x38, 0x31, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6a, 0x6f, 0x75, + 0x72, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x2d, 0x2e, 0x2e, + 0x22, 0x20, 0x7d, 0x09, 0x2c, 0x20, 0x22, 0x6e, 0x6f, 0x6d, + 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x44, 0x6f, 0x72, 0x6f, 0x74, 0x68, + 0x79, 0x20, 0x43, 0x61, 0x6d, 0x70, 0x62, 0x65, 0x6c, 0x6c, + 0x22, 0x20, 0x7d, 0x7d, 0x20, 0x5d, 0x20, 0x7d, 0x20, 0x7d + ))), class = "httr2_response") diff --git a/tests/testthat/fixtures/bowie/dbpedia.org/sparql-f06a60-POST.R b/tests/testthat/fixtures/bowie/dbpedia.org/sparql-f06a60-POST.R index 68bb3e8b..55fe0a2a 100644 --- a/tests/testthat/fixtures/bowie/dbpedia.org/sparql-f06a60-POST.R +++ b/tests/testthat/fixtures/bowie/dbpedia.org/sparql-f06a60-POST.R @@ -1,9 +1,9 @@ structure(list(method = "POST", url = "https://dbpedia.org/sparql?query=PREFIX%20dbo%3A%20%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0ASELECT%20%3Fo%20%3Fp%20%3Fperson%0AWHERE%20%7B%0A%0A%3Fperson%20rdfs%3Alabel%20%27David%20Bowie%27%40en.%0A%3Fperson%20%3Fp%20%3Fo.%0A%0A%7D%0A%0ALIMIT%20300", - status_code = 200L, headers = structure(list(date = "Thu, 07 Sep 2023 10:05:17 GMT", + status_code = 200L, headers = structure(list(date = "Thu, 14 Sep 2023 11:09:07 GMT", `content-type` = "application/sparql-results+json", `content-length` = "103605", - server = "Virtuoso/08.03.3328 (Linux) x86_64-generic-linux-glibc25 VDB", - `content-disposition` = "filename=sparql_2023-09-07_10-05-20Z.json", - expires = "Thu, 14 Sep 2023 10:05:17 GMT", `cache-control` = "max-age=604800", + server = "Virtuoso/08.03.3329 (Linux) x86_64-generic-linux-glibc25 VDB", + `content-disposition` = "filename=sparql_2023-09-14_10-59-47Z.json", + expires = "Thu, 21 Sep 2023 11:09:07 GMT", `cache-control` = "max-age=604800", `access-control-allow-credentials` = "true", `access-control-allow-methods` = "GET, POST, OPTIONS", `access-control-allow-headers` = "Depth,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept-Encoding", `accept-ranges` = "bytes"), class = "httr2_headers"), diff --git a/tests/testthat/fixtures/symogih/bhp-publi.ish-lyon.cnrs.fr-8888/sparql-899626-POST.R b/tests/testthat/fixtures/symogih/bhp-publi.ish-lyon.cnrs.fr-8888/sparql-899626-POST.R index 9f988827..27cdb044 100644 --- a/tests/testthat/fixtures/symogih/bhp-publi.ish-lyon.cnrs.fr-8888/sparql-899626-POST.R +++ b/tests/testthat/fixtures/symogih/bhp-publi.ish-lyon.cnrs.fr-8888/sparql-899626-POST.R @@ -1,6 +1,6 @@ structure(list(method = "POST", url = "http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql?query=PREFIX%20sym%3A%20%3Chttp%3A%2F%2Fsymogih.org%2Fontology%2F%3E%0APREFIX%20syr%3A%20%3Chttp%3A%2F%2Fsymogih.org%2Fresource%2F%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0ASELECT%20%3FKUTy%20%3FKUTyLabel%20%3Fi%20%3Fr%20%3FstDate%20%3FstLabel%0AWHERE%20%7B%0A%0A%3Fr%20sym%3AassociatesObject%20syr%3AAbOb213.%0A%3Fr%20sym%3AisComponentOf%20%3Fi.%0A%3Fi%20sym%3AknowledgeUnitStandardLabel%20%3FstLabel.%0A%3Fi%20sym%3AknowledgeUnitStandardDate%20%3FstDate.%0A%3Fi%20sym%3AhasKnowledgeUnitType%20%3FKUTy.%0A%3FKUTy%20rdfs%3Alabel%20%3FKUTyLabel.%0A%0A%7D%0A%0ALIMIT%2010", status_code = 200L, headers = structure(list(Server = "Virtuoso/07.20.3217 (Linux) x86_64-unknown-linux-gnu", - Connection = "close", Date = "Thu, 07 Sep 2023 10:05:21 GMT", + Connection = "close", Date = "Thu, 14 Sep 2023 11:09:11 GMT", `Accept-Ranges` = "bytes", `Content-Type` = "application/sparql-results+json", `Transfer-Encoding` = "chunked", `Content-Encoding` = "gzip"), class = "httr2_headers"), body = as.raw(c(0x0a, 0x7b, 0x20, 0x22, 0x68, 0x65, 0x61, diff --git a/tests/testthat/test-send_sparql.R b/tests/testthat/test-send_sparql.R index 031f2c1b..b2700682 100644 --- a/tests/testthat/test-send_sparql.R +++ b/tests/testthat/test-send_sparql.R @@ -9,13 +9,17 @@ test_that("send_sparql() returns tibble", { } ORDER BY ?itemLabel LIMIT 3 ' - x=send_sparql(metro_query) + x=send_sparql( + metro_query, + endpoint = "https://query.wikidata.org/", + request_control = spq_control_request() + ) expect_s3_class(x,"tbl") }) test_that("send_sparql() works with dataBNF", { httptest2::with_mock_dir(file.path("fixtures", "auteurs"), { - tib = spq_init() %>% + tib = spq_init(endpoint = "dataBNF") %>% spq_add("?auteur foaf:birthday ?jour") %>% spq_add("?auteur bio:birth ?date1") %>% spq_add("?auteur bio:death ?date2") %>% @@ -23,7 +27,7 @@ test_that("send_sparql() works with dataBNF", { spq_arrange(jour) %>% spq_prefix() %>% spq_head(n = 10) %>% - spq_perform(endpoint = "dataBNF") + spq_perform() }) expect_s3_class(tib, "tbl") expect_gt(nrow(tib), 2) @@ -31,12 +35,12 @@ test_that("send_sparql() works with dataBNF", { test_that("send_sparql() works with dbpedia", { httptest2::with_mock_dir(file.path("fixtures", "bowie"), { - tib = spq_init() %>% + tib = spq_init(endpoint = "dbpedia") %>% spq_prefix(prefixes=c(dbo="http://dbpedia.org/ontology")) %>% spq_add("?person rdfs:label 'David Bowie'@en") %>% spq_add("?person ?p ?o") %>% spq_head(300) %>% - spq_perform("dbpedia") + spq_perform() }) expect_s3_class(tib, "tbl") expect_gt(nrow(tib), 100) @@ -45,7 +49,7 @@ test_that("send_sparql() works with dbpedia", { test_that("send_sparql() works with SyMoGIH", { httptest2::with_mock_dir(file.path("fixtures", "symogih"), { -tib=spq_init() %>% +tib=spq_init(endpoint = "http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?r sym:associatesObject syr:AbOb213") %>% @@ -55,7 +59,7 @@ tib=spq_init() %>% spq_add(". sym:hasKnowledgeUnitType ?KUTy") %>% spq_add("?KUTy rdfs:label ?KUTyLabel") %>% spq_head(n=10) %>% - spq_perform(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") + spq_perform() }) expect_s3_class(tib, "tbl") expect_equal(nrow(tib), 10) @@ -66,12 +70,11 @@ test_that("httr2 options", { skip_if_not_installed("httpuv") - custom_ua_query <- send_sparql( - .query = spq_init() %>% spq_assemble(), + custom_ua_query = spq_init( endpoint = "http://example.com", - dry_run = TRUE, - user_agent = "lalala" - ) + spq_control_request(user_agent = "lalala") + ) %>% + spq_perform(dry_run = TRUE) expect_equal(custom_ua_query[["headers"]][["user-agent"]], "lalala") expect_equal( @@ -79,52 +82,12 @@ test_that("httr2 options", { "example.com?query=%0ASELECT%20%2A%0AWHERE%20%7B%0A%0A%0A%7D%0A%0A" ) - body_form_query <- send_sparql( - .query = spq_init() %>% spq_assemble(), + body_form_query = spq_init( endpoint = "http://example.com", - dry_run = TRUE, - request_type = "body-form" - ) + request_control = spq_control_request(request_type = "body-form") + ) %>% + spq_perform(dry_run = TRUE) expect_equal(body_form_query[["headers"]][["host"]], "example.com") expect_equal(body_form_query[["headers"]][["content-length"]], "53") expect_equal(body_form_query[["headers"]][["content-type"]], "application/x-www-form-urlencoded") }) - -test_that("httr2 options error", { - expect_snapshot( - send_sparql( - .query = spq_init() %>% spq_assemble(), - timeout = "ahahah" - ), - error = TRUE - ) - expect_snapshot( - send_sparql( - .query = spq_init() %>% spq_assemble(), - max_tries = "ahahah" - ), - error = TRUE - ) - expect_snapshot( - send_sparql( - .query = spq_init() %>% spq_assemble(), - max_seconds = "ahahah" - ), - error = TRUE - ) - expect_snapshot( - send_sparql( - .query = spq_init() %>% spq_assemble(), - request_type = "ahahah" - ), - error = TRUE - ) - expect_snapshot( - send_sparql( - .query = spq_init() %>% spq_assemble(), - user_agent = 42 - ), - error = TRUE - ) -}) - diff --git a/tests/testthat/test-spq_control_request.R b/tests/testthat/test-spq_control_request.R new file mode 100644 index 00000000..eaf79c0e --- /dev/null +++ b/tests/testthat/test-spq_control_request.R @@ -0,0 +1,22 @@ +test_that("httr2 options error", { + expect_snapshot( + spq_control_request(timeout = "ahahah"), + error = TRUE + ) + expect_snapshot( + spq_control_request(max_tries = "ahahah"), + error = TRUE + ) + expect_snapshot( + spq_control_request(max_seconds = "ahahah"), + error = TRUE + ) + expect_snapshot( + spq_control_request(request_type = "ahahah"), + error = TRUE + ) + expect_snapshot( + spq_control_request(user_agent = 42), + error = TRUE + ) +}) diff --git a/tests/testthat/test-spq_init.R b/tests/testthat/test-spq_init.R index fc4c4922..c0e6f0b4 100644 --- a/tests/testthat/test-spq_init.R +++ b/tests/testthat/test-spq_init.R @@ -7,3 +7,10 @@ test_that("formatting works", { spq_count(narrative_location_label, sort = TRUE, name = "n_films") }) }) + +test_that("spq_init() errors for DIY request control", { + testthat::expect_snapshot({ + spq_init(request_control = list(max_tries = 1L)) + }, error = TRUE) +}) + diff --git a/tests/testthat/test-spq_perform.R b/tests/testthat/test-spq_perform.R index 3878a0fd..0390e579 100644 --- a/tests/testthat/test-spq_perform.R +++ b/tests/testthat/test-spq_perform.R @@ -1,6 +1,7 @@ test_that("spq_perform() works, replace_prefixes", { httptest2::with_mock_dir(file.path("fixtures", "symogih"), { - tib=spq_init() %>% + tib = spq_init(endpoint = "http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql" + ) %>% spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", syr="http://symogih.org/resource/")) %>% spq_add("?r sym:associatesObject syr:AbOb213") %>% @@ -10,10 +11,7 @@ test_that("spq_perform() works, replace_prefixes", { spq_add(". sym:hasKnowledgeUnitType ?KUTy") %>% spq_add("?KUTy rdfs:label ?KUTyLabel") %>% spq_head(n=10) %>% - spq_perform( - endpoint = "http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql", - replace_prefixes = TRUE - ) + spq_perform(replace_prefixes = TRUE) }) expect_true(all(grepl("syr\\:", tib[["KUTy"]]))) }) diff --git a/tests/testthat/test-spq_set.R b/tests/testthat/test-spq_set.R index fd201c90..eb98227c 100644 --- a/tests/testthat/test-spq_set.R +++ b/tests/testthat/test-spq_set.R @@ -8,7 +8,7 @@ test_that("spq_set() works", { test_that("spq_set() in query", { httptest2::with_mock_dir(file.path("fixtures", "auteurset"), { - tibble = spq_init() %>% + tibble = spq_init(endpoint = "dataBNF") %>% spq_set(anniv = "foaf:birthday") %>% spq_add("?auteur ?anniv ?jour") %>% spq_add("?auteur bio:birth ?date1") %>% @@ -17,7 +17,7 @@ test_that("spq_set() in query", { spq_arrange(jour) %>% spq_prefix() %>% spq_head(n = 10) %>% - spq_perform(endpoint = "dataBNF") + spq_perform() }) expect_s3_class(tibble, "tbl_df") expect_setequal( diff --git a/vignettes/articles/explore.Rmd b/vignettes/articles/explore.Rmd index 3f013f26..d8567fd5 100644 --- a/vignettes/articles/explore.Rmd +++ b/vignettes/articles/explore.Rmd @@ -36,13 +36,16 @@ How can one know whether a service needs `request_type = "body-form"`? ```{r} library("glitter") -spq_init() %>% +query_basis = spq_init( + endpoint = "https://ld.admin.ch/query", + request_control = spq_control_request( + request_type = "body-form" + ) +) +query_basis %>% spq_add("?s ?p ?o") %>% spq_head(n = 10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -58,13 +61,10 @@ If these prefixes are present in `glitter::usual_prefixes`, you don't need to do If they're not, use `glitter::spq_prefix()`. ```{r} -spq_init() %>% +query_basis %>% spq_add("?class a rdfs:Class") %>% spq_head(n = 10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -72,25 +72,19 @@ How many classes are defined in total? This query might be too big for the service. ```{r} -spq_init() %>% +query_basis %>% spq_add("?class a rdfs:Class") %>% spq_count() %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) + spq_perform() ``` We can do the same query for owl classes instead. ```{r} -spq_init() %>% +query_basis %>% spq_add("?class a rdfs:Class") %>% spq_head(n = 10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -99,47 +93,38 @@ Until now we could still be very in the dark as to what the service provides. ### Which classes have instances? ```{r} -spq_init() %>% +query_basis %>% spq_add("?instance a ?class") %>% spq_arrange(class) %>% spq_head(n = 10) %>% spq_select(- instance) %>% spq_select(class, .spq_duplicate = "distinct") %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` ### Which classes have the most instances? ```{r} -spq_init() %>% +query_basis %>% spq_add("?instance a ?class") %>% spq_select(class, .spq_duplicate = "distinct") %>% spq_count(class, sort = TRUE) %>% spq_head(20) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` In this case the class names are quite self explanatory but if they were not we could use ```{r} -spq_init() %>% +query_basis %>% spq_add("?instance a ?class") %>% spq_select(class, .spq_duplicate = "distinct") %>% spq_label(class) %>% spq_count(class, class_label, sort = TRUE) %>% spq_head(20) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -150,55 +135,43 @@ spq_init() %>% Note that you could instead use `spq_add("?property a rdfs:Property")` but in this case it returned nothing. ```{r} -spq_init() %>% +query_basis %>% spq_add("?property a owl:DatatypeProperty") %>% spq_head(n = 10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` How many properties are defined in total? This query might be too big for the service. ```{r} -spq_init() %>% +query_basis %>% spq_add("?property a owl:DatatypeProperty") %>% spq_count() %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) + spq_perform() ``` ### What properties are used? ```{r} -spq_init() %>% +query_basis %>% spq_add("?s ?property ?o") %>% spq_select(- s, - o) %>% spq_select(property, .spq_duplicate = "distinct") %>% spq_head(10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` ### What values does a given property have? ```{r} -spq_init() %>% +query_basis %>% spq_prefix(prefixes = c("schema" = "http://schema.org/"))%>% spq_add("?s schema:addressRegion ?value") %>% spq_count(value, sort = TRUE) %>% spq_head(10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -210,17 +183,14 @@ https://gont.ch/longName`. Which class uses it? ```{r} -spq_init() %>% +query_basis %>% spq_prefix(prefixes = c("gont" = "https://gont.ch/")) %>% spq_add("?s gont:longName ?o") %>% spq_add("?s a ?class") %>% spq_select(-o, -s) %>% spq_select(class, .spq_duplicate = "distinct") %>% spq_head(10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -229,45 +199,36 @@ spq_init() %>% For each organization, what data is there? ```{r} -spq_init() %>% +query_basis %>% spq_prefix(prefixes = c("schema" = "http://schema.org/")) %>% spq_add("?s a schema:Organization") %>% spq_add("?s ?property ?value") %>% spq_select(-value, -s, class, .spq_duplicate = "distinct") %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` And for each postal address? ```{r} -spq_init() %>% +query_basis %>% spq_prefix(prefixes = c("schema" = "http://schema.org/")) %>% spq_add("?s a schema:PostalAddress") %>% spq_add("?s ?property ?value") %>% spq_select(-value, -s, class, .spq_duplicate = "distinct") %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` ## Which data or property name includes a certain substring? ```{r} -spq_init() %>% +query_basis %>% spq_add("?s ?p ?o") %>% spq_filter(str_detect(o, "[Hh]ydro")) %>% spq_select(-s, .spq_duplicate = "distinct") %>% spq_head(10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` @@ -276,16 +237,13 @@ spq_init() %>% ```{r} -spq_init() %>% +query_basis %>% spq_prefix(prefixes = c("schema" = "http://schema.org/")) %>% spq_add("?s a schema:Organization") %>% spq_add("?s schema:name ?name") %>% spq_filter(str_detect(name, "swiss")) %>% spq_head(10) %>% - spq_perform( - endpoint = "https://ld.admin.ch/query", - request_type = "body-form" - ) %>% + spq_perform() %>% knitr::kable() ``` diff --git a/vignettes/articles/glitter_for_dataBNF.Rmd b/vignettes/articles/glitter_for_dataBNF.Rmd index 5d25767f..752fab1e 100644 --- a/vignettes/articles/glitter_for_dataBNF.Rmd +++ b/vignettes/articles/glitter_for_dataBNF.Rmd @@ -26,10 +26,10 @@ Pour limiter la taille et le temps d'exécution de cette vignette chaque jeu de # Explorer les données ```{r explordata} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?s ?p ?o") %>% spq_head(10) %>% - spq_perform(endpoint="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -37,7 +37,7 @@ knitr::kable(tib) # Dates biographiques d'un auteur ```{r dates_biog} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?auteur foaf:birthday ?jour") %>% spq_add("?auteur bio:birth ?date1") %>% spq_add("?auteur bio:death ?date2") %>% @@ -45,7 +45,7 @@ tib=spq_init() %>% spq_arrange(jour) %>% spq_prefix() %>% spq_head(n=10) %>% - spq_perform(endpoint="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -55,7 +55,7 @@ knitr::kable(tib) ```{r fleurs_du_mal} fleurs_du_mal="" -tib=spq_init() %>% +tib=spq_init(endpoint = "dataBNF") %>% spq_add("{fleurs_du_mal} foaf:focus ?Oeuvre") %>% spq_add("?edition rdarelationships:workManifested ?Oeuvre") %>% spq_add("?edition dcterms:date ?date", .required=FALSE) %>% @@ -63,7 +63,7 @@ tib=spq_init() %>% spq_add("?edition dcterms:publisher ?editeur") %>% spq_head(n=10) %>% spq_prefix() %>% - spq_perform("dataBNF") + spq_perform() knitr::kable(tib) @@ -74,11 +74,11 @@ knitr::kable(tib) ```{r doc_num_gallica} doc="" -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("{doc} rdarelationships:electronicReproduction ?URLGallica") %>% spq_add("{doc} dcterms:title ?title") %>% spq_prefix() %>% - spq_perform(endpoint="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -89,12 +89,12 @@ knitr::kable(tib) ```{r expo_virtuelles_bnf} expo="" -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?exposition a {expo}") %>% spq_add("?exposition dcterms:title ?titre") %>% spq_add("?exposition dcterms:subject ?sujet") %>% spq_head(n=30) %>% - spq_perform(endpoint="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -102,12 +102,12 @@ knitr::kable(tib) # Retrouver un nom de personne à partir d'un ISNI ```{r nom_from_isni} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?person isni:identifierValid '0000000121012885'") %>% spq_add("?person foaf:focus ?identity") %>% spq_add("?identity foaf:familyName ?nom") %>% spq_add("?identity foaf:givenName ?prenom") %>% - spq_perform(endpoint="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -116,10 +116,10 @@ knitr::kable(tib) # Identifiant ARK d'une notice à partir du numéro FRBNF ```{r ark_from_frbnf} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?pidArk bnf-onto:FRBNF '11992081'^^xsd:integer") %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -127,14 +127,14 @@ knitr::kable(tib) # Retrouver une oeuvre à partir d'un ISBN ```{r oeuvre_from_isbn} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?work rdfs:label ?title") %>% spq_add("?work dcterms:creator ?creator") %>% spq_add("?manifestation bnf-onto:isbn '2-7028-4777-3'") %>% spq_add("?manifestation rdarelationships:workManifested ?work") %>% spq_add("?creator foaf:name ?name") %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -142,7 +142,7 @@ knitr::kable(tib) # Tous les auteurs morts avant 1924 ```{r auteurs_morts_avant_1024} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?oeuvre dcterms:creator ?auteur") %>% spq_add("?auteur bio:death ?mort") %>% spq_add("?auteur foaf:familyName ?nom") %>% @@ -150,7 +150,7 @@ tib=spq_init() %>% spq_group_by(auteur, nom, mort) %>% spq_arrange(desc(as.integer(mort))) %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -158,10 +158,10 @@ knitr::kable(tib) # Images dans data.bnf.fr ```{r images_databnf} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?image dcterms:type ") %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -170,13 +170,13 @@ knitr::kable(tib) # Ouvrages adaptés pour la jeunesse ```{r ouvrages_jeunesse} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?manifestation bnf-onto:ouvrageJeunesse 'true'^^xsd:boolean") %>% spq_add(". rdarelationships:workManifested ?oeuvre") %>% spq_add(". rdfs:seeAlso ?uri") %>% spq_group_by(uri, oeuvre) %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -184,7 +184,7 @@ knitr::kable(tib) # Portraits d'auteur, issus de Gallica ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?auteur rdf:type skos:Concept") %>% spq_add(". foaf:focus ?person") %>% spq_add("?doc rdarelationships:electronicReproduction ?url") %>% @@ -192,7 +192,7 @@ tib=spq_init() %>% spq_add(". dcterms:subject ") %>% spq_head(n=10) %>% spq_group_by(auteur, url) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -200,14 +200,14 @@ knitr::kable(tib) # Termes spécifiques d'un sujet (RAMEAU) ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?sujet1 skos:prefLabel ?label") %>% spq_add(". skos:narrower ?uri2") %>% spq_add("?uri2 skos:prefLabel ?label2") %>% spq_add("?uri2 skos:narrower ?uri3", .required = FALSE) %>% spq_add("?uri3 skos:prefLabel ?label3", .required = FALSE) %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -215,11 +215,11 @@ knitr::kable(tib) # Sujets RAMEAU de type nom commun ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?sujet dcterms:isPartOf ") %>% spq_add(". skos:prefLabel ?label") %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -227,13 +227,13 @@ knitr::kable(tib) # Alignement entre les sujets RAMEAU et lieux ```{r rameau_et_lieux} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?c a ") %>% spq_add("?lieu foaf:focus ?c") %>% spq_add("?lieu skos:closeMatch ?concept") %>% spq_group_by(lieu, concept , c) %>% spq_head(n=100) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` @@ -241,13 +241,13 @@ knitr::kable(tib) # Liens vers wikipedia pour les auteurs ```{r} -tib=spq_init() %>% +tib=spq_init(endpoint="dataBNF") %>% spq_add("?ConceptA foaf:focus ?auteur") %>% spq_add("?oeuvre dcterms:creator ?auteur") %>% spq_add("?ConceptA rdfs:seeAlso ?wikipedia") %>% spq_filter(str_detect(wikipedia,'wikipedia')) %>% spq_head(n=10) %>% - spq_perform(e="dataBNF") + spq_perform() knitr::kable(tib) ``` diff --git a/vignettes/articles/glitter_for_hal.Rmd b/vignettes/articles/glitter_for_hal.Rmd index 81745d7d..2aa62037 100644 --- a/vignettes/articles/glitter_for_hal.Rmd +++ b/vignettes/articles/glitter_for_hal.Rmd @@ -27,10 +27,10 @@ On s'intéresse à ce document: haldoc:inria-00362381. ## Rechercher toutes les informations associées à ce document ```{r} -tib_info=spq_init() %>% +tib_info=spq_init(endpoint = "hal") %>% spq_add("haldoc:inria-00362381 dcterms:hasVersion ?version") %>% # Ce doc a des versions ?version spq_add("?version ?p ?object") %>% # ?version a des prop. ?p les liant à ?object - spq_perform(e="hal") + spq_perform() head(tib_info) ``` @@ -38,7 +38,7 @@ head(tib_info) ## Rechercher l’URI, le titre, le lien vers le PDF et les auteurs de [toutes les versions de] ce document ```{r} -query_doc = spq_init() %>% +query_doc = spq_init(endpoint = "hal") %>% spq_add("haldoc:inria-00362381 dcterms:hasVersion ?version") %>% # Ce doc a des versions ?version spq_add("?version dcterms:title ?title") %>% # ?version a pour titre ?titre spq_add(". dcterms:creator ?creator") %>% # ...... et pour créateur ?creator @@ -46,7 +46,7 @@ query_doc = spq_init() %>% spq_add("?creator hal:person ?person") %>% # ?creator est une personne ?person spq_add("?person foaf:name ?name") # ?person a pour nom ?name -tib_doc=spq_perform(query_doc,"hal") +tib_doc=spq_perform(query_doc) tib_doc ``` @@ -58,7 +58,7 @@ query_doc_autConcat = query_doc %>% spq_group_by(version, title,pdf) %>% # Groupe les résultats par ?version, ?title, ?pdf spq_summarise(authors = str_c(name, sep = ', ')) # Concatène les noms d'auteur dans ?authors -tib_doc_autConcat = spq_perform(query_doc_autConcat,"hal") +tib_doc_autConcat = spq_perform(query_doc_autConcat) tib_doc_autConcat ``` @@ -66,13 +66,13 @@ tib_doc_autConcat On peut également **agréger/résumer** les résultats renvoyés par la requête, par exemple en **recherchant le nombre d’auteurs d’un document** (par version) ```{r} -tib_nbAutDoc=spq_init() %>% +tib_nbAutDoc=spq_init(endpoint = "hal") %>% spq_add("haldoc:inria-00362381 dcterms:hasVersion ?version") %>% # Ce doc a des versions ?version spq_add("?version dcterms:creator ?creator") %>% # ?version a pour créateur ?creator spq_add("?creator hal:person ?person") %>% # ?creator est une personne ?person spq_group_by(version) %>% # Groupe par ?version spq_summarise(nbperson = n(unique(person))) %>% # Résume: ?nbperson = nb de ?person dist. - spq_perform(e="hal") + spq_perform() tib_nbAutDoc ``` @@ -82,12 +82,12 @@ tib_nbAutDoc On cherche les types associés aux versions de documents. Ces types sont associés à des étiquettes (dans plusieurs langues) qui permettent de comprendre de quoi il s'agit "en langage ordinaire". ```{r} -query_docType=spq_init() %>% +query_docType=spq_init(endpoint = "hal") %>% spq_add("haldoc:inria-00362381 dcterms:hasVersion ?version") %>% # Ce doc a des versions ?version spq_add("?version dcterms:type ?type") %>% # ?version est un document de type ?type spq_add("?type skos:prefLabel ?label") # ?type a pour étiquette ?label -tib_docType=spq_perform(query_docType,"hal") +tib_docType=spq_perform(query_docType) tib_docType ``` @@ -99,7 +99,7 @@ On peut **filtrer les résultats** pour n'afficher que la ligne de résultats po query_docTypeFr=query_docType %>% spq_filter(lang(label) == 'fr') # Filtre pour garder les étiquettes en français -tib_docTypeFr=spq_perform(query_docTypeFr,"hal") +tib_docTypeFr=spq_perform(query_docTypeFr) tib_docTypeFr ``` @@ -114,14 +114,14 @@ Considérons une des "forme-auteur" de Fabien Gandon, [https://data.archives-ouv ```{r} fabien_gandon="" # fabien_gandon = cette forme auteur -query_foAut=spq_init() %>% +query_foAut=spq_init(endpoint = "hal") %>% spq_add("?document dcterms:hasVersion ?version") %>% # ?document a des versions ?version spq_add("?version dcterms:creator ?creator") %>% # ?version a pour créateur ?creator spq_add("?creator hal:person {fabien_gandon}") %>% # ?creator est fabien_gandon ({déf. de l'objet dans R}) spq_add("?version dcterms:type ?type") %>% # ?version a pour type ?type spq_add("?type skos:prefLabel ?label") %>% # ?type a pour étiquette ?label spq_filter(lang(label) == 'fr') # Filtre pour garder les ?label en français -tib_foAut=spq_perform(query_foAut,"hal") +tib_foAut=spq_perform(query_foAut) head(tib_foAut) ``` @@ -136,7 +136,7 @@ query_foAutNbDoc=query_foAut %>% spq_group_by(type, label) %>% # Groupe par ?type et ?label spq_summarise(nbdoc = n(unique(document))) -tib_foAutNbDoc=spq_perform(query_foAutNbDoc,"hal") +tib_foAutNbDoc=spq_perform(query_foAutNbDoc) tib_foAutNbDoc ``` @@ -147,7 +147,7 @@ On peut afficher ces résultats en **ordonnant** les lignes selon le nombre de d query_foAutNbDocOrd=query_foAutNbDoc%>% spq_arrange(desc(nbdoc)) # Ordonne par ordre décroissant de ?nbdoc -tib_foAutNbDocOrd=spq_perform(query_foAutNbDocOrd,"hal") +tib_foAutNbDocOrd=spq_perform(query_foAutNbDocOrd) tib_foAutNbDocOrd ``` @@ -155,7 +155,7 @@ tib_foAutNbDocOrd On peut également s'intéresser aux **dates** de publication. Par exemple ici, on récupère la date de publication, l'année correspondante, et on résume l'information en calculant le nombre de documents par année. ```{r} -tib_dat=spq_init() %>% +tib_dat=spq_init(endpoint = "hal") %>% spq_add("?document dcterms:hasVersion ?version") %>% spq_add("?version dcterms:creator ?creator") %>% spq_add(". dcterms:issued ?date") %>% # ?version est sortie à ?date @@ -164,7 +164,7 @@ tib_dat=spq_init() %>% spq_group_by(year) %>% # Groupe par ?year spq_summarise(nbdoc = n(unique(document))) %>% spq_arrange(year) %>% - spq_perform(e="hal") + spq_perform() tib_dat ``` @@ -176,11 +176,11 @@ Une personne=un IdHAL=plusieurs formes-auteur ## Afficher les URIs de toutes les formes-auteur associées à la forme « Fabien Gandon » via l’IdHAL ```{r} -query_aut=spq_init() %>% +query_aut=spq_init(endpoint = "hal") %>% spq_add("{fabien_gandon} ore:isAggregatedBy ?o") %>% # {fabien gandon} correspond à ?o spq_add("?forme ore:isAggregatedBy ?o") # ?forme correspond à ?o -tib_aut=spq_perform(query_aut,"hal") +tib_aut=spq_perform(query_aut) tib_aut ``` @@ -200,7 +200,7 @@ query_autNbDocYear=query_aut %>% spq_arrange(year) %>% # Ordonne par ordre décroissant de ?year spq_summarise(nbdoc = n(unique(document))) -tib_autNbDocYear=spq_perform(query_autNbDocYear,"hal") +tib_autNbDocYear=spq_perform(query_autNbDocYear) tib_autNbDocYear ```