1

我设立一个服务:HttpError 400试图上传PDF文件在谷歌云存储时

  1. 会收到一封电子邮件的附件文件
  2. 上传该文件到云存储
  3. 使用了文件作为进一步处理的来源

我到达了发生错误的第2步。我正在使用Google服务的发现API进行身份验证。 Mine是一个简单的应用程序,下面是传入的电子邮件处理程序。

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 returned "Upload requests must include an uploadType URL parameter and a URL path beginning with /upload/">

我明白,信息不发布到而且缺少一个URL参数,但我在Google文档中挖掘的越多,我就越能找到清楚如何使用发现模块中的.build以在服务存储之前添加URL路径的内容E”。

- 更新与解决方案 -

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` 

回答

2

你构建调用看起来正确的给我。这个example为如何将文件作为新对象上传到GCS提供了很好的参考。您可以传递包含文档MediaIoBaseUpload文档

+0

中所述的对象内容的io.BytesIO,而不是将文件句柄传递给MediaIoBaseUpload。不幸的是,该示例仅显示如何使用本地计算机上的文件。电子邮件附件是一个谷歌对象,而不是一个普通的python文件对象。到目前为止,问题还没有出现在主体的内容上,而是由端点自己调用。 – ciacicode

+0

正确的 - 第二个链接显示MediaIoUpload与io.BytesIO和任意字节的使用,但也很容易被StringIO的等 –

+0

谢谢你@Angus戴维斯我得到了它与我上面贴的变化工作,即使我上传后无法成功打开pdf。我认为,尽管这与编码有关,所以这个问题本身得到了回答。当这样的错误400出现时,它指向缺少用适当的文件流对象填充的media_body参数。 – ciacicode

相关问题