Python Dropbox API - mikedorais/python_learning GitHub Wiki
Dropbox Python API
Notes on what I've learned about the Python Dropbox API
Note that if you create a temporary access code to use during development of the app, it is supposed to be kept secret. If you think you may have accidentally leaked it out or just want to be safe. You can revoke the token as follows:
dbx = dropbox.Dropbox('access token')
dbx. auth_token_revoke()
May want to look at this example application: Backup and Restore
Installing and importing the api
pip3 install dropbox
import dropbox
Uploading a file:
# open a dropbox with an access token
dbx = dropbox.Dropbox('YOUR_ACCESS_TOKEN')
# Get account information
dbx.users_get_current_account()
# List file items in folder
for entry in dbx.files_list_folder('').entries:
print(entry.name)
# Upload a small file (150 MB or less)
text = 'Hello, World!' # For example just set a string and encode it as bytes
dbx.files_upload(text.encode('utf-8'), '/hello/hello_world.txt')
Uploading a large file
To upload a file larger than 150 MB. Instead, create an upload session with :meth:files_upload_session_start
.
See: https://www.dropboxforum.com/t5/API-support/python-upload-big-file-example/m-p/166627#M6013
# TODO: Use with, exception handling, del
# To ensure cleanup of resources?
dbx = dropbox.Dropbox('YOUR_ACCESS_TOKEN')
# TODO: Check for success
MEGABYTE = 1000000 # 1000 * 1000 Alternate would be 1024 * 1024
CHUNK_SIZE = 150 * MEGABYTE
# Source file path
file_path = '/home/michael/Pictures/2017/03/28/20170328_195058.jpg'
# Destinatoin TODO: Need to figure out mode and autorename parameter
commit_info = dropbox.files.CommitInfo(path="/Uploaded_from_SDK/20170328_195058.jpg")
with open(file_path, mode='rb') as file_to_upload:
session_start_result = dbx.files_upload_session_start(b"",)
# TODO: Check for successful result
session_cursor = dropbox.files.UploadSessionCursor(session_id=session_start_result.session_id, offset=file_to_upload.tell())
# TODO: Check for successful cursor creation
while True:
file_chunk = file_to_upload.read(CHUNK_SIZE)
if len(file_chunk) == 0:
break
print("{} bytes read from file.".format(len(file_chunk)))
dbx.files_upload_session_append_v2(file_chunk, session_cursor)
session_cursor.offset = file_to_upload.tell()
print("{} bytes uploaded.".format(session_cursor.offset))
dbx.files_upload_session_finish(b"", session_cursor, commit_info)
Smart Uploading of File of Any Size
import sys
import os
import datetime
import dropbox
# TODO: Use with, exception handling, del
# To ensure cleanup of resources?
KILOBYTE = 1024
MEGABYTE = KILOBYTE * KILOBYTE
CHUNK_SIZE = 150 * MEGABYTE
# Try shorter sizes to test logic of multiple chunks on smaller files.
# CHUNK_SIZE = MEGABYTE
# CHUNK_SIZE = int(MEGABYTE / 2)
def upload_next_chunk(dbx, file_to_upload, commit_info, session_cursor):
""" Upload the first, next and, last chunk of a file to Dropbox account
Args:
dbx (dropbox.Dropbox): Initialized Dropbox account
file_to_upload (stream): Opened stream to upload, or being uploaded
commit_info (dropbox.files.CommitInfo): Information for how file should be committed to account
sesssion_cursor (dropbox.files.UploadSessionCursor): Session cursor
at beginning of stream writing, intialized to UploadSessionCursor()
first call will populate it appropriately for subsequent calls.
Returns: True if there is more to read and upload, False otherwise
"""
file_chunk = file_to_upload.read(CHUNK_SIZE)
file_chunk_len = len(file_chunk)
if not hasattr(session_cursor, 'session_id'):
# First chunk read. Either upload if less then CHUNK_SIZE or start session
if file_chunk_len < CHUNK_SIZE:
dbx.files_upload(file_chunk, commit_info.path, client_modified=commit_info.client_modified)
else:
# TODO: Check for success
session_start_result = dbx.files_upload_session_start(file_chunk)
session_cursor.session_id = session_start_result.session_id
elif file_chunk_len < CHUNK_SIZE:
# TODO: Check for success
dbx.files_upload_session_finish(file_chunk, session_cursor, commit_info)
else:
# TODO: Check for success
dbx.files_upload_session_append_v2(file_chunk, session_cursor)
session_cursor.offset = file_to_upload.tell()
return file_chunk_len == CHUNK_SIZE
def upload_file(dbx, src_base_path, dest_base_path, file_relative_path):
src_file_path = os.path.join(src_base_path, file_relative_path)
dest_file_path = os.path.join(dest_base_path, file_relative_path)
if not os.path.exists(src_file_path):
# TODO: throw exception? log? return an indicator?
print("file '{}' does not exist!".format(src_file_path))
file_mtimestamp = os.path.getmtime(src_file_path)
# be sure and get time zone aware time in UTC time so that it saves with correct time
# it is being saved who-knows-where in the world.
file_client_modified = datetime.datetime.fromtimestamp(file_mtimestamp, datetime.timezone.utc)
# Destinatoin TODO: Need to figure out mode and autorename parameter
commit_info = dropbox.files.CommitInfo(path=dest_file_path, client_modified=file_client_modified)
session_cursor = dropbox.files.UploadSessionCursor()
with open(src_file_path, mode='rb') as file_to_upload:
while upload_next_chunk(dbx, file_to_upload, commit_info, session_cursor):
pass