title: Google drive chunked uploads in python using rest api
body: <p>I'm trying to upload files &gt; 5mb to google drive with python over the rest api, so i'm using the chunked upload method.
  When the file is small enough to fit in one request everything is fine, but when i have a larger file it fails at the last request with</p>
  <pre><code>header i sended: &quot;{'Content-Length': '416768', 'Content-Type': 'application/tar', 'Content-Range': 'bytes 262144-416768/416768'}&quot;
  content:&quot;Failed to parse Content-Range header.&quot;
  </code></pre>
  <p>And yes this file is only 407kb big to have faster test execution (20mb file also fails).</p>
  <p>This is my code made from this <a href="https://stackoverflow.com/questions/39887303/resumable-upload-in-drive-rest-api-v3">SO Question</a> for the sessionUri, file_name=backup.tar.
  The imported google_api is my script witch returns folder_id and access_token.
  It finishes successfully and return's the sessioUri.</p>
  <pre><code>file_size = str(os.path.getsize(file_name))
  import google_api, base64
  from datetime import datetime
  access_token = google_api.access_token()
  folder_id = google_api.folder_id()
  headers = {
      'Authorization': 'Bearer ' + access_token,
      'Content-Type': 'application/json; charset=UTF-8',
      'X-Upload-Content-Type': 'application/tar',
      'X-Upload-Content-Length': file_size,
      'X-Upload-Content-Range': 'bytes 0-{}/{}'.format(file_size, file_size)
  }
  querystring = {&quot;uploadType&quot;: &quot;resumable&quot;}
  THUMBNAIL_IMAGE = str(open(&quot;drive_image.base64&quot;,&quot;r&quot;).read())
  THUMBNAIL_MIME_TYPE = &quot;image/png&quot;
  f = open(&quot;drive_logo.png&quot;,&quot;rb&quot;)
  urlsafe_thumbnail = base64.urlsafe_b64encode(f.read()).decode('utf8')
  drive_content_hints = '&quot;contentHints&quot;: {&quot;thumbnail&quot;: { &quot;image&quot;: &quot;'+urlsafe_thumbnail+'&quot;, &quot;mimeType&quot;: &quot;image/png&quot; } } '
  drive_parents_folder = '&quot;parents&quot;: [&quot;'+ folder_id +'&quot;]'
  drive_description = '&quot;description&quot;: &quot;This is a backup file&quot;'
  drive_file_name = '&quot;name&quot;: &quot;'+file_name+'&quot;'
  currentdate = datetime.strftime(datetime.today(),&quot;%Y-%m-%dT%H:%M:%SZ&quot;)
  drive_creation_time = '&quot;createdTime&quot;: &quot;'+currentdate+'&quot;'
  drive_modificition_time = '&quot;createdTime&quot;: &quot;'+currentdate+'&quot;'
  payload = '{'+drive_file_name+','+drive_description+','+drive_content_hints+','+drive_creation_time+','+drive_modificition_time+','+drive_parents_folder+'}'
     
  response = requests.post(
      'https://www.googleapis.com/upload/drive/v3/files',
      headers=headers,
      data=payload,
      params=querystring
  )
  if response.status_code == 200:
      sessionUri = response.headers['Location']
  else:
      print(&quot;error&quot;)
      print(response.content)
      return
  </code></pre>
  <p>The problem is with the rest of the code.</p>
  <pre><code>file_size = os.path.getsize(file_name)
  in_file = open(file_name, &quot;rb&quot;)  # opening for [r]eading as [b]inary
  chunk = in_file.read()
  print(file_size)
  BASE_CHUNK_SIZE = 256 * 1024 # 262144
  CHUNK_SIZE = 1 * BASE_CHUNK_SIZE
  TOTAL_BYTES = file_size
  first_byte = 0
  last_byte = CHUNK_SIZE - 1
  import math
  times = int(math.ceil(file_size/CHUNK_SIZE))
  print(times)
  for _ in range(times):
      if last_byte &gt; TOTAL_BYTES:
          last_byte = TOTAL_BYTES -1
          print(&quot;hi&quot;)
      
      data2 = chunk[first_byte:last_byte+1]
  
      bytes = &quot;bytes 0-&quot; + str(CHUNK_SIZE-1) + &quot;/&quot; + str(file_size)
      headers = {
          'Content-Length': str(TOTAL_BYTES),
          'Content-Type': &quot;application/tar&quot;,
          'Content-Range': &quot;bytes &quot; + str(first_byte) +&quot;-&quot;+str(last_byte)+&quot;/&quot;+str(TOTAL_BYTES)
      }
      print(headers)
      response = requests.request(
          &quot;PUT&quot;, sessionUri, data=data2, headers=headers)
      print(response.content)
      byte_range = response.headers[&quot;Range&quot;]
      first_byte = byte_range.split(&quot;=&quot;,1)[1].split(&quot;-&quot;,1)[0]
      last_byte = byte_range.split(&quot;=&quot;,1)[1].split(&quot;-&quot;,1)[1]
      print(last_byte)
      first_byte = int(last_byte)+1
      last_byte = int(first_byte)+CHUNK_SIZE
      print(str(first_byte)+&quot;-&quot;+str(last_byte))
  </code></pre>
  <p>I appreciate your help.</p>