Reputation: 1230
Using the dcc.Upload
, you can build a drag and drop or button-based uploading feature in Dash Plotly dashboard. However, there is a limit in the documentation on handling a specific filetype such as .zip
. Here's a snippet of the uploading html:
dcc.Upload(
id='upload_prediction',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files'),
' New Predictions (*.zip)'
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
accept=".zip",
multiple=True
)
Then when I try to examine the uploaded file with this snippet:
@app.callback(Output('output_uploaded', 'children'),
[Input('upload_prediction', 'contents')],
[State('upload_prediction', 'filename'),
State('upload_prediction', 'last_modified')])
def test_callback(list_of_contents, list_of_names, list_of_dates):
for content in list_of_contents:
print(content)
The content-type after uploading is ‘data:application/x-zip-compressed;base64’. How to handle this type of file in Dash Plotly (for example to extract it somewhere)?
A similar question was asked in the plotly forum without answers: https://community.plot.ly/t/dcc-upload-zip-file/33976
Upvotes: 2
Views: 2620
Reputation: 1230
Dash Plotly provides the uploaded file in the base64 string format. What you need to do is to decode it first, then handle it as bytes string which later can be used to initialize ZipFile
class (It's a built-in tool in python).
import io
import base64
from zipfile import ZipFile
@app.callback(Output('output_uploaded', 'children'),
[Input('upload_prediction', 'contents')],
[State('upload_prediction', 'filename'),
State('upload_prediction', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
for content, name, date in zip(list_of_contents, list_of_names, list_of_dates):
# the content needs to be split. It contains the type and the real content
content_type, content_string = content.split(',')
# Decode the base64 string
content_decoded = base64.b64decode(content_string)
# Use BytesIO to handle the decoded content
zip_str = io.BytesIO(content_decoded)
# Now you can use ZipFile to take the BytesIO output
zip_obj = ZipFile(zip_str, 'r')
# you can do what you wanna do with the zip object here
Upvotes: 7