Python Flask - image proxy
Question: I'm looking for a way to get an image from the web and return it to client
(without saving to disk first). Something like that (taken from
[here](http://flask.pocoo.org/snippets/118/)):

    
    
    import requests
    from flask import Response, stream_with_context
    
    @files_blueprint.route('/', methods=['GET'])
    def get_image():  
        req = requests.get('http://www.example.com/image1.png', stream = True)
        return Response(stream_with_context(req.iter_content()), content_type = req.headers['content-type'])
    

Above code is working but its really slow.  
Any better way?


Answer: Why not use redis to cache and proxy your images? I've written a web app that
need to request images from an API server but may get 403 forbidden sometimes,
so I get the images from the API server and cache them.

  * before: client -> API server:may get 403

  * now with image proxy:

    * not cached:

      * client -> my server:don't find that
      * my server -> API server:get the image,cache it,send to the client
    * cached:

      * client -> my server:find it and get the image from redis and send back

The difference is:

  * before: client <-> API server
  * now: client <-> my server <-> API server

before the client get images **directly** from API server, so may get
problems. Now, all the images point to **my server** so I can do more things.

You can also control the time to expire. With the powerful redis, you should
be easy.

I'll give you a basic example to help you understand it.

    
    
    from StringIO import StringIO
    
    from flask import send_file, Flask
    import requests
    import redis
    
    app = Flask(__name__)
    redis_server = redis.StrictRedis(host='localhost', port=6379)
    
    @app.route('/img/<server>/<hash_string>')
    def image(server, hash_string):
        """Handle image, use redis to cache image."""
        image_url = 'http://www.example.com/blabla.jpg'
        cached = redis_server.get(image_url)
        if cached:
            buffer_image = StringIO(cached)
            buffer_image.seek(0)
        else:
            r = requests.get(image_url)  # you can add UA, referrer, here is an example.
            buffer_image = StringIO(r.content)
            buffer_image.seek(0)
            redis_server.setex(image_url, (60*60*24*7),
                               buffer_image.getvalue())
        return send_file(buffer_image, mimetype='image/jpeg')
    

Note that the example above will get the image and cache it only when someone
visit it, so may cost some time at the first time. You can fetch the images
first by yourself. In my case(I use the way above), I'm fine with it.

The original idea is from [puppy-eyes](https://github.com/cameronmaske/puppy-
eyes). Read the source code for more details.

