2014-02-24 71 views
2

我有一個圖像文件通過使用urlfetch api的Python谷歌應用程序引擎從網址中提取。商店提取的圖像到Blobstore

img = urlfetch.fetch(url).content 

我想將其上傳到blobstore以便能夠將其提供給用戶。因此,我會願意將blob_key保存到數據存儲區。正如Google App Engine Blobstore的文檔中所述,我不想爲用戶創建上傳頁面,因爲這項工作將在服務器端完成。

實現此目的的步驟應該是什麼?

回答

2

更新與應用程序引擎的到來1.9.0應用程序可以使用默認的GCS桶內,它提供了一個已配置桶免配額的文檔!

更多細節here

您還可以發送一個多部分的形式Blob存儲區的upload_url。

這是我的代碼到一個blob上傳到Blob存儲區:

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