I have a small Python/Flask application that should store a picture in MongoDB.
- The a client submits a HTTP POST (JSON) with one of the fields being the base64-encoded image.
- The server should store this image in a MongoDB ImageField. I'm using mongoengine right now.
The Model:
class Image(db.EmbeddedDocument):
data = db.ImageField()
Right now, the relevant server code looks like this:
import Image as PIL
import base64
import cStringIO # I'm trying to give PIL something that can handle common file operations without having to write to disk
imageData = jsondata['image']
file_like = cStringIO.StringIO(base64.decodestring(imageData))
PILImage = PIL.open(file_like)
# new mongo object
img = Image(name="imagename")
img.data = PILImage # assignment of image data
img.save()
This gives me the error #=>ValidationError: ValidationError (Location:53e37ed6844de403e0998182) (image.grid_id: ['images'])
When I change the assignment of the image data to this:
img.data.put(PILImage)
I get the error: #=> ValidationError: Invalid image: read
So I thought it perhaps is looking for an object that supports a 'read' method. When I change the assignment to this:
img.data.put(file_like)
I get the error: #=> "ValidationError: Invalid image: cannot identify image file "
So, I'm able to base64-encode, json.loads(), POST, json.dumps(), base64decode, and create a PIL image from the data, but I somehow can't get the MongoDB ImageField to accept it as an image.
Can anyone help?
One thing: I found that if I simply write the PILImage to disk and then store it by telling mongoengine to
img.data.put("path/to/image/file")
I can work around this, but I would like to avoid filesystem operations, as the application will experience a fair amount of traffic and we suspect IO will be the first bottleneck.