title: HttpError 400 when trying to upload pdf file on Google Cloud Storage
body: <p>I am setting up a service that:</p>
  
  <ol>
  <li>receives an email with an attachment file   </li>
  <li>uploads this file to cloud storage </li>
  <li>uses that file as a source for further processing</li>
  </ol>
  
  <p>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.</p>
  
  <p><strong>handle_incoming_email.py</strong></p>
  
  <pre><code>__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)
  </code></pre>
  
  <p>After I send an email to the service I see the following error in the logs:</p>
  
  <blockquote>
    <p>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/"></p>
  </blockquote>
  
  <p>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'.</p>
  
  <p>-- Update with solution --   </p>
  
  <pre><code>    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`
  </code></pre>