[R] improve binary/text response handling (#20131)

* [R client] better support for binary/compressed responses

* cleanup

* revert change after PR review

* update samples

* fix R tests

* move private api methods to api-client, revert breaking method name change
This commit is contained in:
Matt Pollock
2024-11-24 09:12:39 -05:00
committed by GitHub
parent c33d3aaae9
commit 6399a7a97e
34 changed files with 1522 additions and 1101 deletions

View File

@@ -382,6 +382,52 @@ ApiClient <- R6::R6Class(
# not json mime type, simply return the first one
return(headers[1])
}
},
#' @description
#' Deserialize the response
#'
#' @param local_var_resp The API response
#' @param return_type The target return type for the endpoint (e.g., `"object"`). If `NULL` text will be left as-is.
#' @return If the raw response is corecable to text, return the text. Otherwise return the raw resposne.
DeserializeResponse = function(local_var_resp, return_type = NULL) {
text <- local_var_resp$response_as_text()
if (is.na(text)) {
return(local_var_resp$response)
} else if (is.null(return_type)) {
return(text)
}
return(self$deserialize(text, return_type, loadNamespace("openapi")))
},
#' @description
#' Write response to a file
#'
#' The function will write out data.
#'
#' 1. If binary data is detected it will use `writeBin`
#' 2. If the raw response is coercable to text, the text will be written to a file
#' 3. If the raw response is not coercable to text, the raw response will be written
#'
#' @param local_var_resp The API response
#' @param file The name of the data file to save the result
WriteFile = function(local_var_resp, file) {
if (self$IsBinary(local_var_resp$response)) {
writeBin(local_var_resp$response, file)
} else {
response <- self$DeserializeResponse(local_var_resp)
base::write(response, file)
}
},
#' @description
#' Check response for binary content
#'
#' @param local_var_resp The API response
IsBinary = function(x) {
# ref: https://stackoverflow.com/a/17098690/1785752
b <- readBin(x, "int", n = 1000, size=1, signed=FALSE)
return(max(b) > 128)
}
)
)