Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a clean way to upload files via an endpoint #75

Closed
sellorm opened this issue Feb 28, 2017 · 12 comments
Closed

Provide a clean way to upload files via an endpoint #75

sellorm opened this issue Feb 28, 2017 · 12 comments

Comments

@sellorm
Copy link

sellorm commented Feb 28, 2017

Posting whole files to an endpoint, using the "multipart/formdata" enctype is not currently well supported.

It is possible to retrieve a posted file (see https://github.com/sellorm/plumber-uploader for an example), but this is hacky and fragile at best. This approach basically rips the file name and content from req$postBody.

It would be useful to have something like a req$FILES that could be parsed to obtain filenames and content, for processing by the endpoint author.

Not sure how you'd handle things like accepted file types, or max permitted file size and so on though.

@FvD
Copy link
Contributor

FvD commented Mar 2, 2017

I had not seen your ticket when I sent some code for review yesterday (see #77). In my notes I suggest something that seems similar to what you are suggesting:

We move out all the code related to feather, so that the raw binary body is returned to be handles by the function written in the endpoint. We can return the name of the handle and the name of the file, as both are available in the multiparse object and the tmpfile location of the binary file (as set by tempfile())

That would pretty much do what you suggest right? If so I will change the submission to make it generic, so that it just returns the binary, to be handled by the endpoint.

@sellorm
Copy link
Author

sellorm commented Mar 2, 2017

My use case was different, but I think that any solution will end up being applicable to both use cases.

@trestletech
Copy link
Contributor

I think #77 is the ground work for this feature. This would be really nice but I think there's a decent chunk of work to get us there.

@liori
Copy link

liori commented Nov 14, 2017

Is there any problem with using Rook::Multipart for that? I've just tried doing:

#' @post /echo
function(req){
  list(formContents = Rook::Multipart$parse(req))
}

And it seems to work with curl -v -F foo=bar -F upload=@somefile.txt http://localhost:8993/echo just fine.

@ZJUguquan
Copy link

@liori So cool !!
And we can just get any kinds of data by doing like:

somefile <- readLines(con = formContents$upload$tempfile)

If the file is some kind of binary file, then we can do:

somefile <- readBin(con = formContents$upload$tempfile, "raw", 
                    n = file.size(formContents$upload$tempfile))

@jiangnight
Copy link

@liori @ZJUguquan How can i deal with multiple file from front end

@stewartthomasj
Copy link

Anyone on this thread aware of configuration settings that would control how large of a file we can upload using the techniques described here? I configured an app as described, which works for small files. But for larger files it just sort of hangs and never completes.

@NavinCJ
Copy link

NavinCJ commented Apr 18, 2019

Do we know what annotation to be provided in R function to generate swagger with file upload support?

@TyGu1
Copy link

TyGu1 commented Nov 8, 2019

Thanks for the suggestion @liori .
Unfortunately i am doing sthg wrong it seems, see the following Picture.

  1. First. i test if the plumber api works for another post request. Check,

  2. Second, i check if the file i want to upload is available. Check,

  3. Then i try to implement your idea. That doesnt work.

can you see what is wrong?

image

plumber.R

library(plumber)

#* @apiTitle Plumber Example API

#* Plot a histogram
#* @png
#* @get /plot
function() {
  rand <- rnorm(100)
  hist(rand)
}

#' @post /echo
function(req){
  list(formContents = Rook::Multipart$parse(req))
}

#* Return the sum of two numbers
#* @param a The first number to add
#* @param b The second number to add
#* @post /sum
function(a, b) {
  as.numeric(a) + as.numeric(b)
}

@krlmlr
Copy link

krlmlr commented Jan 6, 2020

mime::parse_multipart() is a rewrite of Rook::Multipart$parse(). I have a working demo here: https://github.com/krlmlr/plumber-uploader/tree/f-multipart.

@JosiahParry
Copy link
Contributor

@krlmlr your uploader worked like a charm for excel files. Thanks!

@schloerke
Copy link
Collaborator

Fixed in #532. Closing.

Please open a new issue and reference this one if you run into any issues! Thank you.

@rstudio rstudio locked as resolved and limited conversation to collaborators Jun 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.