Hi,
Is there any example where I can store independent cache for each user session?
I want to locally store some objects so that when user refreshes the browser those unique settings load without having to ask the user for inputs again.
Hi,
Is there any example where I can store independent cache for each user session?
I want to locally store some objects so that when user refreshes the browser those unique settings load without having to ask the user for inputs again.
Hi @jitz
Great question. My understanding is that the scope of a user session ends when the user refreshes or reloads. So I read this as you are asking about storing user settings.
Any variable defined in the .py
or .ipynb
file you panel serve
is saved and available for the user session. It gone when the session ends, i.e. when the user closes the browser or reloads the page.
In javascript you can save to local storage in the users browser. Panel has no mechanism to store to local storage, but if I can build one using ReactiveHTML
I will add it as an example below.
If you somehow can get an unique id key
representing your user, you can store the information value
in pn.state.cache
via pn.state.cache[key]=value
.
One way to get a unique id is to generate one and store it in the Local Storage or as a cookie. Then you can either store things to the browsers local storage or on the server side.
Here is an example. Its only the beginning of an implementation. The challenge is that the localstorage
is not available before the page has loaded.
import uuid
import panel as pn
import param
import uuid
pn.extension(sizing_mode="stretch_width", template="fast")
pn.state.template.param.update(site="Awesome Panel", title="How do I store user settings across reloads?")
class LocalStorage(pn.reactive.ReactiveHTML):
value = param.Dict(default=None, allow_None=True)
_template = """<div id="local-storage" style="display:hidden"></div>"""
_scripts = {
"render": """
if (data.value===null){
data.value = JSON.parse(window.localStorage.getItem(model.name));
} else {
window.localStorage.setItem(model.name, JSON.stringify(data.value));
}
""",
"value": """
if (data.value===null){
window.localStorage.removeItem(model.name);
} else {
window.localStorage.setItem(model.name, JSON.stringify(data.value));
}
"""
}
def clear(self, event=None):
self.value = None
def update(self, event=None):
self.param.trigger("value")
# Use name as the "key" for localStorage in the browser
storage = LocalStorage(name="my-value")
clear = pn.widgets.Button(name="Clear Local Storage", button_type="primary")
clear.on_click(storage.clear)
update = pn.widgets.Button(name="Update Local Storage", button_type="primary")
update.on_click(storage.update)
pn.Column(
"""You can use the browsers `Local Storage`. Here is an example.""",
storage,
storage.param.value,
clear, update
).servable()
def get_local_storage():
print("local storage", storage.value)
# The local storage value is not available before the app has loaded
pn.state.add_periodic_callback(get_local_storage, period=1000, count=1)
Feel free to open requests on github for getting and setting localstorage as well as cookies.
Definitely worth exploring local storage. In various applications where this was required we usually added an auth provider and then cached data to a database keyed of the authenticated user but that definitely requires a bit more setup.
@Marc Thank you!
I used the storage on server option you recommended. I was able to pickle some of the python object and store them in cache using a unique key. So, now on reload the object would unpickle and load directly on the page.
I also tried to pickle entire panel object but it dint really work. My aim was to be able to reload the state of the panel as it was when the reload happened.