Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streamlit balloons not working in callback for function decorated with fragment #9621

Open
3 of 4 tasks
happinessbaby opened this issue Oct 7, 2024 · 5 comments · May be fixed by #9981
Open
3 of 4 tasks

Streamlit balloons not working in callback for function decorated with fragment #9621

happinessbaby opened this issue Oct 7, 2024 · 5 comments · May be fixed by #9981
Labels
feature:st.balloons feature:st.fragment priority:P3 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working

Comments

@happinessbaby
Copy link

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

I wrote a test code to show balloons in the callback of a function with st.fragment decorator, but it's not showing anything. Below is my reproducible test code. In my actual code, the balloons show halfway and keep on rerunning even though the print line before the st.balloon() call is printed only once.

I'm not sure if it's expected behavior if the balloons don't work in the callback of a fragment. In the test code the balloons don't appear while in my actual code the balloons appear nonstop.

Reproducible Code Example

import streamlit as st

def callback():
    call = st.session_state.test_balloons
    if call:
        print("AAAAAAAAAAA") ## this gets printed
        st.balloons()  ## NO BALLOONS

@st.fragment   ## if I comment out st.fragment, it works
def test():
    button = st.toggle("turn on balloons", on_change=callback, value=True, key="test_balloons")
    # if button: <- These lines work if I uncomment them
    #     st.balloons()

test()

Steps To Reproduce

  1. Run the code as is, there are no balloons when you turn off the toggle then turn it back on
  2. Comment out st.fragment and it works
  3. It also works without using callback

Expected Behavior

Balloons should work in the callback of functions with st.fragment decorator

Current Behavior

No balloons appear when toggle is turned on for balloons in callback

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • Streamlit version: 1.39.0
  • Python version: 3.10
  • Operating System: Linux
  • Browser: Chrome

Additional Information

No response

@happinessbaby happinessbaby added status:needs-triage Has not been triaged by the Streamlit team type:bug Something isn't working labels Oct 7, 2024
Copy link

github-actions bot commented Oct 7, 2024

If this issue affects you, please react with a 👍 (thumbs up emoji) to the initial post.

Your feedback helps us prioritize which bugs to investigate and address first.

Visits

@lukasmasuch
Copy link
Collaborator

I tried to reproduce the issue here. But it almost seems to work as expected. Only the first interaction with the toggle does not seem to trigger the balloons. Can you share a video on how it looks for you?

@lukasmasuch lukasmasuch added status:awaiting-user-response Issue requires clarification from submitter feature:st.balloons feature:st.fragment and removed status:needs-triage Has not been triaged by the Streamlit team labels Oct 8, 2024
@happinessbaby
Copy link
Author

happinessbaby commented Oct 8, 2024

okay, that's strange, because for me it's showing nothing no matter how I switch the toggle. I noticed for your reproduction, the balloon appear even the toggle is switched off. (after you switch it on off the first time)

@lukasmasuch
Copy link
Collaborator

I was able to reproduce this issue locally. It seems that there is an issue with the interaction of fragments, balloons, and callbacks. But not sure why it doesn't work.

@lukasmasuch lukasmasuch added status:confirmed Bug has been confirmed by the Streamlit team priority:P3 and removed status:awaiting-user-response Issue requires clarification from submitter labels Oct 29, 2024
@raethlein
Copy link
Collaborator

raethlein commented Dec 9, 2024

I have looked into this and here is a workaround:

import streamlit as st

balloons_placeholder = st.empty()

def callback():
    call = st.session_state.test_balloons
    if call:
        print("AAAAAAAAAAA") ## this gets printed
        balloons_placeholder.balloons() 
    else:
        balloons_placeholder.empty()

@st.fragment   ## if I comment out st.fragment, it works
def test():
    button = st.toggle("turn on balloons", on_change=callback, value=True, key="test_balloons")

test()

Actually, it does not only affect st.balloons but all st.* commands that are executed within a fragment-registered callback. The root cause is that callbacks are executed outside of the fragment context here, where the delta path index starts from 0. Then, the fragment code is executed based on the context snapshot when the fragment was created. The balloons did not exist when the fragment where created, but instead the fragment-toggle button in this example started at index 0 as well. So the balloons are overridden by the toggle element with the same index.

The workaround here is that we have an empty element within the main app path which exists even when the fragment is created. Since we write into an existing container, the context snapshot for the fragment contains the empty-container, so the toggle button starts at index 1 and not 0. Thus, the toggle does not override the container.

The right thing to do here likely would be to run callbacks that were registered within a fragment run in the fragment context and, thereby, let it write into the fragment container. Though I hope the workaround is sufficient for now!

@raethlein raethlein linked a pull request Dec 9, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature:st.balloons feature:st.fragment priority:P3 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants