[Flask] User uploads file naming conflicts

Anthony Ford ford.anthonyj at gmail.com
Thu Jan 5 14:48:36 EST 2017

So the first step to debuging this would be to try the copy step yourself
(i.e. bypass the builtin code from the img.save function and execute the
copyfileobj call yourself).

import shutil
outfile = open(path,'wb')
shutil.copyfileobj(img.stream, outfile)

and see if you get any errors.

>From what I can tell, copyfileobj should not fail if there's an existing
file, but overwrite the file instead. My testing concurs, so there's some
other issue at hand here.

You might also check that your files are being written with the right
permissions and owner/group.

As for naming conflicts, I always like to datestamp files, or generate a
random nonce. Another option is to hash the file (md5 or sha1), and use the
first N digits of the hash as the filename (if the filename and original
file name are stored in a DB somewhere), or prepend/append them to the
basename of the file. This way if someone uploads the identical file, it
would overwrite, but the filename wouldn't change.

I find iterating to be time consuming and excessive. I've also not found
any elegant way to do so other than globbing, which isn't perfect (such as
if file name ends with numbers, or when you hit more than single digit
increment counter). I did however just get a result from googling, the
seqfile package (https://pypi.python.org/pypi/seqfile), which seems to do
what you want. Haven't used it, so results may vary.

Anthony Ford,
ford.anthonyj at gmail.com

On Thu, Jan 5, 2017 at 1:05 PM, Clint Moyer <contact at clintmoyer.com> wrote:

> Hello everyone,
> My desire is to have a simple upload form for images, but I am not
> sure how to manage naming conflicts.
> My start point was http://flask.pocoo.org/docs/0.12/patterns/fileuploads/
> Which then gets me to here:
> [code: Python]
> MEDIA_DIR = my media directory
> input_name = name field from file input form
> img = request.files[input_name]
> img_name = secure_filename(img.filename)
> path = os.path.join(MEDIA_DIR, img_name)
> img.save(path)
> [/code]
> I have no problem submitting new images with this,
> werkzeug.FileStorage is the suggested object to use, but it seems the
> save() method fails silently. Trying this myself by uploading new
> image with the same name, the file was not uploaded. Not very friendly
> to newcomers, but sensible by Flask 'batteries not included'
> standards.
> I understand this is because the method catches the error:
> [code: Python]
> # https://github.com/pallets/werkzeug/blob/master/werkzeug/
> datastructures.py
> try:
>      shutil.copyfileobj(self.stream, dst, buffer_size)
> [/code]
> My question is, what is best practice for managing naming conflicts?
> Should I iterate existing files and check for matching? Is there a
> useful numerical system I could use to append filenames?
> Thanks in advance,
> --
> Clint
> _______________________________________________
> Flask mailing list
> Flask at python.org
> https://mail.python.org/mailman/listinfo/flask
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/flask/attachments/20170105/88864c15/attachment.html>

More information about the Flask mailing list