How to pass file using html form, Dropzone and Flask

Question:

I am using Dropzone and Flask using html form to pass files. like this below:

<form
   action="/"
   enctype="multipart/form-data"
   method="POST"
   class="dropzone"
   id="myAwesomeDropzone"
   >
                  <div class="fallback">
                    <input
                      name="file"
                      id="file"
                      type="file"
                      accept=".csv, text/csv, text/plain, text/tsv, text/comma-separated-values"
                    />
                  </div>

                  <div class="dz-message needsclick">
                    <i class="h1 text-muted dripicons-cloud-upload"></i>
                    <h3>Drop CSV file here or click to upload.</h3>
                  </div>

                  <div class="clearfix text-right mt-3">
                    <button type="submit" class="btn btn-danger"> <i class="mdi mdi-send mr-1"></i> Submit</button>
                </div>


</form>

Here is my JS below:

<script>
      // when the form myAwesomeDropzone has a file added
      // submit the form

      Dropzone.options.myAwesomeDropzone = {
        autoProcessQueue: false,
        uploadMultiple: false,
        parallelUploads: 100,
        maxFiles: 1,
        maxFilesize: 20,
        acceptedFiles: ".csv",
        addRemoveLinks: true,
        dictRemoveFile: "Remove",
        dictFileTooBig:
          "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
        dictInvalidFileType: "You can't upload files of this type.",
        dictMaxFilesExceeded: "You can only upload 1 file.",
        init: function () {
          var myDropzone = this;

          // if s CSV file is upload, submit the form with the csv file
          this.on("addedfile", function (file) {
            // Enable the submit button
            document.querySelector("button[type='submit']").disabled = false;
          });
        },
      };
    </script>

In the Flask route:

@app.route("/", methods=["POST"])
@login_required
def process_csv_file():
    print("request files: ", request.files)

    file = request.files.get("file")
    print("file: ", file)
    data = pd.read_csv(io.StringIO(file.decode("utf-8")))
    print("data: ")
    print(data.head())
    return "processed"

The request files are empty. I have tried using the button, removing the button and tried debugging whats wrong but I cant understand why the request files are empty. What could be the error?

Thanks in advance

Asked By: JA-pythonista

||

Answers:

You don’t need the file input.

You can make Dropzone do the heavy lifting for you.

Dropzone.options.myAwesomeDropzone = {
   // Set the endpoint called once the file is dropped and autoProcessQueue is true
   url: "/",
   
   // Method used for the ajax request
   method: "post",
   
   // Process queue automatically
   autoProcessQueue: true,
   
   // Set the name of the file input used by Dropzone
   paramName: "file",

   // Handle response once file is uploaded
   complete(file) {
    console.log(file.xhr.response) // Handle response here
    if (file._removeLink) {
      file._removeLink.innerHTML = this.options.dictRemoveFile;
    }
    if (file.previewElement) {
      return file.previewElement.classList.add("dz-complete");
    }
  },

}
Answered By: Adedoyin Akande