From 5a9f81876ba0b5830a1652eb85cdf971f9e39bf7 Mon Sep 17 00:00:00 2001 From: Raffaele Mancuso Date: Tue, 4 Feb 2025 10:30:04 +0100 Subject: [PATCH] Implement timeout in httr Fixes #312 --- R/oa_fetch.R | 24 +++++++++++++++--------- man/oa_fetch.Rd | 7 ++++++- man/oa_request.Rd | 7 ++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/R/oa_fetch.R b/R/oa_fetch.R index 050fbe2..a16a680 100644 --- a/R/oa_fetch.R +++ b/R/oa_fetch.R @@ -83,7 +83,8 @@ oa_fetch <- function(entity = if (is.null(identifier)) NULL else id_type(shorten count_only = FALSE, mailto = oa_email(), api_key = oa_apikey(), - verbose = FALSE) { + verbose = FALSE, + timeout = 30) { output <- match.arg(output) entity <- match.arg(entity, oa_entities()) @@ -142,7 +143,8 @@ oa_fetch <- function(entity = if (is.null(identifier)) NULL else id_type(shorten mailto = mailto, api_key = api_key, parse = output != "raw", - verbose = verbose + verbose = verbose, + timeout = timeout ) } @@ -197,6 +199,9 @@ oa_fetch <- function(entity = if (is.null(identifier)) NULL else id_type(shorten #' If FALSE, returns the raw JSON response as string. #' @param verbose Logical. #' If TRUE, print information about the querying process. Defaults to TRUE. +#' @param timeout Numeric. +#' Number of seconds to wait for a response until giving up. Can not be less than 1 ms. +#' Defaults to 30. #' #' @return a data.frame or a list of bibliographic records. #' @@ -312,7 +317,8 @@ oa_request <- function(query_url, mailto = oa_email(), api_key = oa_apikey(), parse = TRUE, - verbose = FALSE) { + verbose = FALSE, + timeout = 30) { # https://httr.r-lib.org/articles/api-packages.html#set-a-user-agent ua <- httr::user_agent("https://github.com/ropensci/openalexR/") @@ -335,7 +341,7 @@ oa_request <- function(query_url, } # first, download info about n. of items returned by the query - res <- api_request(query_url, ua, query = query_ls, api_key = api_key, parse = FALSE) + res <- api_request(query_url, ua, query = query_ls, api_key = api_key, parse = FALSE, timeout = timeout) res_parsed <- jsonlite::fromJSON(res, simplifyVector = FALSE) res_meta <- res_parsed$meta if (parse) { @@ -364,7 +370,7 @@ oa_request <- function(query_url, if (verbose) cat("=") Sys.sleep(1 / 10) query_ls[[paging]] <- next_page - res <- api_request(query_url, ua, query = query_ls) + res <- api_request(query_url, ua, query = query_ls, timeout = timeout) data <- c(data, res[[result_name]]) i <- i + 1 next_page <- get_next_page("cursor", i, res) @@ -412,10 +418,10 @@ oa_request <- function(query_url, query_ls[[paging]] <- next_page if (parse) { - res <- api_request(query_url, ua, query = query_ls, parse = TRUE) + res <- api_request(query_url, ua, query = query_ls, parse = TRUE, timeout = timeout) if (!is.null(res[[result_name]])) data[[i]] <- res[[result_name]] } else { - raw <- api_request(query_url, ua, query = query_ls, parse = FALSE) + raw <- api_request(query_url, ua, query = query_ls, parse = FALSE, timeout = timeout) data[[i]] <- raw } } @@ -707,8 +713,8 @@ oa_random <- function(entity = oa_entities(), final_res } -api_request <- function(query_url, ua, query, api_key = oa_apikey(), parse = TRUE) { - res <- httr::GET(query_url, ua, query = query, httr::add_headers(api_key = api_key)) +api_request <- function(query_url, ua, query, api_key = oa_apikey(), parse = TRUE, timeout = 30) { + res <- httr::GET(query_url, ua, query = query, httr::add_headers(api_key = api_key), httr::timeout(timeout)) empty_res <- if (parse) list() else "{}" diff --git a/man/oa_fetch.Rd b/man/oa_fetch.Rd index c261ff3..e64599e 100644 --- a/man/oa_fetch.Rd +++ b/man/oa_fetch.Rd @@ -20,7 +20,8 @@ oa_fetch( count_only = FALSE, mailto = oa_email(), api_key = oa_apikey(), - verbose = FALSE + verbose = FALSE, + timeout = 30 ) } \arguments{ @@ -110,6 +111,10 @@ Your OpenAlex Premium API key, if available.} Default to \code{verbose = FALSE}. To shorten the printed query URL, set the environment variable openalexR.print to the number of characters to print: \code{Sys.setenv(openalexR.print = 70)}.} + +\item{timeout}{Numeric. +Number of seconds to wait for a response until giving up. Can not be less than 1 ms. +Defaults to 30.} } \value{ A data.frame or a list. Result of the query. diff --git a/man/oa_request.Rd b/man/oa_request.Rd index 9de2c86..effea5d 100644 --- a/man/oa_request.Rd +++ b/man/oa_request.Rd @@ -13,7 +13,8 @@ oa_request( mailto = oa_email(), api_key = oa_apikey(), parse = TRUE, - verbose = FALSE + verbose = FALSE, + timeout = 30 ) } \arguments{ @@ -50,6 +51,10 @@ If FALSE, returns the raw JSON response as string.} \item{verbose}{Logical. If TRUE, print information about the querying process. Defaults to TRUE.} + +\item{timeout}{Numeric. +Number of seconds to wait for a response until giving up. Can not be less than 1 ms. +Defaults to 30.} } \value{ a data.frame or a list of bibliographic records.