Dash Dev Tools is a set of tools to make debugging and developing Dash apps more productive & pleasant.
These tools are enabled when developing your Dash app and are not intended
when deploying your application to production.
Dash Dev Tools includes:
- Callback Graph - Dash displays a visual representation of your callbacks:
which order they are fired in, how long they take, and what data is passed back and forth between
the Dash app in the web browser and your Python code.
Code Reloading - Dash restarts your app when you change code in your project.
Hot Reloading - Dash automatically refreshes the web browser and
your CSS files when you make a code change so that you don’t need to manually
refresh your browser.
In-App Error Reporting - Dash reports error messages in the browser
instead of your terminal so that you can stay focussed on your app and your code.
Component Validation - Dash will display error messages if you pass
malformed data to your components.
Better Error Messages - Dash prunes certain stack traces from Flask & Dash internals
and logs from Flask, Dash’s underlying web server.
These Dev Tools features are turned on when the app is run in development
run_server and when
See the “Configuring Dash Dev Tools” section at the bottom to turn individual
features on and off.
This initiative was sponsored by a Dash Enterprise customer.
Interested in furthering our work here?
Ask your organization to sponsor Dash development
or license Dash Enterprise.
This feature was originally sponsored by a customer in Dash v0.42.0 and
was recently improved in Dash v1.16.0 by Community Member
in #1179. Many thanks
60 second demo video (no sound)
The Dash Dev Tools Callback Graph provides Live Introspection,
Profiling, and Live Debugging of your callback graph.
type- Whether the callback was a clientside callback or a serverside callback.
call count- The number of times the callback was called during your session
status- Whether the callback was successful or not.
time (avg milliseconds)- How long the request took. This is the same as the summary on the green box.
total- The total time of the request.
compute- The time spent running your callback function and serializing & deserializing the data. Serialization and deserialization is a data conversion step that the
dashframework framework performs when receiving and sending data to the client.
network- The time spent transferring the data from the browser client to the server and back.
user: <task-id>- (Optional) Custom timing events captured by
dash.callback_context.record_timing(see “Custom Timing Events” below)
data transfer (avg bytes)
download- The number of bytes sent from the browser client to the server. This is the data that is passed into your callback function: the
upload- The number of bytes sent from the server back to the browser callback. This is the data that is returned from your callback function: the
outputs- A JSON representation of the data that was returned from the callback.
inputs- A JSON representation of the data that was passed to your callback function as
state- A JSON representation of the data that was passed to your callback function as
The timing data reported above includes the entire time that the callback is running.
To report more granular timing data about certain steps within your callback, use
dash.callback_context.record_timing. For example:
from timeit import default_timer as timer @app.callback(Output('graph', 'figure'), Input('dropdown', 'value')) def update_graph(value): start_1 = timer() # perform some action dash.callback_context.record_timing('task_1', timer() - start_1, 'The 1st task') start_2 = timer() # perform another action dash.callback_context.record_timing('task_2', timer() - start_2, 'The 2nd task') return px.scatter()
With this, the custom timing data is available in two places:
dash.callback_context.record_timing(name, duration=None, description=None)
Records timing information for a server resource.
:param name: The name of the resource. :type name: string :param duration: The time in seconds to report. Internally, this is rounded to the nearest millisecond. :type duration: float or None :param description: A description of the resource. :type description: string or None
By default, Dash includes Code Reloading & Hot Reloading. This means that Dash will automatically refresh your browser when you make a change in your Python or CSS code.
The Code Reloading feature is provided by Flask & Werkzeug via the
A caveat of Code Reloading is that your app code is run twice when
starting: once to start the parent process and another time to run the child process that gets reloaded.
Hot reloading works by running a “file watcher” that examines your working directory to check for changes. When a change is detected, Dash reloads your application in an efficient way automatically.
A few notes about how Code Reloading & Hot Reloading works:
- Hot reloading is triggered when you save a file.
- Dash examines the files in your working directory.
- CSS files are automatically “watched” by examining the
assets/ folder. Learn more about css
- If only CSS changed, then Dash will only refresh that CSS file.
- When your Python code has changed, Dash will re-run the entire file and then refresh the application in the browser.
- Hot reloading will not save the application’s state. For example, if you’ve selected some items in a dropdown, then that item will be cleared on hot-reload.
- Hot reloading is configurable through a set of parameters:
dev_tools_hot_reload, and the
If Hot-Reloading is Too Slow
If your application initialization is too slow for hot reloading, then consider:
.arrowfile format so that loading the file is fast or a
picklefile to save & load all of your variables.
Our intention was to reduce the context switch during development between terminal, code editor, browser and browser debug console. With error messages in the app, you can just focus on your browser and your code editor.
To hide the error message, click on the Blue Dev Tools icon in the bottom right corner and then click on the “Toggle Errors” icon.
Dash’s Dev Tools validates the shape of the properties of components.
For example, if you provide
value as a string to
dcc.Checklist( options=['New York City', 'Montréal', 'San Francisco'], value='New York City' )
Instead of as a list:
dcc.Checklist( options=['New York City', 'Montréal', 'San Francisco'], value=['New York City'] )
You’ll see an error message like:
Invalid argument `value` passed into Checklist. Expected an array. Was supplied type `string`. Value provided: "New York City"
As a Dash component author, you do not need to write any input argument validation logic for your component. However, you will need to provide type definitions within the
propTypes of your component. The more specific, the better. These
propType definitions are used for validation and automatic docstring generation.
Note: You can disable the check by setting
dev_tools_props_check=False. But we strongly recommended to fixing the property type errors instead.
Under the hood, we leverage React’s
Error Handling feature and Type Checking with propTypes. These error messages are parsed & modified by Dash before presented to the user. View the source.
In dev mode, component authors can include source maps or dev bundles in their component suite. These source maps or dev bundles will be served
dev_tools_serve_dev_bundles=True. In production they will be omitted.
The component libraries that are maintained by Plotly (including
dash-table) provide the sourcemaps via
asyncloading. This means that they will be loaded on-the-fly when requested by the browser in the browser’s console regardless of the value of
Dev Tools is configured by the
run_server command, which is typically:
app.run_server(host='127.0.0.1', port='7080', proxy=None, debug=False, dev_tools_ui=None, dev_tools_props_check=None, dev_tools_serve_dev_bundles=None, dev_tools_hot_reload=None, dev_tools_hot_reload_interval=None, dev_tools_hot_reload_watch_interval=None, dev_tools_hot_reload_max_retry=None, dev_tools_silence_routes_logging=None, dev_tools_prune_errors=None, **flask_run_options)
debug=True, all of the Dev Tools features listed below enabled.
Individual dev tools featured can be turned on or off with keyword
app.run_server. These include:
debug, bool, activate all the dev tools listed below.
use_reloader, bool, set to
Falseto turn off Code Reloading. Code Reloading restarts.
dev_tools_ui, bool, set to
Falseto explicitly disable dev tools UI in debugger mode (default=True).
dev_tools_props_check, bool, set to
Falseto explicitly disable Component Validation (default=True).
dev_tools_hot_reload, bool, set to
Trueto enable hot reloading (default=False).
dev_tools_hot_reload_interval, float, interval in seconds at which the renderer will request the reload hash and update the browser page if it changed. (default=3).
dev_tools_hot_reload_watch_interval, float, delay in seconds between each walk of the assets folder to detect file changes. (default=0.5 seconds)
dev_tools_hot_reload_max_retry, int, number of times the reloader is allowed to fail before stopping and sending an alert. (default=8)
dev_tools_silence_routes_logging, bool, remove the routes access logging from the console.
dev_tools_prune_errors, bool, simplify tracebacks to just user code, omitting stack frames from Dash and Flask internals. (default=True)
For example, to turn off the automatic reloader but keep the rest of the development features, you could run:
app.enable_dev_tools(debug=None, dev_tools_ui=None, dev_tools_props_check=None, dev_tools_serve_dev_bundles=None, dev_tools_hot_reload=None, dev_tools_hot_reload_interval=None, dev_tools_hot_reload_watch_interval=None, dev_tools_hot_reload_max_retry=None, dev_tools_silence_routes_logging=None, dev_tools_prune_errors=None)
enable_dev_tools when you want to turn on certain features when deploying your application with
A common use case is to enable the Callback Graph to diagnose performance or network issues in your deployed application:
app.enable_dev_tools( dev_tools_ui=True, dev_tools_serve_dev_bundles=True, )
We do not recommend using these settings in your deployed applications in general usage because:
- Displaying serverside tracebacks is a security vulnerability
- Dev Tools features incur a performance penalty: There is a cost to running component validation and loading the dev bundles.
dev_tools variables can be set with environment variables, just replace the
dash_ and convert to uppercase.
This allows you to have different run configs without changing the code.
By placing these features in
run_server, we prevent you from using these
features in production. As a reminder,
run_servershould not be used
when deploying your application in production. Instead, the app should
be run with
server = app.serverinstance.
We don’t run use dev tools in production because:
- Displaying serverside tracebacks is a security vulnerability
- Dev Tools features incur a performance penalty: there is a cost to component validation and loading the larger dev bundles.