简体   繁体   English

Python Flask-图像代理

[英]Python Flask - image proxy

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 ): 像这样(从此处获取 ):

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? 还有更好的方法吗?

Why not use redis to cache and proxy your images? 为什么不使用Redis缓存和代理图像? 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. 我编写了一个Web应用程序,需要从API服务器请求图像,但有时可能会禁止403,因此我从API服务器获取图像并将其缓存。

  • before: client -> API server:may get 403 之前:客户端-> API服务器:可能会得到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 我的服务器-> API服务器:获取图像,将其缓存,发送给客户端
    • cached: 缓存:

      • client -> my server:find it and get the image from redis and send back 客户端->我的服务器:找到它并从redis获取图像并发回

The difference is: 区别在于:

  • before: client <-> API server 之前:客户端<-> API服务器
  • now: client <-> my server <-> API server 现在:客户端<->我的服务器<-> API服务器

before the client get images directly from API server, so may get problems. 在客户端直接从API服务器获取图像之前,可能会出现问题。 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. 借助强大的Redis,您应该很容易。

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 . 最初的想法来自小狗的眼睛 Read the source code for more details. 阅读源代码以获取更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM