Mohamed-512 / Extra-Streamlit-Components

An all in one place, to find complex or just not available components by default on streamlit.
Apache License 2.0
457 stars 56 forks source link

Cookie manager causing Chat functionality to fail on the community cloud #56

Open sjondavey opened 9 months ago

sjondavey commented 9 months ago

I originally posted my issue on the Streamlit Authenticator project (here but the problem seems to be with the cookie manager. I hope you can help. Below is a basic wrapper of the OpenAI Chat API using Authentication. It works fine locally but when I deploy to the streamlit cloud, it fails after one or two calls to the API.

import openai
import streamlit as st
import streamlit_authenticator as stauth

st.title("ChatGPT-like clone")

openai.api_key = st.secrets["OPENAI_API_KEY"]

authenticator = stauth.Authenticate(
    dict(st.secrets['credentials']),
    st.secrets['cookie']['name'],
    st.secrets['cookie']['key'],
    st.secrets['cookie']['expiry_days'],
    st.secrets['preauthorized']
)

name, authentication_status, username = authenticator.login('Login', 'sidebar') # location is 'sidebar' or 'main'

if authentication_status:

    if "openai_model" not in st.session_state:
        st.session_state["openai_model"] = "gpt-3.5-turbo"

    if "messages" not in st.session_state:
        st.session_state.messages = []

    for message in st.session_state.messages:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

    if prompt := st.chat_input("What is up?"):
        st.session_state.messages.append({"role": "user", "content": prompt})
        with st.chat_message("user"):
            st.markdown(prompt)

        with st.chat_message("assistant"):
            message_placeholder = st.empty()
            full_response = ""
            response = openai.chat.completions.create(
                model=st.session_state["openai_model"],
                messages=st.session_state.messages,
                stream=True,
            )
            for part in response:
                full_response += (part.choices[0].delta.content or "")
                message_placeholder.markdown(full_response + "▌")
            message_placeholder.markdown(full_response)
        st.session_state.messages.append({"role": "assistant", "content": full_response})

elif authentication_status == False:
    st.error('Username/password is incorrect')
elif authentication_status == None:
    st.warning('Please enter your username and password')

As noted in the comments to my post on the Streamlit Authenticator page, the issue seems to be the cookie manager because if you comment out all the cookie management code in the Authenticator, the cloud deployment seems to work. Does anyone know if there is a simple fix to this? I would like to use the Authenticator library with cookies.

I am using Python 3.10.4 and streamlit 1.28.2, streamlit-authenticator=0.2.3 and openai=1.2.4

hunaidkhan2000 commented 7 months ago

@sjondavey Are you experiencing a similar issue where, when using OpenAI, all users can access each other's messages @mkhorasani do you have any suggestions on how to resolve this? I'm in the process of creating a chatbot and despite authentication, all users seem to be able to view each other's messages.

mkhorasani commented 7 months ago

No unfortunately I still am not sure why this is happening.

hunaidkhan2000 commented 7 months ago

I attempted to incorporate a UUID per session into the code, but the values are not retained once I log out and then log back in using the same user ID.

CHerSun commented 7 months ago

Cookies are attached to the domain. When you run in a cloud (shared environment) - all apps hosted there use the same cookies set. Does the user use several apps in the cloud? Do cookies keys overlap? If that's the case - see below.

Mohamed-512, sorry for mentioning this again on your project, but there's a https://pypi.org/project/streamlit-cookies-manager/ which is tailored for use in shared environments. It implements prefix + encryption for cookies, which allows to have a subset of cookies for your app specifically, without overlapping with other apps. Project is outdated, but works finely, just need to patch @st.cache to @st.cache_data.

P.S.: imo, seeing as streamlit-cookies-manager is unmaintained for ~3 years - would be cool if some1 picked up the project really.

hunaidkhan2000 commented 7 months ago

@CHerSun Thanks for the comments. I tried using @st.cache_data, it was not working but let me check cookies manager. Any tutorial available for the same on internet? where a person has used Cookies manager with streamlit authenticator?

sjondavey commented 7 months ago

@sjondavey Are you experiencing a similar issue where, when using OpenAI, all users can access each other's messages @mkhorasani do you have any suggestions on how to resolve this? I'm in the process of creating a chatbot and despite authentication, all users seem to be able to view each other's messages.

Hi @hunaidkhan2000, I think this is a different issue. Have a look at this post: https://discuss.streamlit.io/t/eliminate-states-of-modules-to-avoid-the-accidental-state-sharing-across-users-sessions/27803 and see if that addresses your problem. It seems that If you keep your state (i.e. the messages for the chat) outside of the main streamlit file, then these will be accessible to other users. You may need to keep the messages only in the main streamlit file and pass them to a stateless 'chat' file.

broepke commented 7 months ago

Watching... Same issue for me.