-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[R] improve binary/text response handling #20131
Changes from 5 commits
b3022dd
17f9a7c
3c847fb
47c9dca
09a5f4e
88fc70d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,13 +153,13 @@ | |
|
||
{{/vendorExtensions.x-streaming}} | ||
if (local_var_response$status_code >= 200 && local_var_response$status_code <= 299) { | ||
local_var_response$content | ||
return(local_var_response$content) | ||
} else if (local_var_response$status_code >= 300 && local_var_response$status_code <= 399) { | ||
local_var_response | ||
return(local_var_response) | ||
} else if (local_var_response$status_code >= 400 && local_var_response$status_code <= 499) { | ||
local_var_response | ||
return(local_var_response) | ||
} else if (local_var_response$status_code >= 500 && local_var_response$status_code <= 599) { | ||
local_var_response | ||
return(local_var_response) | ||
} | ||
}, | ||
|
||
|
@@ -543,24 +543,21 @@ | |
if (local_var_resp$status_code >= 200 && local_var_resp$status_code <= 299) { | ||
{{#returnType}} | ||
{{#isPrimitiveType}} | ||
local_var_content <- local_var_resp$response | ||
local_var_resp, "text", encoding = "UTF-8", simplifyVector = FALSE | ||
) | ||
mattpollock marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# save response in a file | ||
if (!is.null(data_file)) { | ||
write(local_var_content, data_file) | ||
private$WriteFile(local_var_resp, data_file) | ||
mattpollock marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
ApiResponse$new(content,resp) | ||
{{/isPrimitiveType}} | ||
{{^isPrimitiveType}} | ||
# save response in a file | ||
if (!is.null(data_file)) { | ||
write(local_var_resp$response, data_file) | ||
private$WriteFile(local_var_resp, data_file) | ||
} | ||
|
||
deserialized_resp_obj <- tryCatch( | ||
self$api_client$deserialize(local_var_resp$response_as_text(), "{{returnType}}", loadNamespace("{{packageName}}")), | ||
private$Deserialize(local_var_resp, "{{returnType}}"), | ||
mattpollock marked this conversation as resolved.
Show resolved
Hide resolved
|
||
error = function(e) { | ||
{{#useDefaultExceptionHandling}} | ||
stop("Failed to deserialize response") | ||
|
@@ -579,10 +576,13 @@ | |
{{! Returning the ApiResponse object with NULL object when the endpoint doesn't return anything}} | ||
local_var_resp$content <- NULL | ||
{{/returnType}} | ||
local_var_resp | ||
} else if (local_var_resp$status_code >= 300 && local_var_resp$status_code <= 399) { | ||
return(local_var_resp) | ||
} | ||
|
||
local_var_error_msg <- local_var_resp$ResponseAsText() | ||
if (local_var_resp$status_code >= 300 && local_var_resp$status_code <= 399) { | ||
{{#returnExceptionOnFailure}} | ||
local_var_error_msg <- local_var_resp$response | ||
|
||
if (local_var_error_msg == "") { | ||
local_var_error_msg <- paste("Server returned ", local_var_resp$status_code, " response status code.") | ||
} | ||
|
@@ -600,7 +600,6 @@ | |
{{/returnExceptionOnFailure}} | ||
} else if (local_var_resp$status_code >= 400 && local_var_resp$status_code <= 499) { | ||
{{#returnExceptionOnFailure}} | ||
local_var_error_msg <- local_var_resp$response | ||
if (local_var_error_msg == "") { | ||
local_var_error_msg <- "Api client exception encountered." | ||
} | ||
|
@@ -618,7 +617,6 @@ | |
{{/returnExceptionOnFailure}} | ||
} else if (local_var_resp$status_code >= 500 && local_var_resp$status_code <= 599) { | ||
{{#returnExceptionOnFailure}} | ||
local_var_error_msg <- local_var_resp$response | ||
if (local_var_error_msg == "") { | ||
local_var_error_msg <- "Api server exception encountered." | ||
} | ||
|
@@ -635,11 +633,58 @@ | |
if (is.null(local_var_resp$response) || local_var_resp$response == "") { | ||
local_var_resp$response <- "API server error" | ||
} | ||
local_var_resp | ||
return(local_var_resp) | ||
{{/returnExceptionOnFailure}} | ||
} | ||
}{{^-last}},{{/-last}} | ||
{{/operation}} | ||
), | ||
private = list( | ||
#' @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 (private$IsBinary(local_var_resp$response)) { | ||
writeBin(local_var_resp$response, file) | ||
} else { | ||
response <- private$Deserialize(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) | ||
}, | ||
|
||
#' @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. | ||
Deserialize = function(local_var_resp, return_type = NULL) { | ||
text <- local_var_resp$ResponseAsText() | ||
if (is.na(text)) { | ||
return(local_var_resp$response) | ||
} else if (is.null(return_type)) { | ||
return(text) | ||
} | ||
return(self$api_client$deserialize(text, return_type, loadNamespace("{{packageName}}"))) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about adding these functions to api_client (which contains other utility functions)? otherwise we will be repeating the same set of functions (private) in every auto-generated API files There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Note that the code will be appear once in generated clients, but will need to be maintained in 2 places:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks. we can use partial mustache files but that can be done in a separate PR instead. |
||
) | ||
) | ||
{{/operations}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we keep the snake case convention for the time being?
changing it results in breaking changes (without fallback) which is not something we want to do in the next minor release v7.11.0 (FYI we allow breaking changes with fallback in minor release)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to use PascalCase, I can think of a solution using lambda but I prefer we deal with it in another PR instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll revert to snake case. I switched to pearl based on the contributing guide, but I appreciate avoiding breaking changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done