Summary
Hi!
I am trying to create a multi-page app that is integrated with a DB connection. I am able to connect to the DB to get the values I need, but my issue comes when I cache the values. I used st.cache_resource and st.cache_data. For both, it works locally only but if I try it on cloud via incognito mode or a friend’s computer, the queries crash because the values are not being cached.
I tried lots of different things, changing how the variable is stored by switching it between st_cache to st_resource and vice versa, I made the query return as a string, as a list, I tried printing it to debug but it only prints locally, never on cloud.
Interstingly, the logged in session state works fine and so does the database connection session state, but the query returned variable session states do not unless its on my local admin streamlit account, but never on the cloud or on incognito mode or others using it
I am super desperate as I cant figure out what I am doing wrong with the cache’ing
Code snippet:
login.py
import streamlit as st
from streamlit.source_util import _on_pages_changed, get_pages
import streamlit_authenticator as stauth
from streamlit_extras.switch_page_button import switch_page
import psycopg2
import hashlib
import pandas as pd
st.set_page_config(page_title="login")
if "saved_user_name" not in st.session_state:
st.session_state["saved_user_name"] = ""
if "saved_user_id" not in st.session_state:
st.session_state["saved_user_id"] = ""
if "login_status" not in st.session_state:
st.session_state['login_status'] = False
st.title("Welcome, please log in below")
@st.cache_resource
def init_connection():
return psycopg2.connect(**st.secrets["postgres"])
@st.cache_resource
def logged_in():
st.session_state["login_status"] = True
switch_page("home")
conn = init_connection()
cursor = conn.cursor()
columns_db = ["id", "first_name", "last_name", "email", "timestamp", "password"]
email_login = st.text_input("Please enter email", placeholder="JohnDoe@gmail.com")
password_login = st.text_input("Please enter password", type="password", placeholder="********")
col1, col2, col3, col4 = st.columns(4)
with col1:
login_button = st.button("Login")
if login_button:
hashed_password ="SHA-512:" + hashlib.sha512(password_login.encode('utf-8')).hexdigest()
cursor.execute("SELECT * FROM public.users WHERE email ilike '{}' AND password = '{}'".format(email_login, hashed_password))
login_results_query = cursor.fetchall()
query_df = pd.DataFrame(login_results_query,columns=columns_db)
@st.cache_data
def save_user_name():
st.session_state["saved_user_name"] = str(query_df["first_name"].values)
@st.cache_data
def save_user_id():
st.write("id val as string", str(query_df["id"].values))
st.session_state["saved_user_id"] = str(query_df["id"].values)
if(hashed_password == query_df["password"].values):
save_user_name()
save_user_id()
logged_in()
else:
st.write("Invalid email or password.")
with col2:
if st.button("Sign Up"):
switch_page("sign_up")
home.py
import streamlit as st
import pandas as pd
from urllib.error import URLError
from streamlit.source_util import _on_pages_changed, get_pages
from streamlit_extras.switch_page_button import switch_page
import sys
from extra_streamlit_components import CookieManager
import psycopg2
import helperfuncs as hf
from pages.login import conn
if "saved_user_name" not in st.session_state:
st.session_state["saved_user_name"] = ""
if "saved_user_id" not in st.session_state:
st.session_state["saved_user_id"] = ""
if "login_status" not in st.session_state:
st.session_state['login_status'] = False
def log_out():
st.session_state['login_status'] = False
switch_page("sign_up")
st.title('WasteDrop')
if(st.session_state["login_status"] == True):
cursor = conn.cursor()
st.write("this is user name", st.session_state.saved_user_name)
st.write("this is id",st.session_state.saved_user_id)
users_name = st.session_state["saved_user_name"]
users_name = users_name.replace("'", "").replace("[","").replace("]","")
st.write("Welcome! ",users_name)
logout_button = st.sidebar.button("log off", on_click=log_out)
user_id = st.session_state["saved_user_id"]
user_id = user_id.replace("'", "").replace("[", "").replace("]", "")
st.write(user_id)
st.header("Create new Binz below")
binz_name = st.text_input("Enter the name of binz to create")
create_binz_but = st.button("Create")
cursor.execute("SELECT binz_name FROM public.binz_owners WHERE user_id = '{}';".format(user_id))
user_binz_list = cursor.fetchall()
user_binz_arr = []
for elem1 in user_binz_list:
for elem2 in elem1:
user_binz_arr.append(elem2)
if create_binz_but:
if(binz_name in user_binz_arr):
st.error(":red[This binz already exists!]")
else:
cursor.execute("INSERT INTO public.binz_owners(binz_name, user_id) VALUES('{}', '{}')".format(binz_name, user_id))
conn.commit()
st.write(":green[Binz created!]")
st.header('View all binz')
cursor.execute("SELECT binz_name FROM public.binz_owners WHERE user_id = '{}';".format(user_id))
binz_results = cursor.fetchall()
binz_results = pd.DataFrame(binz_results, columns=['Binz Name'])
st.dataframe(binz_results)
else:
st.write("Please login to continue")
Expected behavior:
It will cache the user id and user name so when the page switches from login to home page, the user id is able to be inserted into the query to find the users lists
Actual behavior:
It does not cache anything, causing the app to crash the query
- Streamlit version: (get it with
$ streamlit version
) - python version 3.9
- Using Conda? PipEnv? PyEnv? Pex?
- OS version: Windows
- Browser version: Google Chrome
Requirements file
psycopg2-binary==2.9.7
streamlit-extras==0.3.2
streamlit-authenticator==0.2.2
bcrypt==4.0.1
pandas==1.4.1
st-pages==0.4.4
- Link to your deployed app: https://wastedrop.streamlit.app/
- Link to GitHub Repo: GitHub - SamuelMuvdi01/waste_drop