首页 文章

无法在Google App Engine,Python上显示来自 Cloud 存储的图像

提问于
浏览
-1

我在Mac上使用App Engine python开发服务器1.9.20 .

我在Blobstore上取得了成功,但在启动我的网站之前,我正在将代码转换为使用cloudstore .

我在控制台中没有收到任何错误 . 但我没有在浏览器中显示图像 . 浏览器显示“图像未找到图标” . (Safari中的“?”)

我从SO上引用的示例中拼凑了我的 Cloud 存储代码 . 主要来自voscausa的代码(参见下文) .
服务网址看起来是正确的(基于我对样本文档的期望) .

但没有形象 . 如果你知道我做错了什么,我很高兴听到你的意见 .

我将上传的图像blob密钥和URL保存到UserProfile实体 .

class UserProfile(ndb.Model):
    profile_image_url = ndb.StringProperty(indexed=False, default=None)
    profile_image_key = ndb.BlobKeyProperty(indexed=False, default=None)

我写信给GCS并在这里生成一个blobstore密钥:

def CreateFile(filename, upload_file, content_type):
    with gcs.open(filename, 'w',
                  options={b'x-goog-acl': b'public-read'},
                  content_type=content_type) as f:
        f.write(upload_file)
    blobstore_filename = '/gs' + filename
    return blobstore.create_gs_key(blobstore_filename)

我的上传处理程序如下所示:

class UploadHandler(webapp2.RequestHandler):    
    def post(self):
        user = users.get_current_user()
        path = self.request.path
        item = self.request.get('item')
        image_num = self.request.get('image')
        src = self.request.get('src')
        group_id = self.request.get('id')

        if user:
            this_user_qry = UserProfile.query(UserProfile.user_id == user.user_id(), ancestor=user_key(user.user_id()))
            try:
                this_user = this_user_qry.get()
            except:
                logging.error('In UploadHandler, src = profile this_user_qry.get() failed')

        if src == 'profile':
            return_path = '/edit_profile#image'

            #if this_user.profile_image_key != None:

                #''' profile image exists, removing the current image, replaced with this_user.profile_image_key '''
                #blobstore.delete(this_user.profile_image_key)

                #this_user.profile_image_key = None
                #this_user.profile_image_url = None

            bucket_name = os.environ.get('BUCKET_NAME',
                                         app_identity.get_default_gcs_bucket_name())

            file_data = self.request.get("file", default_value=None)
            file_name = self.request.POST["file"].filename
            file_ext = file_name.lower().split('.')[-1]
            gcs_file = "/%s/profile/%s/%s" % (bucket_name, str(user.user_id()), file_name)
            #gcs_file = "/%s/%s" % (bucket_name, file_name)

            mimetypes.init()
            content_type = mimetypes.guess_type(file_name)[0]

            if file_data:
                blob_key = blobstore.BlobKey(CreateFile(gcs_file, file_data, content_type))

                if file_ext in ['png', 'jpg', 'gif']:
                    serving_url = images.get_serving_url(
                        blobstore.create_gs_key('/gs' + gcs_file), secure_url=True)
                elif gae_development:
                    # this SDK feature has not been documented yet !!!
                    serving_url = 'http://localhost:8080/_ah/gcs' + gcs_file
                else:
                    serving_url = 'https://storage.googleapis.com' + gcs_file
                print "\n-new-\nserving_url = %s" % serving_url

                this_user.profile_image_key = blob_key
                this_user.profile_image_url = serving_url
                try:
                    this_user.put()
                except:
                    logging.exception('In UploadHandler, if blob_key, this_user.put()')
                    self.redirect('/upload_image_error')
                else:
                    self.redirect('/edit_profile#image')

[gcs_file,blob_key,serving_url]的打印值为:

gcs_file = /app_default_bucket/profile/112118202356943244222/MichaelEdland_112514.jpg

blob_key = encoded_gs_file:YXBwX2RlZmF1bHRfYnVja2V0L3Byb2ZpbGUvMTEyMTE4MjAyMzU2OTQzMjQ0MjIyL01pY2hhZWxFZGxhbmRfMTEyNTE0LmpwZw ==

serving_url = http://0.0.0.0:8080/_ah/img/encoded_gs_file:YXBwX2RlZmF1bHRfYnVja2V0L3Byb2ZpbGUvMTEyMTE4MjAyMzU2OTQzMjQ0MjIyL01pY2hhZWxFZGxhbmRfMTEyNTE0LmpwZw==

对于Jinja模板:

我将此值传递给模板:

'profile_image_url': this_user.profile_image_url,

这将在配置文件页面上显示图像:

<img border="0" src="{{ profile_image_url | safe }}" width="100%" >

在App Engine控制台 Datastore Viewer

实体种类 Blobinfo 为此一个图像有两个条目

Key Names

1) 3kD4IorO9hfg-J7OrZtmVQ==

2) encoded_gs_file:YXBwX2RlZmF1bHRfYnVja2V0L3Byb2ZpbGUvMTEyMTE4MjAyMzU2OTQzMjQ0MjIyL01pY2hhZWxFZGxhbmRfMTEyNTE0LmpwZw==

filenames 1) MichaelEdland_112514.jpg 2) None

sizes

1) 166464 2) 250

BlobServingUrl 有一个条目

密钥名称和blob_key都是:

encoded_gs_file:YXBwX2RlZmF1bHRfYnVja2V0L3Byb2ZpbGUvMTEyMTE4MjAyMzU2OTQzMjQ0MjIyL01pY2hhZWxFZGxhbmRfMTEyNTE0LmpwZw==

GSFileInfo 密钥名称= encoded_gs_file:YXBwX2RlZmF1bHRfYnVja2V0L3Byb2ZpbGUvMTEyMTE4MjAyMzU2OTQzMjQ0MjIyL01pY2hhZWxFZGxhbmRfMTEyNTE0LmpwZw==

content_type = image/jpeg filename = /app_default_bucket/profile/112118202356943244222/MichaelEdland_112514.jpg

我发现一些有用的东西(要达到这一点):

voscausa的回答很有帮助How to serve cloudstorage files using app engine SDK

和他修改后的代码示例很有用https://github.com/voscausa/appengine-gcs-blobstore-python

在文档中有一个服务网址的示例

我也读过谷歌文档,这让我走得很远 . (由于缺乏声誉,我无法发布链接)

但现在我似乎陷入困境 .

提前致谢 . 在每天使用StackOverflow一年后,我终于要问一个问题了 . :-)可能511(太多信息),但我很感激帮助 .

1 回答

  • 0

    你可以'忘记'图像文件,看看它是否正确传输?即,检查它是作为文本还是二进制转移?

    这个问题可能会有所帮助:How to write raw bytes to Google cloud storage with GAE's Python API

    特别是接受答案的引用:

    我想问题是gcs_file.write()方法需要类型为“str”的数据 .

    在您的CreateFile函数中,f.write(upload_file)语句可能正在错误地写入upload_file .

相关问题