Arthur
Arthur

Reputation: 9

download file from mongo gridfs with python

I have uploaded files to the mongo.But when I want to download from mongo by httpresonse on the web browser,that did not work.

Here is the views.py:

    if filename is not None:
    file_ = db.fs.files.find_one({
    'filename':filename
        })
    file_id = file_['_id']
    wrapper = fs.get(file_id).read()

    response =  StreamingHttpResponse(FileWrapper(wrapper),content_type=file_['contentType'])

    response['Content-Disposition'] = 'attachment; filename=%s' % str(filename)
    response['Content-Length']      = file_['length'] 
    return response

I got this error:

Traceback (most recent call last):
File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
self.finish_response()
File "/usr/lib/python2.7/wsgiref/handlers.py", line 126, in finish_response
for data in self.result:
File "/usr/local/lib/python2.7/dist-packages/django/utils/six.py", line 473, in next
return type(self).__next__(self)
 File "/usr/local/lib/python2.7/dist-packages/django/http/response.py", line 292, in   __next__
return self.make_bytes(next(self._iterator))
 File "/usr/lib/python2.7/wsgiref/util.py", line 30, in next
data = self.filelike.read(self.blksize)
AttributeError: 'str' object has no attribute 'read'

But when I change the StreamingHttpResponse to HttpResponse,the error is as follow:

[30/Jul/2014 17:29:43] "GET /download/cs101/ HTTP/1.1" 200 664
/usr/lib/python2.7/wsgiref/handlers.py:126: DeprecationWarning: 
 Creating streaming     responses with `HttpResponse` is deprecated.
 Use `StreamingHttpResponse`instead if you need the streaming behavior.
for data in self.result:

Traceback (most recent call last):
 File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
   self.finish_response()
 File "/usr/lib/python2.7/wsgiref/handlers.py", line 126, in finish_response
for data in self.result:
 File "/usr/local/lib/python2.7/dist-packages/django/utils/six.py", line 473, in next
return type(self).__next__(self)
 File "/usr/local/lib/python2.7/dist-packages/django/http/response.py", line 292, in __next__
return self.make_bytes(next(self._iterator))
File "/usr/lib/python2.7/wsgiref/util.py", line 30, in next
data = self.filelike.read(self.blksize)
AttributeError: 'str' object has no attribute 'read'

Thanks in advance!

Upvotes: 0

Views: 3783

Answers (1)

mkriheli
mkriheli

Reputation: 1846

You're calling the read method in:

wrapper = fs.get(file_id).read()

So you're getting a str (assuming Python 2, if 3, you're getting bytes). FileWrapper needs file like object, which of course str is not one.

Try to use:

wrapper = fs.get(file_id)

This will return file like object.

OTOH, pymongo's .get() returns a GridOut instance, which already supports iteration, so why not try something like:

wrapper = fs.get(file_id)
response =  StreamingHttpResponse(wrapper, content_type=file_['contentType'])

Upvotes: 1

Related Questions