Closed DyfanJones closed 3 years ago
You are correct that you need to provide encode
and decode
functions for text/csv
. You can take a look on how it is done for application/json
here and here.
For text/csv
content handler might look like (I use base connections and csv parsers here, but this can be amended using whatever you prefer):
library(RestRserve)
encode_decode_middleware = EncodeDecodeMiddleware$new()
encode_decode_middleware$ContentHandlers$set_encode(
"text/csv",
function(x) {
con = rawConnection(raw(0), "w")
on.exit(close(con))
write.csv(x, con, row.names = FALSE)
rawConnectionValue(con)
}
)
encode_decode_middleware$ContentHandlers$set_decode(
"text/csv",
function(x) {
res = try({
con = textConnection(rawToChar(x), open = "r")
on.exit(close(con))
read.csv(con)
}, silent = TRUE)
if (inherits(res, "try-error")) {
raise(HTTPError$bad_request(body = attributes(res)$condition$message))
}
return(res)
}
)
And test
data(iris)
app = Application$new(middleware = list(encode_decode_middleware))
app$add_get("/iris", FUN = function(req, res) {
res$set_content_type("text/csv")
res$set_body(iris)
})
req = Request$new(path = "/iris", method = "GET")
res = app$process_request(req)
iris_out = read.csv(textConnection(rawToChar(res$body)))
head(iris_out)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa
app$add_post("/in", FUN = function(req, res) {
str(req$body)
})
req2 = Request$new(path = "/in", method = "POST", body = res$body, content_type = "text/csv")
res2 = app$process_request(req2)
'data.frame': 150 obs. of 5 variables: $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... $ Species : chr "setosa" "setosa" "setosa" "setosa" ...
@dselivanov thanks for your help. I have updated my example to include this. Feel free to close this ticket :)
Hi all,
Is there away to extend content_type when calling RestRserve endpoints?
Background in request
I am currently developing a package that interfaces into AWS sagemaker R6sagemaker. It is very much in early development however I have managed to get the basics working. I would like to use
RestRserve
to demonstrate R models on AWS SageMaker. By default AWS SageMaker uses the content_type "text/csv" when sending text files over to it's endpoints: AWS Sagemaker content typesExample:
I have developed an example: sagemaker restrserve example, however it fails due to the default "text/csv" content_type.
From reading your documentation I thought I could extend the content_type as follows:
However I still get status code:
415 Unsupported Media Type
. Is there away to extend content_type to include "text/csv"?