plotly dash 下载字节流

plotly dash download bytes stream

我有一个生成 zip 文件的应用程序,我想使用 dcc.download 下载该文件。我认为 zip-creation 工作正常(我通过使用“with”直接下载它来测试它)。但是如何使用 dcc.download 下载流 archive 呢?怎么交才正确?

我的代码如下:

import io
from os import close
import dash
from dash.dependencies import Output, Input
from dash_extensions.snippets import send_bytes
import dash_html_components as html
import dash_core_components as dcc
import base64

import matplotlib.pyplot as plt
import zipfile
from io import BytesIO

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download zip", id="btn_txt"), 
                       dcc.Download(id="download-text")]
                     )

@app.callback(
    Output("download-text", "data"),
    Input("btn_txt", "n_clicks"),
    prevent_initial_call=True,
)
def func(n_clicks):
    archive = BytesIO()
    
    with zipfile.ZipFile(archive, mode="w") as zf:
        for i in range(3):
            plt.plot([i, i])
            buf = io.BytesIO()
            plt.savefig(buf)
            plt.close()
            img_name = "fig_{:02d}.png".format(i)
            zf.writestr(img_name, buf.getvalue())
    
    return send_bytes(archive.read(), "some_name.zip")



if __name__ == "__main__":
    app.run_server(debug=False)

send_bytes 的第一个参数应该是将内容写入 BytesIO 的函数句柄。采用您的示例,代码为

import io
import dash
import dash_html_components as html
import dash_core_components as dcc
import matplotlib.pyplot as plt
import zipfile

from dash.dependencies import Output, Input

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download zip", id="btn_txt"), dcc.Download(id="download-text")])

@app.callback(Output("download-text", "data"), Input("btn_txt", "n_clicks"))
def func(n_clicks):
    def write_archive(bytes_io):
        with zipfile.ZipFile(bytes_io, mode="w") as zf:
            for i in range(3):
                plt.plot([i, i])
                buf = io.BytesIO()
                plt.savefig(buf)
                plt.close()
                img_name = "fig_{:02d}.png".format(i)
                zf.writestr(img_name, buf.getvalue())
    return dcc.send_bytes(write_archive, "some_name.zip")

if __name__ == "__main__":
    app.run_server()