如何使用实验性API将大文件写入Blobstore? [英] How to write Big files into Blobstore using experimental API?

查看:102
本文介绍了如何使用实验性API将大文件写入Blobstore?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两难困境。我使用tipfy作为框架上传scribd store和blobstore中的文件。
我的网络表单行为不是由blobstore.create_upload_url创建的(我只是使用url_for('myhandler'))。我这样做是因为如果我使用blobstore处理程序解析POST响应,并且我不能使用普通的python-scribd api将文件上传到scribd商店。
现在我正在使用scribd saver:

$ p $ class UploadScribdHandler(RequestHandler,BlobstoreUploadMixin):
def post(自我):
uploaded_file = self.request.files.get('upload_file')
fname = uploaded_file.filename.strip()
尝试:
self.post_to_scribd(uploaded_file, fname)
除了异常,e:
#...得到异常消息,并用它做点什么
msg = e.message
#...
#将流重置为零(开始),以便可以再次读取文件
uploaded_file.seek(0)
#removed尝试 - 除非在浏览器窗口中查看调试信息
#创建文件

file_name = files.blobstore.create(_blobinfo_uploaded_filename = fname)
#打开文件并使用files.open(file_name,'a')将文件写入
作为f:
f.write(uploaded_file.read())
#结束文件。在尝试阅读之前先做这件事。
files.finalize(file_name)
#获取文件的Blob键
blob_key = files.blobstore.get_blob_key(file_name)

返回响应('done')

def post_to_scribd(self,uploaded_file,fname):
errmsg =''
uploaded_file = self.request.files.get('upload_file')
fname = uploaded_file如果(fext不在ALLOWED_EXTENSION中):
raise Exception(').filename.strip()
fext = fname [fname.rfind('。')+ 1:如果SCRIBD_ENABLED:
doc_title = self.request.form.get('title')
doc_description = self.request.form,则此文件类型不允许上传\'n')
.get('description')
doc_tags = self.request.form.get('tags')
try:
document = scribd.api_user.upload(uploaded_file,fname,access ='私人')
#while document.g如果不是doc_title:
document.title = fname [:fname.rfind('。')]
else:
document.title = doc_title
if not doc_description:
document.description ='本文档上传于'+ str(datetime.datetime.now())+'\\ \\ n'
else:
document.description = doc_description
document.tags = doc_tags
document.save()
除了scribd.ResponseError错误:
抛出Exception('Scribd失败:错误代码:%d,错误信息:%s \ n'%(err.errno,err.strerror))
,除了scribd.NotReadyError,错误:
提升异常('Scribd失败:错误代码:%d,错误消息:%s\\\
'%(err.errno,err.strerror))
除外:$ b $你可以看到它也将文件保存到Blobstore中。b提示Exception('something wrong exception')

但如果我上传大文件(即5Mb)我收到

  RequestTooLargeError:API调用file.Append()的请求太大。 
请求:docs.upload(access ='private',doc_type ='pdf',file =('PK\x03\x04\\\
\x00\x00\x00\x00\ x00\x01\x10 = \x00\x00(...)','test.pdf'))

我该如何解决它?
谢谢!

解决方案

,对文件API的调用较小,例如这样:

  with files.open(file_name,'a')as f :
data = uploaded_file.read(65536)
while data:
f.write(data)
data = uploaded_file.read(65536)

请注意,对App Engine应用程序的常规请求的有效负载大小限制为10MB;如果您要上传较大的文件,则需要使用常规的blobstore上传机制。


I have dilemma.. I'm uploading files both in scribd store and blobstore using tipfy as framework. I have webform with action is not created by blobstore.create_upload_url (i'm just using url_for('myhandler')). I did it because if i'm using blobstore handler the POST response parsed and I cannot use normal python-scribd api to upload file into scribd store. Now I have working scribd saver:

class UploadScribdHandler(RequestHandler, BlobstoreUploadMixin):
    def post(self):
        uploaded_file = self.request.files.get('upload_file')
        fname = uploaded_file.filename.strip()
        try:
            self.post_to_scribd(uploaded_file, fname)
        except Exception, e:
            # ... get the exception message and do something with it
            msg = e.message
            # ...
        # reset the stream to zero (beginning) so the file can be read again
        uploaded_file.seek(0)
        #removed try-except to see debug info in browser window
        # Create the file

        file_name = files.blobstore.create(_blobinfo_uploaded_filename=fname)
        # Open the file and write to it
        with files.open(file_name, 'a') as f:
            f.write(uploaded_file.read())
        # Finalize the file. Do this before attempting to read it.      
        files.finalize(file_name)
        # Get the file's blob key
        blob_key = files.blobstore.get_blob_key(file_name)

        return Response('done')

    def post_to_scribd(self, uploaded_file, fname):
        errmsg =''
        uploaded_file = self.request.files.get('upload_file')
        fname = uploaded_file.filename.strip()
        fext = fname[fname.rfind('.')+1:].lower()
        if (fext not in ALLOWED_EXTENSION):
            raise Exception('This file type does not allowed to be uploaded\n')
        if SCRIBD_ENABLED:
            doc_title = self.request.form.get('title')
            doc_description = self.request.form.get('description')
            doc_tags = self.request.form.get('tags')
            try:
                document = scribd.api_user.upload(uploaded_file, fname, access='private')
                #while document.get_conversion_status() != 'DONE':
                #   time.sleep(2)
                if not doc_title:
                    document.title = fname[:fname.rfind('.')]
                else:
                    document.title = doc_title
                if not doc_description:
                    document.description = 'This document was uploaded at ' + str(datetime.datetime.now()) +'\n'
                else:
                    document.description = doc_description
                document.tags = doc_tags
                document.save()
            except scribd.ResponseError, err:
                raise Exception('Scribd failed: error code:%d, error message: %s\n' % (err.errno, err.strerror))
            except scribd.NotReadyError, err:
                raise Exception('Scribd failed: error code:%d, error message: %s\n' % (err.errno, err.strerror))
            except:
                raise Exception('something wrong exception')

As you can see it also saves file into blobstore.. But If i'm uploading big file (i.e. 5Mb) I'm receiving

RequestTooLargeError: The request to API call file.Append() was too large.
Request: docs.upload(access='private', doc_type='pdf', file=('PK\x03\x04\n\x00\x00\x00\x00\x00"\x01\x10=\x00\x00(...)', 'test.pdf'))

How can I fix it? Thanks!

解决方案

You need to make multiple, smaller calls to the file API, for instance like this:

with files.open(file_name, 'a') as f:
    data = uploaded_file.read(65536)
    while data:
      f.write(data)
      data = uploaded_file.read(65536)

Note that the payload size limit on regular requests to App Engine apps is 10MB; if you want to upload larger files, you'll need to use the regular blobstore upload mechanism.

这篇关于如何使用实验性API将大文件写入Blobstore?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆