How to send rds file to plumber API using httr package ?

I can't figure out how to implement a Plumber API, where the API will save a .rds file (it will get from the request) in it's working directory and do some data visualization steps and then finally return the result.

These .rds files are data files which is saved using saveRDS() method.

This is the API code

#* @post /test/1
function(req, res){
  fileInfo <- list(formContents = Rook::Multipart$parse(req))
  rdstmpfile <- fileInfo$formContents$rds$tempfile
  rds_file <- file.path("We_Got_RDS.rds")
  file.copy(rdstempfile, rds_file)
}

Client code (will use httr package to send the .rds file)

httr::content(POST('http://0.0.0.0:7000/test/1'),
              body = list(
                rds = upload_file("data.rds", mime::guess_type("data.rds"))
              )
) -> res

What is the content-type of the .rds files ?
How to send the .rds file to plumber API ?
I tried to print fileInfo$formContents but I got NULL. Why I'm getting NULL ? It looks like it's not able to send the .rds file.

httr code:

library(httr)
library(magrittr)

res <- 
  POST(
    "http://0.0.0.0:7000/test/1",
    body = list(
      # send the file with mime type `"application/rds"` so the RDS parser is used
      rds_file = upload_file("data.rds", "application/rds")
    )
  ) %>%
  content()
str(res)
#> List of 1
#>  $ : logi TRUE

plumber.R code:

# Add a rds and multipart form parser
#' @parser rds
#' @parser multi
#' @post /test/1
function(req, res, rds_file) {
  str(rds_file)
  # now that you have the object, save it to a file
  saveRDS(rds_file, "We_Got_RDS.rds")

  TRUE # placeholder return value
}
library(plumber)
pr("plumber_rds.R") %>% pr_run(port = 7000)
#> Running plumber API at http://127.0.0.1:7000
#> Running swagger Docs at http://127.0.0.1:7000/__docs__/
#> List of 1
#>  $ data.rds:'data.frame':	150 obs. of  5 variables:
#>   ..$ Sepal.Length: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#>   ..$ Sepal.Width : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
#>   ..$ Petal.Length: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#>   ..$ Petal.Width : num [1:150] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
#>   ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

You can also access the already processed body information via req$body in your plumber route.

Yes, this approach involves reading the data and saving it, but it is a less complicated solution.


Update: Removed comments within plumber block

1 Like

You can use #* instead of #' to get a nice Run API button in RStudio.

#* Add multipart form parser
#* @parser multi
#* Add rds parser
#* @parser rds
#* @param rds_file:file
#* @post /test/1
#* @png
function(rds_file) {
  plot(rds_file[[1]])
}
2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.

@barret thanks a lot :slight_smile: