Aditya
Aditya

Reputation: 55

R plumber api and data sending through Curl in windows

I need to send a CSV file using Curl in Windows to an R program using the plumber API. I have Curl installed in Windows.

I've tried the following, but it doesn't work. I'm new to R and APIs, sorry.

The Curl command on Windows:

curl -X GET -d '@C:\Users\hp\Document\Final_Training.csv'
       http://localhost:8000/data1

gives the error:

"error":["500 - Internal server error"],"message":["Error in is.data.frame(x):
argument \"data1\" is missing, with no default\n"]}

My R plumber code is:

#* @get /data1
function(data1) {
  write.csv(data1, file="Final_Test.csv", sep=",", row.names=FALSE, 
            col.names=TRUE)
}

Upvotes: 0

Views: 1244

Answers (1)

K. A. Buhr
K. A. Buhr

Reputation: 50819

There are two issues. First, when "form data" is sent over HTTP, it's sent as a sequence of key/value pairs. In particular, in a GET request, it's actually embedded in the URL. For example, in the URL:

https://www.google.com/intl/en/about/?fg=1&utm_source=google.com&...

the key/value pairs are fg=1, utm_source=google.com, etc.

When you write Plumber code, the functions take arguments that correspond to the keys, so if Google was going to decide to deploy Plumber for their "About" page, they might write:

#* @get /intl/en/about
function(fg, utm_source, etc) {
    ...
}

In your code, you have Plumber code for URL /data1 that also expects a data1 key containing the CSV contents:

#* @get /data1         <-- the URL
function(data1) {      <-- which expects a `?data1=...` query parameter
  write.csv(data1, file="Final_Test.csv", sep=",", row.names=FALSE, 
            col.names=TRUE)
}

To get Curl to do this (provide the data from a file using a key data1 and supply it encoded in the URL for a GET request), you need to use a slightly different command line than you're using:

curl -X GET --data-urlencode 'data1@C:\Users\hp\Document\Final_Training.csv'
       http://localhost:8000/data1

That should get the data actually sent to the Plumber process. On the Windows side, you should see an empty Javascript object {} response (so no error). On the R side, you'll see some weird warnings about attempts to set col.names and sep being ignored or something. In addition, what gets written to Final_Test.csv won't be a proper CSV file.

That leads to the second issue. In your plumber code, data1 will be received as a plain character string containing the contents of the CSV file. It will not be a data frame or anything like that. If you just want to write the uploaded file to a CSV file, you'd just write the string data1 to the file directly:

function(data1) {
    cat(data1, file="Final_Test.csv")
}

If you want to load it into a data frame, you'd want to parse the string as a CSV file using something like:

#* @get /data1
function(data1) {
    t <- textConnection(data1)
    X <- read.csv(t)
    close(t)
    print(summary(X))
    list(result=jsonlite::unbox("success"))
}

Upvotes: 1

Related Questions