To use the Upload component you need to two things
- Configure dash-uploader with
du.configure_upload
- Create the upload component with
du.Upload
Typically you also would like to define callbacks (functions that are called automatically when upload finishes).
⚠️ Security note: The Upload component allows uploads of arbitrary files to the server harddisk and one should take this into account (with user token checking etc.) if used as part of a public website! Particularly, theconfigure_upload
opens a route forPOST
HTTP requests. Use thehttp_request_handler
argument for defining your custom validation logic.
4 Custom handling of HTTP Requests
5 How dash-uploader works internally?
You need to configure the dash uploader after you created your dash application instance (app
) and before you create any Upload components
Example
import dash_uploader as du
du.configure_upload(app, r'C:\tmp\uploads')
configure_upload(app, folder, use_upload_id=True, upload_api=None, http_request_handler=None)
The application instance. Usually created using
app = dash.Dash(__name__)
The folder where to upload files. Can be relative
("uploads"
) or absolute (r"C:\tmp\my_uploads"
).
If the folder does not exist, it will be created
automatically.
Determines if the uploads are put into
folders defined by a "upload id". To define an upload id, use the upload_id
parameter of the du.Upload
component. In typical use case, upload id's are unique for different users. In that case, you must use a callable as the app.layout
.
If True, uploads will be put into <folder>/<upload_id>/
;
that is, every user (for example with different
session id) will use their own folder. If False,
all files from all sessions are uploaded into
same folder (not recommended).
The upload api endpoint to use; the url that is used
internally for the upload component POST and GET HTTP
requests. For example, using upload_api="/API/dash-uploader"
would create api endpoint and use address
http://<myhost>[<requests_pathname_prefix>]/API/dash-uploader
for the communication between the front-end and the server. The requests_pathname_prefix
is added automatically, if the dash app
instance has requests_pathname_prefix
. (used with proxies)
New in version 0.5.0
Used for custom configuration on the HTTP POST and GET requests. This can be used to add validation for the HTTP requests (du.HttpRequestHandler
.
See the documentation of @du.HttpRequestHandler
for
more details.
Below are the arguments for the du.Upload
component and their default values.
Upload(
id='dash-uploader',
text='Drag and Drop Here to upload!',
text_completed='Uploaded: ',
text_disabled='The uploader is disabled.',
cancel_button=True,
pause_button=False,
disabled=False,
filetypes=None,
max_file_size=1024,
chunk_size=1,
default_style=None,
upload_id=None,
max_files=1,
)
The html id for the component. This is needed when defining callbacks. Note that ids must be unique in a dash application.
The text to be shown in the upload "Drag and Drop" area. Optional.
The text to show in the upload area after upload has completed succesfully before the name of the uploaded file.
For example, if user
uploaded "data.zip" and text_completed
is
"Ready! ", then user would see text "Ready!
data.zip".
New in version [0.6.0]
The text to show in the upload area when the the component is disabled.
If True, shows a cancel button.
If True, shows a pause button.
New in version [0.6.0]
If True, the file is not allowed to be uploaded.
The filetypes that can be uploaded.
For example ['zip', 'rar']
.
Note that this just checks the extension of the
filename, and user might still upload any kind
of file (by renaming)!
By default, all filetypes are accepted.
The maximum file size in Megabytes. Default: 1024 (=1Gb).
New in version [0.6.0]
The chunk size in Megabytes. Optional. Default: 1 (=1Mb).
Inline CSS styling for the main div element. If None, use the default style of the component. If dict, will use the union on the given dict and the default style. (you may override part of the style by giving a dictionary) More styling options through the CSS classes.
The upload id, created with uuid.uuid1()
or uuid.uuid4(), for example. If None
, creates random session id with uuid.uuid1()
. Defines a subfolder where the files are to be uploaded.
Only used, if use_upload_id
parameter is set to True
in du.configure_upload
.
⚠️ Experimental feature. Read below. For bulletproof implementation, force usage of zip files and keep max_files = 1.
The number of files that can be added to the upload field simultaneously.
Notes:
(1) If even a single file which is not supported file
type (i.e. missing in filetypes
), is added to the upload queue, upload process of all files will be permanently interrupted.
(2) Use reasonably small number in max_files
.
(3) When uploading two (or more) folders with Chrome, there is
a bug in resumable.js which makes only one of the
folders to be uploaded. See:
23/resumable.js#416
(4) When uploading folders, note that the subdirectories
are not created -> All files in the folders will
be uploaded to the single upload folder.
Callbacks can be defined using two different approaches
@du.callback
: short notation, for typical use cases@app.callback
: needs more verbose code. In case you need more control than when using the@du.callback
.
In the following example it is assumed that the du.Upload
component id is dash-uploader
, i.e. the component was created with:
du.Upload(
id='dash-uploader',
)
New in version 0.3.0
Easiest way to call a simple callback after uploading would be something like:
@du.callback(
output=Output('callback-output', 'children'),
id='dash-uploader',
)
def get_a_list(filenames):
return html.Ul([html.Li(filenames)])
The syntax is
@du.callback(
output=<Output>,
id=<Upload_id>,
)
def call_me(filenames):
# Do some processing
return <Dash component>
This is the Output object, just as in regular dash callbacks.
This must be the same id
as used when initiating your du.Upload
component.
A function that takes exactly one argument: filenames
.
A list of strings. These will be the uploaded files. For example:
['C:\tmp\Uploads\166d6f24-a80d-11ea-aa00-f48c5012fb50\dataset.csv']
The return value of the call_me
should be a dash component, as in the regular [dash callbacks].
This method needs more verbose code and it is the conventional "dash way" to create a callback. Use this if @du.callback
does not give you enough control.
The syntax can be seen in the following example
@app.callback(
Output('callback-output', 'children'),
[Input('dash-uploader', 'isCompleted')],
[State('dash-uploader', 'fileNames'),
State('dash-uploader', 'upload_id')],
)
def callback_on_completion(iscompleted, filenames, upload_id):
if not iscompleted:
return
out = []
if filenames is not None:
if upload_id:
root_folder = Path(UPLOAD_FOLDER_ROOT) / upload_id
else:
root_folder = Path(UPLOAD_FOLDER_ROOT)
for filename in filenames:
file = root_folder / filename
out.append(file)
return html.Ul([html.Li(str(x)) for x in out])
return html.Div("No Files Uploaded Yet!")
isCompleted
: boolean flag indicating if uploading has been completed.fileNames
: List of strings of the filenames or None. This does not have the upload folder or the upload_id in it.upload_id
: The upload id used when initiating thedu.Upload
component.
New in version 0.5.0
The HttpRequestHandler
is a class that is meant to be subclassed. It is used as an argument for configure_upload
, and it makes custom HTTP POST and GET request handling possible. For example, if you run your dash app publicly, you should use some validation logic to validate the HTTP requests from the users!
class HttpRequestHandler(BaseHttpRequestHandler):
# You may use the flask.request
# and flask.session inside the methods of this
# class when needed.
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def post_before(self):
pass
def post(self):
self.post_before()
returnvalue = super().post()
self.post_after()
return returnvalue
def post_after(self):
pass
def get_before(self):
pass
def get(self):
self.get_before()
returnvalue = super().get()
self.get_after()
return returnvalue
def get_after(self):
pass
- The React Component of
dash-uploader
sends HTTP POST requests. It could in the future send also HTTP GET requests, or other HTTP requests. - The Flask server (Dash uses Flask underneath) is configured in
configure_upload
to call thepost()
function of thehttp_request_handler
on every HTTP POST request directed to the API endpoint of the dash-uploader. - The values in the POST request are listed in Documentation of resumable.js. Most interesting from these is probably the filename (
resumableFilename
). In addition to these, there isupload_id
added by thedash-uploader
, ifuse_upload_id=True
when callingconfigure_upload
. - You can use the flask.request and flask.session proxies as you like. There you get access to all the HTTP Request parameters and Cookies, for example. As an quick example, to get the request filename, upload_id and some cookie value, you can use:
from flask import request
filename = request.form.get("resumableFilename", default="error", type=str)
upload_id = request.form.get("upload_id", default="", type=str)
cookie_value = request.cookies.get('some_cookie')
- Please refer to the developer documentation for the details.