Control parametrized classes with existing widgets

I have the following pseudocode that I’m trying to improve:

# define global (sidebar) inputs
start_date = pn.widgets.DatePicker()
end_date = pn.widgets.DatePicker()
filter_col = pn.widgets.Select()
filter_values = pn.widgets.MultiSelect()

# create template and add global inputs that all get_data + render_data use
template = pn.template.BootstrapTemplate(
    title="My Dashboard",
    sidebar=[start_date, end_date, filter_col, filter_values],
)

# define 1 (of many) get_data + render_data pairs
# this one has an additional specific input
get_data1_specific_input = pn.widgets.Number()

@pn.depends(start_date, end_date, filter_col, get_data1_specific_input)
def get_data1(foo):
    ... # slow expensive database fetch

@pn.depends(filter_values)
def render_data1():
    # not sure... do i put get_data() here? 
    # this is where my paradigm breaks down and I'm looking for suggestions
    # I don't want to do expensive data fetch many times. 
    # I've thought about caching the datafetch... but I'd rather only call 
    # get_data when I NEED to update the dataframe instead of using caching everywhere.. 

    df = get_data()
    df_filtered = df[df[filter_col].isin(filter_vals)]  # <-- this filtering doesn't need new data fetch
    return df_filtered.hvplot(...)

template.main.append(pn.Card(
    render_data1,
    ...
    render_data_n,
))
template.servable()

I’ve gone down several rabbit holes here, and I have several thoughts/questions:

  • Whenever get_data1 is called, render_data1 must also be called. Not sure how to link them properly in a way that allows render_data1 to run without fetching data again, but render_data1 will always cause get_data1 to be run.
  • There are many pairs of get_data_n and render_data_n I’d like my code to be more dry
    • I thought I could create some sort of parametrized class that is controlled by the global widgets, but I ended up with an extremely verbose non-DRY pattern where I called widget.link(class, value=parameter) for all parameters in the class that I didn’t like at all.
    • Would custom components be helpful?
  • The whole file is layed out with only functions, should I try to make some massive class that is the dashboard? This is appealing to me because I will have many of these apps, but I got lost in the sauce when I started making a class-based app, so any examples would be helpful.

All the tutorials seem to be focused on pretty small scoped examples, so I’m really hoping for some link where someone has got something a bit beefier so I can see what “opinionated panel programming” looks like. There are just so many ways to tie things together and so many indecipherable dead ends that I’m feeling a bit lost. Any sense of direction that people could provide would be super helpful.

thank you all very much.

Great info in this post!!

1 Like