en en en en de en en en en en en en en en en es en en en en es es es en en es en es es de es en es en es en es es en es zh es es zh es es es en es es es es es es es en es es en en en en en en en en en en es es es es en es es es en es es es es en es es es es es es es es en es es es es en en en en en en en en en en en en
My problem is that I have huge callbacks and I don’t have knowledge about JavaScript , so at the moment it’s so difficult for me to apply the conversion.
I was wondering if someone could convert one of my app callbacks and then I will try to convert the rest taking that one as reference:
@app.callback( dash.dependencies.Output('figures_container', 'children'), [dash.dependencies.Input('version1_dropdown', 'value'), dash.dependencies.Input('version2_dropdown', 'value'), dash.dependencies.Input('lang_dropdown', 'value')]) def version_figures(value1, value2, lang_value): if(lang_value is None or value1 is None or value2 is None): return dash.no_update else: versions_stats = R.versions_stats if lang_value == 'Spanish': if value1 == 'Oct 1st 2016': entities_version1 = versions_stats[0] df1 = R.instance_types_es_2016_10_01 if value1 == 'Oct 1st 2020': entities_version1 = versions_stats[18] df1 = R.instance_types_es_2020_10_01 if value1 == 'May 1st 2021': entities_version1 = versions_stats[36] df1 = R.instance_types_es_2021_05_01 if value1 == 'June 1st 2021': entities_version1 = versions_stats[54] df1 = R.instance_types_es_2021_06_01 if value2 == 'Oct 1st 2016': entities_version2 = versions_stats[0] df2 = R.instance_types_es_2016_10_01 if value2 == 'Oct 1st 2020': entities_version2 = versions_stats[18] df2 = R.instance_types_es_2020_10_01 if value2 == 'May 1st 2021': entities_version2 = versions_stats[36] df2 = R.instance_types_es_2021_05_01 if value2 == 'June 1st 2021': entities_version2 = versions_stats[54] df2 = R.instance_types_es_2021_06_01 if lang_value == 'English': if value1 == 'Oct 1st 2016': entities_version1 = versions_stats[72] df1 = R.instance_types_en_2016_10_01 if value1 == 'Oct 1st 2020': entities_version1 = versions_stats[90] df1 = R.instance_types_en_2020_10_01 if value1 == 'May 1st 2021': entities_version1 = versions_stats[108] df1 = R.instance_types_en_2021_05_01 if value1 == 'June 1st 2021': entities_version1 = versions_stats[126] df1 = R.instance_types_en_2021_06_01 if value2 == 'Oct 1st 2016': entities_version2 = versions_stats[72] df2 = R.instance_types_en_2016_10_01 if value2 == 'Oct 1st 2020': entities_version2 = versions_stats[90] df2 = R.instance_types_en_2020_10_01 if value2 == 'May 1st 2021': entities_version2 = versions_stats[108] df2 = R.instance_types_en_2021_05_01 if value2 == 'June 1st 2021': entities_version2 = versions_stats[126] df2 = R.instance_types_en_2021_06_01 bar_figure = F.get_version_bar_figure([value1, value2], [entities_version1, entities_version2]) pie_figure = F.get_version_pie_figure([value1, value2], [entities_version1, entities_version2]) bar_graph = dcc.Graph(id='versions_bar', figure=bar_figure, style={'height':'26.041666666666668vw', 'width':'45.572916666666664vw', 'display': 'inline-block'}) pie_graph = dcc.Graph(id='versions_pie', figure=pie_figure, style={'height':'19.53125vw', 'width':'45.572916666666664vw', 'display': 'inline-block'}) title = html.H3(value1 + " VS " + value2) type_title = html.H3("DBpedia types comparison") types_container = html.Div([ dcc.Graph(id='ontology_version', figure=F.ontology_figure, style={'height':'26.041666666666668vw', 'width':'39.0625vw', 'display': 'inline-block'}), dcc.Graph(id='instance_types_version', figure=F.get_versions_instance_types_figure([value1, value2], df1, df2), style={'height':'26.041666666666668vw', 'width':'45.572916666666664vw', 'display': 'inline-block'}) ] ) return title, html.Br(), bar_graph, pie_graph, html.Hr(), type_title, types_container
As you can see, this callback takes items ( dataframes , lists , figures …) from other local modules ( R , F …). I don’t know if it is possible to convert callbacks in this context.
Hope you can help me. Thanks in advance.
Eduardo August 14, 2021, 5:24pm #2
No estoy seguro, pero quizás lo que puede servirte es usar server side callback, que ejecuta el programa del lado del servidor mejorando el tiempo de respuesta ya que comparte la información sin enviar información desde o hacia el cliente y es fácil de implementar porque solo hay que cambiar la forma en que es llamado el decorador de inputs y outputs, acá hay un link con interesante discusión sobre sus ventajas, espero te sirva:
Show and Tell - Server Side Caching Dash
krakken August 14, 2021, 6:12pm #3
Muchas gracias por la respuesta.
Parece que han actualizado la sintaxis, lo he probado pero no me funciona:
Based on inputs from @np8 and @chriddyp, i have come up with a new syntax (available in dash-extensions 0.0.28). The performance should be the same, but the syntax is simpler (at least that is the intention). Here is the benchmark example using the new syntax, import datetime import dash_core_components as dcc import dash_html_components as html import numpy as np import pandas as pd from dash_extensions.enrich import Dash, ServersideOutput, Output, Input, State, Trigger # Drop down options. …
No sé si serías capaz de mandarme un ejemplo comparativo de un callback “normal” vs un server-side callback.
Eduardo August 14, 2021, 11:10pm #4
La version que yo uso es esta:
tenes que importar la biblioteca que además del server side callback:
from dash_extensions.enrich import DashProxy, Output, Input, Trigger,ServersideOutputTransform, ServersideOutput, State
trae una distinta forma de “app =” en lugar del tradicional:
app = DashProxy(__name__, transforms=[ServersideOutputTransform()])
Esto no altera en nada la ejecucion del codigo que estes usando.
Agregar un dcc.Store que guardara la información a intercambiar entre los callback del lado del servidor:
El decorador del calback va a enviar la información al output que se escribe de esta manera:
@app.callback(ServersideOutput('last_ticker', 'data'), Input('input-1-submit', 'value')
Como podras ver, los inputs que alimenten al output van a ser normales.
Cuando utilizas la información guardada en el dcc.Store como input de otro callback lo haces en forma habitual:
Adicionalmente no es necesario transformar la información a json.
Con esto deberia funcionar, de todas formas @ Emil estuvo haciendo modificaciones hace poco para dividir todos los componentes que tiene en el mismo paquete (enrichments), Dash - How to implement chunked loading of custom components, podes visitar su página para ver si existen otras modificaciones, pero en mi app esta funcionando con esta version.
krakken August 14, 2021, 11:51pm #5
Muchas gracias por la respuesta.
El dcc.Store se debe agregar en la parte del layout donde se quiere tener el output?
Por ejemplo, en el callback que puse en mi pregunta, lo que se devuelve se guarda en un contenedor (div).
Con esta forma que me dices, el dcc.Store sustituiría al div? O se debe agregar aparte?
Podrías escribirme la cabecera equivalente de ese callback con este método que me comentas?
Eduardo August 15, 2021, 1:41am #6
Si, el dcc.Store es un componente como cualquier otro, va dentro del layout en cualquier lado, yo generalmente lo pongo al principio, al igual que los dcc.Interval, ya que son componentes que nunca van a mostrar nada al usuario.
Te adjunto la documentación al respecto, el dcc.Store es el mismo componente que usa Dash:
Emil August 15, 2021, 5:53am #7
@Eduardo I can see that I am tagged, but I am not sure why. I don’t speak spanish
Eduardo August 15, 2021, 7:23am #8
I left a space between the @ and Emil because I didn’t want to tagged you, just indicating him that you did changes in the enrichments module recently.
I explained how I’m using the server side callback (and the version I use) but I don’t know if you did changes after that, then I recommended him to visit your web page.
He is trying to implement the server side callback but needs an example to understand how to implement, because the link I provided in the first post is not working. The code I copied is what I’m using in my app, thanks for asking.
krakken August 15, 2021, 7:33am #9
Entiendo, así que el dcc.Store puedo agregarlo en cualquier parte del layout. Sin embargo debo mantener el contenedor (div) tal y como lo tengo ahora. Es así?
Otra cuestión: debo agregar un dcc.Store para cada callback o basta con tener 1 solo para todos los callbacks?
Eduardo August 15, 2021, 8:02am #10
dcc.Store es un componente que guarda información en memoria, en Dash esa información debe ser json, en este caso de server side no es necesario. Cada información que necesites pasar entre dos callbacks del lado del servidor sin pasar al lado del cliente debe almacenarse en un dcc.Store distinto, esa información almacenada puede usarse tantas veces como lo requieras. A su vez en la documentación podrás ver tres formas distintas de mantener la información en la memoria (local, sesion y otra que no recuerdo).
Si finalmente esa información tiene que ser mostrada en un hrml.Div o no depende de la lógica del programa, no lo puedo decir, pero para intercambiar datos entre callbacks no se necesita pasar por ningún Div.
Espero que se entienda, por lo menos se que no es un problema de idioma
krakken August 15, 2021, 8:27am #11
Creo que ya lo entiendo.
Parece que debo usar un dcc.Store como output para guardar la información de cada callback y luego ese mismo dcc.Store usarlo como input para mostrar la información actualizada.
Es decir, con este método parece que primero se debe guardar la información de los Inputs en un Store y luego ya operar con la información del Store.
Osea que si ahora utilizo 8 callbacks, con este método serían 16 callbacks. Ando mal encaminado?
Eduardo August 15, 2021, 8:59am #12
Por eso en mi primer post comente que quizás el server side callback pueda servirte (o quizás no), depende de la lógica de tu programa.
La idea no es duplicar callbacks, la idea es reemplazar todos aquellos callbacks que no envían información al usuario (no todos los callbacks del programa)
Por ejemplo, un callback realiza una serie de tareas y como resultado envía una gran cantidad de información que será utilizada luego por otro callback, en ese caso el server side callback permite que la información se transmita mucho más rápido (si lees el link que envíe en el primer post ahí explican la lógica del ahorro de tiempo)
En mi caso por ejemplo estoy tomando la información histórica de la cotización de una empresa en los últimos diez años, que luego es utilizada para hacer distintos gráficos, la guardo en el store y luego leo directamente de el y finalmente muestro los gráficos.
Si el proceso solo toma información para mostrar al cliente no es necesario cambiar a server side porque no generaría ningún ahorro de tiempo, solo los callbacks que envían información a otros callbacks deben ser cambiados (por lo tanto no habría duplicación de callbacks.
Reiteró, depende de la lógica de tu programa si esta herramienta puede ser una solución de ahorro de tiempo o no.
krakken August 15, 2021, 2:19pm #13
Lo probaré a ver qué tal.
Gracias por la ayuda.
chriddyp August 17, 2021, 5:10am #14
for the first foreign language dash thread!
schua16 April 25, 2022, 3:34am #15
Hi @Eduardo, would you mind summarising your solution in English as well as I am currently facing the same issue? Thank you!