Created
August 18, 2024 12:57
-
-
Save toolittlecakes/8642d52f7737a2a03695afa89331f3ae to your computer and use it in GitHub Desktop.
st_local_storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# `pip install streamlit_js` | |
# See "https://discuss.streamlit.io/t/saving-data-in-local-storage-via-streamlit/28785/20" | |
import json | |
import uuid | |
from typing import Any | |
import streamlit as st | |
from streamlit_js import st_js, st_js_blocking | |
class StLocalStorage: | |
"""An Dict-like wrapper around browser local storage. | |
Values are stored JSON encoded.""" | |
def __init__(self, prefix: str = "") -> None: | |
self._keys = {} | |
self._prefix = prefix | |
def __getitem__(self, key: str) -> Any: | |
code = f""" | |
return JSON.parse(localStorage.getItem('{self._prefix + key}')); | |
""" | |
id = f"get_{key}" | |
if id not in self._keys: | |
self._keys[id] = str(uuid.uuid4()) | |
result = st_js_blocking(code, key=self._keys[id]) | |
return json.loads(result) if result else None | |
def __setitem__(self, key: str, value: Any) -> None: | |
print("set", key, value) | |
value = json.dumps(value, ensure_ascii=False) | |
code = ( | |
f"localStorage.setItem('{self._prefix + key}', JSON.stringify('{value}'));" | |
) | |
st_js(code) | |
# getitem has to refresh the value | |
get_id = f"get_{key}" | |
if get_id in self._keys: | |
del self._keys[get_id] | |
def __delitem__(self, key: str) -> None: | |
code = f"localStorage.removeItem('{self._prefix + key}');" | |
st_js_blocking(code) | |
# getitem has to refresh the value | |
get_id = f"get_{key}" | |
if get_id in self._keys: | |
del self._keys[get_id] | |
def __contains__(self, key: str) -> bool: | |
val = self.__getitem__(key) | |
return bool(val) | |
ss = st.session_state | |
if __name__ == "__main__": | |
st.title("st_local_storage basic example") | |
"Any values you save will be available after leaving / refreshing the tab" | |
if "ls" not in ss: | |
ss.ls = StLocalStorage() | |
if "key" not in ss: | |
ss.key = ss.ls["key"] | |
ss._key = ss.key | |
st.text_input("Key", key="_key") | |
if ss._key != ss.key: | |
# Order matters here, the condition should remain the same until js code finishes | |
ss.ls["key"] = ss._key | |
ss.key = ss._key | |
# if the key is changed, the value should be refreshed | |
if "value" in ss: | |
del ss["value"] | |
if not ss.key: | |
st.stop() | |
# Same shit as before, but ss.key instead of "key" | |
if f"value" not in ss: | |
ss.value = ss.ls[ss.key] | |
ss._value = ss.value | |
st.text_input("Value", key="_value") | |
if ss._value != ss.value: | |
ss.ls[ss.key] = ss._value | |
ss.value = ss._value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment