plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.19k stars 2.04k forks source link

provide Python function returning stringified dict component IDs #1625

Open anders-kiaer opened 3 years ago

anders-kiaer commented 3 years ago

Is your feature request related to a problem? Please describe. When you use pattern matching callbacks and component IDs of type dictionaries, Dash will automatically stringify the IDs before being sent to the browser/DOM.

As far as I know, even if you use the Dash pytest/selenium plugin, if you want to do certain tests on these components (and select them by ID), you would need to find out + assume how the dictionary ID → string ID conversion is done by Dash.

Describe the solution you'd like A python function callable from somewhere in the dash package which does the conversion, and thereby can safely be used in tests of Dash apps, across dash versions. E.g. something like:

def stringify_id(dict_id: Dict[str, str]) -> str:
    ...

stringify_id({"id": "some_id", "type": "some_type"}) == '{\"id\"\:\"some_id\"\,\"type\"\:\"some_type\"\}'

Additional context It looks like the conversion internally in Dash today is done on the JavaScript side: https://github.com/plotly/dash/blob/597dc22c86de97530fb9b0a9bd9f7876bd0d7601/dash-renderer/src/actions/dependencies.js#L111-L123

One way of supporting the use case above would be to add a Python function doing the same stringify logic, and then add new selenium tests to the Dash test suite to ensure the Python-stringify = JavaScript-stringify. Can we do better? Or maybe there is already a solution for this use case (of testing elements with dict IDs) using e.g. dash_duo?

anders-kiaer commented 3 years ago

Looks like this is already possible :clap: :tada:

>>> from dash.dash import stringify_id
>>> 
>>> stringify_id({"id": "some_id", "type": "some_type"})
'{"id":"some_id","type":"some_type"}'
>>> 
alexcjohnson commented 3 years ago

Ah good 😁 but might be nice if folks find this useful to document this and expose it at the top level.

anders-kiaer commented 3 years ago

I can probably create a PR on this one of the next days. Since the ID could (always in the case of dict IDs) contain CSS special characters, maybe we want at the same time to make it simple to "CSS escape" the stringified ID as well (in order to use it in the selenium wrapped By.id functions in e.g. dash_duo).