Skip to content

Instantly share code, notes, and snippets.

@hartzell
Created June 6, 2020 14:43
Show Gist options
  • Save hartzell/61a82257f1976450e5980d4fb087ee7b to your computer and use it in GitHub Desktop.
Save hartzell/61a82257f1976450e5980d4fb087ee7b to your computer and use it in GitHub Desktop.
Demo of possible bug with Dash Upload component
# this has a problem that the "new_jobs" values aren't reset after
# being used.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from flask import Flask, send_file
server = Flask(__name__)
app = dash.Dash(server=server)
app.layout = html.Div(
children=[
dcc.Store(id="jobs", storage_type="memory"),
html.H1("Jobs"),
html.Div(id="jobs-list"),
html.H2("Upload your files"),
dcc.Upload(
id="upload-data",
children=html.Div(
["Drag and drop or click to select a file to upload."]
),
style={
# "width": "100%",
"height": "60px",
"lineHeight": "60px",
"borderWidth": "1px",
"borderStyle": "dashed",
"borderRadius": "5px",
"textAlign": "center",
"margin": "10px",
},
multiple=True,
),
html.H2("Delete jobs"),
dcc.Dropdown(id="jobs-to-delete", multi=True),
html.Button("Delete Me!", id="delete-jobs-button", n_clicks=0),
],
style={"max-width": "500px"},
)
@app.callback(
Output("jobs-list", "children"), [Input("jobs", "data")],
)
def display_jobs(jobs):
return [html.Div(f"Job: {j}") for j in jobs]
@app.callback(
Output("jobs", "data"),
[
Input("upload-data", "filename"),
Input("delete-jobs-button", "n_clicks"),
],
[State("jobs-to-delete", "value"), State("jobs", "data")],
)
def update_jobs(new_jobs, button, delible_jobs, jobs):
ctx = dash.callback_context
print("---")
print(f"ctx.triggered: {ctx.triggered}")
print(f"Delible: {delible_jobs}")
print(f"New: {new_jobs}")
print(f"Jobs: {jobs}")
if new_jobs is None and delible_jobs is None:
raise PreventUpdate
jobs = jobs or []
if delible_jobs is not None:
jobs = [j for j in jobs if j not in delible_jobs]
if new_jobs is not None:
jobs += new_jobs
return jobs
@app.callback(Output("jobs-to-delete", "options"), [Input("jobs", "data")])
def update_deletable_jobs(jobs):
if jobs is None:
raise PreventUpdate
options = [{"label": f"Job: {j}", "value": j} for j in jobs]
return options
if __name__ == "__main__":
app.run_server(debug=True, port=8888, host="172.16.193.97")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment