I want to upload a file to a web API. According to the documentation, I need to pass a POST request to an upload url, including a list of required upload parameters as well as the file.
The API is private, so I can't share a reproducible example, but I'm struggling to format the final POST request.
Attempt 1: Error: All components of body must be named
upload_content <- httr::content(upload_resp)
upload_url <- upload_content$upload_url
upload_params <- c(upload_content$upload_params, httr::upload_file(file_name))
httr::POST(upload_url, body = list(upload_params))
Attempt 2: Error: All components of body must be named
upload_content <- httr::content(upload_resp)
upload_url <- upload_content$upload_url
upload_params <- upload_content$upload_params
httr::POST(upload_url, body = list(upload_params, httr::upload_file(file_name)))
Attempt 3: Status 400: Bad Request
upload_content <- httr::content(upload_resp)
upload_url <- upload_content$upload_url
upload_params <- c(upload_content$upload_params, httr::upload_file(file_name))
httr::POST(upload_url, body = list(upload_params))
How do I append the file to the upload parameters? And how should I format the body of the POST request?
Are you familiar with Postman? It's a very useful GUI for working with HTTP requests. I love httr
, but sometimes things are easier to debug with Postman. Read more here: https://www.getpostman.com/.
Here's the business end of googledrive::drive_upload()
:
We're using some package-specific wrappers to form and make requests (via httr) but above is the heart of the matter re: handling the body.
1 Like
Thanks Jenny! Before I try and work through the googledrive
wrappers, do I need to make two separate calls to httr::upload_file()
? One for the parameters and meta-data, and one for the file itself?
Unashamed to say I forked googledrive
just to insert print
statements at various intervals. Alas, for all my efforts I still get a 400 status code.
What's bizarre is that I can successfully upload an empty .pdf or .txt file if I omit httr::upload_file
from the request entirely.
I also should have included this earlier, but what I need to replicate is this:
curl '<upload_url>' \
-F 'key=/users/1234/files/profile_pic.jpg' \
<any other parameters specified in the upload_params response>
-F 'file=@my_local_file.jpg'
Hi @daranzolin
Have you seen this SO post? https://stackoverflow.com/a/27372246/5000201
I'd make a guess to say your code would look like:
url <- "your url here"
params <- list('form[key]' = "/users/1234/files/profile_pic.jpg", 'form[file]'="file=@my_local_file.jpg")
response <- POST(url, body = params)
That's just from my understanding of your question (I'm assuming I've missed out some other parameters)
Edit: Doing a search on https://cran.r-project.org/web/packages/httr/vignettes/quickstart.html for 'Request body' also describes a option for encoding the parameters:
r <- POST(url, body = body, encode = "form")
For those still interested, I got this hacky solution to work:
upload_params <- upload_content$upload_params
upload_params[[length(upload_params) + 1]] <- httr::upload_file(file_name)
names(upload_params)[[length(upload_params)]] <- "file"
invisible(httr::POST(url = upload_url,
body = upload_params))
Thanks everyone!
1 Like