Open jgjuara opened 1 year ago
basandome en el codigo para GET propongo:
base_url <- "http://apis.datos.gob.ar/georef/api/"
post_endpoint <- function(endpoint, args) {
# Obtener el token de la variable de entorno
token <- Sys.getenv("GEOREFAR_TOKEN")
url <- paste0(base_url, endpoint)
load <- as.data.frame(x = args) %>%
list() %>%
setNames(., endpoint)
body <- jsonlite::toJSON(load, auto_unbox = T)
# Comprobar si el token está presente
if (is.null(token) | token == "") {
response <- httr::POST(url, body = body,
encode = "raw",
httr::add_headers("Content-Type" = "application/json")
)
} else {
response <- httr::POST(url, body = body,
encode = "raw",
httr::add_headers(Authorization = paste("Bearer",
token),
"Content-Type" = "application/json"))
}
check_status(response)
jsonlite::fromJSON(httr::content(response, "text"))[["resultados"]][endpoint] %>%
tidyr::unnest(cols = c(calles)) %>%
jsonlite::flatten(recursive = T) %>%
dplyr::rename_with(.fn = function(x) {gsub(pattern = "\\$|\\.", replacement = "_", x = x)}) %>%
suppressMessages()
}
#' Obtener Calles
post_calles <- function(id = NULL, nombre = NULL, tipo = NULL, provincia = NULL, departamento = NULL, aplanar = TRUE, campos = NULL, max = NULL, exacto = NULL){
args <- purrr::compact(list(id = id, nombre = nombre, tipo = tipo, provincia = provincia, departamento = departamento, aplanar = aplanar, campos = campos, max = max, exacto = exacto))
endpoint <- "calles"
check_internet()
post_endpoint(endpoint = endpoint, args = args)
}
@TuQmano @pdelboca estaba pensando que en vez de armar toda una nueva tanda de funciones post_*
quizás es mejor hacer una función buscar_*
que tenga una parametro para el método POST/GET.
En vez de:
get_localidades(...)
post_localidades(...)
Tener:
buscar_localidades(metodo = "GET", ...)
buscar_localidades(metodo = "POST", ...)
¿qué les parece?
A mi me gusta. Ver de no agregar muchas mas funciones exportables y que cada endpoint tenga un par segun param que defina el metodo. Ahi surgiría una decision:
base_url <- "http://apis.datos.gob.ar/georef/api/"
get_endpoint <- function(endpoint, args) {
if (! assertthat::noNA(args)) {
stop(c('GET no admite NAs. Los parametros siguientes tienen NAs:', sapply(names(args[is.na(args)]),
function(x) paste0(" ", x),
USE.NAMES = F)))
}
# Obtener el token de la variable de entorno
token <- Sys.getenv("GEOREFAR_TOKEN")
url <- paste0(base_url, endpoint)
# Comprobar si el token esta presente
if (is.null(token) | token == "") {
response <- httr::GET(url, query = args)
} else {
response <- httr::GET(url,
httr::add_headers(Authorization = paste("Bearer", token)),
query = args)
}
parsed <- suppressMessages(jsonlite::fromJSON(httr::content(response, "text")))
check_status(response)
data <- parsed[[gsub(pattern = "-",replacement = "_", x = endpoint)]] %>%
purrr::modify_if(is.null, list)
if (length(data) == 0) {
warning("La consulta devolvio una lista vacia", call. = F)
}
data %>%
dplyr::as_tibble(.name_repair = function(x) {gsub(pattern = "\\$|\\.", replacement = "_", x = x)})
}
post_endpoint <- function(endpoint, args, drop_params) {
# if (! assertthat::noNA(unlist(args))) {
# stop(c('Los parametros siguientes tienen NAs:',
# sapply(filter(.data = as_tibble(apply(sapply(args, is.na),
# MARGIN = 2, FUN = sum),
# rownames = "parametros"), value != 0)$parametros,
# function(x) paste0(" ", x), USE.NAMES = F)))
# }
# Obtener el token de la variable de entorno
token <- Sys.getenv("GEOREFAR_TOKEN")
url <- paste0(base_url, endpoint)
args <- discard(args, is.null)
load <- as.data.frame(x = args) %>%
list() %>%
setNames(., endpoint)
body <- jsonlite::toJSON(load)
# Comprobar si el token está presente
if (is.null(token) | token == "") {
response <- httr::POST(url, body = body,
content_type_json()
)
} else {
response <- httr::POST(url, body = body,
encode = "raw",
httr::add_headers(Authorization = paste("Bearer",
token),
"Content-Type" = "application/json"))
}
parsed <- jsonlite::fromJSON(httr::content(response, "text"))
check_status(response)
data <- parsed[["resultados"]][c(endpoint, "parametros")] %>%
tidyr::unnest(cols = dplyr::all_of(endpoint), keep_empty = T) %>%
jsonlite::flatten(recursive = T) %>%
dplyr::rename_with(.fn = function(x) {gsub(pattern = "\\$|\\.", replacement = "_", x = x)}) %>%
suppressMessages()
if (nrow(filter(data, if_all(.cols = !matches("parametros"), .fns = is.na))) != 0) {
warning("La consulta una o mas respuestas vacias", call. = F)
}
if (drop_params) {
data %>% select(-matches("parametros"))
} else {
data
}
}
#' Consultar Calles
consultar_calles <- function(id = NULL, nombre = NULL, tipo = NULL, provincia = NULL, departamento = NULL, aplanar = TRUE, campos = NULL, max = NULL, exacto = NULL, drop_params = T, post = F){
assertthat::assert_that(is.logical(post), msg = "parametro 'post' debe ser logico")
assertthat::assert_that(is.logical(drop_params), msg = "parametro 'drop_params' debe ser logico")
assertthat::assert_that(max <= 5000 || is.null(max), msg = "parametro 'max' debe ser menor a 5000 o NULL")
args <- list(id = id, nombre = nombre, tipo = tipo, provincia = provincia, departamento = departamento, aplanar = aplanar, campos = campos, max = max, exacto = exacto)
endpoint <- "calles"
check_internet()
if (post) {
post_endpoint(endpoint = endpoint, args = args, drop_params = drop_params)
} else {
get_endpoint(endpoint = endpoint, args = args)
}
}
Sería conveniente agregar funciones que faciliten las consultas por método POST a la API de georef-ar como mencionó @gonzaloazuaga2021 en https://github.com/PoliticaArgentina/geoAr/issues/12#issuecomment-1607489921_