R/utils.R

Defines functions eccc_paginate eccc_request

#' eccc_request
#'
#' @param endpoint The URL endpoint for the API
#' @param path The URL path to append to \code{endpoint}
#' @param query List of parameters to be passed to query
#' @return \code{eccc_resp} object
#' @keywords internal
#' @noRd
#'
eccc_request <- function(endpoint = "https://api.weather.gc.ca/",
                         path, query = list()) {
  if (missing(path)) {
    stop("Failed to provide path to ``eccc_request``", call. = FALSE)
  }

  query[["f"]] <- "json"

  req_url <- httr::modify_url(endpoint, path = path)

  res <- httr::GET(
    req_url,
    httr::user_agent("https://github.com/rywhale/ecccgeometR"),
    query = query
  )

  # Check request content type
  if (httr::http_type(res) != "application/json") {
    stop("API did not return json", call. = FALSE)
  }

  # Parse to json
  parsed <- jsonlite::fromJSON(
    httr::content(res, "text", encoding = "UTF-8")
  )

  # Check for request error
  if (httr::http_error(res)) {
    stop(
      paste(
        "ECCC API request failed.",
        httr::status_code(res),
        parsed$message
      )
    )
  }

  structure(
    list(
      content = parsed,
      path = path,
      response = res,
      query = query
    ),
    class = "eccc_resp"
  )
}

#' eccc_paginate
#'
#' @description Handles pagination by iterating through results
#' @param req \code{eccc_resp} object
#' @return \code{tibble} containing all paged results
#' @keywords internal
#' @noRd
#'
eccc_paginate <- function(req, geometry = TRUE) {
  parsed_req <- req$content$features

  if (geometry) {
    parsed_req <- dplyr::bind_cols(
      parsed_req$properties,
      parsed_req$geometry
    )
  }

  if (!"numberMatched" %in% names(req$content)) {
    return(parsed_req)
  }

  query <- req$query

  # Loop to grab all records
  start_index <- req$content$numberReturned + 1

  while (start_index < req$content$numberMatched) {
    query[["startindex"]] <- start_index

    query_req <- eccc_request(path = req$path, query = query)

    start_index <- start_index + query_req$content$numberReturned

    if (geometry) {
      query_req <- dplyr::bind_cols(
        query_req$content$features$properties,
        query_req$content$features$geometry
      )
    }

    # parsed_req <- dplyr::bind_rows(parsed_req, query_req)
    parsed_req <- vctrs::vec_rbind(parsed_req, query_req)
  }

  parsed_req
}
rywhale/ecccgeometR documentation built on Dec. 22, 2021, 8:19 p.m.