【问题标题】:Store fetched Image to Blobstore将获取的图像存储到 Blobstore
【发布时间】:2014-02-24 15:19:10
【问题描述】:

我有一个使用 python 谷歌应用引擎的 urlfetch api 从 url 中提取的图像文件。

img = urlfetch.fetch(url).content

我想将其上传到 blobstore 以便能够将其提供给用户。因此,我愿意将 blob_key 保存到数据存储区。正如 Google App Engine Blobstore 的文档中所给出的,我不想为用户创建一个上传页面,因为这项工作将在服务器端完成。

实现这一目标的步骤是什么?

【问题讨论】:

    标签: google-app-engine blobstore


    【解决方案1】:

    更新随着 app engine 1.9.0 的到来,应用程序可以使用默认的 GCS 存储桶,该存储桶提供已配置的存储桶和免费配额!

    更多详情here

    您还可以将多部分表单发送到 blobstore upload_url。

    这是我将 blob 上传到 blobstore 的代码:

    from __future__ import unicode_literals
    
    import webapp2
    import mimetypes
    import logging
    from google.appengine.ext.ndb import blobstore                                                      
    from google.appengine.ext.webapp import blobstore_handlers
    from google.appengine.api import urlfetch
    from google.appengine.runtime import DeadlineExceededError
    
    CRLF = b'\r\n'
    BOUNDERY = b'--Th15-Is-ThE-BoUnDeRy--'
    
    
    def _encode_multipart(_fields=None, _files=None):
        """ Generator inserts fields and files to create a multipart payload """
    
        for (field_name, field_value) in _fields or []:
            yield b'--' + BOUNDERY + CRLF
            yield b'Content-Disposition: form-data; name="%s"' % str(field_name) + CRLF
            yield CRLF
            yield str(field_value) + CRLF
    
        for (file_name, file_data) in _files or []:
            yield b'--' + BOUNDERY + CRLF
            yield b'Content-Disposition: form-data; name="file"; filename="%s"' \
                  % str(file_name) + CRLF
            yield b'Content-Type: %s' % mimetypes.guess_type(file_name)[0] + CRLF
            yield CRLF
            yield file_data + CRLF
    
        yield b'--%s--' % BOUNDERY + CRLF
    
    
    def create_upload_url(for_url):
    
        return blobstore.create_upload_url(for_url, max_bytes_per_blob=1048576)
    
    
    def _fetch_blob_update(payload):
    
        upload_url = create_upload_url(webapp2.uri_for('blob_update', _full=True))
        try:
            response = urlfetch.fetch(
                url=upload_url,
                payload=payload,
                method=urlfetch.POST,
                deadline=40,
                follow_redirects=False,
                headers={b'Content-Type': str('multipart/form-data; boundary=%s' % BOUNDERY)}
            )
            if response.status_code != 200:
                logging.error('URL : %s fetch ERROR : %d' % (upload_url, response.status_code))
                return None
            else:
                return response.content
        except (urlfetch.DownloadError, DeadlineExceededError), e:
            logging.error('fetch %s download or deadline error, exception : %s'
                          % (upload_url, str(e)))
            return None
    
    
    def blob_update_by_upload(ndb_key, blob):
        """ update blob using upload to the blobstore """
    
        result = _fetch_blob_update(b''.join(_encode_multipart(_files=[(ndb_key.id(), blob)])))
        return blobstore.BlobKey(result)
    
    
    class BlobUpdate(blobstore_handlers.BlobstoreUploadHandler):
        """ has named route : blob_update """
    
        def post(self):
            """ blob upload handler returns the new blobkey """
    
            blob_info = self.get_uploads('file')[0]
            self.response.headers[b'Content-Type'] = b'text/plain'
            self.response.write(str(blob_info.key()))
    

    路线:

    webapp2.Route(r'/blob_update', handler='....BlobUpdate', name='blob_update')
    

    【讨论】:

      【解决方案2】:

      blobstore 的 fileapi 已被弃用,因此您需要上传到云存储而不是 blobstore。

      import cloudstorage as gcs
      
      filename = "<your bucket + filename>"   
      with gcs.open(filename, 'w') as f:
          f.write(img)
      blobstore_filename = "/gs"+filename
      #this is needed if you want to continue using blob_keys.
      return blobstore.BlobKey(blobstore.create_gs_key(blobstore_filename))
      

      查看 gcs 的文档here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-06
        • 2013-05-06
        • 1970-01-01
        • 1970-01-01
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        相关资源
        最近更新 更多