I am writing a chatbot following the docs on coversational app : Build conversational apps - Streamlit Docs
When running the below code, the log “End of chatbot” will be printed twice , and the title would flash twice too.
I tried to comment out code line by line, it seems query = st.chat_input("Ask me questions?")
would cause the promblem, but i don’t know why
My code skeleton is like:
import streamlit_authenticator as stauth
import streamlit as st
import yaml
from yaml.loader import SafeLoader
def authenticate(authenticator):
# authentication_status: True, False, None
# user: the registered name
# username: the nick name, this is the unique key
auth_status = st.session_state.get("authentication_status")
if auth_status:
with st.sidebar:
st.write(f'Welcome *{st.session_state["name"]}*')
authenticator.logout('Logout', 'sidebar', key='unique_key')
return True, st.session_state["username"]
elif auth_status is False:
st.error('Username or password is incorrect, have you registered?')
elif auth_status is None:
#st.write('Please register or login')
pass
return False, None
def render_sign_in_or_up(config, authenticator):
sign_in, sign_up = st.tabs(['Sign In', 'Sign Up'])
with sign_in:
render_sign_in(config, authenticator)
with sign_up:
render_sign_up(config, authenticator)
def render_sign_in(config, authenticator):
authenticator.login('Login', 'main')
def render_sign_up(config, authenticator):
try:
if authenticator.register_user('Register user', preauthorization=False):
st.success('User registered successfully')
write_config(config) # the newly registered user info is in config
except Exception as e:
st.error(e)
CONFIG_FILE = '/tmp/config.yaml'
def auth():
with open(CONFIG_FILE) as file_:
config = yaml.load(file_, Loader=SafeLoader)
authenticator = stauth.Authenticate(
config['credentials'],
config['cookie']['name'],
config['cookie']['key'],
config['cookie']['expiry_days'],
config['preauthorized']
)
success, username = authenticate(authenticator)
if not success:
render_sign_in_or_up(config, authenticator)
return None
else:
return username
def render_client_side_chat_history(user_id):
if "messages" not in st.session_state:
st.session_state.messages = {}
if user_id not in st.session_state.messages:
st.session_state.messages[user_id] = []
for message in st.session_state.messages[user_id]:
with st.chat_message(message["role"]):
st.markdown(message["content"])
def render_user_query(query, user_id):
st.session_state.messages[user_id].append({"role": "user", "content": query})
with st.chat_message("user"):
st.markdown(query)
def build_chain():
# just return the langchain Chain, nothing related to streamlit
return None
def get_render_bot_answer(chain, user_id, query):
with st.chat_message("assistant"):
bot_response = 'LLM response here' # use the chain to run the query in LLM
st.markdown(bot_response)
st.session_state.messages[user_id].append({"role": "assistant", "content": bot_response})
def chatbot(user_id):
st.title("Chat with me")
chain = build_chain() # wrapper on a langchain chain
render_client_side_chat_history(user_id)
query = st.chat_input("Ask me questions?")
if query:
render_user_query(query, user_id)
get_render_bot_answer(chain, query)
print("End of chatbot")
user_id = auth()
if user_id:
chatbot(user_id)
The config.yaml used in code is like:
credentials:
usernames:
jsmith:
email: jsmith@gmail.com
name: John Smith
password: abc # To be replaced with hashed password
rbriggs:
email: rbriggs@gmail.com
name: Rebecca Briggs
password: def # To be replaced with hashed password
cookie:
expiry_days: 30
key: random_signature_key # Must be string
name: random_cookie_name
preauthorized:
emails:
- melsby@gmail.com