✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚾️ It's finally Baseball season! Root for the home team... & Register for our Sports Analytics Webinar!

Upload Component - file uploaded multiple times

Used the same code as in the user guide:
https://plot.ly/dash/dash-core-components/upload

Noticed that for all the call backs the file is uploaded each time
@app.callback(Output(‘output-data-upload’, ‘children’),
[Input(‘upload-data’, ‘contents’),
Input(‘upload-data’, ‘filename’),
Input(‘upload-data’, ‘last_modified’)])

Reducing the Input call backs limits the number of uploads, however if these are needed the file will be uploaded as many times. My case needed the file name so the file kept uploading twice. For large files the upload and processing happens as many times.
Attached screenshot from the network tab.

Request if anyone can suggest a workaround as the files being uploaded are quite big and could avoid the redundant upload.

1 Like

That’s a good question. Right now, @app.callback will send the contents of the Input and State from the browser to the server whenever any of the Input properties change. In this case, the Input property is very large, so it will be sent on every request.

If you have multiple callbacks that depend on this input, then you can share the state of these inputs between callbacks by persisting it to the disk with a solution like here: Capture window/tab closing event

Alternatively, you could have one callback that writes the file to the disk and the rest of the callbacks could read the file from the disk. Something like:

def serve_layout():
    # see https://community.plotly.com/t/capture-window-tab-closing-event/7375/2
    # for more detail
    session_id = str(uuid.uuid4())
    return html.Div([
         html.Div(session_id, id='session-id', style={'display': 'none'})
         # the rest of your app
    ])

app.layout = serve_layout

@app.callback(
    Output('div', 'children'),
    [Input('upload', 'contents'), [Input('session-id', 'children')])
def save_file(contents, session_id):
    # write contents to file
    write_file(session_id, contents)


@app.callback(
    Output('another-div', 'children'),
    [Input('session-id', 'children'), Input('dropdown', 'value), ...])
def respond_to_file(session_id, contents):
    try:
        df = pd.read_csv(session_id)
    except:
        return html.Div('file doesn\'t exist yet')
    return ... # whatever you do with the file

note how we’re using session-id as a unique ids per user session, so that multiple users can still interact with the app at once.

2 Likes

Ingenious! Thanks this should work for me. Appreciate the assistance.

Hi ,

Can you explain more about this method?
For example, what is ‘div’ in first ‘div’ callback and what is write_file function?
I have tried to use this way, but it seems I can’t save the data to desk.

Thanks in advance