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:.

15 Likes

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.

1 Like

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?

1 Like

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.

1 Like

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?

1 Like

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

1 Like

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)

1 Like

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)
2 Likes

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:

2 Likes

Great work. Will try this out

2 Likes

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

2 Likes

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

2 Likes

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
```-----------
1 Like

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

2 Likes

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

2 Likes

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 ???

1 Like

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

1 Like

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.