Description
Callback validation is great, especially for larger apps with more callbacks. In order to apply callback validation for multi-page apps, the trick described in the Dash Docs under Dynamically Create a Layout for Multi-Page App Validation, needs to be used. This involves creating a layout containing the concatenated layouts of all pages, which is only served if not within a request context (ie for for collback validation, but not for handling a web request). Doing this however makes it tricky to put layouts and callbacks of different pages within the same module.
Consider the following way of defining a layout function for multi-page apps that doesn't require setting app.config.suppress_callback_exceptions = True
:
from .pages import page1, page2, page3
pages = [page1, page2, page3]
def layout_with_validation():
this_layout = my_layout_func
if flask.has_request_context():
return my_layout_func
return [my_layout_func] + [page.layout for page in pages]
If the callbacks for each page are defined along with the layouts within each page module (as they are done in the example multi-page app layout in the Dash Docs), then this will raise a dash.exceptions.LayoutIsNotDefined
exception as the callback
method calls _validate_callback
immediately, before the app.layout
attribute has been assigned. This means layout
attributes and direct uses of app.callback()
can't be combined within the same module while supporting callback validation.
One workaround would be to defer evaluation of the callbacks by wrapping all callbacks in a function that then must be manually called after. This is a bit cumbersome, and makes swapping these pages between multi-page Dash apps and single page ones harder. Are there any more sensible workarounds that this?
Another possibility is changing Dash to defer calling _validate_callback
on each callback until app load, such as in the enable_dev_tools
method.