How to stop callback when opening a page

Hi,
This is in addition to my other question that I am still waiting for a response to

The question is that in the app.py, the first line inside the while True got executed once I open the page, so it creates the file, but the second line got executed only after pressing the submit button, which is what is needed, the point is that why there is the difference, I want both of them to be executed after the pressing the submit button.

App.py

import dash
from dash import html, dcc, Dash, callback, Input, Output
import multiprocessing as mp
import os, sys, time
app = dash.Dash(__name__, use_pages=True)

app.layout = html.Div(
    [
        dcc.Store(id="store", data={}),
        html.Div("Network Traffic Dashboard", style={'fontSize':50, 'textAlign':'center'}),
        html.Div([
            dcc.Link(page['name']+"  |  ", href=page['path'])
            for page in dash.page_registry.values()
        ]),
        html.Hr(),
        html.Div(id='selected_nic'),
        dash.page_container
    ]
)

@callback(
    Output('selected_nic', 'nic'),
    [Input('store', 'data')]
)

def capturing_loop(nic):
    while True:
        file_name = (r'C:/DataCapture/traffic_{}.txt'.format(int(time.time())))
        os.system(f'cmd /c D:/OneDrive/NetPredict/dumpcap/dumpcap -i {nic} -q -a duration:10 -w {file_name}.pcap')
        os.system(f'cmd /c D:/OneDrive/NetPredict/dumpcap/tshark -r "{file_name}.pcap" -V -T fields -e frame.number -e _ws.col.Time -e ip.src -e ip.dst -e ip.proto -E header=y -E separator=, -E occurrence=a > "{file_name}"')
        os.remove(file_name +'.pcap')

if __name__ == "__main__":
    if not os.path.exists(r'c:/DataCapture'):
        os.mkdir(r'c:\DataCapture')
    p1 = mp.Process(target=capturing_loop)
    p1.start()
    app.run_server(debug=False)

home.py

import dash
from dash import dcc, html, Input, Output, State, callback
import pandas as pd
import subprocess, io

dash.register_page(__name__, path='/')

nics_list = subprocess.check_output(f'cmd /c D:/OneDrive/NetPredict/dumpcap/tshark -D')
nics_list = nics_list.decode()
nics_list = nics_list.replace('. ', ',').replace('} (', '},').replace(')\r','')
df = pd.read_csv(io.StringIO(nics_list), sep=",", header=None)
df.fillna(' (Loopback Link, DO NOT select)', inplace=True)
df[2] = '"' + df[2] + '"'

layout = html.Div([
    html.H1(children='Welcome to the Network Traffic Monitoring Dashboard', style={
            'text-align': 'center'}),
    html.Div([
        html.Label(['Please select a graph to start capturing Traffic, then move to page 2:'], style={
                   'font-weight': 'bold'}),
        dcc.RadioItems(
            id='nic_selection',
            options=df[2], persistence=True),
        html.Button(id='submit_btn', n_clicks=0, children='Submit'),
    ])])

@callback(
    Output('store', 'data'),
    [State('nic_selection', 'value')],
    [Input('submit_btn', 'n_clicks')]
)
def update_output(value, n_clicks):
    print('Value is', value)
    if n_clicks is None:
        raise PreventUpdate
    store = value
    return store

The other pages code is not relevant, and very long to post

Help is highly appreciated

Have you considered just combining the callbacks into one? You could just have two outputs and multiple inputs and look for “submit_btn” as the trigger_id.

I believe that rewriting this would make sense to simplify things a bit.

I believe a quick solution tho would be changing while True: to while nic != None:

Hopefully this helps

Thanks, the while nic !=None is the solution

But I am not sure what is meant by combining the two callbacks, they are in separate pages.

What about my other question, if you don’t mind? The link is at the top of this question.

Thanks again.

So again, you can solve it with logic and add an additional if statement like:

while nic != None:
  if nic == 1:
    runyourcode here

This is just putting a band-aide on it but should do the trick.

For combining callbacks, you can add the callback from the home.py file into the app.py file. The home.py file really doesnt server much of a purpose other than triggering a callback in app.py. You are just passing a value to store from submit_btn and then passing store as input to selected_nic. Why not just change `@callback(
Output(‘selected_nic’, ‘nic’),
[Input(‘store’, ‘data’)]
)

def capturing_loop(nic):
while True: …` to something like

@callback(
    Output('selected_nic', 'nic'),
    [Input('submit_btn', 'n_clicks')]
)

def capturing_loop(button_clicks):
    if button_clicks == 1:
        RUNWHATEVERHERE
1 Like

Thanks for the explanation, I am working on something now, once I am done with it, I will work on your suggestion.

Many thanks again