Hi,
I'm a novice coder. Can someone take a look at the following method and tell me if I'm doing something wrong? Sometimes the files I upload to dropbox are corrupts. I'm working with large audiovisual files. This doesn't always happen. Only occasionally.
# Uploads file to dropbox
def upload_file_to_dropbox(self, file_path, dropbox_path, max_retries=5):
for attempt in range(max_retries):
try:
#Step 0: Check if ACCESS_TOKEN is still valid
if self.token_expired():
self.refresh_access_token()
# Step 1: Initiate an upload session
session_start_url = 'https://content.dropboxapi.com/2/files/upload_session/start'
headers = {
'Authorization': 'Bearer ' + self.ACCESS_TOKEN,
'Content-Type': 'application/octet-stream'
}
response = requests.post(session_start_url, headers=headers)
if response.status_code != 200:
print("Failed to initiate upload session:", response.text)
return
session_id = response.json()['session_id']
offset = 0
# Step 2: Upload the file in chunks
chunk_size = 4 * 1024 * 1024 # 4MB chunk size
with open(file_path, 'rb') as file:
while True:
if self.token_expired():
self.refresh_access_token()
chunk = file.read(chunk_size)
if not chunk:
break
upload_url = 'https://content.dropboxapi.com/2/files/upload_session/append_v2'
headers = {
'Authorization': 'Bearer ' + self.ACCESS_TOKEN,
'Content-Type': 'application/octet-stream',
'Dropbox-API-Arg': '{"cursor": {"session_id": "' + session_id + '", "offset": ' + str(offset) + '}}'
}
response = requests.post(upload_url, headers=headers, data=chunk)
if response.status_code == 429:
seconds = response.json()["error"]["retry_after"]
for i in range(seconds, 0, -1):
sys.stdout.write("\rToo many requests. Retrying chunk upload in {:2d} seconds.".format(i))
sys.stdout.flush()
time.sleep(1)
continue
# eventually edit this statement for exponential back off
# for some reason dropbox outputs this response as HTML, instead of JSON
elif 'Error: 503' in response.text:
seconds = 10
for i in range(seconds, 0, -1):
sys.stdout.write("\rDropbox service availability issue. Retrying chunk upload in {:2d} seconds.".format(i))
sys.stdout.flush()
time.sleep(1)
continue
elif response.status_code != 200:
print("Failed to upload chunk:", response.text)
return
offset += len(chunk)
self.bytes_read += len(chunk)
progress = min(self.bytes_read / self.total_size, 1.0) * 100
sys.stdout.write(f"\rUpload progress: {progress:.2f}% ({self.bytes_read}/{self.total_size} bytes)")
sys.stdout.flush()
# Step 3: Complete the upload session
session_finish_url = 'https://content.dropboxapi.com/2/files/upload_session/finish'
headers = {
'Authorization': 'Bearer ' + self.ACCESS_TOKEN,
'Content-Type': 'application/octet-stream',
'Dropbox-API-Arg': '{"cursor": {"session_id": "' + session_id + '", "offset": ' + str(offset) + '}, "commit": {"path": "' + dropbox_path + '", "mode": "add", "autorename": true, "mute": false}}'
}
response = requests.post(session_finish_url, headers=headers, timeout=30)
if response.status_code != 200:
print("Failed to complete upload session:", response.text)
return
return # Exit the function after successful upload
except ConnectionError as e:
if attempt < max_retries - 1:
print(f"ConnectionError: Retry attempt {attempt + 1}")
else:
raise e