We need to use two @st.dialog modals: Confirmation Dialog – Asks for confirmation before an action. Success Dialog – Shows details after the action is completed.
Since Streamlit allows only one dialog at a time, the success dialog does not appear after confirming the first one. We track modal states using st.session_state and call st.rerun(), but the second dialog doesn’t always show.
Questions:
How can we handle multiple dialogs efficiently?
Can we define one dialog in a separate file and call it after the first one closes?
Any best practices to avoid session state conflicts?
" We track modal states using st.session_state and call st.rerun()" looks like the right and efficient thing to do. “[B]ut the second dialog doesn’t always show” hints at a bug in your code, not any inefficiencies.
Yes and yes.
What are session state conflicts?
Anyway, for the case you are describing, you just need to track in session_state the need to show the details. Easy peasy.
@st.dialog(title="Destroy the universe")
def confirm():
st.write("You are about to destroy the universe.")
if st.button("Proceed"):
st.session_state.must_show_details = True
st.rerun()
@st.dialog(title="Details")
def show_details():
st.write("The universe has been destroyed.")
if st.button("Destroy the universe"):
confirm()
if st.session_state.get("must_show_details", False):
st.session_state.must_show_details = False
show_details()
Did it work for your code snippet you have sent here?
I tried implementing confirmation and success dialogs in my Streamlit app, but I’m running into this error:
line 69, in _assert_first_dialog_to_be_opened
raise StreamlitAPIException(
streamlit.errors.StreamlitAPIException: Only one dialog is allowed to be opened at the same time. Please make sure to not call a dialog-decorated function more than once in a script run.
The logic I followed:
A confirmation dialog asks the user to confirm changes before running a pipeline.
If confirmed, the job runs, and a success dialog should appear afterward.
The success modal should only open after rerun to avoid conflicts.
Here simplified version of my implementation
def show_confirm_modal():
"""Displays a confirmation modal before execution."""
st.warning("You have unsaved changes. Do you want to proceed?")
if st.button("Yes, Run Pipeline"):
st.session_state["show_confirm_modal"] = False
st.session_state["success_details"] = st.session_state["on_confirm"]()
st.session_state["open_success_modal_next"] = True # Flag for success modal
st.rerun()
if st.button("Cancel"):
st.session_state["show_confirm_modal"] = False
st.session_state["on_cancel"]()
st.rerun()
@st.dialog("Success")
def show_success_modal(details):
"""Displays a success message after job execution."""
st.markdown(f"Pipeline executed successfully: {details.get('pipeline_name', 'N/A')}")
if st.button("Close"):
st.session_state["dialog_type"] = None
st.rerun()
if run_job:
if changes_detected:
st.session_state["show_confirm_modal"] = True
st.rerun()
else:
st.session_state["success_details"] = self._execute_job(pipeline_name)
st.session_state["show_success_modal"] = True
st.rerun()
# Open modals at the right time
if st.session_state.get("show_confirm_modal", False):
show_confirm_modal()
if st.session_state.get("open_success_modal_next", False):
show_success_modal(st.session_state.get("success_details", {}))
st.session_state["open_success_modal_next"] = False # Reset flag
Issue:
The success dialog does show up after confirming the pipeline execution but with error I posted above
The error occurs when both dialogs seem to be triggered in the same script run.
Since Streamlit reruns the script from top to bottom, how can I properly handle the transition between these two dialogs without violating the “one dialog at a time” rule?
Your whole implementation has even more undefined names. After I defined them in the simplest possible way, I found that, sometimes, the success dialog is shown after you close the confirmation dialog using the cancel button. This happens because you do not set st.session_state.display_success to False.
I couldn’t trigger any “Only one dialog is allowed to be opened at the same time” errors.
From the confirmation dialog (show_confirm_modal()), when we click Yes, I set the st.session_state.must_show_success = Trueand do the rerun to run the script
To call the success dialog which is my 2nd dialog, calling via below snippet.
if st.session_state.get("must_show_success", False):
st.session_state.must_show_success = False
show_success_modal()
So as per the logic seems to fine but when I run the script. I am getting the error of one dialog should be run in a script rule
The code seems to be working now (again, after filling in the missing parts).
What are the missing parts you mentioned is not understandable.