Deploy Dash to Heroku error “Failed to parse 'app.server' as an attribute name or function call”

I have been trying to deploy my Plotly-Dash app to Heroku using Heroku Git (git push heroku master) but it’s not working. My dash is a multi-page application called “sales-dash-analytics”, with the following structure:

app.py
index.py
Procfile
Data (folder)
requirements.txt
runtime.txt
venv
.gitignore
Tabs (folder)
|-- Navbar.py
|-- Sidebar.py
|-- Tab1.py
|-- Tab2.py
|-- Tab3.py

The content in the app.py, index.py, Procfile, requirements.txt and runtime.txt are as follows:

app.py

import dash
import dash_bootstrap_components as dbc

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

server = app.server

index.py

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
from app import app
from Tabs import Sidebar, Tab1, Tab2, Tab3, Navbar

app.layout = html.Div(
    children=[
        Navbar.layout,
        Sidebar.layout
    ])


@app.callback(Output(component_id='tabs-content', component_property='children'),
              [Input(component_id='tabs', component_property='value')])
def render_content(tab):
    if tab == 'tab-1':
        return Tab1.layout
    elif tab == 'tab-2':
        return Tab2.layout
    elif tab == 'tab-3':
        return Tab3.layout


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

Procfile

web: gunicorn index:app.server

requirements.txt

dash==1.17.0
gunicorn==20.0.4
numpy>=1.16.2
pandas>=0.24.2
datetime==4.3
pathlib==1.0.1
plotly~=4.12.0
requests~=2.24.0
sklearn~=0.0
scikit-learn~=0.23.2
dash-bootstrap-components>=0.10.1

runtime.txt

python-3.8.3

The main error I am getting is “Failed to parse ‘app.server’ as an attribute name or function call”. The complete logs is below:

2020-12-05T22:06:25.222560+00:00 heroku[web.1]: Starting process with command `gunicorn index:app.server`
2020-12-05T22:06:27.662369+00:00 app[web.1]: [2020-12-05 22:06:27 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-12-05T22:06:27.663307+00:00 app[web.1]: [2020-12-05 22:06:27 +0000] [4] [INFO] Listening at: http://0.0.0.0:8499 (4)
2020-12-05T22:06:27.663469+00:00 app[web.1]: [2020-12-05 22:06:27 +0000] [4] [INFO] Using worker: sync
2020-12-05T22:06:27.672292+00:00 app[web.1]: [2020-12-05 22:06:27 +0000] [10] [INFO] Booting worker with pid: 10
2020-12-05T22:06:27.728469+00:00 app[web.1]: [2020-12-05 22:06:27 +0000] [11] [INFO] Booting worker with pid: 11
2020-12-05T22:06:28.030227+00:00 heroku[web.1]: State changed from starting to up
2020-12-05T22:06:38.621764+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T22:06:38.621973+00:00 app[web.1]: [2020-12-05 22:06:38 +0000] [11] [INFO] Worker exiting (pid: 11)
2020-12-05T22:06:38.625128+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T22:06:38.625335+00:00 app[web.1]: [2020-12-05 22:06:38 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-12-05T22:06:39.120586+00:00 app[web.1]: [2020-12-05 22:06:39 +0000] [4] [INFO] Shutting down: Master
2020-12-05T22:06:39.120718+00:00 app[web.1]: [2020-12-05 22:06:39 +0000] [4] [INFO] Reason: App failed to load.
2020-12-05T22:06:39.220180+00:00 heroku[web.1]: Process exited with status 4
2020-12-05T22:06:39.396826+00:00 heroku[web.1]: State changed from up to crashed
2020-12-05T22:29:24.169851+00:00 heroku[web.1]: State changed from crashed to starting
2020-12-05T22:29:39.169939+00:00 heroku[web.1]: Starting process with command `gunicorn index:app.server`
2020-12-05T22:29:42.780451+00:00 app[web.1]: [2020-12-05 22:29:42 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-12-05T22:29:42.781251+00:00 app[web.1]: [2020-12-05 22:29:42 +0000] [4] [INFO] Listening at: http://0.0.0.0:50714 (4)
2020-12-05T22:29:42.781419+00:00 app[web.1]: [2020-12-05 22:29:42 +0000] [4] [INFO] Using worker: sync
2020-12-05T22:29:42.787463+00:00 app[web.1]: [2020-12-05 22:29:42 +0000] [10] [INFO] Booting worker with pid: 10
2020-12-05T22:29:42.815689+00:00 app[web.1]: [2020-12-05 22:29:42 +0000] [11] [INFO] Booting worker with pid: 11
2020-12-05T22:29:43.467201+00:00 heroku[web.1]: State changed from starting to up
2020-12-05T22:29:55.475520+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T22:29:55.475751+00:00 app[web.1]: [2020-12-05 22:29:55 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-12-05T22:29:55.482071+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T22:29:55.482328+00:00 app[web.1]: [2020-12-05 22:29:55 +0000] [11] [INFO] Worker exiting (pid: 11)
2020-12-05T22:29:55.892962+00:00 app[web.1]: Traceback (most recent call last):
2020-12-05T22:29:55.893024+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 209, in run
2020-12-05T22:29:55.893530+00:00 app[web.1]: self.sleep()
2020-12-05T22:29:55.893570+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 357, in sleep
2020-12-05T22:29:55.894042+00:00 app[web.1]: ready = select.select([self.PIPE[0]], [], [], 1.0)
2020-12-05T22:29:55.894073+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2020-12-05T22:29:55.894413+00:00 app[web.1]: self.reap_workers()
2020-12-05T22:29:55.894447+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 528, in reap_workers
2020-12-05T22:29:55.894963+00:00 app[web.1]: raise HaltServer(reason, self.APP_LOAD_ERROR)
2020-12-05T22:29:55.895061+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'App failed to load.' 4>
2020-12-05T22:29:55.895088+00:00 app[web.1]: 
2020-12-05T22:29:55.895089+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2020-12-05T22:29:55.895090+00:00 app[web.1]: 
2020-12-05T22:29:55.895117+00:00 app[web.1]: Traceback (most recent call last):
2020-12-05T22:29:55.895146+00:00 app[web.1]: File "/app/.heroku/python/bin/gunicorn", line 8, in <module>
2020-12-05T22:29:55.895333+00:00 app[web.1]: sys.exit(run())
2020-12-05T22:29:55.895392+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 58, in run
2020-12-05T22:29:55.895607+00:00 app[web.1]: WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
2020-12-05T22:29:55.895640+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/base.py", line 228, in run
2020-12-05T22:29:55.895977+00:00 app[web.1]: super().run()
2020-12-05T22:29:55.896006+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/base.py", line 72, in run
2020-12-05T22:29:55.896262+00:00 app[web.1]: Arbiter(self).run()
2020-12-05T22:29:55.896291+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 229, in run
2020-12-05T22:29:55.896681+00:00 app[web.1]: self.halt(reason=inst.reason, exit_status=inst.exit_status)
2020-12-05T22:29:55.896710+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 342, in halt
2020-12-05T22:29:55.897145+00:00 app[web.1]: self.stop()
2020-12-05T22:29:55.897180+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 393, in stop
2020-12-05T22:29:55.897603+00:00 app[web.1]: time.sleep(0.1)
2020-12-05T22:29:55.897657+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2020-12-05T22:29:55.897978+00:00 app[web.1]: self.reap_workers()
2020-12-05T22:29:55.898018+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 528, in reap_workers
2020-12-05T22:29:55.898540+00:00 app[web.1]: raise HaltServer(reason, self.APP_LOAD_ERROR)
2020-12-05T22:29:55.898588+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'App failed to load.' 4>
2020-12-05T22:29:56.024233+00:00 heroku[web.1]: Process exited with status 1
2020-12-05T22:29:56.069125+00:00 heroku[web.1]: State changed from up to crashed
2020-12-05T23:07:36.000000+00:00 app[api]: Build started by user 
2020-12-05T23:09:48.210442+00:00 app[api]: Release v22 created by user 
2020-12-05T23:09:48.210442+00:00 app[api]: Deploy 1bebd78a by user
2020-12-05T23:09:48.512846+00:00 heroku[web.1]: State changed from crashed to starting
2020-12-05T23:10:00.733291+00:00 heroku[web.1]: Starting process with command `gunicorn index:app.server`
2020-12-05T23:10:03.451928+00:00 app[web.1]: [2020-12-05 23:10:03 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-12-05T23:10:03.452505+00:00 app[web.1]: [2020-12-05 23:10:03 +0000] [4] [INFO] Listening at: http://0.0.0.0:16209 (4)
2020-12-05T23:10:03.452611+00:00 app[web.1]: [2020-12-05 23:10:03 +0000] [4] [INFO] Using worker: sync
2020-12-05T23:10:03.456559+00:00 app[web.1]: [2020-12-05 23:10:03 +0000] [9] [INFO] Booting worker with pid: 9
2020-12-05T23:10:03.514433+00:00 app[web.1]: [2020-12-05 23:10:03 +0000] [10] [INFO] Booting worker with pid: 10
2020-12-05T23:10:04.065483+00:00 heroku[web.1]: State changed from starting to up
2020-12-05T23:10:07.937258+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T23:10:07.937568+00:00 app[web.1]: [2020-12-05 23:10:07 +0000] [9] [INFO] Worker exiting (pid: 9)
2020-12-05T23:10:08.045319+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T23:10:08.045481+00:00 app[web.1]: [2020-12-05 23:10:08 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-12-05T23:10:08.307344+00:00 app[web.1]: [2020-12-05 23:10:08 +0000] [4] [INFO] Shutting down: Master
2020-12-05T23:10:08.307419+00:00 app[web.1]: [2020-12-05 23:10:08 +0000] [4] [INFO] Reason: App failed to load.
2020-12-05T23:10:08.370453+00:00 heroku[web.1]: Process exited with status 4
2020-12-05T23:10:08.410332+00:00 heroku[web.1]: State changed from up to crashed
2020-12-05T23:10:08.413573+00:00 heroku[web.1]: State changed from crashed to starting
2020-12-05T23:10:18.000000+00:00 app[api]: Build succeeded
2020-12-05T23:10:18.371731+00:00 heroku[web.1]: Starting process with command `gunicorn index:app.server`
2020-12-05T23:10:20.599099+00:00 app[web.1]: [2020-12-05 23:10:20 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-12-05T23:10:20.599681+00:00 app[web.1]: [2020-12-05 23:10:20 +0000] [4] [INFO] Listening at: http://0.0.0.0:54608 (4)
2020-12-05T23:10:20.599799+00:00 app[web.1]: [2020-12-05 23:10:20 +0000] [4] [INFO] Using worker: sync
2020-12-05T23:10:20.604179+00:00 app[web.1]: [2020-12-05 23:10:20 +0000] [9] [INFO] Booting worker with pid: 9
2020-12-05T23:10:20.644201+00:00 app[web.1]: [2020-12-05 23:10:20 +0000] [10] [INFO] Booting worker with pid: 10
2020-12-05T23:10:20.730096+00:00 heroku[web.1]: State changed from starting to up
2020-12-05T23:10:23.775838+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T23:10:23.776036+00:00 app[web.1]: [2020-12-05 23:10:23 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-12-05T23:10:23.836332+00:00 app[web.1]: Failed to parse 'app.server' as an attribute name or function call.
2020-12-05T23:10:23.836613+00:00 app[web.1]: [2020-12-05 23:10:23 +0000] [9] [INFO] Worker exiting (pid: 9)
2020-12-05T23:10:24.098444+00:00 app[web.1]: [2020-12-05 23:10:24 +0000] [4] [INFO] Shutting down: Master
2020-12-05T23:10:24.098574+00:00 app[web.1]: [2020-12-05 23:10:24 +0000] [4] [INFO] Reason: App failed to load.
2020-12-05T23:10:24.161610+00:00 heroku[web.1]: Process exited with status 4
2020-12-05T23:10:24.195191+00:00 heroku[web.1]: State changed from up to crashed
2020-12-05T23:10:39.144851+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=sales-dash-analytics.herokuapp.com request_id=b9565199-7a60-491d-8c73-20bb5dc9c621 fwd="151.210.165.112" dyno= connect= service= status=503 bytes= protocol=https
2020-12-05T23:10:40.146991+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=sales-dash-analytics.herokuapp.com request_id=10b1a4f2-8831-434c-9dcd-2c991f3c7b76 fwd="151.210.165.112" dyno= connect= service= status=503 bytes= protocol=https

I suspect the reason why I am getting this error is because I initialized my app folder with a virtualenv after I finished working on my app and not before I started working on my app, which is what I probably should have done. I tried to activate virtualevnv when deploying my app but it’s still throwing the same error. I have run out of things to try and I am desperate for any help or hint on where I could have gone wrong.

Reference:

Thank you in advance.

Hi,
See if this links helps:

Hi @Eduardo, thank you for your reply. I followed your link and from my understanding you need to add server = app.server to index.py. I tried doing this but was still getting the same erro.

Hi MinhChau96,
I deployed my app following the docs guide https://dash.plotly.com/deployment then I replaced the example app for my app and had no errors.
The difference I can see between the example and your files is that you are including a runtime.txt file that is not speciffy in the docs and also in the requirements.txt there is no loading Flask:
Flask==1.1.2
Flask-Compress==1.7.0
I have no technical knowledge about deploying heroku app and I can’t tell if any of those observation means something.

For more info see this very extensive work done by dan_baker

Hi @MinhChau96 and @Eduardo

Min I think I’ve found your problem, and it’s the PROCFILE!

If your main python file is app.py , then your PROCFILE for heroku should be exactly:

web: gunicorn app:server

Where:

  • ‘web:’ tells Heroku the dyno main process is a web process
  • ‘gunicorn’ tells heroku that the HTTP server to use is Gunicorn (for which it has native support for)
  • ‘app’ references the filename of the main python file without the .py extension. So if you follow the convention of ‘app.py’ you would use ‘app’ here. But note if your main python file is ‘anything.py’, you would have ‘anything’ in place of ‘app’.
  • ‘server’ references the underlying flask app. Commonly you would define a variable ‘server = app.server’ and this references that variable, I believe.

If that doesn’t work, try:

web: gunicorn index:server

One of those two options should do it!!

:slight_smile:

1 Like

Hi @Eduardo and @dan_baker thank you so much for both your help. I changed the content of my Procfile to web: gunicorn index:server and added server = app.server and from app import app, server to index.py and the deployment finally works! Thank you again for your time and help I really appreciate it.

2 Likes

Glad to hear that it works :smiley:
I have only acted as a facilitator :+1: