-2

I have the following piece of code that handles the image upload for me in a Django Project that I work on:

def upload_handler(source):
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
    with open(filepath, 'wb') as dest:
        shutil.copyfileobj(source, dest)
        return MEDIA_URL + basename(dest.name)

All is working fine with the upload part but mkstemp is saving my image with an additional 6 random suffix after the extension (Ex. test.png -> test.pngbFVeyh). Even if I pass the suffix in the second code line it appends it but also with the additional 6 random characters. Other odd thing that is happening is that in the upload folder (MEDIA_ROOT in my case) it is created alongside another empty plain text document type file with the same name as the picture (Ex. test.pngbFVeyh). I've read the documentation regarding mkstemp but I didn't find any alternative solution.

MariusNV
  • 391
  • 1
  • 3
  • 7

2 Answers2

2
def upload_handler(source):
    # this is creating a temp file and returning an os handle and name
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
    # this next line just clears the file you just made (which is already empty)
    with open(filepath, 'wb') as dest: 
        # this is a strange way to get a fobj to copy :)
        shutil.copyfileobj(source, dest)
        return MEDIA_URL + basename(dest.name)

prefix and suffix do just that, so if you don't want your filename to begin or end with the temporary characters, you need to use both prefix and suffix. For example,

name = os.path.basename(source.name)
prefix, suffix = os.path.splitext(name)
_, filepath = tempfile.mkstemp(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)

but it would be better if you use tempfile.NamedTemporaryFile, as then the file-like object is returned (so you don't have to create fobj from the filename and the temp file is deleted by default when done).

fobj, _ = tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)
shutil.copyfileobj(source, fobj)
Wyrmwood
  • 3,340
  • 29
  • 33
-1

The name is random-generated because it's the purpose of tempfile.mkstemp. The file with that name is created because it's how tempfile.mkstemp works. It is also opened and the file descriptor is returned to you in fd which you ignore. You don't seem to understand how tempfile.mkstemp should be used and you probably need to use something else instead.

wRAR
  • 25,009
  • 4
  • 84
  • 97
  • I've read in the documentation that mkstemp is deleting the temporary file, maybe I am mistaken here... – MariusNV Mar 18 '13 at 11:50
  • @MariusNV the documentation explicitly says "Caller is responsible for deleting the file when done with it.". – wRAR Mar 18 '13 at 11:51
  • Ok this part I get it now, I have to take care of deleting the temporary file right? But how remains with the suffix issue part? – MariusNV Mar 18 '13 at 11:56
  • @MariusNV it's not an issue, it's the purpose of `tempfile.mkstemp`: "to create and return a unique temporary file". – wRAR Mar 18 '13 at 11:58
  • Thank you for your guidance and regarding fd which I ignore that I have to do with it, it's just an integer. Sorry for sounding like a noob... I am a begginer with Python & Django and I really want to understand how it works – MariusNV Mar 18 '13 at 12:14
  • @MariusNV of course file descriptors returned by `os.open` are integers – wRAR Mar 18 '13 at 12:15