Upload file in Flask with Dropzone.js.
Project description
Flask-Dropzone
Upload files in Flask application with Dropzone.js.
Installation
$ pip install flask-dropzone
Quick Start
Step 1: Initialize the extension:
from flask_dropzone import Dropzone
dropzone = Dropzone(app)
This extension also supports the Flask application factory pattern by allowing you to create a Dropzone object and then separately initialize it for an app:
dropzone = Dropzone()
def create_app(config):
app = Flask(__name__)
...
dropzone.init_app(app)
...
return app
Step 2: In addition to manage and load resources by yourself (recommend), you can also use this methods to load resources:
<head>
{{ dropzone.load_css() }}
</head>
<body>
...
{{ dropzone.load_js() }}
</body>
You can assign the version of Dropzone.js through version
argument, the default value is 5.2.0
.
And, you can pass css_url
and js_url
separately to customize resources URL.
Step 3: Creating a Drop Zone with create()
and use config()
to make the configuration
come into effect:
{{ dropzone.create(action='the_url_which_handle_uploads') }}
...
{{ dropzone.config() }}
</body>
Also remember to edit the action
to the URL which handles the uploads.
Beautify Dropzone
Style it according to your preferences through style()
method:
{{ dropzone.load_css() }}
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
Configuration
The supported list of config options is shown below:
Name | Default Value | Info |
---|---|---|
DROPZONE_SERVE_LOCAL |
False |
default to retrieve dropzone.js from CDN |
DROPZONE_MAX_FILE_SIZE |
3 | max allowed file size. unit: MB |
DROPZONE_INPUT_NAME |
file |
the name attr in : <input type="file" name="file"> |
DROPZONE_ALLOWED_FILE_CUSTOM |
False |
see detail below |
DROPZONE_ALLOWED_FILE_TYPE |
'default' |
see detail below |
DROPZONE_MAX_FILES |
'null' | the max files user can upload once |
DROPZONE_DEFAULT_MESSAGE |
"Drop files here to upload" | message displayed on drop area |
DROPZONE_INVALID_FILE_TYPE |
"You can't upload files of this type." | error message |
DROPZONE_FILE_TOO_BIG |
"File is too big {{filesize}}. Max filesize: {{maxFilesize}}MiB." | error message |
DROPZONE_SERVER_ERROR |
"Server error: {{statusCode}}" | error message |
DROPZONE_BROWSER_UNSUPPORTED |
"Your browser does not support drag'n'drop file uploads." | error message |
DROPZONE_MAX_FILE_EXCEED |
"Your can't upload any more files." | error message |
DROPZONE_UPLOAD_MULTIPLE |
False |
whether to send multiple files in one request. |
DROPZONE_PARALLEL_UPLOADS |
2 | how many uploads will handled in per request when DROPZONE_UPLOAD_MULTIPLE set to True. |
DROPZONE_REDIRECT_VIEW |
None |
the view to redierct when upload was completed. |
DROPZONE_ENABLE_CSRF |
False |
enable CSRF protect, see detail below |
You can use these file type:
allowed_file_type = {
'default': 'image/*, audio/*, video/*, text/*, application/*',
'image': 'image/*',
'audio': 'audio/*',
'video': 'video/*',
'text': 'text/*',
'app': 'application/*'
}
If you want to set the allowed file type by yourself, you need to set
DROPZONE_ALLOWED_FILE_CUSTOM
to True
, then add mime type or file extensions to
DROPZONE_ALLOWED_FILE_TYPE
, such as:
app.config['DROPZONE_ALLOWED_FILE_TYPE'] = 'image/*, .pdf, .txt'
Consult the dropzone.js documentation for details on these options.
Save uploads with Flask
import os
from flask import Flask, request
from flask_dropzone import Dropzone
app = Flask(__name__)
dropzone = Dropzone(app)
@app.route('/uploads', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
f.save(os.path.join(the_path_to_save, f.filename))
return 'upload template'
See examples/basic
for more detail.
Parallel Uploads
If you set DROPZONE_UPLOAD_MULTIPLE
as True, then you need to save multiple uploads in
single request.
However, you can't get a list of file with request.files.getlist('file')
. When you
enable parallel upload, Dropzone.js will append a index number after each files, for example:
file[2]
, file[1]
, file[0]
. So, you have to save files like this:
for key, f in request.files.iteritems():
if key.startswith('file'):
f.save(os.path.join(the_path_to_save, f.filename))
Here is the full example:
...
app.config['DROPZONE_UPLOAD_MULTIPLE'] = True # enable parallel upload
app.config['DROPZONE_PARALLEL_UPLOADS'] = 3 # handle 3 file per request
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
for key, f in request.files.iteritems(): # use request.files.items() in Python3
if key.startswith('file'):
f.save(os.path.join(the_path_to_save, f.filename))
return 'upload template'
See examples/parallel-upload
for more detail.
CSRF Protect
The CSRF Protect feature was provided by Flask-WTF's CSRFProtect
extension, so you have to
install Flask-WTF first:
$ pip install flask-wtf
Then initialize the CSRFProtect:
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
# the secret key used to generate CSRF token
app.config['SECRET_KEY'] = 'dev key'
...
# enable CSRF protection
app.config['DROPZONE_ENABLE_CSRF'] = True
csrf = CSRFProtect(app)
Make sure to set the secret key and set DROPZONE_ENABLE_CSRF
to True. Now all the upload request
will be protected!
We prefer to handle the CSRF error manually, because the error response's body will be displayed as tooltip below the file thumbnail.
from flask_wtf.csrf import CSRFProtect, CSRFError
...
# handle CSRF error
@app.errorhandler(CSRFError)
def csrf_error(e):
return e.description, 400
Here I use the e.description
as error message, it's provided by CSRFProtect, one of The CSRF token is missing
and The CSRF token is invaild
.
Try the demo application in examples/csrf
and see
CSRFProtect's documentation for more details.
Server Side Validation
Although Dropzone.js can handle client side validation for uploads, but you still need to setup
server side validation for security conern. Just do what you normally do (extension check,
size check etc.), the only thing you should remember is to return plain text error message as
response body when something was wrong. Fox example, if we only want user to upload file with
.png
extension, we can do the validation like this:
@app.route('/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
if f.filename.split('.')[1] != 'png':
return 'PNG only!', 400 # return the error message, with a proper 4XX code
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
return render_template('index.html')
The error message will be displayed when you hover the thumbnail for upload file:
Todo
- Documentation
- i18n support
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file Flask-Dropzone-1.4.6.tar.gz
.
File metadata
- Download URL: Flask-Dropzone-1.4.6.tar.gz
- Upload date:
- Size: 22.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 44350abfec754ba0d8413596581ad4aaba6c2a0352034c25d2e97de08d0d2c36 |
|
MD5 | c99409b14b0c5fb2d159e2a24b2df73a |
|
BLAKE2b-256 | dee21db3227968db9b1d1da69582759896782aa4beba2011e9e37f00fb193afe |
File details
Details for the file Flask_Dropzone-1.4.6-py2.py3-none-any.whl
.
File metadata
- Download URL: Flask_Dropzone-1.4.6-py2.py3-none-any.whl
- Upload date:
- Size: 22.7 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | bc61d15ebc3db064e009d10bae78d8584f4bfce8bd57e05a6c48c2dff0c2d944 |
|
MD5 | d835279ed2157f123f3c576648be424e |
|
BLAKE2b-256 | 78f412849e5562681d82c40cac14d4a8e1ba5b18e70ab28f112e4d3f0d2cc514 |