如何在 Dash 中处理上传的 zip 文件?

Ary*_*ema 2 python plotly data-science plotly-dash

使用dcc.Upload,您可以在 Dash Plotly 仪表板中构建拖放或基于按钮的上传功能。但是,文档中对处理特定文件类型(例如.zip. 这是上传 html 的片段:

\n\n
dcc.Upload(\n    id=\'upload_prediction\',\n    children=html.Div([\n        \'Drag and Drop or \',\n        html.A(\'Select Files\'),\n        \' New Predictions (*.zip)\'\n    ]),\n    style={\n        \'width\': \'100%\',\n        \'height\': \'60px\',\n        \'lineHeight\': \'60px\',\n        \'borderWidth\': \'1px\',\n        \'borderStyle\': \'dashed\',\n        \'borderRadius\': \'5px\',\n        \'textAlign\': \'center\',\n        \'margin\': \'10px\'\n    },\n    accept=".zip",\n    multiple=True\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,当我尝试使用以下代码片段检查上传的文件时:

\n\n
@app.callback(Output(\'output_uploaded\', \'children\'),\n              [Input(\'upload_prediction\', \'contents\')],\n              [State(\'upload_prediction\', \'filename\'),\n               State(\'upload_prediction\', \'last_modified\')])\ndef test_callback(list_of_contents, list_of_names, list_of_dates):\n    for content in list_of_contents:\n        print(content)\n
Run Code Online (Sandbox Code Playgroud)\n\n

上传后的content-type为\xe2\x80\x98data:application/x-zip-compressed;base64\xe2\x80\x99。如何在 Dash Plotly 中处理这种类型的文件(例如将其提取到某个地方)?

\n\n

在plotly论坛中提出了类似的问题,但没有答案:\n https://community.plot.ly/t/dcc-upload-zip-file/33976

\n

Ary*_*ema 7

Dash Plotly 提供 base64 字符串格式的上传文件。你需要做的是先解码它,然后将其处理为字节字符串,稍后可用于初始化ZipFile类(它是 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
Run Code Online (Sandbox Code Playgroud)