0x4A42
0x4A42

Reputation: 60

Flask - Empty Files When Uploaded

I have a project which allows users to upload files, they will eventually get processed and then serve a result file.

I've just realised, now that I am trying to implement the processing part of the system, that the files are empty when uploaded and I'm not sure where this is going wrong. The files are successfully named and put in the directories, but are empty.

Any help would be much appreciated.

The html form for uploads:

<div class="tile is-vertical is-parent coach" id='fileUploadTile'>
  <div class="tile is-child box has-background-light">

      <form action='/' method='POST' enctype="multipart/form-data">
        <div class='drop-zone'>
          <span class='drop-zone__prompt is-family-monospace'>Drag and drop or click here to upload files</span>

          <input class="drop-zone__input" type="file" multiple name="uploaded_file" id='fileLoader'>

        </div> <!-- end of drop-zone-->
        <div class='buttons are-medium' id='fileButtons'>
          <input type='submit' class="button is-success is-light is-outlined is-family-monospace" id='submitFiles' value='Process file(s)'>
          </form>
          <button class='button is-danger is-light is-outlined is-family-monospace' name='resetFiles' id='resetFiles'>Reset File(s)</button>
        </div> <!-- end of buttons -->
       
    </div> <!-- end of tile is-child -->
   

  </div> <!-- end of tile is-vertical -->

The code which attempts to validate the files (check extensions, file size, name, etc) and then save:

def file_upload():
    if session:
        session_name = session.get('public_user')
        print("New request from " + str(session_name))
        # update when last request was sent
        active_sessions[session_name] = datetime.now()
    else:
        session_token = generate_session_token()
        print("Generating new session... " + session_token)
        session['public_user'] = session_token  # session = key, last request = value
        active_sessions[session_token] = datetime.now()
        os.mkdir('uploads/'+session['public_user']) #create directory for uploaded files

    if request.method == "POST":
        if request.files:
            files_processed = True
            files = request.files.getlist("uploaded_file")
            upload_path = app.config['UPLOAD_FOLDER'] + \
                str(session['public_user'])
            # loop, as possibility of multiple file uploads
            for file_to_upload in files:
                file_to_upload.seek(0, os.SEEK_END)
                file_length = file_to_upload.tell()
                file_name = check_existing_file_name(file_to_upload.filename)
                # Secures file name against user input
                file_name = secure_filename(file_name)
                # Checks the file name isn't blank
                if file_to_upload.filename == "":
                    print("Error with file" + file_to_upload.filename +
                          " - name must not be blank")
                    files_processed = False
                    continue
                # Checks the file has an allowed extension
                elif not allowed_ext(file_to_upload.filename):
                    print("Error with file" + file_to_upload.filename +
                          " - extension not supported")
                    files_processed = False
                    continue
                # Checks file size
                elif file_length > app.config['MAX_FILE_SIZE']:
                    print("Error with file" +
                          file_to_upload.filename + " file too big")
                    files_processed = False
                    continue
                else:  # Else, passes all validation and is saved.
                    file_path = upload_path + "/" + file_name
                    file_to_upload.save(file_path) 
            # If files have been processed, return a render with success message
            if files_processed is True:
                return render_template('index.html', is_home='yes', succ="Now processing your files...")
            else:  # Else, normal redirect.
                return redirect(request.url)
        else:  # If no files request, redirect to index.
            return redirect(request.url)
    else:  # If not a POST request, load page as normal.
        return render_template('index.html', is_home='yes')

Sorry if this is something easy or silly I've missed - this is my first project in Python and my first time using Flask.

Upvotes: 1

Views: 2684

Answers (2)

Carter Mooring
Carter Mooring

Reputation: 41

I was having the same issue and the recommended fix above helped me! From what I understand it is because you file pointer at the end of the file when you grab the file size. This just has to be undone with another file_to_upload.seek(0).

Just for clarity, your code should now look like:

file_path = upload_path + "/" + file_name
file_to_upload.seek(0)
file_to_upload.save(file_path) 

Upvotes: 1

J&#252;rgen Gmach
J&#252;rgen Gmach

Reputation: 6093

This all looks pretty ok.

Unrelated: I would do the check for the empty file name against file_name - not file_to_upload.filename.

About your problem: The only sensible answer could be that with any of your many actions you put the file pointer at the end of the file, and save cannot handle it.

Unfortunately, I have no time to try this on my pc, so please do a seek 0 again - this time just before you call the save method.

I will try this later and update my answer accordingly.

Another way to find out what is going is using a debugger. That is not too complicated.

I made a 5 min video - just for debugging Flask: https://www.youtube.com/watch?v=DB4peJ1Lm2M

Upvotes: 3

Related Questions