HttpError 400尝试在Google云端存储上传PDF文件 [英] HttpError 400 when trying to upload pdf file on Google Cloud Storage
问题描述
- 收到附有附件的电子邮件
- 将此文件上传到云存储
- 使用该文件作为进一步处理的来源
- receives an email with an attachment file
- uploads this file to cloud storage
- uses that file as a source for further processing
我到达错误发生的第2步。我正在使用Google服务的发现API进行身份验证。 Mine是一个简单的应用程序,下面是传入的电子邮件处理程序。
$ b
handle_incoming_email.py
__ author__ ='ciacicode'
导入日志记录
从google.appengine.ext.webapp.mail_handlers导入webapp2
import InboundMailHandler从oauth2client.client获取
从googleapiclient.discovery导入GoogleCredentials
导入构建
$ b凭证= GoogleCredentials.get_application_default()
类LogSenderHandler InboundMailHandler):
def receive(self,mail_message):
logging.info(收到邮件:+ mail_message.sender)
#将附件上传到云存储
filename ='any'
try:
attachment = mail_message.attachments
filename = attachment [0] .filename
body = str(attachment [0] .payload)
除了IndexError:
print len(attachment)
storage = build('storage','v1',credentials = credentials)
req = storage.objects()。 body,'contentType':'application / pdf','name':str(filename),'contentEncoding':'base64'})
resp = req.execute()
return resp
app = webapp2.WSGIApplication([LogSenderHandler.mapping()],debug = True)
在发送电子邮件到服务后,我在日志中看到以下错误:
$ b
HttpError:https:/ /www.googleapis.com/storage/v1/b/ocadopdf/o?alt=json返回
上传请求必须包含一个uploadType网址参数和一个以$ upload />开头的URL
路径 / b>
据我所知,这些信息并没有发布到正确的端点,而且缺少一个URL参数,但是我在Google文档越少,我可以找到明确的东西如何使用发现模块中的.build在服务存储之前添加URL路径。
- 用解决方案更新 -
file = cStringIO.StringIO()
pre>
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`
解决方案您的构建调用对我来说是正确的。此示例提供了有关如何将文件作为新对象上传到GCS。您可以按照 MediaIoBaseUpload 文档
I am setting up a service that:
I arrived at step 2 where the error is occurring. I am using the discovery API for Google services to authenticate. Mine is a simple flask application and below is the incoming email handler.
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)
After I send an email to the service I see the following error in the logs:
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/">
I understand that the information is not POSTed to the right endpoint and that is missing a URL parameter, but the more I dig in the Google documentation the less I can find something clear on how to use .build from the discovery module to add the URL path before the service 'storage'.
-- Update with solution --
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`
解决方案Your build invocation looks correct to me. This example provides a good reference on how to upload a file to GCS as a new object. Instead of passing a file handle to MediaIoBaseUpload, you can pass a io.BytesIO containing the object contents as described in the MediaIoBaseUpload documentation
这篇关于HttpError 400尝试在Google云端存储上传PDF文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!