Hi @Caroline . I was able to solve the above issue using Callback
But now I have come across altogether a different issue - as soon as I get the output dataframe on submitting my form , my main page reloads with the header getting displayed at the bottom.
I am attaching the code and the screenshot for reference.
import streamlit as st
import base64
import os
import openai
import pandas as pd
import numpy as np
from dotenv import load_dotenv
def header(url):
st.markdown(
f'<p style="color:#00308F;font-size:60px;font-weight: bold; font-family: fantasy; font-stretch: extra-expanded; font-style: italic">{url}</p>', unsafe_allow_html=True)
def configure():
load_dotenv()
@st.cache_data
def get_img_as_base64(file):
with open(file, "rb") as f:
data = f.read()
return base64.b64encode(data).decode()
def style_df(df):
df['Rating'] = df['Rating'].astype(float)
df_pred['Rating'] = df_pred['Rating'].map("{:,.1f}".format)
#df_pred.set_index('Strain',inplace=True)
# style
th_props = [
('font-size', '20px'),
('text-align', 'center'),
('font-weight', 'bold'),
('color', '#FF0000'),
('background-color', '#f7ffff'),
]
td_props = [
('font-size', '16x'),
# ('font-weight', 'bold'),
('color', '#FF0000'),
]
table_hover = [
('background-color', 'yellow')
]
table_size = [
('width','150%')
]
styles = [
dict(selector="th", props=th_props),
dict(selector="td", props=td_props),
dict(selector='tr:hover',props=table_hover),
dict(selector='tr:hover',props=table_size)
]
# table
df2=df_pred.style.set_properties(**{'text-align':'left'}).set_table_styles(styles)
return df2
openai.api_key=os.getenv('API_KEY')
st.set_page_config(page_title='Cannabis Strain Selector')
header("Cannabis Strain Recommendation System")
df = pd.read_csv(os.path.join(os.getcwd(),"cannabis.csv"))
df.replace(to_replace=['None'], value=np.nan, inplace=True)
df['Strain'] = df['Strain'].str.replace("-"," ")
flavor = (
df['Flavor'].str.get_dummies(',').sum()
.rename('Unique Flavors')
.reset_index(name='count')
.sort_values('count', ascending=False, ignore_index=True)
)
effects = (
df['Effects'].str.get_dummies(',').sum()
.rename('Unique Effects')
.reset_index(name='count')
.sort_values('count', ascending=False, ignore_index=True)
)
flavor = list(flavor['index'])
effects = list(effects['index'])
img = get_img_as_base64("image.png")
side = get_img_as_base64("side.png")
page_bg_img = f"""
<style>
[data-testid="stAppViewContainer"] > .main {{
background-image: url("data:image/png;base64,{img}");;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}}
</style>
"""
st.markdown(page_bg_img, unsafe_allow_html=True)
sidebar_bg_img = f"""
<style>
[data-testid="stSidebar"] > .css-6qob1r.e1fqkh3o3 {{
background-image: url("data:image/png;base64,{side}");;
background-position: 10% 80%;
}}
</style>
"""
st.markdown(sidebar_bg_img, unsafe_allow_html=True)
def both_val_not_provided(url):
st.markdown(
f'<p style="color:#FF0000;font-size:30px;font-weight: bold; font-family: fantasy; font-stretch: extra-expanded; font-style: italic">{url}</p>', unsafe_allow_html=True)
button_with_flav_eff = st.button("Recommend top 3 strains",key='flav_eff')
df_pred = pd.DataFrame(columns=['Strain','Type','Rating','Description'],index=range(3))
def generate_response(prompt):
response = openai.Completion.create(
engine="text-davinci-002",
prompt=prompt,
max_tokens=1024,
n=1,
stop=None,
temperature=0.7,
)
return response.choices[0].text
def app():
configure()
flav = st.sidebar.multiselect(label = "Flavor",options = flavor,default=[])
eff = st.sidebar.multiselect(label = "Effects", options = effects,default=[])
if st.session_state.flav_eff==True:
if flav==[] and eff==[]:
both_val_not_provided("No option selected, select something")
st.session_state.flav_eff==False
if flav!=[] and eff==[]:
both_val_not_provided("Select Effect as well")
st.session_state.flav_eff==False
if flav==[] and eff!=[]:
both_val_not_provided("Select Flavor as well")
st.session_state.flav_eff==False
if flav!=[] and eff!=[]:
prompt = f"Generate 3 cannabis strains that has {flav} flavors and {eff} effects."
response = generate_response(prompt)
response = response.strip()
response = [y for y in (x.strip() for x in response.splitlines()) if y]
bool_first_fail = True
bool_second_fail = True
bool_third_fail = True
bool_fourth_fail = True
#finding if chatgpt gives any response
try:
response[0] = response[0].split(':')[0]
response[0] = response[0].split('1. ')[1]
except Exception:
st.subheader("No strain available, change inputs!")
bool_first_fail = False
#only executed if chatgpt gives response
if bool_first_fail:
#find if the chatgpt's strain exists in our database
try:
x = list(df['Strain'].eq(response[0]))
y = x.index(True)
except Exception:
st.subheader("Strain doesn't exist in our database, but chatgpt gave response.")
bool_second_fail = False
# executed if atleast one response from chatgpt exists in our database and can be displayed
if bool_second_fail:
#Saving the first reposnse in our database.
df_pred.loc[df_pred.index[0], 'Strain'] = response[0]
df_pred.loc[df_pred.index[0], 'Type'] = df.iloc[y][1]
df_pred.loc[df_pred.index[0], 'Rating'] = df.iloc[y][2]
df_pred.loc[df_pred.index[0], 'Description'] = df.iloc[y][5]
#check if second response is given by chatgpt or not
try:
response[1] = response[1].split(':')[0]
response[1] = response[1].split('2. ')[1]
x = list(df['Strain'].eq(response[1]))
y = x.index(True)
except:
both_val_not_provided("I could find only 1 suggestion. Try again or just show one option ?")
st.write("before clicking")
st.write(st.session_state)
def show_df():
df_pred.drop(index=[1,2],inplace=True)
df_pred.set_index('Strain',inplace=True)
df2 = style_df(df_pred)
return st.table(df2)
with st.form("Show what you have"):
submit = st.form_submit_button(on_click=show_df)
That’s how the page looks before I invoke the form
and thats how my page looks after invoking the form
As you can see , the title of the page somehow comes down after the form is clicked. Any idea why this might be happening ?