Show and Tell - Server Side Caching

I haven’t tested it, but i believe so. As I understand, they are just “normal” pattern matching callbacks. However it does not work with the new decorator that omits the app object.

Thank you for the reply. The new @callback is what I was referring to and your reply confirms my observation.

Any plan to make it work for the new @callback? or is it even possible to make it work when an dash AIO component has no knowledge of app object and in the meantime flask_caching is coupled with an app object?

I believe it should be possible, I already have a few ideas on how to address it.

ive pip installed and it did not work any idea?
ModuleNotFoundError: No module named ‘dash_extensions.enrich’

What OS, dash and dash-extensions versions are you using?

1 Like

Hello @Emil,

Still getting a lot of use out of your dash-extensions package so thanks again!

I had a question in regards to dash-labs and the latest syntax with dash-extensions. I was trying out the new /pages feature with one of my apps that utilizes dash-extensions. I was having issues getting any of my callbacks to run (both normal and serverside), and so I updated dash-extensions package and checked the latest documentation. I think it might be tied to some changes in dash-extensions’ syntax. My imports used to look like this:

from dash_extensions.enrich import ( 
    Dash,
    ServersideOutput,
    Output,
    Input,
    State,
    FileSystemStore,
)

However, referencing your repo, it looks like I should just be importing ServersideOutputTransform() and DashProxy. This resulted in two issues for me:

  1. I can no longer set the output_defaults when using DashProxy as the parameter is not recognized. Is there still a way to modify the backend and session_check parameters?
  2. Even after passing ServersideOutputTransform() to the transforms keyword argument, using ServersideOutput in my callbacks results in a NameError: name 'ServersideOutput' is not defined. I’m not sure what I’m missing here as ServersideOutput is still used in the documentation.

I’m assuming this is all tied to the fact that the documentation no longer shows the output, input, or state custom objects. Is there a new way to register the callbacks on the Dash app object? Either way, so far, I’ve had no luck getting the dash-extensions’ callbacks to run when trying to use the new /pages feature.

Thanks again for supporting this package, any help/guidance is appreciated!

@bigmike Could you post a minimal example demonstrating what is is that isn’t working? I have recently update dash-extensions to support the Dash 2 syntax, so that is expected to work. However, I haven’t played around with the pages feature of dash-labs, so I can’t say if that introduces some incompability.

I went ahead and slightly modified the /pages example to try and highlight the issue.
app.py:

from dash_extensions.enrich import ( 
    Dash,
    FileSystemStore,
)
import dash
import dash_bootstrap_components as dbc
import dash_labs as dl


# Setup file caching
fss = FileSystemStore(cache_dir="cache")
output_defaults = dict(
    backend=fss, session_check=False
)  # Turned off session check in order to share global data

# App Instance
app = Dash(
    __name__,
    plugins=[dl.plugins.pages],
    external_stylesheets=[dbc.themes.BOOTSTRAP],
    output_defaults=output_defaults,
)

navbar = dbc.NavbarSimple(
    dbc.DropdownMenu(
        [
            dbc.DropdownMenuItem(page["name"], href=page["path"])
            for page in dash.page_registry.values()
            if page["module"] != "pages.not_found_404"
        ],
        nav=True,
        label="More Pages",
    ),
    brand="Multi Page App Plugin Demo",
    color="primary",
    dark=True,
    className="mb-2",
)

app.layout = dbc.Container(
    [
        navbar,
        dl.plugins.page_container,
    ],
    fluid=True,
)

if __name__ == "__main__":
    app.run_server(debug=True, host="0.0.0.0")

The home page shown below uses the dash-extensions callback and results in a 404 error. This can be fixed by commenting out from app import app and adding from dash import callback then using the @callback syntax. However, the serverside outputs will no longer work correctly once you do this. The resulting error when using a serverside output is that the object returned is not “JSON serializable” . I assume this is because dash-extensions is no longer taking care of the serialization and the callback is trying to return the entire object to the browser instead of just the key.

pages/home.py:

from dash_extensions.enrich import (
    Output,
    Input,
)
import dash

dash.register_page(__name__, path="/")
from app import app
from dash import dcc, html
import plotly.express as px

df = px.data.medals_wide(indexed=True)

layout = html.Div(
    [
        html.H1("Dash Extensions:"),
        dcc.Checklist(
            id="heatmaps-medals",
            options=[{"label": x, "value": x} for x in df.columns],
            value=df.columns.tolist(),
        ),
        dcc.Graph(id="heatmaps-graph"),
    ]
)


@app.callback(Output("heatmaps-graph", "figure"), Input("heatmaps-medals", "value"))
def filter_heatmap(cols):
    fig = px.imshow(df[cols])
    return fig

This is the standard dash syntax that works without issue.

standard.py

import dash

dash.register_page(__name__, path="/test")

from dash import dcc, html, Output, Input, callback
import plotly.express as px

df = px.data.medals_wide(indexed=True)

layout = html.Div(
    [
        html.H1("Standard Dash Library"),
        dcc.Checklist(
            id="heatmaps-medals",
            options=[{"label": x, "value": x} for x in df.columns],
            value=df.columns.tolist(),
        ),
        dcc.Graph(id="heatmaps-graph2"),
    ]
)


@callback(Output("heatmaps-graph2", "figure"), Input("heatmaps-medals", "value"))
def filter_heatmap(cols):
    return px.imshow(df[cols])

Hello all,
I have a simple question for the usage of ServersideOutput.
Is it necessary to convert all instances of Input, Output, State in an Dash app from dash.dependencies to dash_extensions.enrich to enable ServersideOutput?
I am using DashProxy object to initiate the app and using ServersideOutput in 1 out of 40 callbacks.

from dash_extensions.enrich import DashProxy, ServersideOutputTransform
app = DashProxy(
    transforms=[
        ServersideOutputTransform(backend=fss),  # enable use of ServersideOutput objects
    ],
    external_stylesheets=[dbc.themes.BOOTSTRAP],
)

I am facing some errors when deploying Dash docker to Azure App Service and eliminating all possible root causes.
Thank you!

Hey everyone,

Does anyone know if it is possible to ignore certain arguments when using memoization? It appears this should be possible as flask caching has an “args_to_ignore” parameter but I’m unsure where to include this parameter in the callback.

Thanks in advance for any help!

Hi @Emil

Thanks for the sample code a couple of years ago,

How do i install dash_extensions in pycharm. New to python and not able to figure this out but it seems that this would be greatly helpful.

Sorry, if the question is already answered. Please direct me to the answer if already answered.

You can just use pip like with other packages :slight_smile:

Hi @raaja.yoga
Welcome to the community, I hope this image will help you with the installation of dash_extensions

As you can see, I clicked on the ‘terminal’ tab at the very bottom, and then I typed that pip install text to install dash-extensions

Hi @Emil,

In the documentation of ServerSideOutputTransform, you mentioned that

it is recommended to perform scheduled cleanups outside business hours

How can cleanups be scheduled? Will restarting the app cleanup the cache?

Thanks for your help!

The cleanup can be scheduled using you method of choice. It could be a cron job, and scheduled background task in Python, a task scheduled by Windows scheduler. The best choice depends on you infrastructure setup.

Sorry, can I clarify what does a cleanup entail? Deleting the files cached in the file system? How would something like that work when deployed to something like Heroku? I apologize for these questions as I’m pretty new to the idea of caching. Thanks!

If you are using a file system store, then yes it would be deleting files. On Heroku, the file system is ephemeral, so I am not sure if manual cleaning is needed at all.

Hello everyone, i’m starting in dash and i fin usefull this dcc store concept, but i’m not pretty sure how to use in my code… now i set this compenent in a div into the layout and the first callback (the tradicional callback) set and save the data here so like 10 callbacks (taditional callbacks) take the data and process this information in order to make graphs etc… but reading this article i guess that here i can find a better way in order to make faster the app execution… @Emil can you share a code, like at the beggining, explaining the method? i couldn’t find it in your git hub repo.

Thanks in advance

Yes, you can find documentation here,

1 Like

I am getting error “AttributeError: ‘Output’ object has no attribute ‘backend’”, i have used following syntax.What could be the reason

@callback(
    ServersideOutput("store-data", "data"), 
    ServersideOutput("store-data2", "data"),
    ServersideOutput("store-data3", "data", arg_check=False, session_check=False),
    Output("data_refresh", "children"),
    Output("container","children"),
    Output("client-id-store","data"),
    Input("refresh_button","n_clicks"),
    State("url","search"),
    State("client-id-store","data"),
    State("store-data", "data"),
    State("store-data2", "data"),
    State("store-data3", "data")
    , memoize=True)