Could PyScript be used as dash clientside callback instead of javascript?

PyScript has been just released recently here. Could it be used instead of javascript as a dash clientside callback?

I am showing here an example of clientside callback using javascript where it changes the yaxis’ scale from linear to log scale.
This function has one Output (plotly graph as dcc.Graph) and two Inputs (dcc.Store and dcc.RadioItems).
I know how to write a similar clientside function in PyScript. However, I don’t know how to use those dash components as Output and Inputs!

To implement PyScript in html, I usually add the tag <pyscript> then I can insert my function. But how could I implement this through dash clientside function and how to use dash components as Output and Inputs?

I greatly appreciate if someone can simply show me how to replace the javascript clientside callback in this example below to PyScript clientside callback. Thanks in advance!

from dash import Dash, dcc, html, Input, Output
import pandas as pd

import json

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = Dash(__name__, external_stylesheets=external_stylesheets)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')

available_countries = df['country'].unique()

app.layout = html.Div([
    dcc.Graph(
        id='clientside-graph'
    ),
    dcc.Store(
        id='clientside-figure-store',
        data=[{
            'x': df[df['country'] == 'Canada']['year'],
            'y': df[df['country'] == 'Canada']['pop']
        }]
    ),
    'Indicator',
    dcc.Dropdown(
        {'pop' : 'Population', 'lifeExp': 'Life Expectancy', 'gdpPercap': 'GDP per Capita'},
        'pop',
        id='clientside-graph-indicator'
    ),
    'Country',
    dcc.Dropdown(available_countries, 'Canada', id='clientside-graph-country'),
    'Graph scale',
    dcc.RadioItems(
        ['linear', 'log'],
        'linear',
        id='clientside-graph-scale'
    ),
    html.Hr(),
    html.Details([
        html.Summary('Contents of figure storage'),
        dcc.Markdown(
            id='clientside-figure-json'
        )
    ])
])


@app.callback(
    Output('clientside-figure-store', 'data'),
    Input('clientside-graph-indicator', 'value'),
    Input('clientside-graph-country', 'value')
)
def update_store_data(indicator, country):
    dff = df[df['country'] == country]
    return [{
        'x': dff['year'],
        'y': dff[indicator],
        'mode': 'markers'
    }]

## Clientside Callback
app.clientside_callback(
    """
    function(data, scale) {
        return {
            'data': data,
            'layout': {
                 'yaxis': {'type': scale}
             }
        }
    }
    """,
    Output('clientside-graph', 'figure'),
    Input('clientside-figure-store', 'data'),
    Input('clientside-graph-scale', 'value')
)


def update_graph_scale(data, scale):
    return {
        'data': data,
        'layout': {
            'yaxis': {'type': scale}
        }
    }




@app.callback(
    Output('clientside-figure-json', 'children'),
    Input('clientside-figure-store', 'data')
)
def generated_figure_json(data):
    return '```\n'+json.dumps(data, indent=2)+'\n```'


if __name__ == '__main__':
    app.run_server(debug=True)

1 Like

I am wondering why this question/topic didn’t grap much attention so far!
Am I missing something here?
I think it would be really valuable if we can write a clientside function in PyScript instead of javascript, especially for people who have in-depth knowledge in python but not in JS, right?

Hi @tmoussa ,
with Pyscript it’s probably not possible. However, if we find a way to use pyodide instead, we’ll update this post.

Thanks @adamschroeder for the response. Will be waiting.