Skip to content

Immediate callback validation makes combining layout and callbacks in same module difficult  #519

Closed
@ned2

Description

@ned2

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions