【问题标题】:Google App Engine - Error uploading file to blobstore from Python codeGoogle App Engine - 从 Python 代码上传文件到 blobstore 时出错
【发布时间】:2013-06-22 01:59:54
【问题描述】:

我正在开发一个应用程序来处理打到我邮箱的电子邮件。我已修改我的邮件设置,将收到的邮件转发到 myapp。到达 myapp 的邮件将被路由到处理程序脚本(“handle_incoming_email.py”),在那里进行处理。我的 app.yaml 文件如下所示

app.yaml

application: myapp
version: 1-1
runtime: python27
api_version: 1
threadsafe: false
default_expiration: "360d"

handlers:
- url: /_ah/mail/.+
  script: myapp/utils/handle_incoming_email.py

邮件处理脚本如下

handle_incoming_email.py

import logging
import urllib
import base64
import traceback
from google.appengine.ext import webapp
from google.appengine.ext import blobstore
from google.appengine.api import urlfetch
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler


class ReceiveEmail(InboundMailHandler):

    def receive(self, message):
        try:
            for filename, filecontents in message.attachments:
                if filecontents.encoding:
                    # data = filecontents
                    data = filecontents.decode()
                    # data = filecontents.payload
                    # data = filecontents.payload.decode()
                    # data = base64.b64decode(filecontents.decode())
                    # data = base64.b64decode(filecontents.payload)
                    # data = base64.b64decode(filecontents.payload.decode())

                upload_url = blobstore.create_upload_url('http://myapp.appspot.com/settings/saveItem/')
                form_fields = {'field_name': data}
                form_data = urllib.urlencode(form_fields)
                result = urlfetch.fetch(url=upload_url,
                                        payload=form_data,
                                        method=urlfetch.POST,
                                        headers={'Content-Type': 'application/x-www-form-urlencoded'})
                logging.info(result)
        except Exception, e:
            traceback.print_exc()

application = webapp.WSGIApplication([ReceiveEmail.mapping()], debug=True)


def main():
    run_wsgi_app(application)
if __name__ == "__main__":
    main()

我的要求是为每个带有附件的邮件创建一个实体。为此,我需要解析邮件中的附件并将其上传到 blobstore。但是,当我尝试将附件上传到 blobstore 时,出现以下错误:

此 URL 不接受请求的内容类型。

正如您在“handle_incoming_email.py”中的注释代码中看到的那样,我尝试了不同的方法(试错法)来获取正确的数据,但无济于事。

谁能指导我解决这个问题!

谢谢!!!

【问题讨论】:

  • 上传?为什么不将其写入 blobstore。
  • @voscausa :根据documentation,不推荐将文件写入 blobstore。此外,我可能需要将文件附件作为 multipart/form-data 从我的代码发布到第 3 方 API。

标签: google-app-engine python-2.7 blobstore urlfetch


【解决方案1】:

我认为此代码示例将解决您的问题。您可能只需要使用此代码中的 encode_multipart_formdata 函数。并且不要忘记正确设置内容类型。

class BlobstoreUpload(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')
    blob_info = upload_files[0]
    return self.response.write(blob_info.key())

  @classmethod
  def encode_multipart_formdata(cls, fields, files, mimetype='image/png'):
    """
    Args:
      fields: A sequence of (name, value) elements for regular form fields.
      files: A sequence of (name, filename, value) elements for data to be
        uploaded as files.

    Returns:
      A sequence of (content_type, body) ready for urlfetch.
    """
    boundary = 'paLp12Buasdasd40tcxAp97curasdaSt40bqweastfarcUNIQUE_STRING'
    crlf = '\r\n'
    line = []
    for (key, value) in fields:
      line.append('--' + boundary)
      line.append('Content-Disposition: form-data; name="%s"' % key)
      line.append('')
      line.append(value)
    for (key, filename, value) in files:
      line.append('--' + boundary)
      line.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
      line.append('Content-Type: %s' % mimetype)
      line.append('')
      line.append(value)
    line.append('--%s--' % boundary)
    line.append('')
    body = crlf.join(line)
    content_type = 'multipart/form-data; boundary=%s' % boundary
    return content_type, body


class UserProfile(webapp2.RequestHandler):
  def post(self):
    picture = self.request.POST.get('picture')

    # Write new picture to blob
    content_type, body = BlobstoreUpload.encode_multipart_formdata(
      [], [('file', name, image)])
    response = urlfetch.fetch(
      url=blobstore.create_upload_url(self.uri_for('blobstore-upload')),
      payload=body,
      method=urlfetch.POST,
      headers={'Content-Type': content_type},
      deadline=30
    )
    blob_key = response.content

【讨论】:

  • @Dmitry 它也对我有用。感谢 Jithu 提出问题并感谢 Dmitry 的答复。
  • @Dmitry 你能告诉我们是否要从本地目录上传文件,那么参数'files'应该是什么?
  • @omair_77 本地目录?你的意思是?序列如下所示:(input_name, filename, file_content_as_string)
  • @Dmitry 我正在尝试使用您提供的代码将文件从我的 PC 上传到 blobstore,文件上传正常,但我没有收到 response.content 中的 blob.key
猜你喜欢
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 2015-02-07
  • 1970-01-01
  • 2012-10-05
相关资源
最近更新 更多