Add support for internationalization of multilingual figures
@T4rk1n ci sta già lavorando.
Dal 8/7/2024.
- Lingua principale
- Python
- Stelle
- 18.8k
- Fork
- 2.8k
- Merge medio
- 16h 26m
- PR unite (30g)
- 21
Descrizione
Hello! This feature request comes from a project that uses Dash, but the problems/changes are in plotly modules so I opened the ticket here.
Context: The goal is to render a dashboard with various figures (graphs and maps) in different languages. At the moment, it is required to build 4 Dash layouts to serve 4 languages, making development less convenient (can’t use standard translation tools) and requiring 4 times the memory for hosting (this was profiled). I am not the author of the project, but for a hackathon I looked at using the Flask i18n extension, and found out that Dash is not directly compatible; then after finding a compat trick, I found out that it wasn‘t enough.
Details:
This is a Dash app https://github.com/jeremymoreau/covid19mtl/blob/master/app/__init__.py viewable at https://covid19mtl.ca/en . (It’s not using latest plotly or dash for stability or familiarity I suppose.)
1) I looked for Flask i18n guides and tried to add Flask-i18n which uses a classic gettext approach with a LazyString class that is rendered to a localized string at request time.
LazyString was rejected during JSON encoding. I looked at this method https://github.com/plotly/plotly.py/blob/v4.6.0/packages/python/plotly/_plotly_utils/utils.py#L100 which led me to define as_plotly_json https://github.com/jeremymoreau/covid19mtl/pull/21/files#diff-828aeb2697b4cf1e4ba7120b38810cccR5-R9 to be compatible, and it worked for Dash HTML components (example https://github.com/jeremymoreau/covid19mtl/pull/21/files#diff-4599052b1ffcd344c72d72ce59a64186R399 — this is in template.py file that github hides by default even if there is a line link ☹️)
Now, how to upstream this? plotly doesn’t know about flask, but dash itself doesn’t transform to JSON, that code is in _plotly_utils and is not extensible, so I couldn’t send a quick PR. «Not extensible» I mean that a list of conversion functions is hard-coded and tried in order. Other approaches like Pyramid’s adapters or https://pypi.org/project/json-encoder/ based on single-dispatch can be extended from downstream code. But these rely on types (object class), whereas the existing approach checks for the presence of attributes (special method like tolist) or special values (pandas funky NaN and such).
Would you be open to reworking this? I think a hybrid approach could work (detect special methods like as_plotly_json or fancy scipy stack objects first, then delegate to a single-dispatched function that checks types to handle datetime, decimal, etc, and expose that function so that Dash can register a conversion function for the LazyString type.
2) The LazyString class is rejected by checks in plotly figure classes, so we can’t translate all the labels. This blocked my efforts. I didn’t try to make a str subclass because built-in classes often have shortcuts in codebases (starting with CPython itself!) so your overriden methods are not getting called when you expect and it’s a dead end. We didn’t try applying translations using JavaScript because it would require to write more gettext integration, and some of the labels are inside SVG sub-documents which wouldn’t be easy to get.
How can we satisfy plotly type checks when passing a custom class that should be transformed (i.e. call str) at render time?
Thanks for reading and considering this! I am sure more than one person would like to make multilingual plots and dashboards, so it would be great if I could contribute some useful code upstream.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Valutazione
Questa issue non è ancora stata valutata.