Reputation: 60
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
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
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