Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dash.no_update is not serializable by json is raised if other, not serializiable type is passed as output #3090

Open
smoky1337 opened this issue Nov 22, 2024 · 1 comment
Labels
bug something broken P2 considered for next cycle

Comments

@smoky1337
Copy link

smoky1337 commented Nov 22, 2024

Hi everyone,

thanks for providing such a wonderful package. I had an issue and I have been cracking my head at this long enough to belief this is a bug with dash.no_update not being serializiable. While writing this issue, I found that dash.no_update is not the issue but obfusicates the real error.

Situation: Given a user picked date range, I gather data and display it. However, I want to cover the case when there simply is no data to present.
For this, I aim to not update the already presented data and instead show an alert, notifiying the user of the absence of data.

See this line (context below):

return no_update, no_update, True, df

df is an AssertionError. Apparently, those are not serializiable by json. However, see error log at bottom, dash reports that dash.no_update seems to be the culprit.

The error below is resolved by parsing df into a string via ´str(df)´

@callback(
    Output(component_id='figcontainer', component_property='figure'),
     Output(component_id='table', component_property='data'),
     Output(component_id="alert", component_property='is_open'),
     Output(component_id="alert",component_property='children'),
    Input(component_id='date_picker', component_property='start_date'),
    Input(component_id='date_picker', component_property='end_date'),
)
def update_graph(start, end):
    df = get_bookings_in_interval(start, end)
    # if there is no data, keep previous states and use alert
    if type(df) is AssertionError:
        return no_update, no_update, True, df

    #else simply display the information and dont update the alert
    all_appointments, best_days_with_numbers, cleaning_schedule = create_dfs(df)
    
    fig = create_figure(start, end, all_appointments, cleaning_schedule)

    
    return fig.to_dict(), best_days_with_numbers.to_dict(orient="records"), no_update, no_update


#either returns a df or an AssertionError
def get_bookings_in_interval(start, end):
    df = None
    try:
        data = get(#do something)
        assert data.status_code == 200 , "Failed to fetch bookings"
        parsed_data = dict(data.json())
        assert len(parsed_data["bookings"]) > 0, "No items in Response")
        #do something
            
    except AssertionError as e:
        print(e)
        return e

    return data

Environment used:


dash                      2.18.2
dash-bootstrap-components 1.6.0
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0

Error Log:

dash.exceptions.InvalidCallbackReturnValue: The callback for `[<Output `figcontainer.figure`>, <Output `table.data`>, <Output `alert.is_open`>, <Output `alert.children`>]`
returned a value having type `NoUpdate`
which is not JSON serializable.


The value in question is either the only value returned,
or is in the top level of the returned list,

and has string representation
`<dash._callback.NoUpdate object at 0x000002A7FA5ACBE0>`

In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.

Expected behavior

As dash.no_update is explicitly mentioned, I expected it to be culprit. I think the error hint should either reflect the possibility of other returned values being the issue or explicitly state the correct one.

Screenshots

@gvwilson gvwilson changed the title [BUG] dash.no_update is not serializable by json is raised if other, not serializiable type is passed as output dash.no_update is not serializable by json is raised if other, not serializiable type is passed as output Nov 26, 2024
@gvwilson gvwilson added bug something broken P2 considered for next cycle labels Nov 26, 2024
@yuvashrikarunakaran
Copy link
Contributor

from dash import no_update
from dash.dependencies import Input, Output

@callback(
Output(component_id='figcontainer', component_property='figure'),
Output(component_id='table', component_property='data'),
Output(component_id="alert", component_property='is_open'),
Output(component_id="alert", component_property='children'),
Input(component_id='date_picker', component_property='start_date'),
Input(component_id='date_picker', component_property='end_date'),
)
def update_graph(start, end):
df = get_bookings_in_interval(start, end)

# Handle the case where there is an AssertionError
if isinstance(df, AssertionError):
    return no_update, no_update, True, str(df)  # Convert AssertionError to a string

# Otherwise, process the data normally
all_appointments, best_days_with_numbers, cleaning_schedule = create_dfs(df)
fig = create_figure(start, end, all_appointments, cleaning_schedule)

return (
    fig.to_dict(),
    best_days_with_numbers.to_dict(orient="records"),
    no_update,
    no_update,
)

def get_bookings_in_interval(start, end):
df = None
try:
data = get(# do something)
assert data.status_code == 200, "Failed to fetch bookings"
parsed_data = dict(data.json())
assert len(parsed_data["bookings"]) > 0, "No items in response"
# Process the data and return
df = process_data(parsed_data) # Replace with actual processing logic
except AssertionError as e:
print(e)
return e # Return AssertionError for handling in the callback
return df

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P2 considered for next cycle
Projects
None yet
Development

No branches or pull requests

3 participants