Streamlit s'est vraiment imposé en 2026 comme le framework Python de référence pour transformer un script d'analyse de données en application web interactive — sans écrire une seule ligne de HTML, CSS ou JavaScript. Avec la sortie de Streamlit 1.55.0 en mars 2026, le framework introduit des conteneurs dynamiques, le binding d'URL et une intégration ASGI native qui changent la façon dont les data scientists francophones construisent leurs tableaux de bord. Dans ce guide, on va construire ensemble un dashboard data science complet, l'optimiser, et le déployer gratuitement sur Streamlit Community Cloud.
Honnêtement, après avoir bricolé pas mal de dashboards en Dash et Flask ces dernières années, revenir à Streamlit donne presque envie de pleurer (de joie). Mais bon, voyons ça en pratique.
Pourquoi choisir Streamlit pour vos dashboards data science en 2026
Contrairement à Flask ou Django, Streamlit ne demande aucune connaissance front-end. Vous écrivez du Python pur, et le framework gère le rendu des widgets, la gestion d'état et le serveur web. Trois éléments expliquent l'adoption massive du framework cette année :
- Productivité extrême — un dashboard fonctionnel se construit en moins de 100 lignes de code Python.
- Écosystème mature — 38 000 étoiles GitHub, plus de 90 % des entreprises Fortune 50 l'utilisent en interne, et des milliers de composants communautaires sont disponibles (streamlit-aggrid, streamlit-option-menu, streamlit-extras… la liste est longue).
- Déploiement gratuit — Streamlit Community Cloud héberge gratuitement les applications publiques liées à un dépôt GitHub.
En face, Dash (Plotly) offre plus de contrôle pixel-perfect, mais avec une courbe d'apprentissage nettement plus raide. Gradio, lui, reste centré sur les démonstrations de modèles ML Hugging Face. Pour un dashboard analytique généraliste ? Streamlit reste le choix le plus rapide. Point.
Installation et configuration de l'environnement
Streamlit 1.55.0 supporte Python 3.9 à 3.14, mais Python 3.12 ou 3.13 offre le meilleur compromis entre performance et compatibilité avec les bibliothèques data science. Créez un environnement virtuel dédié — c'est la base — pour éviter les conflits de dépendances.
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
pip install --upgrade pip
pip install streamlit==1.55.0 pandas==2.3.0 plotly==5.24.1 numpy==2.4.0
Vérifiez l'installation avec la commande de démonstration intégrée :
streamlit hello
Cette commande lance un navigateur sur http://localhost:8501 et affiche une galerie d'exemples interactifs. Si la page s'ouvre, votre installation est fonctionnelle. Sinon, c'est probablement un souci de PATH ou d'environnement virtuel mal activé (j'ai été là, plusieurs fois).
Structure de projet recommandée pour un dashboard data science
mon-dashboard/
├── app.py # Point d'entrée principal
├── pages/ # Pages secondaires
│ ├── 1_Ventes.py
│ ├── 2_Modele_ML.py
│ └── 3_KPIs.py
├── data/
│ └── ventes_2026.csv
├── utils/
│ ├── __init__.py
│ ├── chargement.py
│ └── graphiques.py
├── .streamlit/
│ └── config.toml # Theme et configuration
├── requirements.txt
└── README.md
Première application Streamlit en 5 minutes
Allez, on passe au concret. Créez un fichier app.py avec le code suivant. Cet exemple charge un jeu de données de ventes, ajoute des filtres latéraux et affiche des KPIs.
import streamlit as st
import pandas as pd
import numpy as np
st.set_page_config(
page_title="Dashboard Ventes 2026",
page_icon="bar_chart",
layout="wide",
initial_sidebar_state="expanded",
)
st.title("Dashboard Ventes — Edition 2026")
st.caption("Analyse interactive des ventes trimestrielles")
# Generation de donnees factices reproductibles
rng = np.random.default_rng(42)
df = pd.DataFrame({
"date": pd.date_range("2026-01-01", periods=120, freq="D"),
"region": rng.choice(["Ile-de-France", "PACA", "Bretagne", "Occitanie"], 120),
"produit": rng.choice(["Logiciel", "Service", "Formation"], 120),
"ventes": rng.integers(500, 5000, 120),
})
# Filtres dans la barre laterale
with st.sidebar:
st.header("Filtres")
regions = st.multiselect(
"Regions",
options=df["region"].unique(),
default=df["region"].unique(),
)
produits = st.multiselect(
"Produits",
options=df["produit"].unique(),
default=df["produit"].unique(),
)
filtre = df[df["region"].isin(regions) & df["produit"].isin(produits)]
# Indicateurs cles
col1, col2, col3, col4 = st.columns(4)
col1.metric("Total ventes", f"{filtre['ventes'].sum():,} EUR", "+12,4 %")
col2.metric("Ventes moyennes", f"{filtre['ventes'].mean():.0f} EUR", "+3,2 %")
col3.metric("Transactions", len(filtre), "-1,8 %")
col4.metric("Regions actives", filtre["region"].nunique())
st.divider()
st.dataframe(filtre, use_container_width=True, hide_index=True)
Lancez l'application avec streamlit run app.py. Toute modification du fichier déclenche un rechargement automatique — un détail qui change la vie quand on itère.
Maîtriser les widgets interactifs de Streamlit
Streamlit propose plus de 30 widgets natifs. Les nouveautés 2026 méritent une attention particulière, car elles débloquent des cas d'usage avancés (oui, vraiment).
Widgets essentiels pour un dashboard
st.selectboxetst.multiselect— désormais avec un paramètrefilter_modequi permet à l'utilisateur de chercher en tapant.st.slideretst.date_input— idéaux pour filtrer des plages temporelles.st.toggle— alternative moderne àst.checkboxpour les options on/off.st.menu_button(nouveau en 2026) — un bouton déroulant avec popover, parfait pour construire des menus et barres d'outils.st.iframe(nouveau en 2026) — pour intégrer des URL externes ou du HTML brut.
import streamlit as st
from datetime import date
# Selection de plage de dates
periode = st.date_input(
"Periode d'analyse",
value=(date(2026, 1, 1), date(2026, 4, 30)),
min_value=date(2025, 1, 1),
max_value=date(2026, 12, 31),
)
# Slider numerique
seuil = st.slider("Seuil minimum (EUR)", 0, 10000, 500, step=100)
# Selectbox avec filtrage
ville = st.selectbox(
"Ville",
options=["Paris", "Lyon", "Marseille", "Toulouse", "Bordeaux", "Lille"],
filter_mode="contains", # Nouveaute 2026
)
# Toggle moderne
mode_avance = st.toggle("Mode analyse avancee", value=False)
if mode_avance:
st.info("Activation des graphiques temps reel et exports PDF")
Afficher et manipuler des DataFrames Pandas
st.dataframe a reçu pas mal d'améliorations en 2026 : sélection programmable, mode "single-row-required", alignement de colonnes configurable, et configuration fine des colonnes via st.column_config. C'est le genre de petites évolutions qui, mises bout à bout, font une vraie différence en production.
import streamlit as st
import pandas as pd
df = pd.read_csv("data/ventes_2026.csv", parse_dates=["date"])
selection = st.dataframe(
df,
use_container_width=True,
hide_index=True,
on_select="rerun",
selection_mode="multi-row",
column_config={
"date": st.column_config.DateColumn(
"Date", format="DD/MM/YYYY"
),
"ventes": st.column_config.NumberColumn(
"Ventes (EUR)",
format="%d EUR",
help="Chiffre d'affaires hors taxes",
),
"satisfaction": st.column_config.ProgressColumn(
"Satisfaction",
min_value=0,
max_value=100,
format="%d %%",
),
},
)
# Recuperation des lignes selectionnees
if selection.selection.rows:
lignes = df.iloc[selection.selection.rows]
st.write(f"Total selectionne : {lignes['ventes'].sum():,} EUR")
Pour permettre l'édition directe des données par l'utilisateur, utilisez st.data_editor. Toute modification est renvoyée sous forme de DataFrame Pandas — parfait pour les outils de saisie ou d'annotation, et bien plus rapide à mettre en place qu'un formulaire HTML traditionnel.
Visualisations interactives avec Plotly et Altair
Streamlit prend en charge nativement Matplotlib, Seaborn, Plotly, Altair, Bokeh, et propose ses propres graphiques rapides (st.line_chart, st.bar_chart, st.scatter_chart, st.map). Pour un dashboard 2026, Plotly reste à mon avis le meilleur compromis entre interactivité et lisibilité.
import streamlit as st
import plotly.express as px
# Evolution temporelle
fig_temps = px.line(
df, x="date", y="ventes", color="region",
title="Evolution des ventes par region",
template="plotly_white",
)
fig_temps.update_layout(height=400, hovermode="x unified")
st.plotly_chart(fig_temps, use_container_width=True)
# Repartition en camembert
col_a, col_b = st.columns(2)
with col_a:
fig_pie = px.pie(
df, names="produit", values="ventes",
title="Repartition par produit", hole=0.4,
)
st.plotly_chart(fig_pie, use_container_width=True)
with col_b:
fig_bar = px.bar(
df.groupby("region")["ventes"].sum().reset_index(),
x="region", y="ventes",
title="Total par region",
color="ventes", color_continuous_scale="Viridis",
)
st.plotly_chart(fig_bar, use_container_width=True)
Optimiser les performances avec st.cache_data et st.cache_resource
Sans cache, Streamlit réexécute votre script entier à chaque interaction. Pour un dashboard chargeant des fichiers volumineux ou interrogeant une base de données, ce comportement devient rapidement insupportable (croyez-moi, j'ai testé). Heureusement, deux décorateurs résolvent élégamment le problème.
st.cache_data — pour les résultats sérialisables
À utiliser quand votre fonction renvoie un DataFrame, une liste, un dictionnaire ou tout objet sérialisable via pickle. Streamlit retourne une copie de l'objet à chaque appel, ce qui garantit la sécurité des mutations.
import streamlit as st
import pandas as pd
@st.cache_data(ttl=3600, max_entries=10, show_spinner="Chargement des ventes...")
def charger_ventes(chemin: str, annee: int) -> pd.DataFrame:
df = pd.read_parquet(chemin)
return df[df["date"].dt.year == annee]
ventes_2026 = charger_ventes("data/ventes.parquet", 2026)
Le paramètre ttl=3600 invalide le cache après une heure — parfait pour des données qui se rafraîchissent régulièrement. max_entries, lui, limite le nombre d'entrées stockées en mémoire (bien utile sur Community Cloud où la RAM est plafonnée).
st.cache_resource — pour les ressources non sérialisables
À utiliser pour les objets coûteux à instancier, et que vous ne voulez créer qu'une seule fois : connexions de base de données, modèles de machine learning, clients d'API. L'objet est partagé entre toutes les sessions et tous les utilisateurs.
import streamlit as st
import joblib
from sqlalchemy import create_engine
@st.cache_resource
def charger_modele():
return joblib.load("models/random_forest_v3.joblib")
@st.cache_resource
def connexion_postgres():
return create_engine(st.secrets["postgres"]["url"])
modele = charger_modele()
engine = connexion_postgres()
Attention : les objets en cache de ressources étant partagés, toute mutation est globale. C'est un piège dans lequel on tombe vite. Pour des objets propres à une session, utilisez plutôt st.session_state.
Applications multi-pages avec st.Page et st.navigation
L'API moderne pour les applications multi-pages utilise st.Page et st.navigation depuis Streamlit 1.36. En 2026, st.navigation reçoit un paramètre expanded, et st.Page accepte les URL externes ainsi qu'un paramètre visibility pour masquer des pages tout en gardant leur route active.
# app.py
import streamlit as st
ventes = st.Page("pages/ventes.py", title="Ventes", icon="bar_chart", default=True)
modele = st.Page("pages/modele.py", title="Modele ML", icon="robot")
kpi = st.Page("pages/kpi.py", title="KPIs", icon="chart")
admin = st.Page("pages/admin.py", title="Administration", visibility="hidden")
externe = st.Page(
"https://docs.streamlit.io",
title="Documentation",
)
pg = st.navigation(
{
"Analyses": [ventes, modele, kpi],
"Outils": [externe, admin],
},
expanded=True,
position="sidebar",
)
pg.run()
Cette approche remplace l'ancienne convention du dossier pages/ auto-détecté, et offre un contrôle bien plus fin sur la navigation. Si vous démarrez un nouveau projet aujourd'hui, partez directement sur st.navigation.
Fragments et reruns partiels avec st.fragment
Le décorateur @st.fragment, introduit en 1.37, permet de réexécuter uniquement une portion du code lors d'une interaction utilisateur, plutôt que le script entier. C'est, à mon sens, l'optimisation la plus impactante pour les dashboards complexes.
import streamlit as st
import time
st.title("Dashboard avec rafraichissement intelligent")
# Fragment qui se rafraichit toutes les 5 secondes sans toucher au reste
@st.fragment(run_every=5)
def afficher_metriques_temps_reel():
import random
cpu = random.randint(20, 80)
ram = random.randint(40, 90)
col1, col2 = st.columns(2)
col1.metric("CPU", f"{cpu} %")
col2.metric("RAM", f"{ram} %")
# Fragment qui ne reexecute que ses widgets internes
@st.fragment
def panneau_filtres():
region = st.selectbox("Region", ["Nord", "Sud", "Est", "Ouest"])
if st.button("Appliquer"):
st.rerun(scope="fragment") # Recharge juste le fragment
return region
afficher_metriques_temps_reel()
region_choisie = panneau_filtres()
st.write(f"Region active : {region_choisie}")
Sans fragment, chaque clic sur un widget rechargerait l'ensemble de l'application — y compris les requêtes lourdes. Avec st.fragment, seul le bloc concerné est réexécuté. Sur un dashboard avec 5 ou 6 sections indépendantes, le gain de réactivité est franchement spectaculaire.
Connexion aux sources de données avec st.connection
st.connection simplifie radicalement l'accès à PostgreSQL, MySQL, SQLite, Snowflake, BigQuery ou n'importe quelle source via SQLAlchemy. Les identifiants sont stockés dans .streamlit/secrets.toml et la connexion est mise en cache automatiquement.
# .streamlit/secrets.toml
[connections.ventes_db]
type = "sql"
url = "postgresql://utilisateur:motdepasse@localhost:5432/ventes"
import streamlit as st
conn = st.connection("ventes_db", type="sql")
df = conn.query(
"SELECT region, SUM(montant) AS total FROM ventes "
"WHERE date_vente >= :debut GROUP BY region",
params={"debut": "2026-01-01"},
ttl=600,
)
st.dataframe(df)
Gestion d'état avec st.session_state
Le session_state est un dictionnaire persistant entre les reruns d'une même session utilisateur. Indispensable pour conserver des paniers, des connexions utilisateur, des historiques de recherche — bref, tout état qui doit survivre aux interactions.
import streamlit as st
if "compteur" not in st.session_state:
st.session_state.compteur = 0
st.session_state.historique = []
col1, col2, col3 = st.columns(3)
if col1.button("Incrementer"):
st.session_state.compteur += 1
st.session_state.historique.append(st.session_state.compteur)
if col2.button("Decrementer"):
st.session_state.compteur -= 1
st.session_state.historique.append(st.session_state.compteur)
if col3.button("Reinitialiser"):
st.session_state.compteur = 0
st.session_state.historique.clear()
st.metric("Compteur", st.session_state.compteur)
st.line_chart(st.session_state.historique)
Déployer son dashboard sur Streamlit Community Cloud
Streamlit Community Cloud héberge gratuitement les dashboards publics liés à un dépôt GitHub. C'est, de loin, la voie la plus rapide entre votre code local et un partage URL avec vos collègues.
Étapes de déploiement détaillées
- Préparer le dépôt GitHub — créez un dépôt public contenant
app.py, le dossierpages/et un fichierrequirements.txtlistant toutes les dépendances avec leurs versions. - Fixer les versions — utilisez
pip freeze > requirements.txtdans votre environnement virtuel local pour garantir la reproductibilité. - Créer un compte sur
share.streamlit.ioavec votre identifiant GitHub. - Cliquer sur « New app » — sélectionnez le dépôt, la branche et le fichier d'entrée (
app.py). - Configurer les secrets dans l'interface (mots de passe, clés API) — ils sont accessibles via
st.secrets. - Déployer — Streamlit installe les dépendances et lance l'application. Surveillez les logs pour repérer les imports manquants (c'est souvent là que ça coince la première fois).
Limites de Community Cloud à connaître
- 1 Go de RAM par application, environ 50 à 100 utilisateurs simultanés.
- Le dépôt doit être public — pour des données sensibles, privilégiez Snowflake Streamlit ou un déploiement Docker.
- Les applications inactives plus de 7 jours sont mises en veille (redémarrage automatique au prochain accès).
- Pas de domaine personnalisé : l'URL est de la forme
monapp.streamlit.app.
Alternatives de déploiement pour la production
Pour des cas d'usage professionnels, trois options complètent Community Cloud :
- Docker — flexibilité maximale, contrôle des ressources, intégration avec Kubernetes pour la mise à l'échelle horizontale.
- Snowflake Streamlit — pour les organisations utilisant Snowflake, avec SSO, gouvernance d'équipe et applications privées.
- Hugging Face Spaces — gratuit, idéal pour des démos de modèles ML avec GPU disponibles.
Bonnes pratiques pour un dashboard performant en 2026
- Cachez systématiquement les chargements de fichiers et requêtes SQL avec
@st.cache_data(ttl=...). - Utilisez les fragments pour les zones interactives qui n'ont pas besoin de recharger toute l'application.
- Configurez un thème dans
.streamlit/config.tomlpour une identité visuelle cohérente. - Limitez la taille des DataFrames affichés — utilisez
st.dataframe(df.head(1000))et proposez des téléchargements viast.download_button. - Versionnez les données avec DVC ou Git LFS si vos fichiers dépassent 100 Mo.
- Stockez les secrets dans
.streamlit/secrets.toml(jamais dans le code) et ajoutez ce fichier au.gitignore. - Activez le mode wide avec
st.set_page_config(layout="wide")pour les tableaux de bord à plusieurs colonnes. - Profilez votre application avec
cProfileavant de blâmer Streamlit pour la lenteur — neuf fois sur dix, c'est une fonction Pandas mal optimisée qui est en cause.
Comparaison Streamlit, Dash et Gradio en 2026
- Streamlit — le meilleur pour les dashboards data science généralistes, prototypes rapides, outils internes. Productivité maximale.
- Dash (Plotly) — le meilleur pour les applications enterprise pixel-perfect, contrôle fin du layout, gros trafic. Courbe d'apprentissage plus raide.
- Gradio — le meilleur pour les démos de modèles ML, intégration native Hugging Face, partage public via lien
.gradio.live.
Pour la majorité des projets data science francophones — analyse exploratoire, reporting, démonstration de modèle ML, dashboard KPI — Streamlit reste le choix par défaut grâce à son ratio fonctionnalités/temps de développement tout simplement imbattable.
FAQ — Questions fréquentes sur Streamlit
Streamlit est-il gratuit ?
Oui. Streamlit est un framework open-source sous licence Apache 2.0, et Streamlit Community Cloud propose un hébergement gratuit pour les applications publiques. Les versions payantes (Snowflake Streamlit) ciblent les besoins d'entreprise avec applications privées, SSO et gouvernance.
Quelle est la différence entre st.cache_data et st.cache_resource ?
st.cache_data renvoie une copie sérialisée de l'objet et convient aux DataFrames, listes et dictionnaires. st.cache_resource renvoie l'objet original partagé entre toutes les sessions, parfait pour les modèles ML et connexions de base de données. Dans 90 % des cas, st.cache_data est le bon choix.
Combien d'utilisateurs simultanés Streamlit peut-il supporter ?
Une instance Streamlit gère environ 50 à 100 utilisateurs simultanés selon la complexité de l'application et les ressources serveur. Chaque session consomme entre 50 et 200 Mo de RAM. Pour davantage d'utilisateurs, il faut déployer plusieurs instances derrière un load balancer avec sticky sessions.
Comment protéger un dashboard Streamlit avec une authentification ?
Streamlit propose désormais une authentification native via OAuth2 (Google, Microsoft, Auth0) configurable dans secrets.toml. Pour un contrôle plus fin, utilisez streamlit-authenticator, qui gère utilisateurs, mots de passe hashés et rôles. En production enterprise, Snowflake Streamlit offre du SSO intégré.
Streamlit fonctionne-t-il avec des bibliothèques GPU comme PyTorch ?
Oui. Streamlit ne fait aucune hypothèse sur votre code Python — vous pouvez charger un modèle PyTorch ou TensorFlow sur GPU dans une fonction décorée par @st.cache_resource, puis l'utiliser dans votre application. Pour héberger sur GPU gratuitement, Hugging Face Spaces est une excellente alternative à Community Cloud.
Peut-on faire des graphiques 3D avec Streamlit ?
Absolument. Plotly et PyDeck (intégré nativement à Streamlit via st.pydeck_chart) supportent les visualisations 3D et géospatiales. PyDeck est particulièrement adapté aux cartes interactives à grande échelle (millions de points), tandis que Plotly excelle pour les nuages de points 3D et les surfaces scientifiques.