【问题标题】:How can I retrieve a file object from the blobstore within a handler?如何从处理程序中的 blobstore 检索文件对象?
【发布时间】:2012-04-21 13:03:29
【问题描述】:

我在 blobstore 中保存了一个文档,并试图在处理程序(处理任务)中检索它。我已经阅读了 the appengine documentation 关于如何使用 blobstore 的内容,但我很难让它适用于我的情况。我在处理程序中尝试了以下操作,但似乎无法将对象作为保存的文件返回(例如 .pdf 或 .txt)

class SendDocuments(webapp2.RequestHandler):
    def post(self):
        document_key = self.request.get("document_key")
        document_key = Key(str(document_key))
        the_document = DocumentsModel.all().filter("__key__ =", document_key).get()
        file_data = blobstore.BlobInfo.get(str(the_document.blobstore_key)) # returns a blobinfo object
        file_data.open() # returns a blobreader object
        file_data.open().read() # returns a string

我也试过

class ServeSavedDocument(blobstore_handlers.BlobstoreDownloadHandler):
  def get(self, blob_key):
    self.send_blob(blob_key, save_as=True)
    return

class SendDocuments(webapp2.RequestHandler):
    def post(self):
        document_key = self.request.get("document_key")
        document_key = Key(str(document_key))
        the_document = DocumentsModel.all().filter("__key__ =", document_key).get()
        grab_blob = ServeSavedDocument()
        file_data = grab_blob.get(self, str(the_document.blobstore_key))

但是对 ServeSavedDocument 的调用失败了

'NoneType' object has no attribute 'headers'

我查看了files api,但唯一没有保存文件的示例似乎只是返回 blob 键,即

blob_key = files.blobstore.get_blob_key(file_name)    

从处理程序中获取 blobstore 中已保存文件的最佳方法是什么?

编辑 1:

我正在尝试以可以使用以下代码在发布请求中编码为文件的格式/状态从 blobstore 检索 txt 文件或 pdf 文件

from google.appengine.api import urlfetch
from poster.encode import multipart_encode
# assuming here that file_data is the file object
payload = {}
payload['user_id'] = '1234123412341234'
payload['test_file'] = MultipartParam('test_file', filename=file_data.filename,
                                      filetype=file_data.type,
                                      fileobj=file_data.file)
data,headers= multipart_encode(payload)
send_url = "http://127.0.0.0/"
t = urlfetch.fetch(url=send_url, payload="".join(data), method=urlfetch.POST, headers=headers)

【问题讨论】:

  • 您的意思是“对象已作为保存的文件返回”?文件只是数据的容器; Blobstore API 返回该数据。您是在尝试为用户提供 blob,还是在应用程序中使用数据?前者在 blobstore 文档中有一个完整的工作示例;你试过吗?
  • 嗨尼克,我必须通过阅读文档来掌握如何让 blobstore 将 blob 返回给用户。我要做的是获取存储在 blobstore 中的文本文件,并通过使用 python 海报库在多部分发布请求中对文件进行编码,将其发送到外部(文件处理 API)。

标签: python google-app-engine blobstore


【解决方案1】:

好的,经过一番折腾,我发现这行得通!关键是在 blobinfo 对象上简单地调用 open()。

class SendDocuments(webapp2.RequestHandler):
    def post(self):
        document_key = self.request.get("document_key")
        document_key = Key(str(document_key))
        the_document = DocumentsModel.all().filter("__key__ =", document_key).get()
        file_data = blobstore.BlobInfo.get(str(the_document.blobstore_key))
        payload = {}
        payload['user_id'] = '1234123412341234'
        payload['test_file'] = MultipartParam('the_file', filename="something",
                                      filetype=file_data.content_type,
                                      fileobj=file_data.open())

【讨论】:

    【解决方案2】:

    看看 BlobReader 类,我想这就是你要找的: https://developers.google.com/appengine/docs/python/blobstore/blobreaderclass

    它允许对 blobstore 数据进行类似文件的读取访问:

    # blob_key = ..
    
    # Instantiate a BlobReader for a given Blobstore value.
    blob_reader = blobstore.BlobReader(blob_key)
    # Read the entire value into memory. This may take a while depending
    # on the size of the value and the size of the read buffer, and is not
    # recommended for large values.
    value = blob_reader.read()
    

    【讨论】:

    • 您好,谢谢您的建议。我已经尝试过了,但是值作为字符串返回,但我需要它是一个类似对象的文件,以便它适合多部分后编码 - 请参阅上面的编辑 1 :)
    • 你对类文件对象的定义是什么? blobstore.BlobReader 是最接近文件对象的,它在 Python 的上下文中是众所周知的 (docs.python.org/library/stdtypes.html#file-objects)。
    • 您好,对任何缺乏解释表示歉意 - 我还在学习 :) 除了语义之外,我的目标是找到一种在多部分发布请求中对文件进行编码的方法 - 我已经举了一个例子在帖子的第一次编辑中。
    【解决方案3】:

    试试这个,指定文件名,然后在send_blob()中输入:

    def mime_type(filename):
        return guess_type(filename)[0]
        class ServeSavedDocument(blobstore_handlers.BlobstoreDownloadHandler):
            def get(self):
                blob_key = self.request.get("blob_key")
                if blob_key:
                    blob_info = blobstore.get(blob_key)               
                    if blob_info:
                        save_as1 =  blob_info.filename
                        type1=mime_type(blob_info.filename)
                        self.send_blob(blob_info,content_type=type1,save_as=save_as1)
    

    【讨论】:

    • 您好,感谢您的代码。假设您打算让该类与 def mime_type 具有相同的缩进级别,我试图实现这一点,但是 type1 被返回为 None。 self.send_blob 也因“NoneType”对象没有属性“headers”而失败。
    猜你喜欢
    • 1970-01-01
    • 2012-05-15
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多