Progress bar works on local host but not when deployed on heroku

Hello everyone

The app I created works just fine on my local host but the css for the progress bar not not take in effect when I publish to heroku.

Below are some snippets of my code
app.py

import dash
import dash_bootstrap_components as dbc

app = dash.Dash(__name__, suppress_callback_exceptions=True, external_stylesheets=[dbc.themes.COSMO],
                meta_tags=[{"name":"viewport",
                            "content": "width=device-width,initial-scale=1.0"}])
app.title = 'My app'

server = app.server


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

index.py:

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from home import create_home_page
from app import app, server


server = app.server
app.config.suppress_callback_exceptions = True

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content'),
    html.Link(rel="shortcut icon", href="assets/mylogo.png")
])


@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])


def display_page(pathname):
    if pathname == '/home':
        return create_home_page()

    else:
        return create_home_page()

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

home.py:

import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
import pandas as pd
from app import app
import pandas as pd
import numpy as np


df = pd.read_csv("df.csv")

def create_home_page():
    layout = html.Div([

    html.Link(
        rel='stylesheet',
        href='/assets/style.css'
    ),

    dbc.Container([

    html.Center(

        html.A(
            href="https://community.plotly.com/", target= "blank",
            children=[
                html.Img(src="/assets/my_logo.jpg", style={"width": "150px"}, )
                    ]
            )
        ),
        html.Center([dcc.Markdown('''
        ### **Player vs Player**
        ''')]),
        dbc.Row([
            dbc.Col([
                html.Br(),
                dcc.Dropdown(id="hero1",
                             options=[{"label": name, "value": name} for name in sorted(df["name"].unique())],
                             value="Fighter1"
                             ),
                html.Br(),
                html.Div(id="heroimage1"),
                html.Br(),
                html.Div(id="herofaith1progess"),
                html.Br(),
                html.Div(id="herospeed1progess"),
                html.Br(),
                html.Div(id= "herostamina1progess"),
                html.Br(),
                html.Div(id= "herostrengthprogess1"),

            ], lg=6, md=6),

            dbc.Col([
                html.Br(),
                dcc.Dropdown(id="hero2",
                             options=[{"label": name, "value": name} for name in sorted(df["name"].unique())],
                             value="Fighter2"
                             ),
                html.Br(),
                html.Div(id="heroimage2"),
                html.Br(),
                html.Div(id="herofaith2progess"),
                html.Br(),
                html.Div(id="herospeed2progess"),
                html.Br(),
                html.Div(id= "herostamina2progess"),
                html.Br(),
                html.Div(id= "herostrengthprogess2"),

            ], lg=6, md=6),
        ]),

    ]),

], style={"background-image": "url(/assets/custom_background_3q.jpg)",
          "background-size": "cover", "min-height": "660px", "overflow-x": "hidden"},)

    return layout

@app.callback(Output(component_id="heroimage1", component_property="children"),
              Output(component_id="herofaith1progess", component_property="children"),
              Output(component_id="herospeed1progess", component_property="children"),
              Output(component_id="herostamina1progess", component_property="children"),
              Output(component_id="herostrengthprogess1", component_property="children"),
              Input(component_id="hero1", component_property="value"))
def display_hero1_stats(hero1):
    hero_row = df.loc[df["name"] == hero1]
    image = hero_row["image"].values[0]

    hero1image = html.Center([html.Img(src=image, style={"width": "200px"})]),

    faith = hero_row["faith"]
    faith_pb = html.Center(dbc.Progress(children=[str("Faith: ") , int(faith)], max=50, value=faith, striped=True,))

    speed = hero_row["speed"]
    speed_pb = html.Center(dbc.Progress(children=[str("Speed: ") , int(speed)],max="50", value=speed, color="success",
                                        striped=True))

    stamina = hero_row["stamina"]
    stamina_pb = html.Center(dbc.Progress(children=[str("Stamina: ") , int(stamina)], max="50", value=stamina,
                                          color="danger", striped=True))

    strength = hero_row["strength"]
    strenth_pb = html.Center(dbc.Progress(children=[str("Strength: ") , int(strength)],  max="50", value=strength,
                                          striped=True, color="warning"))

    return hero1image, faith_pb, speed_pb,  stamina_pb, strenth_pb

@app.callback(Output(component_id="heroimage2", component_property="children"),
              Output(component_id="herofaith2progess", component_property="children"),
              Output(component_id="herospeed2progess", component_property="children"),
              Output(component_id="herostamina2progess", component_property="children"),
              Output(component_id="herostrengthprogess2", component_property="children"),
              Input(component_id="hero2", component_property="value"))
def display_hero2_stats(hero2):
    hero_row = df.loc[df["name"] == hero2]
    image = hero_row["image"].values[0]

    hero2image = html.Center([html.Img(src=image, style={"width": "200px"})]),

    faith = hero_row["faith"]
    faith_pb = html.Center(dbc.Progress(children=[str("Faith: ") , int(faith)], max=50, value=faith, striped=True,))

    speed = hero_row["speed"]
    speed_pb = html.Center(dbc.Progress(children=[str("Speed: ") , int(speed)],max="50", value=speed, color="success",
                                        striped=True))

    stamina = hero_row["stamina"]
    stamina_pb = html.Center(dbc.Progress(children=[str("Stamina: ") , int(stamina)], max="50", value=stamina,
                                          color="danger", striped=True))

    strength = hero_row["strength"]
    strenth_pb = html.Center(dbc.Progress(children=[str("Strength: ") , int(strength)],  max="50", value=strength,
                                          striped=True, color="warning"))

    return hero2image, faith_pb, speed_pb,  stamina_pb, strenth_pb

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

Progress bar - local host:

Progress bar - heroku:

Thank you

I have the same problem 2 years layer. I’m deploying to Azure.

Any way you can post your code? I use Azure and I haven’t seen issues like this. I don’t use progress bars though.

Yes I am trying to create a minimum reproducible example today! Partly because I think the way I’m doing it is very bad, and cleaning things up would reveal a better solution. Namely, I’m using a callback to update the progress bar for a long running process in a “main” callback.

Pseudo code off the top of my head:

def call_long_running_process(df, progress_callback):
    figs = []
    for i in range(10):
        # ... create figs with df ... 
        progress_callback(i * 10)
    return figs

def register_callbacks(dash_app, azure):
    
    progress_storage = {"progress": 0}

    def progress_callback(progress):
        progress_storage["progress"] = progress

    @dash_app.callback(
        [Output("progress", "value"), Output("progress", "label")],
        [Input("progress-interval", "n_intervals")]
    )
    def update_progress(n):
        progress = progress_storage["progress"]
        return progress, f"{int(progress):0d} %" if progress >= 5 else ""

    @dash_app.callback(
        [Output(f"graph-{i}", "figure") for i in range(N_PLOTS)],
        [Input(f"graph-{i}", "selectedData") for i in range(N_PLOTS)],
        [State('working-dataset', 'data')],
    )
    def callback(*args):
        selected_points_per_plot = args[:N_PLOTS]
        working_dataset = args[N_PLOTS]
        df = read_json(working_dataset)
        figs = call_long_running_process(df, progress_callback)
        return figs

    return dash_app

Hmm… have you tried with just a background callback and setting the progress that way?

1 Like

That looks very promising thank you! I wasn’t aware of that - my dash app knowledge is locked in pre-2.6 haha (as is copilot it seems!). I need to start looking at the docs to find all the new fancy things.

EDIT: actually this is the second time I’ve seen recommendations for celery+redis. After some brief reading I think that will solve a lot of problems with this particular app!

3 Likes