mongodb / flask-pymongo

PyMongo support for Flask applications
BSD 2-Clause "Simplified" License
721 stars 175 forks source link

TypeError: argument must be an int, or have a fileno() method while trying to use send_file #136

Closed AstraSerg closed 4 years ago

AstraSerg commented 4 years ago

Hi. I have data in the mongodb:

db.fs.files.find()
{ "_id" : ObjectId("5da4cee17ad6b383c8c3f7ed"), "filename" : "kot_accounts_2019-09-filtered.xlsx", "contentType" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "md5" : "3095642c99eafb93e2c0d35ac5dd07f5", "chunkSize" : 261120, "length" : NumberLong(76937), "uploadDate" : ISODate("2019-10-14T19:39:13.770Z"), "file_type" : "list", "round_id" : "kot_2019-10-14_19:43:46", "mess" : "test2", "mess_type" : "prefix" }

And trying to send it to browser:

@app.route('/getdbfile/<path:filename>', methods=['GET',])
def getdbfile(filename):
    res = mongo.send_file(filename)
    return res

But if I trying to get file with filename kot_accounts_2019-09-filtered.xlsx I'm getting the error:

TypeError: argument must be an int, or have a fileno() method.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./app.py", line 388, in getdbfile
    res = mongo.send_file(filename)
  File "/usr/local/lib/python3.6/dist-packages/flask_pymongo/__init__.py", line 198, in send_file
    data = wrap_file(request.environ, fileobj, buffer_size=1024 * 255)
  File "/usr/local/lib/python3.6/dist-packages/werkzeug/wsgi.py", line 530, in wrap_file
    return environ.get("wsgi.file_wrapper", FileWrapper)(file, buffer_size)
SystemError: <built-in function uwsgi_sendfile> returned a result with an error set

What I'm doing wrong?

dcrosta commented 4 years ago

This looks like a bug, or rather a mismatched expectation between werkzeug (which states that the object passed to wrap_file() must have a read() method only) and uwsgi, which seems to want an actual file with fileno().

This blog suggests a potential work-around, which you might try.

AstraSerg commented 4 years ago

Thanks a lot, it helped! And thank you for the great library! I could create PR to insert this info to your doc but didn't find where is it, sorry.

dcrosta commented 4 years ago

Glad that worked! If you'd like to add a note, we can maybe add a "troubleshooting" section to https://github.com/dcrosta/flask-pymongo/blob/master/docs/index.rst, I'd accept a PR for that.

AstraSerg commented 4 years ago

Excellent, I'll do it.