使用Flask(Python)从GAE数据存储中提供图像

6
我希望避免使用GAE的Webapp,因此我使用以下代码将图像上传到Blobstore(代码片段来自:http://flask.pocoo.org/mailinglist/archive/2011/1/8/app-engine-blobstore/#7fd7aa9a5c82a6d2bf78ccd25084ac3b)。请注意,保留了HTML标签。
@app.route("/upload", methods=['POST'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        header = f.headers['Content-Type']
        parsed_header = parse_options_header(header)
        blob_key = parsed_header[1]['blob-key']
        return blob_key

它返回的似乎是一个Blobkey,类似于这样:

2I9oX6J0U5nBCVw8kEndpw==

我尝试使用以下代码显示最近存储的Blob图像:

@app.route("/testimgdisplay")
def test_img_display():
    response = make_response(db.get("2I9oX6J0U5nBCVw8kEndpw=="))
    response.headers['Content-Type'] = 'image/png'
    return response

不幸的是,这部分无法正常工作,我得到了以下错误:

BadKeyError: Invalid string key 2I9oX6J0U5nBCVw8kEndpw==

你们有遇到过这个错误吗?看起来Blobkey格式良好,但我找不到线索。


我认为问题在于你得到的blobkey似乎是base64编码的。 - Sebastian Kreft
谢谢,它让我朝着正确的方向前进了 ;) - Koffee
2个回答

8

在获取 Blob 的调用中出现了一个简单的错误,我写成了:

db.get("2I9oX6J0U5nBCVw8kEndpw==")

正确的调用应该是:

blobstore.get("2I9oX6J0U5nBCVw8kEndpw==")

对于那些想完整实现通过GAE Blobstore和Flask上传/服务图片而不使用Webapp的人,这里是完整的代码:

渲染上传表单的模板:

@app.route("/upload")
def upload():
    uploadUri = blobstore.create_upload_url('/submit')
    return render_template('upload.html', uploadUri=uploadUri)

请将您的 uploadUri 放置在表单路径中(HTML):
<form action="{{ uploadUri }}" method="POST" enctype="multipart/form-data">

以下是处理图片上传的函数(出于实际原因,我返回了blob_key,请按照您的模板进行替换):

@app.route("/submit", methods=['POST'])
def submit():
    if request.method == 'POST':
        f = request.files['file']
        header = f.headers['Content-Type']
        parsed_header = parse_options_header(header)
        blob_key = parsed_header[1]['blob-key']
        return blob_key

现在假设您使用以下路径提供图像:

/img/imagefilename

那么您的图像服务功能为:

@app.route("/img/<bkey>")
def img(bkey):
    blob_info = blobstore.get(bkey)
    response = make_response(blob_info.open().read())
    response.headers['Content-Type'] = blob_info.content_type
    return response

最后,在模板中需要显示图像的任何位置,您只需放置以下代码:

<img src="/img/{{ bkey }} />

0

我认为Flask和Webapp在提供Blobstore图像方面并没有更好或更差的区别,因为它们都使用Blobstore API来提供Blob

你所谓的Blobkey只是一个字符串,需要转换为一个键(这里称为resource):

from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, resource):
        resource = str(urllib.unquote(resource))
        blob_info = blobstore.BlobInfo.get(resource)
        self.send_blob(blob_info)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接