✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

Refresh page on POST-request

I want my Dash-App to react to external POST-requests. Right now my solution is to integrate my Dash-App with a manually created Flask-server and to make POST-requests to that server.

The requests trigger the function, however i would have to reload the page for the change to be reflected in the shown layout. I tried out flask.redirect(flask.request.url), which in theory should redirect me to the current URL, so it should refresh the page.

However, that doesn’t happen. Here is my code:

import flask
import dash
import dash_html_components as html

text_style = {
    'color': 'blue',
}

server = flask.Flask(__name__)
app = dash.Dash(__name__, server=server)

app.layout = html.Div(id='dummy', children='Test text', style=text_style)

@server.route('/test', methods=['POST'])
def req():
    print('Request triggered!')  # For debugging purposes, prints to console
    if text_style['color'] == 'blue':  # Toggle textcolor between red and blue
        text_style['color'] = 'red'
    else:
        text_style['color'] = 'blue'
    return flask.redirect(flask.request.url)  # Should redirect to current page/ refresh page

if __name__ == '__main__':
    app.run_server(debug=True)

When i make a post request (import requests; requests.post('http://127.0.0.1:8050/test')), i can see the message Request triggered! printed to the console and when i refresh the page, the textcolor changed.

How can i automate the page refreshment? Is there maybe a way, that doesn’t require a melange of Flask and Dash?

So you would like a request from client A to the server to trigger a refresh for another client B? I don’t think that is possible with the current architecture of Dash. How should B get the information (without requesting it from the server)?

A workaround would be to add an Interval component, which triggers a callback that pulls the desired update(s) at fixed internals T, e.g. once per second. Client B would then get the information from A with a delay (< T).

Hi @Emil and thanks for your reply. I modified my app, so that it has an Interval-component. I added:

app.layout = html.Div([
    ...
    dcc.Interval(
        id='interval-component',
        interval=1*1000, # in milliseconds
    ),
    html.Div(id='none', style={'display': 'none'}),
])

@app.callback(Output('none', 'children'),
              [Input('interval-component', 'n_intervals')])
def timer(_):
    return None

I can now see Updating... Displayed, when i run the app. When i know make a POST-request i continue to see Request triggered! printing to the console, however the change in textcolor is not reflected automatically. I still have to refresh the page manually for the change to take effect.

You need to pull the update (of whatever you are updating) via the callback of the Interval component. Using your previous example, it would be something along the lines of,

@app.callback(Output('dummy', 'style'),
              [Input('interval-component', 'n_intervals')])
def timer(n_intervals):
    return text_style

Aaah of course! Thank you very much, that solved it.