Check if dialog is open, and close the dialog manually

Is it possible to check whether any dialog is currently open?

My use case is this:

async def async_task(user_input):
    await asyncio.sleep(100)
    return "Result: " + user_input

user_input = st.text_input("Your input here")
if st.button("Run job"):
    @st.experimental_dialog("Received", width="small")
    def show_received_dialog():
        with st.container(border=False, height=150):
            st.write("Received: " + user_input)
    show_received_dialog()

    result = asyncio.run(async_task())

    ## sample code here
    # if st.is_dialog_open():
    #    st.close_dialog()

    @st.experimental_dialog("Completed", width="small")
    def show_completed_dialog():
        with st.container(border=False, height=150):
            st.write("Thanks for waiting!")
            st.write(result)
    show_completed_dialog()

Right now it is throwing an error that I cannot run multiple dialogues together.

I am not sure if you know when the dialog is close.
If thing the best is to add a second st.button().
You can “hide” it inside the dialog

        st.session_state.user_input = st.text_input("Enter your input:", "")
        if st.button("Run job"):
            st.session_state.dialog_step = 1

        if 'dialog_step' not in st.session_state:
            st.session_state.dialog_step = 0

            # Dialog function to show the first dialog
        @st.experimental_dialog("Task Progress", width="small")
        def show_progress_dialog():
            st.write("Received: " + st.session_state.user_input)
            if st.button("Next"):
                st.session_state.dialog_step = 2
                st.rerun()

        # Dialog function to show the second dialog
        @st.experimental_dialog("Task Progress", width="small")
        def show_progress_dialog2():
            st.write("⏳ Thanks for waiting!")
            if st.button("Close"):
                st.session_state.dialog_step = 3  # Or reset to 1 if you want to start over
                st.rerun()
        # Show dialogs based on the current step
        if st.session_state.dialog_step == 1:
            show_progress_dialog()
        elif st.session_state.dialog_step == 2:
            show_progress_dialog2()


Thanks for the solution, but I’m not too sure where the async task will fall in here. If I place it within “Next”, it will not trigger if the user exits the dialog without clicking next.
If I place it before the “Next” button, it will run and wait for the task to complete, before “Next” can be clicked.
In fact, the users should not need to click a “Next” button as I intend it to be a notification, not a step to be completed.

The reason why I want to make it a dialog is because a st.toast is too small and easily missed by my users, and they will ask me “why is it not running?”

Few solution here, you can make a spinner, we see it’s loading. There is some nice spinner you can add :
(GitHub - andfanilo/streamlit-lottie: Streamlit component to render Lottie animations by @andfanilo)

I am not sure a double pop-up windows to notice the user is the best approach.

        import asyncio

        async def async_task(user_input):
            await asyncio.sleep(10)
            return "Result: " + user_input

        user_input = st.text_input("Your input here")
        if st.button("Run job"):
            with st.spinner('Loading...'):
                result = asyncio.run(async_task(user_input))
            st.write(result)

with lottie_spinner

 import asyncio
        def load_lottiefile(filepath: str):
            with open(filepath, "r") as f:
                return json.load(f)

        lottie_path = r'PATHTOJSON.json'
        self.lottie_spinner = load_lottiefile(lottie_path)

        async def async_task(user_input):
            await asyncio.sleep(10)
            return "Result: " + user_input

        user_input = st.text_input("Your input here")
        if st.button("Run job"):
            with st_lottie_spinner(self.lottie_spinner, key=f"spinner", height=100):
                result = asyncio.run(async_task(user_input))
            st.write(result)

Hi @Faltawer, thanks for the reply.

At first, I have already a st.progress() running, and also have tried using stqdm as well. The issue is that my page is quite long, and the user won’t really scroll to the progress bar portion.

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