Dash: No crashing on syntax errors

Created on 19 Nov 2018  路  8Comments  路  Source: plotly/dash

Right now if I have an app running and I change the Python source, it reloads, and with client-side hot-reloading the experience is really awesome. But. If I make an error in my Python, the whole loop crashes and I need to go to my terminal to restart the app.

The ideal workflow from my perspective would be for the app to try to reload, and if there's a Python error, it would tell me on the console and then not exit but rather keep watching the file and if I re-save, it would load the file again, such that I could just look at my console, fix the error and resave, without having to leave my editor.

@T4rk1n @rmarren1 any thoughts on the feasibility of this?

All 8 comments

it would tell me on the console

Or, when we are displaying these errors in the front-end, show the error message in the browser. Then, you'll never need to look at your terminal after you start your app!

We always run our flask apps with app.run which according to the flask docs is not good for development with reloading and results in app crashing on syntax errors. http://flask.pocoo.org/docs/0.12/server/#in-code

Is there some alternative we could use like app.run_debug() or something?

In essence, what I want is what I get when I run while true; do python app.py; sleep 1; done :)

This bit of code from the flask-failsafe module looks similar to what we want: https://github.com/mgood/flask-failsafe/blob/master/flask_failsafe.py

Wraps an app factory to provide a fallback in case of import errors.
Takes a factory function to generate a Flask app. If there is an error
creating the app, it will return a dummy app that just returns the Flask
error page for the exception.
This works with the Flask code reloader so that if the app fails during
initialization it will still monitor those files for changes and reload
the app.

Ideally, instead of the 'dummy app' we can just present the syntax error on the front end using https://github.com/plotly/dash-renderer/pull/100 (Dev Tools)

Hi, I've tested flask_failsafe and it works fine. I created a server.py which imports my app.py. Only limitation is that it seems expects the app to have a run function, instead of run_server. So I had to write app.run = app.run_server.

Why this naming differs from Flask naming? (I a am a beginner in both Flask and Dash)

Edit: create_app().server.run(port="8050", debug=True) could be the preferred syntax, as app.server is the underlying Flask server

Thanks for looking into this @eric-burel - it's not something we've gotten to yet but would certainly improve the experience. Ideally I'd like us to find a solution that doesn't require users to do anything special with their app code though.

They seem to say it's not doable in Flask related issue, hence the mandatory use of flask run command for a fully working reload: https://github.com/pallets/flask/issues/2424

I am not knowledgeable enough in Python to have any idea of a version without user intervention based on failsafe. The tough part seems to be their call to from app import app inside the create_app function.

Here is the final version of my server.py after a few try and learn:

from flask_failsafe import failsafe


@failsafe
def create_app():
    # note that the import is *inside* this function so that we can catch
    # errors that happen at import time
    from app import app
    return app.server


if __name__ == "__main__":
    # app.server is the underlying flask app
    create_app().run(port="8050", debug=True

and the run command becomes python server.py instead of python app.py

Was this page helpful?
0 / 5 - 0 ratings