Black Lives Matter. Please consider donating to Black Girls Code today.

How to make callbacks sequential

So I am making a dash app which takes a csv file as input. The first call back reads the file and creates a global data frame, the next call back should reads that dataframe and update graph. Now the same functions are activated simultaneously so the second functions gives an error.
How to load callbacks sequentially?

dataframe=None
def parse_contents(list_of_contents,filename):
	content_type, content_string = str(list_of_contents).split(',')
	decoded = base64.b64decode(content_string)
	try:
		if 'csv' in filename:
			df = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
			print('File loaded Successfully')
			return df 
		elif 'xls' in filename:
			df = pd.read_excel(io.BytesIO(decoded))
			print('File Loaded Successfully')
			return df
	except Exception as e:
		print(e)
@app.callback(Output('output','children'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename'),
               Input('upload-data', 'last_modified')])
def update_data(list_of_contents, list_of_names, list_of_dates):
	global dataframe
	if list_of_names is not None:
		print('Tweet Initiated')
		dataframe = parse_contents(list_of_contents,list_of_names)
		return 'File Loaded Successfully'
@app.callback(Output('graph','children'),
	[Input('upload-data', 'contents'),
    Input('upload-data', 'filename'),
    Input('upload-data', 'last_modified')])
def update_graph(list_of_contents, list_of_names, list_of_dates):
	if list_of_names is not None:
		print('Graph Initiated')
		tweets_per_day = dataframe.groupby('created_at').count()
		return str(tweets_per_day)

In dash, each Input triggers the callback so if you want two callbacks to be always be sequential you need the output of the first callback to be the only Input of the second. You should then use dash state to add in any other variables you need.

Your first callback outputs to Output('output','children') so set your second callback to be triggered only when ('output','children') is modified. I.e. your second callback should look like this:

@app.callback(Output('graph','children'),
	[Input('output','children')],
    [State('upload-data', 'filename')])
def update_graph(_, list_of_names):
	if list_of_names is not None:
		print('Graph Initiated')
		tweets_per_day = dataframe.groupby('created_at').count()
		return str(tweets_per_day)

Thanks for the help, but the second function is still triggering at initialization of my program. As it shows an error

AttributeError: 'NoneType' object has no attribute 'groupby'

Because its accessing a global variable which will be updated by the first function. So how to deal with that ?

You can add:

from dash.exceptions import PreventUpdate

And then at the top of that callback add:

if dataframe is None:
    raise PreventUpdate

This will prevent the callback from being triggered if dataframe isn’t defined

**edited to if dataframe is None: