Closed
Description
I wanted to kick off a quick discussion about how we deal with dev mode settings. We've got a few PRs open that introduce new dev mode features and I want to make sure that we have the right abstraction in place.
For context, please read the thread from #369 (comment) and the "debug, dev, production" section in this issue: #312 and an issue by one of the flask developers about running debug mode: #16
Requirements:
- We minimize the risk that users run these features that have security implications accidentally in production mode
- See Do not encourage Flask.run in production #16 for a discussion on this. This is why we made
debug=False
the default behaviour while including
in all of our examples.if __name__ == '__main__': app.run_server(debug=True)
- See Do not encourage Flask.run in production #16 for a discussion on this. This is why we made
- We allow users to turn on wsgi-compatible features if they are using gunicorn in their dev environment
- This means that we can't just stick these features in
run_server
asgunicorn
won't userun_server
- In Add unminified components bundle support. #369, there was a suggestion to make a separate method that
run_server
calls (enable_dev_mode
). That way, users using gunicorn in their dev env can just call this function
- This means that we can't just stick these features in
- There is a simple flag to turn on and off all of the dev mode features. Additionally a way to turn individual features on and off (e.g. turn off hotloading but turn on sourcemaps)
- For users using
run_server
as a dev environment, they shouldn't have to change their code before deploying it to the dev environment.- This means that these settings can not live in the constructor like the rest of the dash arguments.
- This limits us to either having them as part of
run_server
or as an env variable.env
variable is too hard for our users.
With these constraints, the only solution that I see is:
- The
debug=True
command inapp.run_server(debug=True)
ends up doing two things:- Passes
debug=True
intoflask.run(debug=True)
for auto-reloading - Calls
app.set_debug_mode(debug=True)
- Passes
- Each dev mode feature that we write gets its own additional setting that's prefixed with
debug_
:debug_flask=True
- This is the setting that allows users to turn on/off flask's debug environment (i.e.app.server.run(debug=debug_flask))
. This would include auto-reloading and the werkzeug debugger.debug_javascript_bundles=True
- This turns on/off the source maps/unminified bundles Add unminified components bundle support. #369debug_hot_reload=True
- This turns on/off hot reloading. Ifdebug_hot_reload=True
butdebug_flask=False
, then an error is raised (because we need flask's autodebugger - right?)debug_display_javascript_errors=True
- This turns on/off displaying the JS error messages in the front-end app (bubbling the error messages up from the browser console to the app) [WIP] Dash dev tools dash-renderer#64debug_display_python_debugger=True
- This turns on/off displaying the python debugger in the browser context and highlighting the error messages ([WIP] Dash dev tools dash-renderer#64). Ifdebug_display_python_debugger=True
butdebug_flask=False
, then an error is raised (because we need flask's autodebugger - right?)debug_display_callback_dag=True
- This turns on/off the graph of the callback visualdebug_hide_url_route_logs=True
- This turns on the HTTP request logging (and we turn it off by default) - remove werkzeug url print statements by default? #382
- dash-renderer may need some of these settings. So, they'll get serialized like the rest of the config settings: as an element in Dash's JSON config element (
<script id="_dash-config">{...}</script>
or w/e)
Drawbacks:
- Because of Do not encourage Flask.run in production #16, technically, these aren't on by default. However, all of our examples use
app.run_server(debug=True)
and I instinctively write this whenever I create an app, so it's practically the default option. - Previously,
debug=True
was 1-1 with flask'sapp.server.run(debug=True)
. Now,debug=True
will set many other settings. This is OK, if a user needs to turn this off but they want something else on, they can do something like:app.run_server(debug=False, debug_javascript_bundles=True)
orapp.run_server(debug=True, debug_flask=False)
Naming:
- I think these names should be read as "Debug mode: " rather than "Debug ". That is, instead of
debug_javascript
(which reads as "Debug javascript"), we'd have more specificdebug_server_dev_javascript
(which reads as "Debug mode: Serve dev javascript"). - That is, these settings should be tightly integrated with the underlying the feature, allowing users to turn on and off any particular feature.
Does this sound right @plotly/dash ? Sorry for holding things up here, but I want to make sure that we're laying down the right foundation 🚧
Metadata
Metadata
Assignees
Labels
No labels