tags:

views:

50

answers:

3

I'm using the following django/python code to stream a file to the browser:

wrapper = FileWrapper(file(path))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Length'] = os.path.getsize(path)
return response

Is there a way to delete the file after the reponse is returned? Using a callback function or something? I could just make a cron to delete all tmp files, but it would be neater if I could stream files and delete them as well from the same request.

A: 

One way would be to add a view to delete this file and call it from the client side using an asynchronous call (XMLHttpRequest). A variant of this would involve reporting back from the client on success so that the server can mark this file for deletion and have a periodic job clean it up.

Manoj Govindan
Doesn't sound like a good idea to me - there's no need for an additional message from the client to the server. Cleaning up the temp files periodically is much better.
loevborg
@loevborg: The OP *asked* for alternatives. Hence. `I could just make a cron to delete all tmp files, but it would be neater ...`
Manoj Govindan
+1  A: 

Mostly, we use periodic cron jobs for this.

Django already has one cron job to clean up lost sessions. And you're already running it, right?

See http://docs.djangoproject.com/en/dev/topics/http/sessions/#clearing-the-session-table

You want another command just like this one, in your application, that cleans up old files.

See this http://docs.djangoproject.com/en/dev/howto/custom-management-commands/

Also, you may not really be sending this file from Django. Sometimes you can get better performance by creating the file in a directory used by Apache and redirecting to a URL so the file can be served by Apache for you. Sometimes this is faster. It doesn't handle the cleanup any better, however.

S.Lott
A: 

You can use a NamedTemporaryFile:

from django.core.files.temp import NamedTemporaryFile
def send_file(request):
    newfile = NamedTemporaryFile(suffix='.txt')
    # save your data to newfile.name
    wrapper = FileWrapper(newfile)
    response = HttpResponse(wrapper, content_type=mime_type)
    response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(modelfile.name)
    response['Content-Length'] = os.path.getsize(modelfile.name)
    return response

temporary file should be deleted once the newfile object is evicted.

fylb
`temporary file should be deleted once the newfile object is evicted`: is there a built-in mechanism to automatically delete `NamedTemporaryFile` instances?
Manoj Govindan
if I'm correct, objects are destroyed by the garbage collector once all references to it are destroyed.When you step out of the send_file function, there should be no more reference to the newfile object, hence it could be removed the next time the GC runs.The destructor of NamedTemporaryFile states: def close(self): if not self.close_called: self.close_called = True self.file.close() self.unlink(self.name) def __del__(self): self.close()
fylb
fylb, you're right, but it's not guaranteed that the object will be garbage-collected and its __del__ method called. Who knows what the garbage collector will do? Better to clean up manually periodically.
loevborg