Introduction
An API built in Flask which uploads files to DropBox
.
Background
- The user selects the files from the form.
- The files are sent in the request body to the Flask server.
- The API uploads the files to
DropBox
.
Note
- The API can upload into one shot and multi-part as well.
- The API can be tested with the Postman client as well.
Technologies Used
- Flask: Version 1.0.2
- Jinja: Version 2.10
- DropBox API: Version 9.3.0
- Python: Version 3.6.5
Prerequisites
- Make a
DropBox
developers' account to get the access token for the DropBox
API. - Paste the access token in the config.py file
Setting Up
Code Overview
In the initialization block, I'm importing all the required modules and packages, creating a DropBox
object, which requires an access token as the argument, and defining the chunk sizes.
After that, we create a Flask
instance ( __name__
is the name of the current Python module. The app needs to know where it's located to set up some paths).
I created a simple form to test my API and set its route to the homepage.
The source code is as follows:
from flask import Flask, request, render_template
import dropbox
import config
import os
dbx = dropbox.Dropbox(config.exports['token'])
chunk_size = config.exports['chunkSize'] * 1024 * 1024
max_chunk = config.exports['maxChunk'] * 1024 * 1024
app = Flask(__name__)
@app.route('/')
def index():
return render_template('upload.html')
When the POST
request is made, flask checks the files in the request.
It reads the file from start to finish in the file.seek()
. Then it calculates the file size and stores it in the fileSize
variable.
After that, it sets the file pointer back to the start so that the file can be read again.
The logic compares the file size with the max_chunk
and one shot uploads if it's <= max_chunk
.
If the file size exceeds the max_chunk
, then an upload session is created which basically reads chunks of 1 MB and sends the chunks to DropBox
. Finally, it checks the file to see if it has reached the final chunk and finishes the session, otherwise it keeps on sending chunks to DropBox
until the file comes to an end (Multi-part upload).
Note
DropBox
can one shot upload if the file size is <= 150 MB. - Otherwise, it multi-part uploads.
- The
max_chunk
and chunk_size
variables can be altered in the config.py file.
The source code is as follows:
@app.route('/upload', methods=['POST'])
def uploader():
files = request.files.getlist('file')
for file in files:
try:
filename = file.filename
destination_path = os.path.join(config.exports['targetFolder'], filename)
file.seek(0, 2)
fileSize = file.tell()
file.seek(0)
if fileSize <= max_chunk:
dbx.files_upload(file.read(), destination_path)
else:
upload_session_start_result = dbx.files_upload_session_start(file.read(chunk_size))
cursor = dropbox.files.UploadSessionCursor
(session_id=upload_session_start_result.session_id,
offset=file.tell())
commit = dropbox.files.CommitInfo(path=destination_path)
while file.tell() < fileSize:
if (fileSize - file.tell()) <= chunk_size:
print(dbx.files_upload_session_finish(file.read(chunk_size), cursor, commit))
else:
dbx.files_upload_session_append_v2(file.read(chunk_size), cursor)
cursor.offset = file.tell()
except Exception as err:
print("Failed to upload {}\n{}".format(file, err))
finally:
file.close()
print("Finished upload.")
return render_template('complete.html')
Note
You can check out my other projects on the github link below: