80

Is there a way to receive multiple uploaded files with Flask? I've tried the following:

<form method="POST" enctype="multipart/form-data" action="/upload">
  <input type="file" name="file[]" multiple="">
  <input type="submit" value="add">
</form>

And then printed the contents of request.files['file']:

@app.route('/upload', methods=['POST'])
def upload():
  if not _upload_dir:
    raise ValueError('Uploads are disabled.')

  uploaded_file = flask.request.files['file']
  print uploaded_file
  media.add_for_upload(uploaded_file, _upload_dir)
  return flask.redirect(flask.url_for('_main'))

If I upload multiple files, it only prints the first file in the set:

<FileStorage: u'test_file.mp3' ('audio/mp3')>  

Is there a way to receive multiple files using Flask's built-in upload handling? Thanks for any help!

Haldean Brown
  • 12,411
  • 5
  • 43
  • 58

4 Answers4

130

You can use method getlist of flask.request.files, for example:

@app.route("/upload", methods=["POST"])
def upload():
    uploaded_files = flask.request.files.getlist("file[]")
    print uploaded_files
    return ""
Iron Fist
  • 10,739
  • 2
  • 18
  • 34
Fedor Gogolev
  • 10,391
  • 4
  • 30
  • 36
29
@app.route('/upload', methods=['GET','POST'])
def upload():
    if flask.request.method == "POST":
        files = flask.request.files.getlist("file")
        for file in files:
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))

It works for me.

for UPLOAD_FOLDER if you need add this just after app = flask.Flask(name)

UPLOAD_FOLDER = 'static/upload'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Julien
  • 303
  • 4
  • 6
15

Using Flask 1.0.2+:

files = request.files.getlist("images")

Where images is the key of the key/value pair. With the Value being the multiple images.

Jack
  • 2,891
  • 11
  • 48
  • 65
  • 3
    Thanks! And as it may help others prevent some searching, note that `file.filename` gives the name of the file for each `file` in `files`. – Hans Bouwmeester Feb 24 '19 at 08:57
8

this is a working solution for flask version '1.0.2':

images = request.files.to_dict() #convert multidict to dict
for image in images:     #image will be the key 
    print(images[image])        #this line will print value for the image key
    file_name = images[image].filename
    images[image].save(some_destination)

basically, images[image] has an image file with save function added to it Now do whatever you like to do with the data.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • to_dict doesn't get list of image. – TomSawyer Feb 22 '21 at 16:36
  • 1
    @TomSawyer Which flask version are you using? can you put print(type(request.files)) in your code and see what is the type of request.files. If it is multidict then to_dict method should give you a dictionary object in return. – SATYAJEET RANJAN Feb 23 '21 at 18:07
  • 1
    @Jean-François Fabre This is a workig solution for flask 2.0.1 too, but `to_dict` doesn't seem to the the whole list of files when I use `FormData` in JS. It only fetches the first file, Anything I am doing wrong? – collinsmarra Nov 17 '21 at 04:50
  • @collinsmarra before the for loop print the images and see what you are getting I am using this code in many projects and it returns me one file or more that one file based on what i send from client side. If possible check the code on your client side JS. You might find a clue there. – SATYAJEET RANJAN Dec 16 '21 at 04:54