Summary
My app runs for a while and generates some_text
then displays it with st.markdown() inside a column.
There is an st.button() in the column that copies some_text
to the clipboard.
When the user clicks the button, I want some_text
copied, but I want to stop all further updates. Specifically, I don’t want some_text
to be generated again.
How do I interrupt streamlit to keep it from re-running all the code?
Steps to reproduce
Code snippet:
import streamlit as st
import pyperclip
def copy_to_clipboard(text):
pyperclip.copy(text)
st.info("Text copied to clipboard!")
some_text = "lorum ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
st.markdown(some_text)
if st.button(f"Copy to Clipboard",):
copy_to_clipboard(some_text)
If applicable, please provide the steps we should take to reproduce the error or specified behavior.
Expected behavior:
When the user clicks the button, I want some_text
copied to the clipboard, but that’s it, no other processing should run.
Actual behavior:
When the user clicks the button, some_text
is copied to the clipboard, but the page is re-rendered and all processing re-runs, taking a while to re-generated the text unnecessarily (and incurring additional expense).
Debug info
- Streamlit version: 1.23.1
- Python version: 3.10.11
- Using Conda? PipEnv? PyEnv? Pex? No
- OS version: Windows 11
- Browser version: Microsoft Edge Version 114.0.1823.51 (Official build) (64-bit)
Requirements file
streamlit
pyperclip
Links
- Link to your GitHub repo:
- Link to your deployed app:
Additional information
If needed, add any other context about the problem here.
After the button is pressed, you may use the’st.stop()’ function to halt Streamlit and stop any further code execution. This function halts the script’s execution and prevents the app from rendering further.
An updated example of your code snippet that uses’st.stop()’ is provided here:
import streamlit as st
import pyperclip
def copy_to_clipboard(text):
pyperclip.copy(text)
st.info("Text copied to clipboard!")
some_text = "lorum ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
st.markdown(some_text)
if st.button(f"Copy to Clipboard"):
copy_to_clipboard(some_text)
st.stop() # Stop further code execution
With this change, when the button is pressed, the code ‘copy_to_clipboard(some_text)’ will be run before the call to’st.stop()', which stops any further processing or rendering, is made.
Keep in mind that the program will stop updating its display and responding to user input after calling’st.stop()'. After copying the text to the clipboard, you may continue using the app by adding more code outside of the “if” section to handle other interactions or display components.
Hi @Abishek_Haththakage -
Thank you very much for the reply!
I had in fact tried st.stop(), but I saw the behavior you described and the app was essentially unusable.
Your tip prompted me to look in a different direction and I brought in session state.
Now, the first time through some_text
is generated and added to session state.
When the Copy to Clipboard button is clicked, some_text
is set to the value previously stored in session state.
It requires a bit more code, but I like the result!
Again, thanks!!
import streamlit as st
import pyperclip
from time import sleep
def copy_to_clipboard(text):
pyperclip.copy(text)
st.info("Text copied to clipboard!")
try:
some_text = st.session_state['some_text']
except KeyError:
st.write("Generating some_text...")
sleep(5)
some_text = "lorum ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
st.session_state['some_text'] = some_text
st.markdown(some_text)
if st.button(f"Copy to Clipboard"):
copy_to_clipboard(some_text)
If you want to see the app I was working on, you can check it out here:
AffordableData/Summarizer (github.com)