- Streamlit permet de créer rapidement des interfaces personnalisées pour chatbots IA, mais il faut plus de flexibilité que les composants de chat intégrés.
- L’API Chat de Botpress gère la logique du chatbot, la recherche d’informations et les workflows, accessibles via un client Python personnalisé.
- L’application Streamlit gère les conversations, affiche les réponses en temps réel et s’intègre avec des sessions utilisateur dynamiques.
À ma connaissance, Streamlit est le moyen le plus rapide pour lancer une application web personnalisable. Si vous souhaitez créer un chatbot IA et le déployer sur votre propre interface, je ne vois pas de meilleure option.
La seule limite concerne la bibliothèque d’éléments de chat. Elle est surtout conçue pour l’API d’OpenAI et son client Python.
C’est très pratique : quelques lignes de code suffisent pour interagir avec une technologie de pointe, ce qui est… génial.
Mais ce n’est pas tout.
Et si vous souhaitez avoir plus de contrôle sur votre bot ? Par exemple, vous pourriez vouloir un flux de travail en plusieurs étapes, ou bien la génération augmentée par récupération (RAG). Ajouter ce type de fonctionnalités implique généralement de devoir assembler différentes bibliothèques avec de nombreuses dépendances.
Ou bien, est-ce vraiment le cas ?
Dans ce tutoriel, je vais créer un client chatbot hébergé sur Streamlit. Je vais vous montrer une interface pour itérer rapidement et personnaliser votre chatbot. Ensuite, vous apprendrez à intégrer le chatbot avec un client Python personnalisé, inspiré d’OpenAI.
Si vous faites du prototypage, les dépendances et détails techniques ne devraient pas vous freiner.
Et, pour aller plus vite, si vous voulez passer directement à la pratique, le code est disponible sur GitHub.
C’est parti 💣
Étape 1 : Créer la logique du chatbot
Que ce soit pour automatiser des tâches ou pour un chatbot de prise de rendez-vous, tout est possible ici.
Je vous encourage à explorer la variété des cas d’usage des chatbots GenAI si vous cherchez de l’inspiration. Pour simplifier, je vais reprendre mon sommelier, Winona, qui commence à être connu.
Notre petit bot sophistiqué et serviable peut être créé en quelques étapes. Je vais faire court, mais il existe de nombreux tutoriels détaillés et très utiles à consulter.
1. Lui donner des instructions
Dans le studio, allons dans Accueil dans la barre latérale à gauche.

Vous devriez voir la section Instructions au centre. Cliquez dessus pour ajouter ou modifier les instructions en texte libre.

Cela donne des directives, une personnalité et des limites à notre bot. Avec un langage simple, vous pouvez orienter efficacement votre bot vers le comportement souhaité. Rendez-le plus humain, et
2. Construire le Flow
C’est ici que se trouve le cœur de la personnalité du bot : accès à des infos précises, étapes rigides, exécution de code, etc.
Ne sous-estimez pas la puissance de la simplicité. Un seul nœud autonome peut rivaliser avec les agents de raisonnement. J’en ai un relié à ma base de connaissances (KB).

3. Ajouter la base de connaissances
Si les instructions donnent le ton, la KB apporte les faits concrets. Dans mon cas, il s’agit des vins du jeu de données Wine Reviews : une liste de vins, descriptions et prix. Je vais l’utiliser comme inventaire de vins pour notre bot sommelier.
Je clique sur Tables dans le panneau de gauche, puis sur Nouvelle table en haut à gauche, et je lui donne un nom explicite.

Cliquez sur les points de suspension verticaux (⋮) en haut à droite, puis sur Importer.

Glissez votre fichier .csv dans la fenêtre qui s’ouvre et suivez les instructions à l’écran.
Pour rendre la table accessible à votre bot, allez dans Bases de connaissances dans la barre latérale gauche.

Cliquez sur la petite icône de table verte et sélectionnez la source souhaitée. Cliquez sur Ajouter des tables.

Assurez-vous que votre flow a accès à la base de connaissances et tout est prêt.

Étape 2: Ajouter l’intégration Chat API
Le point de contact entre le bot et notre client local est l’API Chat. Pour l’ajouter à notre bot, faites défiler jusqu’à Canaux de communication et cliquez sur … Plus.

Parcourez les intégrations si vous le souhaitez. Nous cherchons Chat. J’ai dû faire défiler un peu pour le trouver.

Cliquez sur l’intégration puis sur Installer l’intégration dans la fenêtre qui s’ouvre.

Une fois installée, vous verrez l’ID de l’API Chat à la fin de l’URL du webhook. Vous en aurez besoin plus tard.
Étape 3: Écrire le client Python
L’API Chat propose plusieurs endpoints pour effectuer des opérations CRUD sur les utilisateurs, conversations et messages. Comme promis, je vais regrouper tout ça dans un client Python qui pourra remplacer un client OpenAI.
1. Ajouter vos identifiants
class BotpressClient:
def __init__(self, api_id=None, user_key=None):
self.api_id = api_id or os.getenv("CHAT_API_ID")
self.user_key = user_key or os.getenv("USER_KEY")
self.base_url = f"{BASE_URI}/{self.api_id}"
self.headers = {
**HEADERS,
"x-user-key": self.user_key,
}
Vous pouvez ajouter votre ID Chat API dans un fichier .env – c’est utile pour le débogage, mais pas indispensable. Nous gérerons l’ID API et la clé utilisateur lors de la création de l’app Streamlit.
Je garde BASE_URI et HEADERS dans un fichier séparé constants.py, pour plus de clarté.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. Créer les méthodes de requête
def _request(self, method, path, json=None):
url = f"{self.base_url}{path}"
try:
response = requests.request(method, url, headers=self.headers, json=json)
response.raise_for_status()
return response.json()
except requests.HTTPError:
return response.status_code, response.text
# --- Core API Methods ---
def get_user(self):
return self._request("GET", "/users/me")
def create_user(self, name, id):
user_data = {"name": name, "id": id}
return self._request("POST", "/users", json=user_data)
def set_user_key(self, key):
self.user_key = key
self.headers["x-user-key"] = key
def create_and_set_user(self, name, id):
new_user = self.create_user(name, id)
self.set_user_key(new_user["key"])
def create_conversation(self):
return self._request("POST", "/conversations", json={"body": {}})
def list_conversations(self):
return self._request("GET", "/conversations")
def get_conversation(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}")
def create_message(self, message, conversation_id):
payload = {
"payload": {"type": "text", "text": message},
"conversationId": conversation_id,
}
return self._request("POST", "/messages", json=payload)
def list_messages(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}/messages")Comme mentionné, presque toutes correspondent à un endpoint de l’API. Je les regroupe simplement dans une classe.
3. Créer un écouteur SSE
C’est là que ça devient un peu technique. Pour écouter les mises à jour de conversation et les transmettre à l’interface Streamlit, le client a besoin d’une méthode pour écouter et transmettre les événements envoyés par le serveur du bot.
def listen_conversation(self, conversation_id):
url = f"{self.base_url}/conversations/{conversation_id}/listen"
for event in sseclient.SSEClient(url, headers=self.headers):
print(event.data)
if event.data == "ping":
continue
data = json.loads(event.data)["data"]
yield {"id": data["id"], "text": data["payload"]["text"]}Cette fonction prend l’identifiant de la conversation (qui sera récupéré automatiquement dans l’app) et transmet les données reçues en temps réel.
Étape 4: Créer l’application Streamlit
Tout est prêt, il est temps de construire le chatbot. Je m’appuie sur le guide Streamlit pour créer une app de chat LLM, avec quelques fonctionnalités en plus.
1. Adapter le code de base
En théorie, l’application fonctionne avec très peu de modifications du code de base fourni dans l’exemple Streamlit.
# app.py
from client import BotpressClient
import streamlit as st
from constants import CONVERSATION_ID
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["USER_KEY"]
)
if "messages" not in st.session_state:
messages = client.list_messages(CONVERSATION_ID)
next_token = messages["meta"]["nextToken"]
st.session_state.messages = messages["messages"][::-1]
for message in st.session_state.messages:
with st.chat_message(message["userId"]):
st.markdown(message["payload"]["text"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
client.create_message(prompt, conversation_id=CONVERSATION_ID)
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
Ici, on lit des variables secrètes. Créez donc un fichier .streamlit/secrets.toml et placez vos variables dedans :
CHAT_API_ID = ”YOUR_API_ID”
USER_KEY = ”YOUR_USER_KEY”Le principal traitement se fait dans :
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
où le client se connecte aux éléments de chat pour envoyer et recevoir les messages.
Cela fonctionne, mais ce n’est pas idéal pour plusieurs raisons :
- Vous devez avoir créé une nouvelle conversation séparément.
- Les anciens messages seront formatés différemment des nouveaux, car ils n’ont pas d’attribution de rôle (utilisateur ou assistant).
- Impossible de changer de conversation.
2. Créer dynamiquement les conversations
En partant de zéro, je vais créer automatiquement une nouvelle conversation ou ouvrir la plus récente :
# app.py
from client import BotpressClient
import streamlit as st
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["users"][0]["key"]
)
# user info
user = client.get_user()
user_id = user["user"]["id"]
conversations = client.list_conversations()["conversations"]
conversation_ids = [conv["id"] for conv in conversations]
# conversation
def create_conversation():
res = client.create_conversation()
print(f"Created new conversation: {res}")
conversation_id = res["conversation"]["id"]
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
st.rerun()
if not conversations:
create_conversation()
if "active_conversation" not in st.session_state:
st.session_state["active_conversation"] = conversations[0]["id"]
Notez que j’ai modifié les clés secrètes pour pouvoir stocker plusieurs utilisateurs. Modifiez votre fichier .streamlit/secrets.toml en conséquence :
[[users]]
key = "your_user_key"Vous pouvez répéter ce bloc autant de fois que nécessaire, en stockant les utilisateurs comme un tableau de tables.
3. Permettre aux utilisateurs de créer et de changer de conversation
Comme indiqué, cela crée un menu déroulant en haut avec un bouton pour choisir votre conversation.
col1, col2 = st.columns([5, 1])
with col1:
conversation_id = st.selectbox(
"Select Conversation",
options=[conv["id"] for conv in conversations],
index=conversation_ids.index(st.session_state.active_conversation),
)
with col2:
st.markdown("<div style='height: 1.9em'></div>", unsafe_allow_html=True)
if st.button("➕"):
create_conversation()
selected_conversation = client.get_conversation(conversation_id)4. Attribuer le bon rôle aux anciens messages
On va corriger le problème de formatage en attribuant le rôle utilisateur ou assistant à chaque ancien message :
if (
"messages" not in st.session_state
or st.session_state.get("active_conversation") != conversation_id
):
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
messages = client.list_messages(conversation_id)
next_token = messages["meta"].get("nextToken")
for message in messages["messages"][::-1]:
role = "user" if message["userId"] == user_id else "assistant"
text = message["payload"]["text"]
st.session_state.messages.append({"role": role, "content": text})Cela rend notre code conforme à la structure attendue par Streamlit.
5. Ajouter la logique de messagerie
C’est à peu près la même chose qu’avant, adaptée à la nouvelle structure.
# display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
client.create_message(prompt, conversation_id=conversation_id)
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
stream = client.listen_conversation(conversation_id=conversation_id)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})5. Créer un utilisateur
La logique est prête, mais il faut créer un utilisateur pour lancer l’application. J’ai choisi de le faire séparément pour simuler une inscription. Bonne nouvelle, j’ai aussi écrit un script :
# create_user.py
import argparse
from pathlib import Path
from client import *
from constants import *
secrets_path = Path(".streamlit") / "secrets.toml"
template = """[[users]]
key="{}"
"""
client = BotpressClient()
def create_user(name, id, add_to_secrets=True):
res = client.create_user(name, id)
if not add_to_secrets:
return res
secrets_path.touch(exist_ok=True)
with open(secrets_path, "a") as f:
f.write(template.format(res["user"]["id"], res["key"]))
return res
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Create a Botpress user and optionally store secrets."
)
parser.add_argument("--name", required=True, help="Display name of the user.")
parser.add_argument(
"--id", required=True, help="User ID. If omitted, one is generated by the API."
)
parser.add_argument("--chat_api_id", help="ID for the Botpress Chat API integration. Taken from `.env` file if not provided.")
parser.add_argument(
"--no-secrets",
action="store_true",
help="Do not append to .streamlit/secrets.toml.",
)
args = parser.parse_args()
print(f"Creating user: {args.name} (ID: {args.id or 'auto-generated'})")
result = create_user(name=args.name, id=args.id, add_to_secrets=not args.no_secrets)
print("✅ User created:")
print(result)
Si vous avez votre ID Chat API, vous pouvez lancer :
python create_user.py –name VOTRE_NOM –id UN_ID_UTILISATEUR –chat_api_id VOTRE_CHAT_API_ID
Cela créera l’utilisateur et l’ajoutera à votre fichier secrets.
Étape 5 : Lancer l’application
Une fois votre logique créée et votre utilisateur configuré, il est temps de tester l’application. Installez les dépendances, puis lancez:
streamlit run app.py
Et voilà, vous verrez notre bot en action.

Lancez un chatbot Streamlit dès aujourd’hui
Si vous faites du prototypage avec Streamlit, vous savez que la personnalisation ne doit pas se faire au détriment de la simplicité. Les chatbots sont là pour résoudre des problèmes, pas en créer.
Botpress propose un éditeur visuel en glisser-déposer, des dizaines d’intégrations officielles et des points d’accès API accessibles. Vous pouvez ainsi concevoir, tester et déployer sur de nombreux canaux de communication.
Commencez à créer dès aujourd’hui. C’est gratuit.
FAQ
Pourquoi choisir Streamlit plutôt qu’un autre framework front-end pour créer un chatbot?
Vous choisirez Streamlit pour créer un chatbot si vous cherchez une solution rapide basée sur Python, qui permet de prototyper des applications interactives sans expertise front-end. Streamlit gère les éléments d’interface comme les composants de chat et la gestion d’état avec très peu de code.
Un chatbot Streamlit convient-il à un usage en production ou seulement pour des prototypes ?
Un chatbot Streamlit est idéal pour les prototypes et les outils internes. Pour une application publique avec beaucoup de trafic ou un style avancé, il faudra ajouter des couches supplémentaires comme des reverse proxies, renforcer la sécurité et éventuellement utiliser un framework front-end plus robuste pour gérer la montée en charge.
Dans quelle mesure peut-on personnaliser l’apparence et l’interface d’un chatbot conçu avec Streamlit ?
Streamlit permet d’ajuster les styles de base comme les couleurs, polices et la mise en page, mais il reste moins flexible que les frameworks web classiques. Pour un design vraiment personnalisé, il faut intégrer du HTML/CSS ou JavaScript, ce qui est possible mais plus complexe que d’utiliser les widgets intégrés de Streamlit.
Puis-je intégrer un chatbot Streamlit à un site web existant, ou doit-il fonctionner de manière autonome ?
Un chatbot Streamlit fonctionne généralement comme une application web indépendante avec sa propre URL. Il est possible de l’intégrer dans un site existant via une iframe, mais il faudra alors gérer le style et la sécurité pour garantir une expérience utilisateur fluide.
Combien coûte le déploiement d’un chatbot Streamlit pour un usage public ?
Déployer un chatbot Streamlit peut être gratuit si vous l’hébergez localement ou sur Streamlit Community Cloud pour de petites applications. Mais pour un usage public à grande échelle, les coûts varient généralement de 5 à 50 $US par mois sur des plateformes cloud comme Heroku, AWS ou DigitalOcean, selon le trafic et les besoins de disponibilité.





.webp)
