4

I need to send a json file with multiple values and receive it in R using plumber, ive tried this but it doesnt seem to work,

library("rjson")
#install.packages("rjson")
#* @get /predict
#* @post /predict
function(predict) {
  # Load the package required to read JSON files.
  library("rjson")
  # Give the input file name to the function.
  result <- fromJSON(file = "input_v3.json")
  print(result)
  result <- as.data.frame(result)
  write.table(result, file="testing_v3_xyz.csv", sep=",", row.names=FALSE, col.names=TRUE, append = T)
}


The curl command i used is curl -F data=@input_v3.json http://xx.xxx.xxx.xx:8000/predict

I need to send it a an ip address that is Rstudio in Desktop running on aws

Aditya
  • 55
  • 1
  • 7

1 Answers1

6

plumber unpacks JSON transparently if you send it in via --data:

library(plumber)

#* parse JSON
#* @param a  a vector
#* @param b  a vector
#* @get /predict
#* @post /predict
function(a, b) {
  result <- data.frame(a = as.numeric(a), b = as.numeric(b))
  write.table(result, file="testing_v3_xyz.csv", sep=",",
              row.names=FALSE, col.names=TRUE, append = T)
}

Running this API locally I get:

$ cat foo.json 
{ "a":["1","2","3","4","5","6","7","8" ], "b":["1","2","3","4","5","6","7","8" ] }
$ curl --data @foo.json  http://localhost:8414/predict
{}
$ cat ~/learning/stackoverflow/testing_v3_xyz.csv 
"a","b"
1,1
2,2
3,3
4,4
5,5
6,6
7,7
8,8

If the top level of the JSON is an array as opposed to an object, you cannot use named parameters to get the data into the function. However, you can use req$postBody to access the posted content:

library(plumber)

#* parse JSON
#* @param req  the request object
#* @get /predict
#* @post /predict
function(req) {
  result <- as.data.frame(lapply(jsonlite::fromJSON(req$postBody), unlist))
  write.table(result, file="testing_v3_xyz.csv", sep=",", row.names=FALSE, col.names=TRUE, append = T)
}

For me this works for sample data like this:

[
  { "a":["1","2","3","4","5","6","7","8" ],
    "b":["1","2","3","4","5","6","7","8" ] },
  { "a":["1","2","3","4","5","6","7","8" ], 
    "b":["1","2","3","4","5","6","7","8" ] }
]
Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75
  • 1
    { "a":["1","2","3","4","5","6","7","8" ], "b":["1","2","3","4","5","6","7","8" ] } Its in this format – Aditya Aug 21 '18 at 09:18
  • @Aditya Ok, I have updated my answer to reflect this data structure. – Ralf Stubner Aug 21 '18 at 09:27
  • Hey thanks a lot! I worked it out from your previous answer, this is exactly what i did! Thanks a ton! – Aditya Aug 21 '18 at 09:52
  • Just one more thing, if i had data in this format, { { "a":"1", "b":"1" }, { "a":"1", "b":"1" } } How do i get it to write in a csv file row by row? like first a,b in one row, then the next in another? – Aditya Aug 21 '18 at 11:01
  • @Aditya that's not a legal JSON structure, since elements within curly braces must be named. Do you mean `[ { "a":"1", "b":"1" }, { "a":"1", "b":"1" } ]`? – Ralf Stubner Aug 21 '18 at 11:05
  • Yes sorry, like that! – Aditya Aug 21 '18 at 11:07
  • Essentially sending multiple data in this format instead of the one i specified earlier. – Aditya Aug 21 '18 at 11:08
  • Thanks a lot! Exactly what i was looking for! – Aditya Aug 21 '18 at 15:55
  • how does this work with the swagger interface? when i run the R plumber it opens up the swagger interface – nerdlyfe Jul 07 '20 at 21:31
  • @ElChapo It works just the same. When I run the plumber API from RStudio the swagger API opened at `http://127.0.0.1:7338/__swagger__/`. So I only have to connect to `http://127.0.0.1:7338/predict` using `curl`. – Ralf Stubner Jul 13 '20 at 08:24
  • If using curl in powershell, use quotes for --data parameter value: curl --data '@foo.json' http://localhost:8414/predict – umbersar Apr 20 '21 at 07:17