2

I've built a Python Flask App API that responds with JSON. I want the response to now include both JSON and an image.

How can I create as a single HTTP response that passes both JSON data and an image?

For the JSON, I'm using return jsonify({some dict}).

And for the image, I've read to make the image a StringIO object and then on it to use .get_value() and pass StringIO.get_value() as an argument to response() and return that. The image is produced by matplotlib (see https://gist.github.com/wilsaj/862153)

While http responses can't send more than one content type, the means for passing the image would seem to imply that it's simply text. Is that true? If so, can the image simply be wrapped in the JSON also, as a separate key from the other JSON data being passed?

These posts would seem to suggest yes, that images can be transferred via JSON with a Byte array.

How can I add an image file into json object?

Binary Data in JSON String. Something better than Base64

I've read that generally it is better to pass URLs to the images in JSON and then download the images on the client side. But my images are generated dynamically, need not persist and I'd rather not have to save the images as files and serve them if possible, so does the Byte array seem to be the correct direction?

Community
  • 1
  • 1
Eduardo Moreno
  • 121
  • 2
  • 7
  • One potential solution is to use a completely different approach—send back data in the JSON file instead of an image from matplotlib, and create the graph on the client side. – Dietrich Epp Oct 03 '15 at 19:11

1 Answers1

2

You can encode the image data as base64.

Based on the code you've linked this could look like this:

import base64
import StringIO

# ...

png_output = StringIO.StringIO()
canvas.print_png(png_output)

# ...

some_dict["imagedata"] = base64.b64encode(png_output.getvalue())

For use in a web browser (Javascript application) you could directly generate Data URIs in the format

data:image/png;base64,<BASE64 ENCODED IMAGE DATA>

which could be fed directly into the src attribute of an image tag.

try-catch-finally
  • 7,436
  • 6
  • 46
  • 67
  • 1
    Base64 drastically increases the data size. If the image is slightly large, it will not be ideal to send it in one request at all. – Gaurav Raj Aug 15 '20 at 07:04