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
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");
}
},
}
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
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");
}
},
}