Cached-to-file variable lag

:wave: howdy, team!

I want to run Streamlit where text inputs’ content caches to file. This experiences a lag by-one update problem similar to this historical issue. Expanding, the file content lagging oscillating resets the value inducing data concerns.

Minimum reproducible example:

import streamlit as st 

with open("tmp", "r+") as f:
	value = f.read()

st.write('original value or from file:')
st.write(value)
value = st.text_input('change value:', value)
st.write(value)

with open("tmp", "w+") as f:
	f.write(value)

Timeline:

  • start file, input text, and value all 0
  • update input text 1 > value and file both 1
  • update input text 2 > value 2 but file 1
  • update input text 3 > value 2 and file 2
  • update input text 3 > value 3 but file 2
  • update input text 3 > value and file both 3

Had expected value and file to remain synchronized. Or at least input text to not reset. Also noting if you run R between editing input text, problem goes away.

Video uploaded here in Youtube. First half of video demonstrates issue. Second half shows difference in browser element focus which appears to relate to oscillating change in functionality which is only speculation on related play in.

I assume the community does this ballpark (although different to my implementation to avoid this issue) but am having trouble knowing what to search to pivot. Kindly share a working example or link previous.

Locally deployed

$ streamlit --version
Streamlit, version 1.37.1
$ python3 --version
Python 3.12.3
$ pip3 --version
pip 24.2 from /opt/homebrew/lib/python3.12/site-packages/pip (python 3.12)

Hey @asdf31415 ! Thanks for the issue and welcome back!

Yes this would be impacted by the off-by-one issue you found. Part of the main problem is that you are changing the arguments to st.text_input. Streamlit uses the arguments as the “identity” of a widget. Change the arguments, and Streamlit will interpret it differently.

import streamlit as st 
import os

if os.path.exists("tmp.txt"):
    with open("tmp.txt", "r+") as f:
        st.session_state.value = f.read()
else:
    with open("tmp.txt", "w+") as f:
        f.write("")
    
    st.session_state.value = ""

st.write('original value or from file:')
st.write(st.session_state.value)

def handle_change():
    with open("tmp.txt", "w+") as f:
        f.write(st.session_state.value)

value = st.text_input('change value:', "", key="value", on_change=handle_change)
st.write(value)

Note I made the code self-running and added some things, but instead of having the file written when the script finishes, write the file when a change happens on the text input.

Hope that helps!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.