How does Flask appear to be skipping print statements
I have a Dash application that lets the user filter a pandas dataframe, which results in a graph. They can also download a CSV of the filtered dataframe. This is accomplished by passing arguments to the URL, retrieving the arguments using flask.request.args
, refiltering the database, and writing the output to a file.
While working on this solution, I added print statements to help me track variable values. Although the download link is working with the desired result, I came across some behavior that I don't fully understand. I think this may have something to do with @app.server.route
and when/how it is executed.
For example:
Print
statements are not always executed. They are executed sometimes.- They seem to have a higher rate of execution once I apply filters, rather than clicking the download link with no filters applied.
- After applying a filter, clicking the download link, and confirming that it caused the
print
statements to execute, reloading the app and applying the same filter may result in theprint
statements not executing.
The download link always performs as intended, but I do not understand how the dataframe is being filtered and written via @app.server.route('/download_csv')
, while also skipping over the print
statements.
UPDATE
I have produced an MRE for Jupyter notebooks. Please note that you must pip install jupyter-dash
for this code to execute.
Some notes:
- I ran three tests where I would click the download CSV link 10x each.
- In the first two tests, the print statements executed 8/10 times.
- In the final test, they executed 3/10 times.
- In the third test, I cleared the age dropdown and performed most of the tests with it as 'Null.' Sometimes print statements will execute and return 'Null', however most times there was no execution.
The MRE is below:
Update 2
After waiting 24hrs and running the code again, all of the lines in @app.server.route
seem to be executing. That is, until I click the download button quickly after changing filters. When this happens, I can get the print
statements to not execute. Despite not executing, the other lines are. Some guesses as to what is going on:
- When the
print
statements don't execute, it seems that a previous version of the code is being executed. Perhaps it is stored in some temporary memory location? - It seems that restarting the system or long periods of inactivity cause the current version of the code to become the default when
print
statements don't execute. print
statements seem to execute less frequently after quick filter changes and download requests.
import plotly.express as px
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import numpy as np
# Load Data
df = pd.DataFrame({'id':np.arange(100), 'name':['cat', 'dog', 'mouse', 'bird', 'rabbit']*20, 'age':np.random.randint(1,30,size=100)})
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
html.H1("JupyterDash Demo"),
dcc.Graph(id='graph'),
html.Label([
"names",
dcc.Dropdown(
id='names', clearable=False,
value='cat', options=[
{'label': names, 'value': names}
for names in df.name.unique()
])
]),
html.Label([
"age",
dcc.Dropdown(
id='age', clearable=True,
options=[
{'label': att, 'value': att}
for att in df.age.unique()
])
]),
html.Br(),
html.A(
"Download CSV",
id="download_csv",
href="#",
className="btn btn-outline-secondary btn-sm"
)
])
# Define callback to update graph
@app.callback(
[Output('graph', 'figure'),
Output('download_csv', 'href')],
[Input("names", "value"),
Input('age', 'value')]
)
def update_figure(names, age):
if not names:
names = 'Null'
fil_df = df
else:
fil_df = df[df['name'].isin([names])]
fig = px.bar(
fil_df, x='id', y='age',
title="Animals"
)
if not age:
age = 'Null'
fil_df = fil_df
else:
fil_df = fil_df[(fil_df['age'].isin([age]))]
fig = px.bar(
fil_df, x='id', y='age', title="Animals"
)
return fig, "/download_csv?value={}/{}".format(names, age)
app.run_server(mode='inline')
@app.server.route('/download_csv')
def download_csv():
value = flask.request.args.get('value')
value = value.split('/')
selected_1 = value[0]
selected_2 = value[1]
print(selected_1)
print(selected_2)
str_io = io.StringIO()
df.to_csv(str_io)
mem = io.BytesIO()
mem.write(str_io.getvalue().encode('utf-8'))
mem.seek(0)
str_io.close()
return flask.send_file(mem,
mimetype='text/csv',
attachment_filename='downloadFile.csv',
as_attachment=True)
from Recent Questions - Stack Overflow https://ift.tt/3t8XA4K
https://ift.tt/eA8V8J
Comments
Post a Comment