I have been trying out DiskCache. It is very, very promising. As I can get the cache is working between sessions and on (--dev
) restarts. It also support a lot of advanced caching strategies like expiration.
And it’s simple to use. And it could be even simpler if I could get the @cache.memoize annotation to work. See memoize not working in Panel.
Video
Code
import time
import numpy as np
import pandas as pd
import panel as pn
import param
from diskcache import FanoutCache
pn.config.sizing_mode = "stretch_width"
EXPIRE = 5 * 60 # 5 minutes
CACHE_DIRECTORY = "cache"
cache = FanoutCache(directory=CACHE_DIRECTORY)
# pn.state.cache["cache"]=cache # Maybe I should cache the cache or something?
# restart
def _get_data(value):
value_str = str(value)
if value_str in cache:
return cache[value_str]
else:
print("loading data", value)
time.sleep(1)
df = pd.DataFrame(np.random.randint(0, 100, size=(100, 4)), columns=list("ABCD"))
cache[value_str] = df
print("data loaded")
return df
class MyApp(param.Parameterized):
value = param.Integer(default=0, bounds=(0, 10))
data = param.Integer()
clear_cache = param.Action()
def __init__(self, **params):
super().__init__(**params)
self.data_panel = pn.pane.Str()
self.loading_spinner = pn.widgets.indicators.LoadingSpinner(
width=25, height=25, sizing_mode="fixed"
)
self.clear_cache = self._clear_cache
self.view = pn.Column(
self.loading_spinner,
self.param.value,
self.data_panel,
self.param.clear_cache,
max_width=500,
)
self._update_data()
@param.depends("value", watch=True)
def _update_data(self):
self.loading_spinner.value = True
self.data_panel.object = f"Data: {_get_data(self.value)}"
self.loading_spinner.value = False
def _clear_cache(self, *events):
cache.clear()
if __name__.startswith("bokeh"):
MyApp().view.servable()
```