Using Flask and Ajax to upload file(s) asynchronously

  ajax, flask, python, windows

I am trying to upload files using a flask server with ajax. I am using Windows 10. The idea is to do so without having to make the user wait until the upload/processing are done. Currently, I have the code below, which works fine – if I don’t use any concurrency/threads in the upload_ajax function, the uploading occurs. However, if the user leaves the page, I get a 400 error. What I would like to do is just send off a greenlet or thread to do the job. However:

  • If I use a greenlet, then the upload_ajax function runs and returns, but upload_files never runs.
  • If I use a thread, then upload_ajax does not return, and the program just ends without an error (not sure why), and upload_files never runs.

Is there a way to accomplish what I am trying here?

flask route for posting from ajax:

@app.route('/uploadajax', methods=['POST'])
def upload_ajax():
    file_paths = {}

    @copy_current_request_context
    def upload_files():
        print('HERE:t', len(request.files.getlist("file")))
        for i, file in enumerate(request.files.getlist("file")):
            if file.filename == '':
                continue

            if file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
                file_paths[i]=os.path.join(app.config['UPLOAD_FOLDER'], filename)

    #gevent.spawn(upload_files)
    t = threading.Thread(target=upload_files)
    t.start()
    #upload_files()
    print('HERE2')
    return url_for('home')

upload.html:

<!doctype html>
<html>
  <head>
    <title>File Upload</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  </head>
  <body>
    <h1>File Upload</h1>
    <form id="upload-file" method="POST" enctype="multipart/form-data">
      <p><input type="file" name="file" multiple></p>
      <p><button id="upload-file-btn" type="button">Upload</p>
    </form>
  </body>

  <script>
    $(function() {
      $('#upload-file-btn').click(function() {
          var form_data = new FormData($('#upload-file')[0]);
          $.ajax({
              type: 'POST',
              url: '/uploadajax',
              data: form_data,
              contentType: false,
              cache: false,
              processData: false,
              async: true,
              complete: function(data) {
                  window.location.href = '/';
              },
          });
      });
  });
  </script>
</html>

Source: Windows Questions

LEAVE A COMMENT