New Component: Streamlit-chat, a new way to create chatbots

Streamlit-Chat is a simple component, which provides a chat-app like interface, which makes a chatbot deployed on Streamlit have a cool UI.

Source code:

Authors: @yashppawar @YashVardhan-AI
Installation: pip install streamlit-chat or pip3 install streamlit-chat
Usage:

import streamlit as st
from streamlit_chat import message

message("My message") 
message("Hello bot!", is_user=True)  # align's the message to the right

Demo: https://share.streamlit.io/ai-yash/st-chat/main/examples/chatbot.py created by @YashVardhan-AI for us :slight_smile:
Thank you so much for reading :heart:.

This was my first time making a package and publishing it so forgive me if I made any mistakes, I am open to suggestions but might take time to act on them :sweat_smile:, even the first time making something using react. Thank you Streamlit team, it was fun making it.

Greetings, Yashppawar. You’ve got a great concept going there, however, is there any way you could put the chatbox below the prior chats, like in Whatsapp?

Hello @KinePi, Thank you
yes, it is possible to have the text input below the prior chats, it can be achieved using st.empty() as a placeholder

import streamlit as st
from streamlit_chat import message

placeholder = st.empty()
input_ = st.text_input("you:")
message_history.append(input_)

with placeholder.container():
    for message_ in message_history:
        message(message_)

However, in this method, if there are many messages, the text_input gets out of the viewing area, maybe will have to limit the number of messages to be displayed, or maybe have the container of fixed height and a scroll bar (not sure how to do that) :slight_smile:


Edit: was just playing around and I have the following code, but there is a bit of delay between the previous messages and the latest message.

better one I think
import streamlit as st
from streamlit_chat import message

 for message_ in message_history:
        message(message_)   # display all the previous message

placeholder = st.empty()  # placeholder for latest message
input_ = st.text_input("you:")
message_history.append(input_)

with placeholder.container():
    message(message_history[-1]) # display the latest message

currently its possible but ill advised we are working on it.

Such a great component!! Now I can make a QA system with it, thank you so much! I’m wondering will you add function of returning picture or datatable?

And also are you planning to add support for ‘\n’ or html?

Didn’t have any plan for adding HTML or Markdown support, not sure if ‘\n’ works, if not will add that soon. We can try to add HTML & MarkDown support I am afraid we might have to write a lot more CSS for that., will try it after January 3, 2022 (Exams)

Thanks a lot! That would be so nice, and for datatable, pictures, html and markdown in reply, I’ve got a temporary solution

if type(output)==str:
  message(output)
else:
  message(“the result is”)
  st.columns((1,10))
  cols[1].write(output)

Hi @yashppawar

This looks super awesome! And I see you already managed to add it to the tracker :partying_face: thanks for your contribution

Happy Streamlitin’
Fanilo :balloon:

Great work. Will try this out

Great work over here @yashppawar :sparkles:, Can’t wait to try it out

I think we may need a container with fixed height to make the page more like chat UI commonly used.

I have one question.

I’m try “streamlit-chat”. but happened error following


ImportError: cannot import name ‘Literal’ from ‘typing’ (/usr/lib/python3.7/typing.py)

Traceback:

File "/usr/local/lib/python3.7/dist-packages/streamlit/script_runner.py", line 430, in _run_script
    exec(code, module.__dict__)File "/content/app.py", line 7, in <module>
    from streamlit_chat import messageFile "/usr/local/lib/python3.7/dist-packages/streamlit_chat/__init__.py", line 3, in <module>
    from typing import Any, Literal, Optional, Union
```-----------

If you’re able to switch to an environment with python 3.8+ you should at least get past that import error.
See pep 586

If you need to work with 3.7, I’d suggest opening an issue on the st-chat github.
Maybe they can include an option with typing_extensions or without Literal

This is awesome! Thanks @yashppawar @YashVardhan-AI!

Great work!

Is there a more recent example of this that I can look at ?

My text seems to show only the latest text and is not showing as the user text , is showing as the bot text instead.
Pls refer to my code , based on the example from above post , below.
Thanks!

import streamlit as st
from streamlit_chat import message

message_history= []

message("My message") 

for message_ in message_history:
    message(message_)   # display all the previous message

placeholder = st.empty()  # placeholder for latest message
input_ = st.text_input("you:")
message_history.append(input_)

with placeholder.container():
    message(message_history[-1]) # display the latest message

Ok updated but still issues with new message … if the user pressed enter twice , there should be 2 lines right ?

import streamlit as st
from streamlit_chat import message

message_history =

message(“Welcome to Streamlit-Chat”)
message(“Welcome to Streamlit-Chat2”)

for message_ in message_history:
message(message_) # display all the previous message

placeholder = st.empty() # placeholder for latest message
input_ = st.text_input(“you:”)
message_history.append(input_)

with placeholder.container():
message(message_history, is_user=True) # display the latest message

for t in message_history:
message(t, is_user=True) # why not new chat line ???

ok … I got to something like this using session_state …

import streamlit as st
from streamlit_chat import message

message(“Welcome to Streamlit-Chat”)

if ‘message_history’ not in st.session_state:
st.session_state.message_history =

for message_ in st.session_state.message_history:
message(message_,is_user=True) # display all the previous message

placeholder = st.empty() # placeholder for latest message
input_ = st.text_input(“you”)
st.session_state.message_history.append(input_)

with placeholder.container():
message( st.session_state.message_history[-1], is_user=True) # display the latest message

Thanks, @yashppawar for this excellent library.

I am able to manage user input at the base. however, if the response is an HTML page then it is displayed below the text box. I did not face this issue when the response is text.

Your quick help is appreciated.