mongodb / flask-pymongo

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

Use of contentType inside send_file. #120

Open corneauf opened 5 years ago

corneauf commented 5 years ago

As per the documentation here, the contentType field has been deprecated. However, it is still used here and here.

Currently, if someone saves an image through the gridfs module and use send_file it will leave the mimetype as text/html. Using the recommended method from the documentation of GridFS of putting the mimetype inside the metadata field will also not work.

Therefore, one must either pass contentType='image/base64' to the GridFS.put function or change the mimetype of the response_class object returned by send_file.

This behavior can only be noticed once you look at the sources. Therefore, I suggest moving to using the metadata field instead.

Working example:

from gridfs import GridFS
from flask import Flask
from flask_pymongo import PyMongo

app = Flask("app")
app.config['MONGO_URI'] = 'mongodb://localhost:27017/test'
mongo = PyMongo(app)
fs = GridFS(mongo.db)

filename = "..." # PNG image

fs.put(open(filename, 'rb'), filename=filename)

response = mongo.send_file(filename)

print(response.mimetype)
dcrosta commented 5 years ago

PyMongo itself does not attempt to set the content_type field on GridFS files -- that's one of the features of Flask-PyMongo when you use save_file. It's not expected that PyMongo would set the field, so if you are writing data to GridFS with PyMongo, you should set the field yourself when you write, or set the content-type on the response, as you suggest.

Regarding the deprecation: it doesn't look like PyMongo has taken any steps to deprecate usage of contentType or md5 or to move them into metadata; as of today, GitHub master on pymongo doesn't have any deprecation warnings for those fields.

Trying to change Flask-PyMongo may prove tricky. Any existing installations may need data migration, or we may have to live with dual reads for a long time (maybe not the worst thing). But the bigger concern is what will happen in PyMongo itself in this regard -- I don't want to duplicate work there, or do something that will cause incompatibility in the future.