How to update Dash webpage when backend files are updated

Viewed 18

I'm designing a Dash web application which takes in data from the backend. The backend consists of reading files (in the past day) that are mounted onto a RHEL directory with an ETL process (a python script that runs at 4am everyday). I have already designed a process to read in files and display them in graphs. However, I'm looking for ways to refresh the dash application whenever files are uploaded to the directory-basically updating my data everyday or every half day. I realize I will have to do a Polling mechanism or something of the sort. So I started looking into the dcc.interval component of Dash.

Currently, I hardcode a date of August 31 and want to refresh data every 20seconds until September 6th. I defined a function which takes in a date, in this range, and returns a dataframe as an output (after reading in files). From there, whenever my interval function is called, I want to update the graphs.

My layout (basically I have 9 graphs, 2 dropdowns, and 1 dcc interval). The dropdowns are meant to update the data based on user selection (if user selects a province, show only that province data):


firstdate='2022-08-31'
df=collectData(firstdate)

app.layout = html.Div([
    
    html.H1("Netstat Data Analytics Dashboard"),
    html.Div(id='output_container', children=[]),
    
    html.Br(),
    dcc.Dropdown(
        id='provinces',
        options=createDropdownProvinces(df),
        value='All Provinces'
    ),
    
    dcc.Dropdown(
        id='my-input',
        options=createDropdown(df)
    ),
    
    dcc.Interval(
        id='interval-component',
        interval=1*20000, #every 5 ms,
        n_intervals=0
    ),
    
    html.Div(id='live-update-text'),
    html.H3("Metric - Acc_InitialERabEstabSuccRate"),
    dcc.Graph(id='my_graph', figure=fig),
    
    ...more dcc graphs...
])

My callback function:

#Since I need to update ALL graphs depending on 3 inputs: (i) If I invoke a refresh, (ii) if the user selects a province -Dropdown1, or (iii) if a user selects a NodeId - Dropdown2
@app.callback(
    Output('my_graph', 'figure'),
    Output('my_graph2', 'figure'),
    #... more Output graphs (in total I have 9 graphs)
    Input('interval-component', 'n_intervals'),
    Input(component_id='provinces', component_property='value'),
    Input(component_id='my-input', component_property='value')
)
def update_output_Province(intervals, inputValueProvinces, inputValueNode):
    triggered_id=ctx.triggered_id
    if triggered_id=='provinces': #If the user selects provinces
        if inputValueProvinces!='All Provinces':
            filtered_df=df[df['Province'] == inputValueProvinces]
        else: 
            filtered_df=df
        
    elif triggered_id=='my-input': #if user selects dropdown2
        if inputValueNode!='All Nodes':
            filtered_df=df[df['NodeId'] == inputValueNode]
        else: 
            filtered_df=df
    
    elif triggered_id=='interval-component': #if a refresh is requested        
        #update df
        print(intervals)
        
        newdate=datetime.strptime(firstdate, "%Y-%m-%d")
    
        newdate+=timedelta(days=intervals) #add number of intervals as days to update data collection
        print(newdate) #for error debugging
        df=collectData(str(newdate.date()))
        print(df)
        filtered_df=df.copy()
        
    fig=px.scatter(filtered_df, x='Time', y='Acc_InitialERabEstabSuccRate', color='NodeId', hover_name='NodeId')

    fig2=px.scatter(filtered_df, x='Time', y='Int_DlThroughput_kbps', color='NodeId', hover_name='NodeId')
    
    return fig, fig2, fig3, etc...

The problem with this code is the FIRST time that the interval_component is called it's value is 19, I don't understand why, shouldn't it be 1,2,3,4 and so on every 20 seconds? Since my dataframe is unable to collect data beyond September 6th, it returns an empty dataframe and I receive errors. Any suggestions?

0 Answers
Related