Function with 2 return values is only considered 1 by callback

Good afternoon Dash community,
When processing a CSV file, using substantially the boilerplate code provided by Dash for the Upload widget, I have added a path to dcc.Store (in app.layout) in addition to the printing of the CSV file using dash_table.DataTable. The return therefore has two return values, and this aligns with the @app.callback with two Output’s.
Why then does Dash have a callback error when I am returning 2 outputs?

dash._grouping.SchemaLengthValidationError: Schema: [<Output raw_df_store.data>, <Output output-data-upload.children>] Path: () Expected length: 2 Received value of length 1:

`def parse_contents(contents, filename):
content = contents.split(‘,’)[1]
decoded = base64.b64decode(content)

try:
    if 'csv' in filename:
        # Assume that the user uploaded a CSV file
        raw_df = pd.read_csv(
            io.StringIO(decoded.decode('utf-8')))
        raw_df_dict = raw_df.to_dict('records')


except Exception as exception:
    print(exception)
    return None, html.Div([
        f'There was an error processing this file. Exception - {exception}'
    ])

raw_df_print = html.Div([
    html.H5(f'File uploaded: {filename}'), 
    dash_table.DataTable(
        raw_df_dict,[{'name': i, 'id': i} for i in raw_df.columns]
    ),
])

return raw_df_dict, raw_df_print

@app.callback([Output(‘raw_df_store’, ‘data’),
Output(‘output-data-upload’, ‘children’)],
[Input(‘upload-data’, ‘contents’),
State(‘upload-data’, ‘filename’)],
prevent_initial_call=True
)
def update_output(file_content, filename):
if file_content is not None:
filename = filename[0]
return [parse_contents(file_content[0], filename)]

return None`

Examining the error, it seems that additional round brackets, (), are added before the outer list square brackets 's. Would it be these that are causing the issue? and if so, why would they be added and how do I exclude them before being passed to the callback?

Hello @mrcnz,

Welcome to the community!

I think you should have your return value not be listed within the brackets. I am assuming that this is causing it to be treated as one entry in a list, verse two separate values.

Good afternoon
Thank you for your response. I agree, however what I can work out is how to stop Dash including these brackets. When terminal printing the two return values they are lists of dictionaries as expected, but when examining the error output, they are encased in [( )]. Why would this be, and how to I work around this behaviour? I understand the outer list, it’s really the () I cannot understand.
Kind regards and thank you

Functions that return multiple values are a tuple.

In order to return it as a list, I would wrap the return value from the function in brackets, and remove the last brackets.

Good morning @jinnyzor

Thank you so much for your input. After hunting, I found my error.
In the following function, I was returning a list (I originally had return [parse_contents(file_content[0], filename)]).

The following now works as expected

def update_output(file_content, filename): if file_content is not None: filename = filename[0] return parse_contents(file_content[0], filename)

Thank you so much for the input.
Kia Ora (both hello/thank you in Maori)

2 Likes