I want a data frame to a @post request body, and do something (say, time series analysis) and return a data frame
Or maybe send JSON and inside the post function, convert it to a data frame and do something and return a data frame
I am new to plumber and am having trouble understanding this
Converting to JSON is feasible but you have to handle these things by yourself - zero-row table, the Date attributes, etc.
So if you only want to pass the data.frame, a safer (probably better) way is to use the rds serializer.
#* @post /api
#* @serializer rds
function() {
...
}
out <- httr::POST(
url,
encode = "raw",
body = body,
httr::content_type("application/octet-stream"),
...
)
# you may need to check httr::status_code() == 200L
# or if is.raw(httr::content(out)) is TRUE, first
base::unserialize(httr::content(out))
Thank you for your comment; but I have a query.
This is what I am doing:
#'@post /testdf
#'@serializer rds
function(req){
data <- (req$postBody)
return(ncol(data))
}
User:
data <- read.csv("XYZ.csv")
result <- POST(url = 'http://127.0.0.1:8000/testdf', body = data, encode = "raw"
httr::content_type("application/octet-stream"))
But it says this:
Error in body_raw(body) : is.raw(body) is not TRUE
Can you tell me what I am doing wrong here
Sorry, I didn't notice that you were asking "POSTING the data.frame". I misunderstood for "REQUSTING the data.frame". There're workarounds for this. I remembered https://github.com/ozean12/protopretzel uses this.
However, I don't have time to write an example for you. But if you really need it, I can make an example later.
I didn't find what I am looking for here at https://github.com/ozean12/protopretzel
Thanks for the help, though. If you could provide and example whenever you can, that'd be great. Thanks!
@mansi-aggarwal-2504 It's there actually. Here the example. Put the three files in the same folder. Run main.R to launch a server. Run client.R to test.
#* @post /api
#* @serializer rds
function(req) {
req$robj
}
(A better example is this: https://github.com/ozean12/protopretzel/blob/master/R/protobuf_filter.R)
library(plumber)
x <- plumb("plumber.R")
x$filter("robj", function(req) {
req$rook.input$rewind()
req$robj <- unserialize(req$rook.input$read())
plumber::forward()
})
x$run(debug = TRUE, port = 9999)
out <- httr::POST(
"http://127.0.0.1:9999/api",
encode = "raw",
body = serialize(iris, NULL),
httr::content_type("application/octet-stream")
)
# you may need to check httr::status_code() == 200L
# or if is.raw(httr::content(out)) is TRUE, first
base::unserialize(httr::content(out))

That might be what you are looking for, you can try that, just replace with your hostname.
(requires plumber >= 0.4.7)
plumber.R
library(plumber)
#* Sort df
#* @param df
#* @json
#* @post /sortdfjson
function(df) {
df[order(df$Height),]
}
#* Sort df
#* @param df
#* @serializer rds
#* @post /sortdfrds
function(df) {
df[order(df$Height),]
}
entrypoint.R
library(plumber)
pr <- plumb("plumber.R")
pr$run()
In another R session (replace hostname:port). You basically put your data.frame in a json format and add a name (the name of your parameter) in front.
a <- paste0('{"df":',jsonlite::toJSON(trees), '}', sep = '')
class(a) <- "json"
req <- httr::POST(url = "http://127.0.0.1:3540/sortdfjson",
httr::accept_json(),
body = a,
httr::write_disk("response.json", overwrite = TRUE))
df1 <- jsonlite::fromJSON(httr::content(req, as = "text"))
req <- httr::POST(url = "http://127.0.0.1:3540/sortdfrds",
httr::accept_json(),
body = a,
httr::write_disk("response.rds", overwrite = TRUE))
df2 <- readRDS("response.rds")
On a clean installation of R 3.6.3, having just installed plumber 0.4.6 from CRAN, I tried to recreate the last example (with plumber.R and entrypoint.R). I get this error:
Error in parseBlock(lineNum, file) : No such @serializer registered: rds
I can use the html and json serializers, but it will not start with rds set. I'm happy to create a different issue if this isn't just me not understanding something additional I was supposed to do to set up the example.
You would at least need 0.4.7 to use rds serializer as it was added in #387 , really sorry for that.
You can either install from github with remotes::install_github("rstudio/plumber") or create your own rds serializer...
Thanks! No apology needed at all, the examples are extremely helpful.