Search code examples
rfileplumber

How to send RDS file to an R plumber API?


I work with the R plumber API. I've created a very simple api that receives an RDS file (a data.frame). On this received rds, I perform a few basic operations and then return this modified data.frame.
With swagger, I can graphically test whether my API is working and it's not. I can't get the RDS file to work. I tried to follow the example here How to send rds file to plumber API using httr package ? but without success

Here below is my code :

library(plumber)
library(dplyr)
library(magrittr)
library(data.table)

#* Get dataframe and create feature
#* @parser multi
#* Add rds parser
#* @parser rds
#* @param df:file
#* @post /dataframe
function(req, res, df) {
  str(df)
  return(df[,1])
}

I get this error with swagger UI :

enter image description here


Solution

  • Insert a browser() in there to see why your code is failing:

    function(req, res, df) {
      browser()
      str(df)
      return(df[,1])
    }
    

    For me, I generated started with saveRDS(head(mtcars), file="mt.rds"), then uploaded it. From here,

    Browse[2]> df
    $mt.rds
                         mpg cyl  disp  hp drat    wt  qsec vs am gear carb
    Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
    Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
    Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
    Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
    Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
    Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
    

    So you need to use df[[1]] (or a name if you know it):

    function(req, res, df) {
      return(df[[1]][,1])
    }
    

    With that running, I'm able to do this:

    library(httr)
    library(magrittr)
    res <- 
      POST(
        "http://127.0.0.1:9999/dataframe",
        body = list(
          # send the file with mime type `"application/rds"` so the RDS parser is used
          df = upload_file("mt.rds", "application/rds")
        )
      ) %>%
      content()
    str(res)
    # List of 6
    #  $ : int 21
    #  $ : int 21
    #  $ : num 22.8
    #  $ : num 21.4
    #  $ : num 18.7
    #  $ : num 18.1