drf-chunked-upload
This simple django app enables users to upload large files to Django Rest
Framework in multiple chunks, with the ability to resume if the upload is
interrupted.
This app is based to a large degree on the work of Julio Malegria,
specifically his django-chunked-upload app.
License: MIT-Zero.
Installation
Install via pip:
pip install drf-chunked-upload
And then add it to your Django INSTALLED_APPS
:
INSTALLED_APPS = (
# ...
'drf_chunked_upload',
)
Typical usage
-
An initial PUT request is sent to the url linked to ChunkedUploadView
(or
any subclass) with the first chunk of the file. The name of the chunk file
can be overriden in the view (class attribute field_name
). Example:
r = requests.put(
upload_url,
headers={
"Content-Range": "bytes {}-{}/{}".format(index, index + size - 1, total),
},
data={"filename": build_file},
files={'file': chunk_data},
)
-
In return, the server will respond with the url
of the upload, and the
current offset
. Example:
{
'id': 'f64ebd67-83a3-45b6-8acd-c749ea1ed4cd'
'url': 'https://your-host/<path_to_view>/f64ebd67-83a3-45b6-8acd-c749ea1ed4cd',
'file': 'https://your-host/<path_to_file>/f64ebd67-83a3-45b6-8acd-c749ea1ed4cd.part',
'filename': 'example.bin',
'offset': 10000,
`created_at`: '2021-05-18T17:12:50.318718Z',
'status': 1,
'completed_at': None,
'user': 1
}
-
Repeatedly PUT subsequent chunks to the url
returned from the server.
Example:
upload_url = "https://your-host/<path_to_view>/f64ebd67-83a3-45b6-8acd-c749ea1ed4cd"
r = requests.put(
upload_url,
headers={
"Content-Range": "bytes {}-{}/{}".format(index, index + size - 1, total),
},
data={"filename": build_file},
files={'file': chunk_data},
)
-
Server will continue responding with the url
and current offset
.
-
Finally, when upload is completed, POST a request to the returned url
.
This request must include the checksum (hex) of the entire file. Example:
upload_url = "https://your-host/<path_to_view>/f64ebd67-83a3-45b6-8acd-c749ea1ed4cd"
r = requests.post(upload_url, data={"md5": "fc3ff98e8c6a0d3087d515c0473f8677"})
-
If everything is OK, server will response with status code 200 and the data
returned in the method get_response_data
(if any).
If you want to upload a file as a single chunk, this is also possible! Simply
make the first request a POST and include the checksum digest for the file. You
don't need to include the Content-Range
header if uploading a whole file.
If you want to see the list of pending chunked uploads, make a GET
request to
the URL linked to ChunkedUploadView
(or any subclass). You will get a list of
pending chunked uploads (for the currently authenticated user only).
Possible error responses:
- Upload has expired. Server responds 410 (Gone).
id
does not match any upload. Server responds 404 (Not found).- No chunk file is found in the indicated key. Server responds 400 (Bad
request).
- Request does not contain
Content-Range
header. Server responds 400 (Bad
request). - Size of file exceeds limit (if specified). Server responds 400 (Bad request).
- Offsets do not match. Server responds 400 (Bad request).
- Checksums do not match. Server responds 400 (Bad request).
Settings
Add any of these variables into your project settings to override them.
DRF_CHUNKED_UPLOAD_EXPIRATION_DELTA
- How long after creation the upload will expire.
- Default:
datetime.timedelta(days=1)
DRF_CHUNKED_UPLOAD_PATH
- Path where uploaded files will be stored.
- Default:
'chunked_uploads/%Y/%m/%d'
DRF_CHUNKED_UPLOAD_CHECKSUM
- The type of checksum to use when verifying checksums. Options include
anything supported by Python's hashlib (md5, sha1, sha256, etc)
- Default:
'md5'
DRF_CHUNKED_UPLOAD_COMPLETE_EXT
- Extension to use for completed uploads. Uploads will be renamed using this
extension on completion, unless this extension matched
DRF_CHUNKED_UPLOAD_INCOMPLETE_EXT
. - Default:
'.done'
DRF_CHUNKED_UPLOAD_INCOMPLETE_EXT
- Extension for in progress upload files.
- Default:
'.part'
DRF_CHUNKED_UPLOAD_STORAGE_CLASS
- Storage system (should be a class)
- Default:
None
(use default storage system)
DRF_CHUNKED_UPLOAD_USER_RESTRICED
- Boolean that determines whether only the user who created an upload can
view/continue an upload.
- Default:
True
DRF_CHUNKED_UPLOAD_ABSTRACT_MODEL
DRF_CHUNKED_UPLOAD_MAX_BYTES
- Max amount of data (in bytes) that can be uploaded.
None
means no limit. - Default:
None
Support
If you find any bug or you want to propose a new feature, please use the
issues tracker. Pull requests are accepted.