Reputation: 55
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
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