So, we render streamlit apps in an iFrame inside our main application with a communication bridge using post-robot. Our SDK is declared as custom components so we can use it to invoke different methods. And we need to find a sure fire way to differentiate between renders due to resizing and actual backend code re-execution so our API methods can skip such re-renders without complete memoization for every re-render.
Now the problem is that:
- Even resizing the sidebar triggers a
streamlit:render
event with no way of distinguishing between a resize or call being made from the backend.
We’ve tried:
- Looking for differences in the event object, found none.
- Checking if our event.detail.args.params keyword param (dict from the backend) is the same object reference but it’s new every time.
- Passing an ever changing call_id param down from python wrapper (component function) to track changes (hoping to detect a backend event vs resize) but this causes an infinite loop.
Present workaround is to:
- Do deep equality check on params+key and not re-trigger if the params+key remain the same. Meaning the developers would need to change the key/param in order to execute the same method again. Example:
if st.button("View details"):
desktop.open(OpenParams(records=Entity(**entity_dict)))
If a user presses the button multiple times, multiple tabs won’t open. But they will open if they interact with something else in between (desktop.open is un-mounted). And if we don’t do this equality check based memoization then they’ll get a new tab even upon resizing the window depending on what they interacted with before. This makes the app behaviour very non deterministic.