plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.

Home Page:https://plotly.com/dash

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] support multiple URL path levels in path template

yreiss opened this issue · comments

I'd like to suggest the following behavior for interpreting path templates as part of the pages feature.

The following example can illustrate the requested behavior:

dash.register_page("reports", path_template="/reports/<product>/<feature>/<report_type>/<data_version>")

def layout(product: str | None = None, feature: str | None = None, report_type: str | None = None, data_version: str | None = None) -> Any:
    return html.Div(f"{product} {feature} {report_type} {data_version}")

For '/reports' layout will be called with None for all input arguments.
For '/reports/spaceship' layout will be called with 'spaceship' for product and None for the rest.
Etc.

A template may also combine arguments and static parts. For instance the following two templates may both be supported:

"/reports/<product>/<feature>/types/<report_type>/<data_version>"
"/reports/<product>/<feature>/sub_features/<sub_feature>/<report_type>/<data_version>"

When registering the pages, conflicts should be checked and error raised upon conflict. The rule is that one template should not be a superset of the other. For example, the following templates conflict:

"/reports/<product>/<feature>/types/<report_type>/<data_version>"
"/reports/<product>/<feature>/types/<report_type>"

Here's my suggested python code for checking a conflict between two templates:


def is_variable(var: str) -> bool:
    return var[0] == '<' and var[-1] == '>'

def is_template_confict(tpl1: str, tpl2: str) -> bool: # return True if there is a conflict
    vars1 = tpl1.split('/')
    vars2 = tpl2.split('/')
    for ind in range(min(len(vars1), len(vars2))):
        if is_variable(vars1[ind]) != is_variable(vars2[ind]):
            return False
        if not is_variable(vars1[ind]) and vars1[ind] != vars2[ind]: 
            return False  # both are static and not equal

    return True