Streamlit UI disappearing

Hi. I’m currently building a streamlit app locally and am struggling with implementing the UI. So the code I’m struggling with is a part of the function of a larger class but what I want to happen is for 3 sliders to pop up for the user to adjust & submit when ready. After the user presses the submit button, it should trigger the calling of three functions and return some data from them. But the problem is that whenever one of the sliders are altered in the slightest, the entire page clears before I can alter the other two or press the submit button. Any idea why?

#Function that will recommend places for the user to eat, stay, and do while on vacation
    def planTrip(self, city): 
        self.city = city

        restaurauntBudget = st.slider("How much of your budget are you willing to spend on food (in percent)", min_value=0.0, max_value=1.00)

        lodgingBudget = st.slider("How much of your budget are you willing to spend on lodging (in percent)", min_value=0.0, max_value=1.00)

        excursionsBudget = st.slider("How much of your budget are you willing to spend on fun (in percent)", min_value=0.0, max_value=1.00)

        budgetBtn = st.button('Finalize budget')

        if budgetBtn: 
            resSuggest = self.getRestaurants(restaurauntBudget)
            lodgeSuggest = self.getLodging(lodgingBudget)
            funSuggest = self.getFun(excursionsBudget)
1 Like

Hi @vegas,

Could you please share the full code?

Best,
Charly

1 Like

It’s difficult to devise an answer for sure, but you should be able to utilize Streamlit’s session state to preserve certain values across reruns—something along those lines:

import streamlit as st

def planTrip(self, city): 
    self.city = city

    if 'restaurauntBudget' not in st.session_state:
        st.session_state['restaurauntBudget'] = 0.0
    if 'lodgingBudget' not in st.session_state:
        st.session_state['lodgingBudget'] = 0.0
    if 'excursionsBudget' not in st.session_state:
        st.session_state['excursionsBudget'] = 0.0

    restaurauntBudget = st.slider("How much of your budget are you willing to spend on food (in percent)", min_value=0.0, max_value=1.00, key='restaurauntBudget')
    lodgingBudget = st.slider("How much of your budget are you willing to spend on lodging (in percent)", min_value=0.0, max_value=1.00, key='lodgingBudget')
    excursionsBudget = st.slider("How much of your budget are you willing to spend on fun (in percent)", min_value=0.0, max_value=1.00, key='excursionsBudget')

    budgetBtn = st.button('Finalize budget')

    if budgetBtn:
        # Update session state when button is pressed
        st.session_state['restaurauntBudget'] = restaurauntBudget
        st.session_state['lodgingBudget'] = lodgingBudget
        st.session_state['excursionsBudget'] = excursionsBudget
        
        # Call the functions and display results
        resSuggest = self.getRestaurants(st.session_state['restaurauntBudget'])
        lodgeSuggest = self.getLodging(st.session_state['lodgingBudget'])
        funSuggest = self.getFun(st.session_state['excursionsBudget'])

        # Display suggestions or results here
        st.write("Restaurant Suggestions:", resSuggest)
        st.write("Lodging Suggestions:", lodgeSuggest)
        st.write("Fun Activities Suggestions:", funSuggest)

Good luck!

Charly

1 Like

Hi, thank you so much for reaching out. The code is apart of a school project & the instructors have set the repositories to private but I can share the contents of my recent commit below:

import streamlit as st
from PIL import Image
import os
import google.generativeai as genai
import vertexai
from vertexai.preview.vision_models import ImageGenerationModel
import csv
from google.cloud import bigquery

#Set up Travel Page
st.set_page_config(page_title="Travel Page")
st.sidebar.header('Travel Page How-To')
st.sidebar.write("This page is dedicated to helping you plan your dream vacation. Just tell us a little bit about your travel preferences and we'll handle the rest.")

#Setting up Gemini model
genai.configure(api_key=st.secrets["API_KEY"])
textModel = genai.GenerativeModel('gemini-pro')
picModel = genai.GenerativeModel('gemini-pro-vision')

#Setting up vertex model
vertexai.init(project="sds-project-414416", location="us-east4")
imageModel = ImageGenerationModel.from_pretrained("imagegeneration@005")


class TravelPage: 

    def __init__(self, budget = None, companions=None, companionsdescription=None, duration=None, interest=None, city = None):
        self.budget = budget
        self.companions = companions
        self.companionsdescription = companionsdescription
        self.duration = duration
        self.interest= interest
        self.city = city

    #Gets the user's ideal vacation budget
    def getBudget(self): 
        self.budget = st.slider("What is Your Budget?", 0, 10000)

    #Gets the user's ideal vacation budget
    def getDuration(self): 
        self.duration = st.select_slider("How Long Are You Planning On Traveling?", ['1 day', '2 days', '3 days', '4 days', '5 days', '6 days', '1 week', '2 weeks', '3 weeks', '1 month', '1 month+'])

    #Gets the user's ideal vacation budget
    def getCompanions(self): 
        self.companions = st.number_input('How Many People Do You Plan On Traveling With?', min_value=0, max_value= 100)

    #Gets the user's ideal vacation budget
    def getCompanionsDescription(self): 
        self.describeCompanions = st.selectbox("Who Do You Plan On Traveling With?", ['Self', 'Friends', 'Family', 'Coworkers', 'Signficant Other', 'Other'])

    #Gets the user's ideal vacation budget 
    def getInterest(self): 
        self.interest = st.text_input('What Do Yo Like to Do While Traveling? Separate the items by comma (e.g. hiking, swimming, shopping))')


    #If the user didn't know where they wanted to go, a list of countries they selected will be inputted and a list of city,countries will be aoutputted
    def onSubmitDontKnow(self, userCountries): 
        findLocations = "Can you suggest 10 cities to travel for someone that would like to go to the following countries: "
        for country in userCountries: 
            findLocations += country + ", "

        findLocations += "You can recommend more than one city per country. Put the results in a single sentence, separated by a comma, in the format of city, country for each city."
        suggestPlaces = textModel.generate_content(findLocations)

        self.suggestionsPage(suggestPlaces.text)

    #If the user choose to upload a picture, Gemini will recommend cities that have loactions similar to the picture
    def onSubmitPic(self, img): 
        findLocations = "Can you suggest 10 cities to travel for someone that would like to go to the somewhere like this picture. Put the results in a single sentence, separated by a semicolon, in the format of city, country for each city."
            
        suggestPlaces = picModel.generate_content([findLocations, img])
        suggestPlaces.resolve()
        if suggestPlaces.text: 
            self.suggestionsPage(suggestPlaces.text)
        else: 
            st.warning('Error Generating Content')

    #Function to make sure that the user only inputted one selection for country output 
    def is_valid_country(self, userDontKnow, pictureUpload, userKnow): 
        if userDontKnow and not(pictureUpload or userKnow): 
            return True
        if userKnow and not(pictureUpload or userDontKnow): 
            return True
        if pictureUpload and not(userKnow or userDontKnow): 
            return True
        return False
        
    """Look into streamlit containers & emptying the page"""
    #Function used to simulate the homepage
    def homePage(self): 
        st.header("Your AI Travel Planner")
        st.subheader("Tell Us a Little About Your Traveling Preferences")

        #Collect information about user travel preferences
        userKnow = st.text_input("If You Already Know Where You Want to Go, Let Us Know Here. Please Input it in City, Country Format")

        #User upload image
        pictureUpload = st.file_uploader("Or You Could Use An Image As Inspiration. Upload A Place You'd Like to Go Below and We'll Find A Couple Spots We Think You'll Enjoy (png or jpg format only)", type=['png', 'jpg'] )
        if pictureUpload: 
                img = Image.open(pictureUpload)

        userDontKnow = st.multiselect("If Not, Let Us Help. What Continents Would You Like to Travel?", ['Europe', 'Africa', 'Asia', 'North America', 'South America', 'Australia', 'Anarticta'])

        #Create a multiselect button that will add options as the user chooses countries
        if userDontKnow: 
            countries = []
            if 'Africa' in userDontKnow: 
                countries.extend(["Algeria", "Angola", "Benin", "Botswana", "Burkina Faso", "Burundi", "Cabo Verde", "Cameroon", "Central African Republic", "Chad", "Comoros", "Congo", "Democratic Republic of the Congo", "Djibouti", "Egypt", "Equatorial Guinea", "Eritrea", "Ethiopia", "Eswatini", "Gabon", "Gambia", "Ghana", "Guinea", "Guinea-Bissau", "Ivory Coast", "Kenya", "Lesotho", "Liberia", "Libya", "Madagascar", "Malawi", "Mali", "Mauritania", "Mauritius", "Morocco", "Mozambique", "Namibia", "Niger", "Nigeria", "Rwanda", "São Tomé and Príncipe", "Senegal", "Seychelles", "Sierra Leone","Somalia", "South Africa", "South Sudan", "Sudan", "Swaziland", "Tanzania", "Togo", "Tunisia", "Uganda", "Zambia", "Zimbabwe"])
            if 'Antartica' in userDontKnow: 
                countries.append("Antartica")
            if 'Europe' in userDontKnow: 
                countries.extend(["Albania", "Andorra", "Armenia", "Austria", "Azerbaijan","Belarus", "Belgium", "Bosnia and Herzegovina", "Bulgaria", "Croatia","Cyprus", "Czech Republic", "Denmark", "Estonia", "Finland", "France","Georgia", "Germany", "Greece", "Hungary", "Iceland", "Ireland","Italy", "Kosovo", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg","Malta", "Moldova", "Monaco", "Montenegro", "Netherlands", "North Macedonia","Norway", "Poland", "Portugal", "Romania", "Russia", "San Marino","Serbia", "Slovakia", "Slovenia", "Spain", "Sweden", "Switzerland","Turkey", "Ukraine", "United Kingdom", "Vatican City"])
            if 'Asia' in userDontKnow: 
                countries.extend(["Afghanistan","Armenia","Azerbaijan","Bahrain","Bangladesh","Bhutan","Brunei","Cambodia","China","Cyprus","East Timor","Egypt","Georgia","India","Indonesia","Iran","Iraq","Japan","Jordan","Kazakhstan","North Korea","South Korea","Kuwait","Kyrgyzstan","Laos","Lebanon","Malaysia","Maldives","Mongolia","Myanmar","Nepal","Oman","Pakistan","Palestine","Philippines","Qatar","Russia","Saudi Arabia","Singapore","Sri Lanka","Syria","Taiwan","Tajikistan","Thailand","Turkey","Turkmenistan","United Arab Emirates","Uzbekistan","Vietnam","Yemen"])
            if 'North America' in userDontKnow: 
                countries.extend(["Canada", "Mexico", "United States", "Antigua and Barbuda", "Bahamas", "Barbados", "Belize", "Costa Rica", "Cuba", "Dominica", "Dominican Republic", "El Salvador", "Grenada", "Guatemala", "Haiti", "Honduras", "Jamaica", "Nicaragua", "Panama", "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines", "Trinidad and Tobago"])
            if 'South America' in userDontKnow: 
                countries.extend(["Argentina", "Bolivia", "Brazil", "Chile", "Colombia","Ecuador", "Guyana", "Paraguay", "Peru", "Suriname","Uruguay", "Venezuela"])
            if 'Australia' in userDontKnow: 
                countries.append("Australia")
                
            userCountries = st.multiselect("Select up to 10 countries that you would like to visit.", options=countries)

            #Ensures that the user selects >=10 countries to minimize mistakes with AI
            if len(userCountries) > 10: 
                st.warning("To get the best experience out of your AI travel planner, please select no more than 10 countries")

        self.getBudget()
        self.getCompanions()
        self.getCompanionsDescription()
        self.getDuration()
        self.getInterest()

        #Depending on how the user put their desired vacation spot in, the submitBtn will trigger different behaviors
        submitBtn = st.button('Submit')
        if submitBtn:
            #Verifies that the user only entered one option
            if self.is_valid_country(userDontKnow, pictureUpload, userKnow): 
                if userDontKnow: 
                    self.onSubmitDontKnow(userCountries)
                elif pictureUpload: 
                    self.onSubmitPic(img)
                else: 
                    self.planTrip(userKnow)
            else: 
                st.warning('Please only select one input for country selection.')

    #Function use to similuate a suggestions page, based on gemini suggestions
    def suggestionsPage(self, locations): 
        st.header('Suggestion Page')
        st.subheader("Based on your suggestions we think you'll enjoy the following places. Look at the suggestions shown and choose your favorite ")
        

        #Create components to showcase locations. Component includes city name, descripition & images
        cities = list(locations.split(';'))

        """col1, col2 = st.columns([0.6, 0.4])
        for city in cities:
            with col1: 
                st.subheader(city)
                cityDescription = textModel.generate_content('Come up with 2-3 sentences, in paragraph form to describe ' + city)
                if cityDescription: 
                    st.write(cityDescription.text)
                else: 
                    st.warning("Error generating content")
            with col2:                     
                images = imageModel.generate_images('Pull an image from the following location'+ city)
                if images:
                    images[0].save(location="traveling.jpg")
                    st.image("traveling.jpg", width=250)"""

        #Button reacts prematurely or erases the entire page
        chosenCity = st.radio("Choose your favorite so we can build your dream vacation:", options=cities)
        submitBtn = st.button("Create Vacation")
        if submitBtn:
            self.planTrip(chosenCity)
        
            
    def getRestaurants(self, restaurauntBudget):
        #Find restaurants
        findRestaurants = "Can you return a list of popular restaurants to eat at " + self.city + " for someone eating with a party of " + str(self.companions) + " and a budget of " + str(self.budget * restaurauntBudget) + ". Put the results in a single sentence, separated by a semicolon"

        suggestFood = textModel.generate_content(findRestaurants)
        if suggestFood.text: 
            return suggestFood.text
        else: 
            st.warning('Error generating content')
        

    def getLodging(self, lodgingBudget): 
       #Find lodging
        findLodging = "Can you return a list of popular places to stay while visitng " + self.city + " for staying with a party of " + str(self.companions) + "and a budget of " + str(self.budget * lodgingBudget) + ". Put the results in a single sentence, separated by a semicolon"

        suggestLodging = textModel.generate_content(findLodging)
        if suggestLodging.text: 
            return suggestLodging
        else: 
            st.warning(suggestLodging.text)

    
    def getFun(self, excursionsBudget):  
        findExcursions = "Can you return a list of popular things to do in " + self.city + " for someone who likes to do" 

        for interest in self.interest: 
            findExcursions += interest + ', '
            
        findExcursions += "Traveling with a party of " + str(self.companions) + " and a budget of " + str(self.budget * excursionsBudget)+ ". Put the results in a single sentence, separated by a semicolon"

        suggestFun = textModel.generate_content(findExcursions)

        if suggestFun.text: 
            return suggestFun.text
        else: 
            st.warning('Error generating content')

    #Function that will recommend places for the user to eat, stay, and do while on vacation
    def planTrip(self, city): 
        self.city = city

        restaurauntBudget = st.slider("How much of your budget are you willing to spend on food (in percent)", min_value=0.0, max_value=1.00)

        lodgingBudget = st.slider("How much of your budget are you willing to spend on lodging (in percent)", min_value=0.0, max_value=1.00)

        excursionsBudget = st.slider("How much of your budget are you willing to spend on fun (in percent)", min_value=0.0, max_value=1.00)

        budgetBtn = st.button('Finalize budget')

        if budgetBtn: 
            resSuggest = self.getRestaurants(restaurauntBudget)
            lodgeSuggest = self.getLodging(lodgingBudget)
            funSuggest = self.getFun(excursionsBudget)

            #Add the sections later
            restaurants = st.multiselect("Choose your favorites", option=resSuggest)
            lodging = st.multiselect("Choose your favorites", option=lodgeSuggest)
            fun = st.multiselect("Choose your favorites", option=funSuggest)
            finalSelections = st.button('Finalize trip')

            if finalSelections: 
                self.saveTrip(str(restaurants), str(lodging), str(fun))

 
    #Function that will be used to save a user's trip & save it to bigquery
    def saveTrip(self, restaurants, lodging, excursions): 
        #Insert data into Bigquery
        myquery = "INSERT INTO `sds-project-414416.back_to_the_future.travel_info` (location, budget, traveling_partners, trip_duration, restaurants, lodging, excursions) VALUES (\"%s\", \"%s\", \"%d\", \"%s\", \"%s\", \"%s\", \"%s\" )" % (self.city, self.budget, self.companions, self.duration, restaurants, lodging, excursions) #find out symbol for integers

        QUERY = (myquery)
        insert_job = client.query(QUERY)
        row = insert_job.result()

        #Write info into file
        my_trip = {
            "Location": self.city,
            "Budget" : self.budget, 
            "Traveling Partners" : self.companions, 
            "Trip Duration": self.duration, 
            "Restaurants" : restaurants, 
            "Lodging" : lodging, 
            "Fun" : excursions
        }

        fields = ["Location", "Budget", "Traveling Partners", "Trip Duration", "Restaurants", "Lodging", "Fun"]

        with open('my_trip.csv', fieldnames = fields) as csvfile: 
            writer = csv.DictWriter(csvfile, fieldnames=fields)
            writer.writeheader()
            writer.writerows(my_trip)

        st.download_button("Save Your Trip To Your Computer", data=csv, file_name='my_trip.csv', mime='text/csv')
        

user = TravelPage()
user.homePage()
1 Like

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