How to pass the curl -F parameter in the httr package? - r

Hi I try to translate this curl instruction using httr
curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3
Without the -F parameter the instruction is :
httr::POST(
url = "http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3",
add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd")
)
)
I think I have to use the httr::upload_file function but I didn't manage to use this without error.
Do you have any idea how I can do that ?
Regards

Here is how to construct this curl request with httr package. I used httpbin.org to test the request sent.
You'll use POST filling the body with a list. encode argument controls how this list will be handle and by default it is the correct multipart you need.
res <- httr::POST(
url = "http://httpbin.org/post",
httr::add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd"),
# Add the file and metadata as body using a list. Default encode is ok
body = list(
file = httr::upload_file("test.txt"),
filename = "test.txt",
parent_dir = "/"
)
)
httr_ouput <- httr::content(res)
One way to check this is ok is to compare output with the curl command you know is working
out <- sys::exec_internal(
'curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://httpbin.org/post'
)
curl_output <- jsonlite::fromJSON(rawToChar(out$stdout))
#compare body
identical(curl_output$files, httr_ouput$files)
#> TRUE
identical(curl_output$form, httr_ouput$form)
#> TRUE
You can also do it with the crul package, another wrapper above curl; The logic is identical
con <- crul::HttpClient$new(
url = "http://httpbin.org/post"
)
crul_req <- con$post(
body = list(
file = crul::upload("test.txt"),
filename = "test.ext",
parent_dir = "/"
)
)
crul_output <- jsonlite::fromJSON(crul_req$parse())

Related

Adding --data to R curl_fetch_memory()

I want to create an R script to use instead of a curl request.
Using curl, I use a Google API which requires the --data option. I am not sure how to add this option to my curl request using the curl package.
The request that works using Git Bash is as follows:
API_KEY="[xyz]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=$API_KEY" \
--header 'Content-Type: application/json' \
–-data '{"url": "https://www.example.com/"}'
This is my R code, which doesn't send the necessary URL to return anything good:
library(curl)
API_KEY = "xyz"
h <- new_handle()
handle_setheaders(h,
"Content-Type" = "application/json"
)
r <- curl_fetch_memory(url = paste0("https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=",API_KEY), h)
So how can I add the --data option using the curl package?
You can use the lower-level curl if you really want to. In this case your original CURL command is performing a POST action with a JSON encoded body. The equivalent of that in the R curl library would be
library(curl)
API_KEY <- "xyz"
url <- paste0("https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=", API_KEY)
payload <- charToRaw('{"url": "https://www.example.com/"}')
h <- new_handle()
handle_setopt(h, post=TRUE, postfields=payload)
handle_setheaders(h, "Content-Type" = "application/json")
r <- curl_fetch_memory(url = url, h)
cat(rawToChar(r$content))

Writing Curl POST in R: uploading an image to a website

I am trying to upload an image to a website. Below is the successful curl function:
curl --location --request POST 'http://xxxxx?laboratoryResultVisibleId=LR-116807&assayAttribute=Trace&onBehalfOf=minnie' \
--header 'Authorization: Basic U1JWR0JMLUdEQklPTDpQZjgyNTE5Mw==' \
--form 'imageFile=#/C:/Users/minnie/Downloads/plot.png'
I am writing my R code as follows:
username <- "minnie"
url <- "http://xxxxx"
auth <- authenticate(user='abc', password='xyz', type="basic")
header <- list(username)
names(header) <- "X-On-Behalf-Of"
filepath <- "C:/Users/minnie/Downloads/plot.png"
post_zip <- httr::POST(
url = url,
auth,
body = list(
laboratoryResultVisibleId = 'LR-116807',
assayAttribute = 'Trace',
file = httr::upload_file(filepath),
userid = username
),
httr::add_headers("Content-Type"="multipart/form-data")
)
post_zip
content(post_zip, "text")
and I got the following feedback:
Response [http://xxxxx]
Date: 2020-11-18 22:30
Status: 200
Content-Type: application/json;charset=UTF-8
Size: 43 B
> content(post_zip, "text")
[1] "{\"success\":false,\"message\":\"No File found\"}"
It seems that no file has been found. Any clue? Thank you so much for your help :-)
I feel like this has something to do with http vs https, can you try changing to https?
The problem resides in the file path. We should use the file.path () function in R to let the server know it is a file path, rather than a character string.
filepath <- file.path(getwd(), "plot.png")
post_zip <- httr::POST(
url = url,
auth,
body = list(
laboratoryResultVisibleId = 'LR-116807',
assayAttribute = 'Trace',
imageFile = httr::upload_file(filepath),
userid = username
),
httr::add_headers("Content-Type"="multipart/form-data")
)
post_zip
content(post_zip, "text")

Reading API - code from Curl to R

I am trying to read a json from an authenticated API using R, but not sucessfully.
I have the Curl code and tried to convert it to R using "curlconverter" library and also tried to get it using "httr" library.
curl -X GET \
'https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1' \
-H 'Cache-Control: no-cache' \
-H 'x-glb-token: mytoken'
I would appreciate a solution to write this code in R.
library(curlconverter) # devtools::install_github("hrbrmstr/curlconverter")
u <- "curl -X GET 'https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1' -H 'Cache-Control: no-cache' -H 'x-glb-token: mytoken'"
straighten(u) %>%
make_req()
That makes:
httr::VERB(verb = "GET", url = "https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1",
httr::add_headers(`Cache-Control` = "no-cache",
`x-glb-token` = "mytoken"))
which very straightforwardly (if one has done any research before posting a question) translates to:
httr::GET(
url = "https://api.cartolafc.globo.com/auth/liga/gurudocartola-com",
httr::add_headers(
`Cache-Control` = "no-cache",
`x-glb-token` = "mytoken"
),
query = list(
`orderBy` = "campeonato",
`page` = 1L
)
)
The back-ticks are there solely to remind me they are parameters (and, they sometimes contain dashes or other chars which force a back-tick quote).

Translating a curl command to R using httr (specifically '--data-binary #')

I am trying to transcribe some sound files to text using bing speech-to-text.
The following command works in command line (using git bash on Windows 10):
curl -v -X POST "https://speech.platform.bing.com/speech/recognition/interactive/
cognitiveservices/v1?language=<LANG>&format=detailed" -H "Transfer-Encoding:
chunked" -H "Ocp-Apim-Subscription-Key: <MY KEY>" -H "Content-type:
audio/wav; codec=audio/pcm; samplerate=16000" --data-binary #<MY .WAV-FILE>
I've tried this, but it doesnt work:
httr::POST(url = myURL,
add_headers("Ocp-Apim-Subscription-Key" = key,
"Content-type" = "audio/wav; codec=audio/pcm; samplerate=16000",
"Transfer-Encoding" = "chunked"),
body = (list("file" = upload_file("PATH_TO_FILE.wav"))),
verbose())
It returns this output:
Response
[https://speech.platform.bing.com/speech/recognition/dictation/
cognitiveservices/v1?language=<LANG>&format=detailed]
Date: 2017-11-29 13:29
Status: 200
Content-Type: text/plain
Size: 75 B
I believe that the request is related to the interpretation of the .wav file, and that I need to somehow add the '--data-binary' tag to the httr-request. I can see that my "content-type" is plain text, although i've specified. Furthermore: the API documentation specifies that i need to prefix my wav-file with an at-sign.
Any help would be much appreciated.
cheers.
EDIT: Link to API documentation
https://learn.microsoft.com/da-dk/azure/cognitive-services/speech/getstarted/getstartedrest?tabs=curl#tabpanel_AFC9x30-dR_curl
I figured it out.
The key is to set the proper MIME type in the body. Not setting this MIME type can result in wrongful interpretation on the receiving end, even though we get a response 200 back.
body <- list(file = httr::upload_file(
paste0(path, "/", f),
type = "audio/wav; codec=audio/pcm; samplerate=16000"))
where paste0(path, "/", f) is a path to an audio file.
myURL <- sprintf('https://speech.platform.bing.com/speech/recognition/%s/cognitiveservices/v1?language=%s&format=%s',
"dictation",
"da-DK",
"detailed")
rs <- httr::POST(
url = myURL,
httr::add_headers(.headers = c("Ocp-Apim-Subscription-Key" = key)),
httr::add_headers(.headers = c("Transfer-Encoding" = "chunked")),
body = body)

Writing Curl POST in R

What is the correct way of writing this Curl POST in R?
I would like to have R read the contents of a file as "values" in the post form.
curl -X POST https://api.priceapi.com/jobs \
-d "token=token" \
-d "country=country" \
-d "source=source" \
-d "currentness=currentness" \
-d "completeness=completeness" \
-d "key=key" \
-d 'values=<values>'
So far I have this-
library(RCurl)
library(RJSONIO)
url = "https://api.priceapi.com/jobs"
file.name = ".../output 1 .txt"
results = postForm(url, token="token",
country="country,
source="source",
currentness="currentness",
completeness="completeness,
key="key",
values=fileUpload(filename = file.name))
It returns "Error: Bad Request"
I also tried it using httr post request-
r = POST(url, body = list(token="token",
country="country,
source="source",
currentness="currentness",
completeness="completeness,
key="key",
values=upload_file(file.name)) )
Here upload_file is not uploading the contents of the file but, I am guessing it is passing the path to the file (as a string) into the "values" parmeter.
Naturally that does not return the correct results.
The result of the httr POST request is;
Response [https://api.priceapi.com/jobs]
Date: 2016-12-13 10:11
Status: 400
Content-Type: application/json; charset=utf-8
Size: 228 B
{
"success": false,
"reason": "parameter value invalid",
"parameter": "value",
"valid values": "An array or a string containing values separated by newline",
"comment": "Make sure the parameter 'value' has a valid value!"
I could solve this by using
file=readLines(".../output 1.txt")
inputValues <- paste(file,collapse="\n")
and then passing inputValues in the values parameter.

Resources