Module 1 — Premiers pas et modèle d'exécution de Streamlit
Streamlit tient sur une promesse : un fichier Python devient une application web. Aucun serveur à écrire, aucun modèle de composants à apprendre, aucun mélange de langages. Cette promesse repose sur un choix de conception assez radical, qu'il vaut mieux comprendre dès la première page, sinon toutes les décisions du cours paraîtront étranges. Ce module installe l'outil, écrit une première application, puis explique en détail ce qui se passe quand on clique.
Installer et lancer
L'installation ne demande qu'une seule commande, dans un environnement virtuel isolé pour ne pas contaminer le reste des projets :
python -m venv .venv
# Windows :
.venv\Scripts\activate
# macOS ou Linux :
source .venv/bin/activate
pip install streamlit pandas scikit-learn
La bibliothèque s'utilise ensuite via une seule commande, qui lit un fichier Python et sert son contenu sur http://localhost:8501 :
streamlit run app.py
L'ouverture du navigateur est automatique. Deux points valent d'être retenus. Le serveur détecte les modifications du fichier et propose de réexécuter, ce qui rend le cycle de développement très court. La commande streamlit hello ouvre une application de démonstration qui reste un excellent bac à sable pour tester une idée avant de la coder.
Une première page pour le fil rouge
Le cours entier construit un tableau de bord de prédiction de résiliation pour l'équipe commerciale d'un opérateur de télécoms. La toute première version tient dans une page. On charge un fichier de clients, on affiche un titre, un aperçu du tableau, et deux indicateurs.
import streamlit as st
import pandas as pd
st.set_page_config(page_title="Suivi de la résiliation", page_icon="📊", layout="wide")
st.title("Tableau de bord — Résiliation clients")
st.write("Version initiale : lecture du fichier clients, aperçu et indicateurs.")
clients = pd.read_csv("donnees/clients.csv")
col_gauche, col_droite = st.columns(2)
col_gauche.metric("Clients suivis", len(clients))
col_droite.metric("Ancienneté moyenne", f"{clients['anciennete_mois'].mean():.1f} mois")
st.dataframe(clients.head(20), use_container_width=True)
Six appels de fonctions et l'application existe. st.set_page_config doit être le tout premier appel Streamlit du fichier ; l'appeler après un st.write lève une erreur explicite. st.title et st.write produisent du texte, st.metric un cartouche d'indicateur, st.dataframe un tableau interactif avec tri par colonne et recherche.
Le modèle d'exécution : le script rejoué à chaque interaction
Voici l'idée centrale du framework, et la seule qui change tout le reste. À chaque interaction de l'utilisateur — un clic sur un bouton, un déplacement de curseur, la sélection d'une option — Streamlit relance le script Python du haut en bas. Il n'y a pas de gestionnaire d'événements, pas de mise à jour partielle, pas de rappel enregistré. On appelle cela le modèle de réexécution complète.
Un exemple rend la mécanique concrète. Ajoutons un bouton et un compteur :
compteur = 0
if st.button("Incrémenter"):
compteur += 1
st.write(f"Compteur : {compteur}")
L'intuition venue d'autres frameworks dit « le compteur augmente à chaque clic ». La réalité est différente : à chaque clic, le fichier est relancé, la variable compteur retrouve sa valeur initiale de zéro, le bouton produit True pour cette exécution, la variable passe à 1, la ligne suivante affiche 1. Au clic suivant, tout recommence : le compteur reste à 1, jamais 2. Pour conserver un état d'une exécution à l'autre, il faudra st.session_state, qui est le sujet du module 6.
Cette réexécution est plus qu'un détail d'implémentation. Elle façonne toute la façon d'écrire une application Streamlit. On ne pense plus « quand l'utilisateur clique, mettre à jour ceci » mais « à chaque exécution, décrire ce qui doit s'afficher en fonction de l'état courant des composants ». Le code devient déclaratif, comme une page qui se redessine intégralement à chaque changement.
Les conséquences pratiques
Trois habitudes en découlent, et les mauvaises surprises viennent presque toujours de leur oubli.
Isoler les calculs coûteux. Sans précaution, un modèle est rechargé du disque et une base est requêtée à chaque interaction, même pour un simple clic. C'est le rôle de st.cache_data et st.cache_resource, présentés au module 5. Une application qui recharge un modèle de 300 Mo à chaque curseur devient inutilisable en dix secondes.
Distinguer l'état persistant du reste. Ce qui doit survivre à une réexécution — la sélection en cours, la page ouverte, un panier — vit dans st.session_state. Ce qui doit se recalculer à partir des composants — un total, un graphique filtré — reste dans des variables locales. Confondre les deux mène à des bogues difficiles à localiser.
Écrire le script comme une vue. L'ordre du code est l'ordre d'affichage. Une valeur n'est disponible qu'après l'appel du composant qui la produit ; un st.button en fin de script ne peut pas influencer un graphique tracé plus haut, à moins d'utiliser un formulaire ou un rappel. Cette contrainte force une écriture en flux naturel, du plus général au plus détaillé.
Ce que voit l'utilisateur, ce que voit le développeur
Côté navigateur, Streamlit affiche une page web ordinaire, avec une URL et une barre de menu. Côté serveur, chaque onglet est une session, indépendante des autres : deux utilisateurs voient chacun leur propre état, tirent chacun leur propre exécution. Le journal de la commande streamlit run affiche chaque réexécution avec une trace complète des exceptions, ce qui reste l'outil de mise au point le plus efficace au début.
La confusion la plus fréquente en arrivant sur Streamlit vient d'un mauvais transfert d'habitudes venues de React, Vue ou Tkinter. Il n'y a pas d'événements à intercepter, pas de composants à mettre à jour à la main. Chaque composant renvoie une valeur — la position du curseur, le contenu du champ, True si le bouton vient d'être cliqué — et le script relit ces valeurs à chaque tour. Écrire une phrase du code, s'imaginer le script relancé du haut, et se demander « qu'est-ce qui s'affiche cette fois ? » : cette gymnastique devient rapidement naturelle.
En résumé
- Streamlit s'installe et se lance en deux commandes, et la commande
streamlit runsert un fichier Python comme une application web sur le port 8501. - La toute première ligne d'appel Streamlit doit être
st.set_page_config; les composants commest.title,st.dataframeoust.metricconstruisent la page dans l'ordre d'écriture du code. - À chaque interaction, le script est relancé du haut en bas : les variables locales repartent de zéro, seuls les composants et
st.session_stateconservent une valeur d'une exécution à l'autre. - Ce modèle impose trois habitudes : mettre en cache les calculs coûteux, distinguer l'état persistant, écrire le script comme une description de la vue actuelle plutôt que comme une suite d'événements.
Module suivant : les composants de saisie et d'affichage, ceux dont la valeur alimentera les prochains scores de résiliation.