Dash - 'Error loading layout'

Hi there, I am trying to run a dash app instance on pythonanywhere.com with my main flask app.

When I run the sample code from dash tutorial

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for Python.
    '''),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'title': 'Dash Data Visualization'
            }
        }
    )
])

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

I get an error displayed on my browser 'Error loading layout’

WSGI

import sys
project_home = u'**********'
if project_home not in sys.path:
    sys.path = [project_home] + sys.path

from werkzeug.wsgi import DispatcherMiddleware
from flask_app import server as app1
from dash_app import app as app2

application = DispatcherMiddleware(app1, {
    '/dash':    app2.server
})

I haven’t been able to find any threads related to this specific error. Any help/comment is welcomed!

See Dash - pythonanywhere deployment issue

Thanks for your reply.

Actually I have seen that thread and followed what you suggested before this. I don’t see any errors on my server log too.

Perhaps start by seeing if the problem is associated with a minimal version that just sets application to your Dash app.server.

Another suggestion, try app = dash.Dash(__name__). The name param (which we’re setting to the current module here) will be passed onto the Flask server that is created. Sometimes this doesn’t matter, but sometimes this is important for Flask.

Thank you for your reply.

I managed to find a similar solution that worked for me here

I think the issue is with DispatcherMiddleWare. Though I am not quite sure why the suggested structure here (http://flask.pocoo.org/docs/0.12/patterns/appdispatch/#combining-applications) wouldn’t work for flask and dash.

After playing around I worked out what the problem is (then discovered someone else already had worked it out too).

The issue is that when you mount the Dash app at /dash, while the dispatcher is aware of this prefix, the Dash app itself is not. In particular the API requests from the client are still being directed to their various endpoints at the root. For example the failed request that leads to the error you see is going to /_dash-layout, when it should be going to /dash/_dash-layout. As suggested in the post I linked to, you can fix this by updating Dash’s request route prefix to make it relative rather than absolute, like this:

app.config.requests_pathname_prefix = ''

This however will break if you provide a custom value of url_base_pathname when creating a Dash instance. I think a more general solution could be this, however I haven’t tested it all that thoroughly:

app.config.requests_pathname_prefix = app.config.routes_pathname_prefix.split('/')[-1]

Also, I think the reason that Stackoverflow answer you linked to works, is not because it solves this problem, but because it just works around it by having the Dash app’s Flask instance be mounted at the root and therefore does not have to worry about the discrepancy between prefixes. The approach I’ve suggested, is more general, allowing you to mount the Dash instance wherever you want.

1 Like

@chriddyp, I wonder, do you think that could be a potentially more robust default value for requests_pathname_prefix within the Dash class?

I’ve created a gh repo for anyone interested in seeing an example of such a setup: mbkupfer/dash-with-flask

I threw this together over the weekend and I do plan to refine the example a bit more once I get the time. That said, I thought I would put this out now in case someone needed it before now and then.

Big shout out to ned. You are a Dash genius! @nedned

1 Like

Hello, im trying to test this tutorial

wheb i deploy application to heroku server i see this errors:

2019-02-20T14:31:08.000000+00:00 app[api]: Build succeeded
2019-02-20T14:31:26.499387+00:00 app[web.1]: [2019-02-20 14:31:26,497] ERROR in app: Exception on / [GET]
2019-02-20T14:31:26.499434+00:00 app[web.1]: Traceback (most recent call last):
2019-02-20T14:31:26.499443+00:00 app[web.1]: File “/app/.heroku/python/lib/python3.6/site-packages/flask/app.py”, line 2292, in wsgi_app
2019-02-20T14:31:26.499445+00:00 app[web.1]: response = self.full_dispatch_request()
2019-02-20T14:31:26.499447+00:00 app[web.1]: File “/app/.heroku/python/lib/python3.6/site-packages/flask/app.py”, line 1808, in full_dispatch_request
2019-02-20T14:31:26.499449+00:00 app[web.1]: self.try_trigger_before_first_request_functions()
2019-02-20T14:31:26.499451+00:00 app[web.1]: File “/app/.heroku/python/lib/python3.6/site-packages/flask/app.py”, line 1855, in try_trigger_before_first_request_functions
2019-02-20T14:31:26.499454+00:00 app[web.1]: func()
2019-02-20T14:31:26.499456+00:00 app[web.1]: File “/app/.heroku/python/lib/python3.6/site-packages/dash/dash.py”, line 988, in _setup_server
2019-02-20T14:31:26.499459+00:00 app[web.1]: self._validate_layout()
2019-02-20T14:31:26.499460+00:00 app[web.1]: File “/app/.heroku/python/lib/python3.6/site-packages/dash/dash.py”, line 965, in _validate_layout
2019-02-20T14:31:26.499462+00:00 app[web.1]: ‘’
2019-02-20T14:31:26.499478+00:00 app[web.1]: dash.exceptions.NoLayoutException: The layout was None at the time that run_server was called. Make sure to set the layout attribute of your application before running the server.
2019-02-20T14:31:26.500318+00:00 app[web.1]: 10.11.189.35 - - [20/Feb/2019:14:31:26 +0000] “GET / HTTP/1.1” 500 291 “https://dashboard.heroku.com/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0”
2019-02-20T14:31:26.501975+00:00 heroku[router]: at=info method=GET path="/" host=apptesterg.herokuapp.com request_id=2d9c060e-a375-4e70-89af-27d823deac03 fwd=“188.162.172.33” dyno=web.1 connect=0ms service=4ms status=500 bytes=456 protocol=https

any help pls, what im doing wrong?

I am getting “Error loading layout” error also. Here is the details of my implementation:

  1. I have created Python Dash simple application as the example mentioned in the top
  2. Deploy it in EC2 ubuntu instance using gunicorn WSGI
  3. I have nginx setup for proxy service that routes to WSGI to Python Dash running on port 5201
  4. While hitting the url it’s giving me “Error loading layout”

But when I run the same without gunicorn WSGI but using vanilla python script locally, it’s rendered the “Hello Dash” screen.

Please help me solving the problem

Regarding the issue of @supalkc-dash
Here is one thing that would cause your app to work locally but fail if deployed:

When you put the instantiation and preparation of the layout inside of
if __name__ == "__main__":

If you are deploying, you need to make sure that the code that prepares your layout will be read even when app.py is imported.

I know this because this happened to me just now. :neutral_face:

1 Like

@human42 Thanks for the reply, but I am not sure I am understanding the problem.

My dash file name is Dashboard.py having app instantiated as below:

flaskserver = flask.Flask(___name ___)
app = dash.Dash(
___name ___,
meta_tags=[{“name”: “viewport”, “content”: “width=device-width”}],
title=‘Monitoring Dashboard’,
server=flaskserver,
update_title=‘Refreshing
’,
suppress_callback_exceptions=False,
serve_locally = False if (UTILS.get_os_name() == ‘linux’) else True
)
def init():

  • print(‘initiating resources’)*

And My wsgi.py file is having following simple line:

from Dashboard import init
init()
#You can add additional code here if required prior start the app
##
from Dashboard import app
app = app.server

And I run following gunicorn command in ubuntu:
$gunicorn --bind 0.0.0.0:5101 —reload wsgi:app

Where is wrong in it?

I notice that in this code that you have provided I do not see a line that instantiates your layout.
I’m expecting something that goes like this:
app.layout = (your layout here)

Dash Docs about Layout:
Part 2. Layout | Dash for Python Documentation | Plotly

My question is: where is your layout instantiated?
Asking this question especially because the error you are getting is talking about the layout.

Thanks for responding.

See below the code snippets for layout instantiation:

flaskserver = flask.Flask(___name ___)

app = dash.Dash(
___name ___,
meta_tags=[{“name”: “viewport”, “content”: “width=device-width”}],
title=‘Monitoring Dashboard’,
server=flaskserver,
update_title=‘Refreshing
’,
suppress_callback_exceptions=False,
serve_locally = False if (UTILS.get_os_name() == ‘linux’) else True
)

app.layout = DashboardLayout.get_layout(app)

Note: I have created a separate py module namely DashboardLayout.py containing the get_layout() method as below:

def get_layout(app):
return html.Div(
[
- - - - - – - - - - - -
app.get_asset_url(‘my-logo.png’)
- - - - - - - -
]

Try transferring your get_layout(app) function into the file that creates your dash app instead of importing it from DashboardLayout. Try this deploying in AWS again and please report back if it works. Also, I sincerely apologize, I was genuinely unaware that you had promptly responded to me. I know it’s very late but here’s my suggestion.