Hello streamlit community!
I am having trouble writing an app which controls values which are written to yaml files (and read from the same files to initialise). I believe there should be a simple solution for this. Here is a minimal example:
test.yaml
var: 0.5
the naive approach
import streamlit as st
from yaml import load, dump, Loader, Dumper
with open('test.yaml', 'r') as f:
p = load(f, Loader = Loader)
for k, v in p.items():
p[k] = st.slider(k, 0.0, 1.0, v, key = k)
with open('test.yaml', 'w') as f:
dump(p, f, Dumper = Dumper)
causes the widget to snap back to its former value every second time it is changed. I know this is expected behaviour due to the rerun upon widget change (although I still find it hard to properly wrap my head around this even after having used streamlit for a while). An almost perfect solution
import streamlit as st
from yaml import load, dump, Loader, Dumper
if not 'p' in st.session_state:
with open('test.yaml', 'r') as f:
st.session_state['p'] = load(f, Loader = Loader)
p = {}
for k, v in st.session_state['p'].items():
p[k] = st.slider(k, 0.0, 1.0, v, key = k)
with open('test.yaml', 'w') as f:
dump(p, f, Dumper = Dumper)
eliminates the snapping back and keeps the file and widget values in sync. The only problem with this solution is that my actual app has multiple pages and when I navigate to another page after changing the widget and come back the widget reloads with the initial value that is still stored in st.session_state['p']
which is not the value in the file at that point. I would need a way to pop p
from st.session_state
upon page reload or have some sort of “page session state” or keep the widget function caching over page changes for this solution to work.
I tried more complicated solutions without success by changing the order of execution of the statements with callback functions or calling st.rerun()
under some conditions. It it becomes hard to follow through the execution of this simple code to find a solution that works.
I would be grateful for any help you can provide!