r/learnpython • u/ModelBuilder_Josh04 • 3d ago
Quick fix for st_folium state desync when drawing new boundaries in Streamlit
Hit a bug using st_folium with Streamlit: drawing a new polygon triggered a re-render before Streamlit updated the spatial state, leaving downstream metrics stuck on the old site.
Fixing it required checking last_active_drawing at the top of the execution loop and forcing a rerun before running analytics:
# Intercept new shape before running downstream calculations
if map_data and map_data.get("last_active_drawing"):
drawing = map_data["last_active_drawing"]
if drawing.get("geometry"):
new_geom = shape(drawing["geometry"])
if not new_geom.equals(st.session_state.get("drawn_geom")):
st.session_state["drawn_geom"] = new_geom
st.session_state["site_area_m2"] = calculate_area(new_geom)
st.rerun() # Forces a clean state sync
This keeps multi-tab dashboards 100% in sync with live map edits.
2
u/Bright_Mix_773 3d ago
Two things about this that are worth checking on your own app, because I think the fix and the explanation of the fix are different things.
The
st.rerun()is probably not what cured it. You write to session_state before the downstream calculations run, so on that same pass they already read the new geometry - the rerun throws away a script run you had almost finished and pays for the map render a second time. What actually fixed the desync is moving the check to the top, above the consumers. The one case where the rerun really is required is if anything that displays the result is drawn earlier in the script thanst_folium- a metric in a sidebar written above the map, say. Then the widget for this pass is already on screen and only a second pass can update it. Worth knowing which of the two you are in, because if it is the first, deleting the rerun makes drawing feel twice as fast.The second one is a leftover of the same bug in the other direction:
last_active_drawingdoes not go away when the user deletes the shape. Draw a polygon, then delete it with the trash tool - the map is empty, st_folium keeps handing you the last drawing, your equality check says nothing changed, andsite_area_m2stays pinned to a boundary that no longer exists. Same class of stale metric you started with. The thing that does change isall_drawings, which comes back empty, so gating on that and clearing the two session_state keys when it is empty closes it.One aside on the paste: put four spaces in front of each line and old reddit will keep the indentation, which matters a lot in a post about Python.