AttributeError: 'Div' object has no attribute 'keys'

Hi, I am new to plotly dash.

I am running the code below:

app = dash.Dash(
    __name__,
    meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
server = app.server

def build_banner(header,hd_subtitle):
    return html.Div(
        id="banner",
        className="banner",
        children=[
            html.Div(
                id="banner-text",
                children=[
                    html.H5(str(header)),
                    html.H6(str(hd_subtitle)),
                ],
            ),
            html.Div(
                id="banner-logo",
                children=[
                    #html.A([
                    #     html.Button(
                    #   id="learn-more-button", children="LEARN MORE", n_clicks=0
                    #),
                    #],href='https://www.google.com'),
                    html.Button(
                       id="learn-more-button", children="LEARN MORE", n_clicks=0
                    ),
                    #html.Button(
                    #    id="learn-more-button", children="LEARN MORE", n_clicks=0
                    #),
                    html.A([
                         html.Img(id="logo",src=app.get_asset_url("logo.png")),
                    ],href='https://www.google.com'),
                ],
            ),
        ],
    )

def generate_section_banner(title):
    return html.Div(className="section-banner", children=title)

def build_top_panel():
    return html.Div(
        id="top-section-container",
        className="row",
        children=[
            # Metrics summary
            html.Div(
                id="summary-lol1",
                className="six columns",
                children=[
                    generate_section_banner("Customer Base"),
                    dcc.Graph(id='histinst'),
                ],
            ),
            html.Div(
                id="summary-lol2",
                className="six columns",
                children=[
                    generate_section_banner("Service Visit Booking"),
                    dcc.Graph(id="histsr"),
                ],
            ),
        ],
    )

def build_tab():
    return [
        html.Div(
            id="status-container",
                    children=[
                        html.Div(id='none',children=[],style={'display': 'none'}),
                        html.Div(
                            id="graphs-container",
                            className="row",
                            children=[
                                build_top_panel(),
                                html.Br(),
                                #build_chart_panel()
                            ],
                        ),
                    ],
                ),
    ]

app.layout = html.Div(
    id="big-app-container",
    children = [
        
        build_banner("sky","Introducing Fluid Viewing"),
            
        html.Hr(),
        
        html.Div(
            id="app-container",
            children=[
                build_tab(),
            ],
        ),
        
    ],
)

per = df['master_mesh_olive_post_code_test.first_install_date'].dt.to_period("M")

@app.callback(
    [Output('histinst', 'figure')],
    [Input('none', 'children')]
)
def update_histogram_install(none):
    df_install = pd.DataFrame({'count' : df.groupby(per).size()}).reset_index()
    trace = go.Bar(x=df_install['master_mesh_olive_post_code_test.first_install_date'].astype(str), 
                   y=df_install['count'], hoverinfo="x")
    return {
        'data': trace,
        'layout': go.Layout(title='Customer Base Number',
                            hovermode="closest",
                            xaxis={'title': "Dates", 'titlefont': {'color': 'black', 'size': 14},
                                   'tickfont': {'size': 9, 'color': 'black'}},
                            yaxis={'title': "Number of Customers", 'titlefont': {'color': 'black', 'size': 14, },
                                   'tickfont': {'color': 'black'}})}

@app.callback(
    [Output('histsr', 'figure')],
    [Input('none', 'children')]
)
def update_histogram_service(none):
    df_service = df.groupby(per).agg({"master_mesh_olive_post_code_test.number_of_service_visit_booked": "sum"}).reset_index()
    trace = go.Bar(x=df_service['master_mesh_olive_post_code_test.first_install_date'].astype(str), 
                   y=df_service['master_mesh_olive_post_code_test.number_of_service_visit_booked'], hoverinfo="x")
    return {
        'data': trace,
        'layout': go.Layout(title='Service Booking',
                            hovermode="closest",
                            xaxis={'title': "Dates", 'titlefont': {'color': 'black', 'size': 14},
                                   'tickfont': {'size': 9, 'color': 'black'}},
                            yaxis={'title': "Number of Services Booked", 'titlefont': {'color': 'black', 'size': 14, },
                                   'tickfont': {'color': 'black'}})}

I keep getting the error:
106
107 @app.callback(
ā€“> 108 [Output(ā€˜histinstā€™, ā€˜figureā€™)],
109 )
110 def update_histogram_install():
ā€¦
AttributeError: ā€˜Divā€™ object has no attribute ā€˜keysā€™
Can someone please guide me on this one?
In place of df the dataframe any random value can be considered.

Not quite sure what the error is exactly since I canā€™t run your code (you havenā€™t defined df).

BUT you have two callbacks with a shared output Output('histinst', 'figure'). This is not supported by Dash.

@sjtrnyā€¦
I only have one output with Output(ā€˜histinstā€™, ā€˜figureā€™) and the other one is Output(ā€˜histisrā€™, ā€˜figureā€™).
In place of that df any random values can be usedā€¦ as I have used now. But it still throws the same error.

app = dash.Dash(
    __name__,
    meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
server = app.server

def build_banner(header,hd_subtitle):
    return html.Div(
        id="banner",
        className="banner",
        children=[
            html.Div(
                id="banner-text",
                children=[
                    html.H5(str(header)),
                    html.H6(str(hd_subtitle)),
                ],
            ),
            html.Div(
                id="banner-logo",
                children=[
                    #html.A([
                    #     html.Button(
                    #   id="learn-more-button", children="LEARN MORE", n_clicks=0
                    #),
                    #],href='https://www.google.com'),
                    html.Button(
                       id="learn-more-button", children="LEARN MORE", n_clicks=0
                    ),
                    #html.Button(
                    #    id="learn-more-button", children="LEARN MORE", n_clicks=0
                    #),
                    html.A([
                         html.Img(id="logo",src=app.get_asset_url("logo.png")),
                    ],href='https://www.google.com'),
                ],
            ),
        ],
    )

def generate_section_banner(title):
    return html.Div(className="section-banner", children=title)

def build_top_panel():
    return html.Div(
        id="top-section-container",
        className="row",
        children=[
            # Metrics summary
            html.Div(
                id="summary-lol1",
                className="six columns",
                children=[
                    generate_section_banner("Customer Base"),
                    dcc.Graph(id='histinst'),
                ],
            ),
            html.Div(
                id="summary-lol2",
                className="six columns",
                children=[
                    generate_section_banner("Service Visit Booking"),
                    dcc.Graph(id="histsr"),
                ],
            ),
        ],
    )

def build_tab():
    return [
        html.Div(
            id="status-container",
                    children=[
                        html.Div(id='none',children=[],style={'display': 'none'}),
                        html.Div(
                            id="graphs-container",
                            className="row",
                            children=[
                                build_top_panel(),
                                html.Br(),
                                #build_chart_panel()
                            ],
                        ),
                    ],
                ),
    ]

app.layout = html.Div(
    id="big-app-container",
    children = [
        
        build_banner("sky","Introducing Fluid Viewing"),
            
        html.Hr(),
        
        html.Div(
            id="app-container",
            children=[
                build_tab(),
            ],
        ),
        
    ],
)


@app.callback(
    [Output('histinst', 'figure')],
    [Input('none', 'children')]
)
def update_histogram_install(none):
    trace = go.Bar(x=[1,2,3,4,5], 
                   y=[1,6,7,2,4], hoverinfo="x")
    return {
        'data': trace,
        'layout': go.Layout(title='Customer Base Number',
                            hovermode="closest",
                            xaxis={'title': "Dates", 'titlefont': {'color': 'black', 'size': 14},
                                   'tickfont': {'size': 9, 'color': 'black'}},
                            yaxis={'title': "Number of Customers", 'titlefont': {'color': 'black', 'size': 14, },
                                   'tickfont': {'color': 'black'}})}

@app.callback(
    [Output('histsr', 'figure')],
    [Input('none', 'children')]
)
def update_histogram_service(none):
    trace = go.Bar(x=[1,2,3,4,5], 
                   y=[1,6,7,2,4], hoverinfo="x")
    return {
        'data': trace,
        'layout': go.Layout(title='Service Booking',
                            hovermode="closest",
                            xaxis={'title': "Dates", 'titlefont': {'color': 'black', 'size': 14},
                                   'tickfont': {'size': 9, 'color': 'black'}},
                            yaxis={'title': "Number of Services Booked", 'titlefont': {'color': 'black', 'size': 14, },
                                   'tickfont': {'color': 'black'}})}

Sorry misread your code. I get a different error to you:

dash.exceptions.NonExistentIdException: 
                            Attempting to assign a callback to the
                            component with the id "histinst" but no
                            components with id "histinst" exist in the
                            app's layout.


                            Here is a list of IDs in layout:
['banner', 'banner-text', 'banner-logo', 'learn-more-button', 'logo', 'app-container', 'big-app-container']

Which is due to how you are constructing your layout here

children=[
                build_tab(),
            ]

This should just be children = build_tab(), since the build_tab function returns a list.

@sjtrny
Thank you. But it still doesnā€™t solve my problem.
Let me give you the entire piece of code.

app = dash.Dash(
    __name__,
    meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
server = app.server
def build_banner(header,hd_subtitle):
    return html.Div(
        id="banner",
        className="banner",
        children=[
            html.Div(
                id="banner-text",
                children=[
                    html.H5(str(header)),
                    html.H6(str(hd_subtitle)),
                ],
            ),
            html.Div(
                id="banner-logo",
                children=[
                    html.Button(
                       id="learn-more-button", children="LEARN MORE", n_clicks=0
                    ),
                    html.A([
                         html.Img(id="logo",src=app.get_asset_url("logo.png")),
                    ],href='https://www.accenture.com/in-en'),
                ],
            ),
        ],
    )
def generate_section_banner(title):
    return html.Div(className="section-banner", children=title)
def build_tabs():
    return html.Div(
        id="tabs",
        className="tabs",
        children=[
            dcc.Tabs(
                id="app-tabs",
                value="tab2",
                className="custom-tabs",
                children=[
                    dcc.Tab(
                        id="Specs-tab",
                        label="Control Tower",
                        value="tab1",
                        className="custom-tab",
                        selected_className="custom-tab--selected",
                    ),
                    dcc.Tab(
                        id="Control-chart-tab",
                        label="Business Metric",
                        value="tab2",
                        className="custom-tab",
                        selected_className="custom-tab--selected",
                    ),
                ],
            )
        ],
    )
def build_tab_1():
    return [
        html.Div(
            id="set-specs-intro-container",
            children=[
                ###Any stock image
                html.Img(id="Landing-page",src=app.get_asset_url("ct.jpg"),
                        style={
                            'height': '100%',
                            'width': '100%'
                        }
                        )
            ],
        ),
    ]
def build_top_panel():
    return html.Div(
        id="top-section-container",
        className="row",
        children=[
            # Metrics summary
            html.Div(
                id="summary-lol1",
                className="six columns",
                children=[
                    generate_section_banner("Customer Base"),
                    dcc.Graph(id='histinst',style={'width': '67.5vh', 'height': '45vh'}),
                ],
            ),
        ],
    )

def build_chart_panel():
    return html.Div(
        id="control-chart-container",
        className="twelve columns",
        children=[
            # Piechart
            html.Div(
                id="ooc-piechart-outer-1",
                className="three columns",
                children=[
                    generate_section_banner("Single vs Multi Screen Users"),
                    dcc.Graph(id="pie-sm"),
                ],
            ),
        ],
    )
def build_tab_2():
    return [
        html.Div(
            id="status-container",
                    children=[
                        html.Div(id='none',children=[],style={'display': 'none'}),
                        html.Div(
                            id="graphs-container",
                            className="row",
                            children=[
                                build_top_panel(),
                                html.Br(),
                                build_chart_panel()
                            ],
                        ),
                    ],
                ),
    ]
app.layout = html.Div(
    id="big-app-container",
    children = [
        
        build_banner("sky","Introducing Fluid Viewing"),
            
        html.Hr(),
        
        html.Div(
            id="app-container",
            children=[
               build_tabs(),
               # Main app
               html.Div(id="main-app-content"),
            ],
            #children=build_tab_2()
        ),
        
    ],
)

@app.callback(Output("histinst", "selectedData"), [Input("histinst", "clickData")])
def update_selected_data(clickData):
    if clickData:
        return {"points": []}

@app.callback(
    Output("histinst", "figure"),
    [Input('none', 'children')]
)
def update_histinst(none):
    xVal = [1,2,3,4,5]
    yVal = [1,6,7,2,4]
    layout = go.Layout(
        bargap=0.01,
        bargroupgap=0,
        barmode="group",
        margin=go.layout.Margin(l=10, r=0, t=0, b=50),
        showlegend=False,
        plot_bgcolor="#323130",
        paper_bgcolor="#323130",
        dragmode="select",
        font=dict(color="white"),
        xaxis=dict(
            showgrid=False,
        ),
        yaxis=dict(
            showticklabels=False,
            showgrid=False,
            zeroline=False,
        ),
    )

    return go.Figure(
        data=[
            go.Bar(x=xVal, y=yVal,
                   hoverinfo="x"),
        ],
        layout=layout,
    )

@app.callback(
    [Output("main-app-content", "children")],
    [Input("app-tabs", "value")],
)
def render_tab_content(tab_switch):
    if tab_switch == "tab1":
        return build_tab_1()
    else:
        return build_tab_2()

The idea is to have 2 tabs. First tab with an image and the other one with a bar chart

Itā€™s still the same error

Thanks. Your error actually makes more sense than mine. Iā€™ll try it again. If I get a solution Iā€™ll upload it.

Try upgrading Dash to get a better error message. There was a recent bug in Dash that ā€œhidā€ the error message behind this AttributeError: 'Div' object has no attribute 'keys' message.

1 Like