Dropbox is one of the most widely used file storage and file sharing platforms and is used by a wide variety of businesses. Dropbox has put the effort into building a powerful API that allows you to utilise Dropbox in your own applications, and it’s ideal for Python automations.
Using the Dropbox Python SDK, you can upload, download, share, and delete files from your Python script. It’s fairly simple to use and there’s loads of documentation available and a vibrant developer community.
In this project, I’ll cover the main things you might need to do from within a Python automation, including connecting to Dropbox, listing files, downloading files, uploading files, and sharing files.
First, open a terminal and install the Python SDK via the PyPi package manager by entering pip3 install dropbox
. This will download the latest version and the required dependencies.
pip3 install dropbox
Next, import the packages below. As well as the dropbox
package itself, we’re importing AuthError
from exceptions
so we can throw more descriptive exception messages. We’ll also be using the pathlib
library and the Pandas package for manipulating data.
import pathlib
import pandas as pd
import dropbox
from dropbox.exceptions import AuthError
In order to use the Dropbox API you will first need to go to the Dropbox developers site and create an application. You’ll need to create a permanent access token that you can use to authenticate your application against your Dropbox account.
DROPBOX_ACCESS_TOKEN = 'xxxxxxxxxxxxx'
Rather than just running the API commands, we’ll also create some reusable functions to serve as a simple wrapper around the regular Dropbox API. The first function we’re creating is called dropbox_connect()
and will connect
to the Dropbox API using the DROPBOX_ACCESS_TOKEN
we’ve set up. We’ll wrap this in a try except block to catch any exceptions thrown.
def dropbox_connect():
"""Create a connection to Dropbox."""
try:
dbx = dropbox.Dropbox(DROPBOX_ACCESS_TOKEN)
except AuthError as e:
print('Error connecting to Dropbox with access token: ' + str(e))
return dbx
Next, we’ll create a function to get a list of files in a Dropbox folder. This function will take a dbx
connection and a folder
path as arguments. The folder
path is the path to the folder you want to list the files in relative to the App folder of your Dropbox account.
To make the file list a bit easier to handle from within your Python automation, I’ve used Pandas to turn the list of files into a DataFrame. The files will be sorted in descending order by the server_modified
timestamp, so the most recent ones appear at the top.
def dropbox_list_files(path):
"""Return a Pandas dataframe of files in a given Dropbox folder path in the Apps directory.
"""
dbx = dropbox_connect()
try:
files = dbx.files_list_folder(path).entries
files_list = []
for file in files:
if isinstance(file, dropbox.files.FileMetadata):
metadata = {
'name': file.name,
'path_display': file.path_display,
'client_modified': file.client_modified,
'server_modified': file.server_modified
}
files_list.append(metadata)
df = pd.DataFrame.from_records(files_list)
return df.sort_values(by='server_modified', ascending=False)
except Exception as e:
print('Error getting list of files from Dropbox: ' + str(e))
Downloading a file from Dropbox using Python is slightly more complex. We’ll connect to Dropbox using dropbox_connect()
, then we’ll use with open()
to open a local filepath and write the file to it when it’s downloaded using the dbx.files_download()
function.
def dropbox_download_file(dropbox_file_path, local_file_path):
"""Download a file from Dropbox to the local machine."""
try:
dbx = dropbox_connect()
with open(local_file_path, 'wb') as f:
metadata, result = dbx.files_download(path=dropbox_file_path)
f.write(result.content)
except Exception as e:
print('Error downloading file from Dropbox: ' + str(e))
To upload a file to Dropbox using Python we ‘ll use the dbx.files_upload()
function. We’ll use pathlib.Path()
to create the right path to our local file we want to upload and will store it in local_file_path
.
We’ll use with open()
again to open the file for reading, then we’ll use dbx.files_upload()
to upload the file to the Dropbox folder. If the file exists, it will be overwritten.
def dropbox_upload_file(local_path, local_file, dropbox_file_path):
"""Upload a file from the local machine to a path in the Dropbox app directory.
Args:
local_path (str): The path to the local file.
local_file (str): The name of the local file.
dropbox_file_path (str): The path to the file in the Dropbox app directory.
Example:
dropbox_upload_file('.', 'test.csv', '/stuff/test.csv')
Returns:
meta: The Dropbox file metadata.
"""
try:
dbx = dropbox_connect()
local_file_path = pathlib.Path(local_path) / local_file
with local_file_path.open("rb") as f:
meta = dbx.files_upload(f.read(), dropbox_file_path, mode=dropbox.files.WriteMode("overwrite"))
return meta
except Exception as e:
print('Error uploading file to Dropbox: ' + str(e))
Finally, we’ll create a shareable link to a file already in Dropbox. This is a great way to share a large file with colleagues using a URL, rather than having to download the file and upload it to their machine.
Changing the URL parameter from ?dl=0
to ?dl=1
will return a shareable link to the file that allows downloading.
def dropbox_get_link(dropbox_file_path):
"""Get a shared link for a Dropbox file path.
Args:
dropbox_file_path (str): The path to the file in the Dropbox app directory.
Returns:
link: The shared link.
"""
try:
dbx = dropbox_connect()
shared_link_metadata = dbx.sharing_create_shared_link_with_settings(dropbox_file_path)
shared_link = shared_link_metadata.url
return shared_link.replace('?dl=0', '?dl=1')
except dropbox.exceptions.ApiError as exception:
if exception.error.is_shared_link_already_exists():
shared_link_metadata = dbx.sharing_get_shared_links(dropbox_file_path)
shared_link = shared_link_metadata.links[0].url
return shared_link.replace('?dl=0', '?dl=1')
Matt Clarke, Saturday, December 18, 2021