Ritchie Ritchie - 2 months ago 37
Python Question

Response streamed [200 OK]> is not JSON serializable stream image python

I am looking for a way to serve some images from the bing map without sharing the URL (because it contains the secret key) and return it to the client (without saving to disk first). I'm using this method from here

def get_stream_from_url(url):
req = requests.get(url, stream = True)
return Response(stream_with_context(req.iter_content()), content_type = req.headers['content-type'])


I use it in another method, where I generate a list with those info for those image, so basically I wan to put the sream response inside the json as a value of key
url
:

def images_data_and_url(self, data):
results = []
for i in range(1, 13):
image = {}
description = data['description']
url = self.get_stream_from_url(data['url'])
tile = {"description": description
"url": url}
results.append(image)
print results
return json.dumps(results)


EDIT:
If I print the results I have this:

<type 'list'>: [{'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>} , {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>},{'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}, {'description': ' this is an example', 'url': <Response streamed [200 OK]>}]


If I do like this I get this error

<Response streamed [200 OK]> is not JSON serializable


This because of the function
get_stream_from_url
returns a response :/ My problem is that I don't know how to send it in another way?

In HTML I get the data and assign per the data for each image like this:

<img class="image1 " data-description="The description" src="">


Can somebody help me, how to encode the stream so I can send it as with the JSON data?

Answer

Flask is overkill for this. I've created a library called wsinfo, which is available here: https://github.com/linusg/wsinfo.

With it, the code is as simple as:

import base64
import wsinfo
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


def html_image(data, content_type):
    f = StringIO(data)
    encoded = base64.b64encode(f.read())
    return "data:{};base64,{}".format(content_type, encoded)

url = "http://t0.tiles.virtualearth.net/tiles/a1210223003.jpeg?g=854&mkt=en-US&token=AtAixlkrsDwLlwTwXFZqpVP9nKyV-KbP5TbBJHWAIDVaovuYWZOHCKvUOksICp8t"
w = wsinfo.Info(url)
img = html_image(w.content, w.content_type)

with open("out.html", "w") as html:
    html.write('<img class="image1" data-description="The description" src="{}" />'.format(img))

The code runs with both Python 2 and 3, and results in an HTML file called out.html, where the image is embedded.