I'm trying to upload files > 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
header i sended: "{'Content-Length': '416768', 'Content-Type': 'application/tar', 'Content-Range': 'bytes 262144-416768/416768'}"
content:"Failed to parse Content-Range header."
And yes this file is only 407kb big to have faster test execution (20mb file also fails).
This is my code made from this SO Question 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.
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 = {"uploadType": "resumable"}
THUMBNAIL_IMAGE = str(open("drive_image.base64","r").read())
THUMBNAIL_MIME_TYPE = "image/png"
f = open("drive_logo.png","rb")
urlsafe_thumbnail = base64.urlsafe_b64encode(f.read()).decode('utf8')
drive_content_hints = '"contentHints": {"thumbnail": { "image": "'+urlsafe_thumbnail+'", "mimeType": "image/png" } } '
drive_parents_folder = '"parents": ["'+ folder_id +'"]'
drive_description = '"description": "This is a backup file"'
drive_file_name = '"name": "'+file_name+'"'
currentdate = datetime.strftime(datetime.today(),"%Y-%m-%dT%H:%M:%SZ")
drive_creation_time = '"createdTime": "'+currentdate+'"'
drive_modificition_time = '"createdTime": "'+currentdate+'"'
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("error")
print(response.content)
return
The problem is with the rest of the code.
file_size = os.path.getsize(file_name)
in_file = open(file_name, "rb") # 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 > TOTAL_BYTES:
last_byte = TOTAL_BYTES -1
print("hi")
data2 = chunk[first_byte:last_byte+1]
bytes = "bytes 0-" + str(CHUNK_SIZE-1) + "/" + str(file_size)
headers = {
'Content-Length': str(TOTAL_BYTES),
'Content-Type': "application/tar",
'Content-Range': "bytes " + str(first_byte) +"-"+str(last_byte)+"/"+str(TOTAL_BYTES)
}
print(headers)
response = requests.request(
"PUT", sessionUri, data=data2, headers=headers)
print(response.content)
byte_range = response.headers["Range"]
first_byte = byte_range.split("=",1)[1].split("-",1)[0]
last_byte = byte_range.split("=",1)[1].split("-",1)[1]
print(last_byte)
first_byte = int(last_byte)+1
last_byte = int(first_byte)+CHUNK_SIZE
print(str(first_byte)+"-"+str(last_byte))
I appreciate your help.