Problem with streamlit widgets

Hi,

I have an issue with my code refreshing each time after selcting a campsite and pressing a submit the page refreshes. I have set the session state for the variables and have similar code that works without issue. I would be very grateful if anyode has any idea how to prevent this.

I have included my code below and the version of python and streamlit I am using.

The code is drawing a map using coordinates given user ip address and the user adds markers on the map. The code will then search for nearby campsites and a multiselect box is presented to confirm choice of campsites. After pressing submit the page refreshes. Thee is no error produced unfortunately.

Python version: 3.11.1
Streamlit version: 1.40.0

   # Display content based on selected option
    if option == "My Toolbox":
        st.sidebar.write("Use this option to store your camping know how.")
        st.sidebar.write("Use this option to store your camping know how. ")
        st.title("My Toolbox")
        st.write("This is the My Toolbox page.")

    elif option == "Plot a route":
        st.sidebar.write("Use this option to plot a route on a map. You can draw a route "
                         "and view all the nearby campsites for each route plot.")

        # Initialize the Streamlit app for route plotting
        st.title("Interactive Route Plotting")
        st_data = None  # Variable to store map data

        # Get the user's IP address
        #  Voketswil 'lat': 47.3895115, 'lng': 8.687449599999999}
        user_ip = requests.get('https://api.ipify.org').text

        coordinates = get_coordinates_from_ip(user_ip)

        if coordinates:
            lat, lon = coordinates
            print(f"Latitude: {lat}, Longitude: {lon}")
        else:
            print("Failed to retrieve coordinates.")

        # Create a Folium map centered at the specified location
        # Create a Folium map
        m = folium.Map(location=[lat, lon], zoom_start=13)
        # Add the Draw plugin to the map
        draw = Draw(
            draw_options={
                'polyline': True,
                'polygon': False,
                'circle': False,
                'rectangle': False,
                'marker': True,
                'circlemarker': False,
            },
            edit_options={'edit': True}
        )
        draw.add_to(m)

        # Create a container for the button and map
        container = st.container()

        # Create a column for the map
        col1 = st.columns([1])[0]

        with col1:
            # Display the map in Streamlit
            st_data = st_folium(m, width=600, height=400, use_container_width=True)

        # Button to find nearby campsites
        if st.button("Find nearby campsites"):
            # Get coordinates of the markers from the map

            # Get the coordinates of the markers
            coordinates = []
            for drawing in st_data['all_drawings']:
                if drawing['geometry']['type'] == 'Point':
                    coordinates.append(
                        (drawing['geometry']['coordinates'][1], drawing['geometry']['coordinates'][0]))

            RADIUS = 5000  # Search radius in meters

            # Get campsites for each coordinate
            for coordinate in coordinates:
                campsites = get_all_campsites(coordinate, RADIUS, google_api_key)

                # place_name = geolocator.reverse(coordinate, language="en")
                place_name = geolocation_reverse(coordinate)

                # st.write(place_name)
                st.write(f"The nearby campsite(s) for {place_name}:")

                st.write("click to expand")
                import datetime

                for campsite in campsites:

                    # Initialize session state for campsites if it doesn't exist

                    st.session_state['campsite_list'][campsite['name']] = campsite

                    with st.expander(f"{campsite['name']}"):

                        # Get the weather forecast for the campsite
                        params = {
                            "lat": campsite['location'][0],  # Use the campsite's latitude
                            "lon": campsite['location'][1],  # Use the campsite's longitude
                            "appid": weather_api_key,
                            "units": "metric"  # Use metric units for temperature
                        }

                        response = get_five_day_weather(params)
                        # st.write(response)

                        # Display the weather forecast section
                        if isinstance(response, list):
                            cols = st.columns(5)
                            for i, day in enumerate(response):
                                with cols[i]:
                                    icon_url = f"http://openweathermap.org/img/wn/{day['weather'][0]['icon']}@2x.png"
                                    st.image(icon_url)
                                    date = datetime.datetime.strptime(day['dt_txt'], '%Y-%m-%d %H:%M:%S')
                                    st.write(f"{date.strftime('%A')}")
                                    st.write(f"{day['weather'][0]['description']}")
                                    st.write(f"High: {round(day['main']['temp_max'])}°C")
                                    st.write(f"Low: {round(day['main']['temp_min'])}°C")
                        else:
                            st.write("No weather forecast available")

                        # Add a blank line space above the weather forecast section
                        st.empty()
                        st.markdown(" ")

                        # Call the function to display the campsite details
                        result = display_campsite_details(campsite)

                        # Print out the result in the main function using Streamlit's st.write function
                        for line in result:
                            if line.startswith("**Photos:"):
                                for photo in campsite['photos']:
                                    st.image(photo)
                                break
                            else:
                                st.write(line)

            selected_names = st.session_state['selected_names']

            with st.form("my_form"):
                selected_campsites = st.multiselect('Select Campsites',
                                                    list(st.session_state['campsite_list'].keys()),
                                                    default=st.session_state.get('selected_names', []))
                if st.form_submit_button("Submit"):
                    print(st.session_state['campsite_list'])

Is this what you mean by “the page refreshes”?
https://docs.streamlit.io/get-started/fundamentals/main-concepts#data-flow

Yes. How do I stop the page from refreshing ? I have captured the campsites in st.session_state[‘campsite_list’] and initialized this at the start of the code with if ‘campsite_list’ not in st.session_state:
st.session_state[‘campsite_list’] = {}

The page doesn’t refresh. The script reruns. Reruns are the mechanism to change the UI in response to the user actions, so you cannot avoid them. You can use fragments to rerun only the body of a function instead of the whole script.

1 Like

Thanks. I figured out the issue. It is not a streamlit problem, just an issue with the loop.