2

I have a basic Python Flask API set up right not that takes an ID as a parameter for a GET request. Inside the get request logic, I am doing a get request on another resource to retrieve an image associated with the ID that was passed in:

image = requests.get(url = image_url)
image = Image.open(BytesIO(image.content))
print(image.format)

The image format that it returns in JPEG.

I want to add this as part of the response of my API. This is the definition of my GET endpoint:

@app.route('/getmsg/', methods=['GET']) 
def respond():

This is how I am trying to return the image that I got from the other resource:

return {"image": send_file(image, mimetype='image/jpeg'), "data": jsonify(return_list)}

I already tried following this stackoverflow question: How to return images in flask response?

Which is how I got to where I am at now. I make a get request through this endpoint: http://localhost:5000/getmsg/?id=7187167507933759112.

I have also tried to return just the image like so:

return send_file(image, mimetype='image/jpeg')

But it gives me the same error.

Everything works except the returning of the image.

I expect to be able to see the image in the response of the get request, but right now it gives 500 internal server error.

This is the response that I get in the terminal:

TypeError: <Response 693 bytes [200 OK]> is not JSON serializable

Any guidance on what I am doing wrong would be greatly appreciated. Thanks.

Ryan Fasching
  • 449
  • 2
  • 11
  • 21

1 Answers1

5

From the documentation of send_file():

Sends the contents of a file to the client. This will use the most efficient method available and configured.

It means that send_file itself is a response. That is why you are getting this error: Response 693 bytes [200 OK]

One possible solution to send an image would be to base64_encode the file. Something like this:

with open("yourfile.ext", "rb") as image_file:
    encoded_string = base64.b64encode(image_file.read())

And then send the response like:

return {"image": encoded_string, "data": jsonify(return_list)}

And decode the string on the other end like:

base64.b64decode(coded_string)

This is also make the size of the response smaller, thus improving performance as well.

Hope this helps. Good luck.

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
  • 1
    Would this still work if I am not reading the file from the file system? I am getting the image from a GET request of another API. That API gives me back that image. Would I still be able to encode the image? – Ryan Fasching Oct 22 '19 at 14:25
  • As long as you are getting an image file, yes. – Harshal Parekh Oct 22 '19 at 20:51
  • I get an error saying `TypeError: Object of type bytes is not JSON serializable` any thoughts? – Ken May 01 '21 at 03:01