Appending to text area using session state

I am using Python 3.11 with Streamlit 1.28.0 locally on a Mac. I am trying to append to a text_area using session_state:

import time

import streamlit as st

st.text_area("Logs", key="logs_text_area")

for i in range(4):
    st.session_state.logs_text_area += f"Log {i}"
    time.sleep(1)

When I run this, I just get:

2023-11-06 12:18:25.199 Uncaught app exception
Traceback (most recent call last):
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 534, in _run_script
    exec(code, module.__dict__)
  File "/Users/user/code/repo/web.py", line 8, in <module>
    st.session_state.logs_text_area += f"Log {i}"
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/metrics_util.py", line 396, in wrapped_func
    result = non_optional_func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/state/session_state_proxy.py", line 125, in __setattr__
    self[key] = value
    ~~~~^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/metrics_util.py", line 396, in wrapped_func
    result = non_optional_func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/state/session_state_proxy.py", line 103, in __setitem__
    get_session_state()[key] = value
    ~~~~~~~~~~~~~~~~~~~^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/state/safe_session_state.py", line 94, in __setitem__
    self._state[key] = value
    ~~~~~~~~~~~^^^^^
  File "/Users/user/code/repo/venv/lib/python3.11/site-packages/streamlit/runtime/state/session_state.py", line 457, in __setitem__
    raise StreamlitAPIException(
streamlit.errors.StreamlitAPIException: `st.session_state.logs_text_area` cannot be modified after the widget with key `logs_text_area` is instantiated.

What am I doing wrong? How can one continually append to a text_area using session_state?

Check the Caveats and Limitations section of the session state docs:

1 Like

Thanks for sharing the link!

I see this:

Modifying the value of a widget via the Session state API, after instantiating it, is not allowed and will raise a StreamlitAPIException

However, that quote doesn’t really state why that constraint was made. I feel it is reasonable to append more text to a text_area.

Is the underlying answer that appending is just unsupported?

It is unclear what effect would be intended by setting a widget’s session_state after its function has been called. The state of the widget displayed in the webapp has already been set and the function has already returned its value. If the user alters the widget’s value in the interface, this will be reflected in its session_state value at the start of the next run - presumably over-writing your attempt to set its value.

If you would like to alter the state of the widget in the webapp, the widget’s session_state value must be set before the function is called. I’m not really sure what your code is trying to achieve, so it’s difficult to suggest a solution. Are you intending to just display a log which the user cannot edit? If so, use st.text rather than st.text_area to display text rather than generate a widget for its input.

1 Like

Yeah I was trying to have a continually appended logs tab. And thanks for the suggestion to use st.text over st.text_area, it’s a good one.

I ended up going with a for loop and st.write so it wraps automatically. Looks like st.text doesn’t support wrapping long lines.

I think my error is being used to async callbacks, where one can update entities anytime from a handle. However, Streamlit doesn’t take this paradigm, it’s more about repeated re-execution of a script, instead of updating widgets after they’re printed within the same script’s execution.

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