尝试在Google云端存储上上传pdf文件时出现HttpError 400

时间:2016-04-28 13:02:43

标签: python google-app-engine flask google-cloud-storage google-cloud-platform

我正在设置一项服务:

  1. 收到附件附件的电子邮件
  2. 将此文件上传到云端存储
  3. 将该文件用作进一步处理的来源
  4. 我到达了发生错误的第2步。我正在使用Google服务的发现API进行身份验证。我的是一个简单的烧瓶应用程序,下面是传入的电子邮件处理程序。

    handle_incoming_email.py

    __author__ = 'ciacicode'
    
    import logging
    import webapp2
    from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
    from oauth2client.client import GoogleCredentials
    from googleapiclient.discovery import build
    
    credentials = GoogleCredentials.get_application_default()
    
    
    class LogSenderHandler(InboundMailHandler):
        def receive(self, mail_message):
            logging.info("Received a message from: " + mail_message.sender)
            # upload attachment to cloud storage
            filename = 'any'
            try:
                attachment = mail_message.attachments
                filename = attachment[0].filename
                body = str(attachment[0].payload)
            except IndexError:
                print len(attachment)
    
            storage = build('storage', 'v1', credentials=credentials)
            req = storage.objects().insert(bucket='ocadopdf', body={'body': body, 'contentType': 'application/pdf', 'name': str(filename), 'contentEncoding': 'base64'})
            resp = req.execute()
            return resp
    
    
    app = webapp2.WSGIApplication([LogSenderHandler.mapping()], debug=True)
    

    我向服务发送电子邮件后,我在日志中看到以下错误:

      

    HttpError:https://www.googleapis.com/storage/v1/b/ocadopdf/o ?alt = json返回   “上传请求必须包含uploadType网址参数和网址   以/ upload /“>

    开头的路径

    我知道这些信息没有发布到正确的端点,而且缺少一个URL参数,但是我在Google文档中挖掘的越多,我就越不清楚如何使用.build从发现模块到在服务“存储”之前添加URL路径。

    - 使用解决方案更新 -

        file = cStringIO.StringIO()
        file.write(body)
        media = http.MediaIoBaseUpload(file, mimetype='application/pdf')
        storage = build('storage', 'v1', credentials=credentials)
        req = storage.objects().insert(bucket='ocadopdf', body={'name': str(filename), 'contentEncoding': 'base64'}, media_body=media)
        resp = req.execute()
        return resp`
    

1 个答案:

答案 0 :(得分:2)

您的构建调用对我来说是正确的。这个example为如何将文件作为新对象上传到GCS提供了很好的参考。您可以传递包含对象内容的io.BytesIO,而不是将文件句柄传递给MediaIoBaseUpload,如MediaIoBaseUpload文档中所述