Ryan Fasching
Ryan Fasching

Reputation: 541

How to return image as part of response from a GET request in Flask?

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.

Upvotes: 2

Views: 10480

Answers (1)

Harshal Parekh
Harshal Parekh

Reputation: 6017

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.

Upvotes: 5

Related Questions