Regarde ton terminal. Si tout ce que tu vois, c'est un flot de print() gris, tu passes à côté d'un des plaisirs simples du développement : une sortie lisible, colorée, qui guide l'œil vers l'essentiel. Quand un script traite des centaines d'éléments, affiche un tableau de résultats ou affiche une erreur au milieu d'un mur de texte, la différence entre une sortie brute et une sortie structurée, c'est la différence entre comprendre en une seconde et relire trois fois.
C'est le terrain de Rich, la bibliothèque Python de Textualize (les créateurs de Textual). Elle ajoute des couleurs, des styles, des tableaux, des barres de progression, du Markdown, de la coloration syntaxique et des statuts animés à ton terminal, avec une API qui tient en quelques lignes. Le tout sans dépendre d'un environnement graphique : ça marche sur Windows, macOS et Linux, dans le terminal comme dans un notebook.
Dans ce tutoriel, tu vas remplacer tes print() par une sortie riche : colorer et styliser du texte, afficher des tableaux dignes d'un rapport, animer des barres de progression, colorer du code source, inspecter des objets, et même améliorer tes messages d'erreur. À la fin, ton terminal te remerciera.
Prérequis et installation
Rich est une bibliothèque purement Python, sans dépendance système. Elle fonctionne avec Python 3.7 ou plus récent. L'installation tient en une commande :
pip install richVérifie que tout est en place en affichant la version. Les exemples de ce tutoriel utilisent la série 13.x, et l'API présentée est stable depuis plusieurs versions. Rich détecte automatiquement si la sortie est un terminal interactif ou un fichier redirigé, et adapte son comportement en conséquence.
python -c "import rich; print(rich.__version__)"Pourquoi Rich plutôt qu'un print() ou colorama
Colorer un terminal n'est pas nouveau : les codes d'échappement ANSI existent depuis des décennies, et des bibliothèques comme colorama les enveloppent proprement. Mais Rich va beaucoup plus loin qu'une simple coloration. Les différences qui comptent :
- Un balisage inline : [bold red]texte[/bold red] dans une chaîne, au lieu d'appels de fonctions enchevêtrés.
- Des composants prêts à l'emploi : tableaux, arbres, panneaux, barres de progression, Markdown, coloration syntaxique.
- Une gestion fine du terminal : largeur, hauteur, détection des capacités, repli automatique sans couleur si la sortie est redirigée.
- Des tracebacks et un inspecteur d'objets qui transforment le débogage.
En clair, colorama te donne des pinceaux ; Rich te donne un atelier complet. Une fois que tu auras goûté à un tableau bien aligné ou à une barre de progression animée, tu ne voudras plus revenir aux print() bruts.
Ton premier print() version Rich
Le raccourci le plus spectaculaire : importer print depuis rich. Il remplace le print() standard et comprend le balisage entre crochets. C'est la porte d'entrée la plus simple :
from rich import print
print("Hello, [bold magenta]World[/bold magenta]!")
print("[green]Succès[/green] :", 42)
print("[red]Erreur[/red] : fichier introuvable")Le texte entre crochets est un balisage : bold active le gras, magenta la couleur, et la balise fermante [/bold magenta] revient au style précédent. Tu peux combiner plusieurs styles dans la même chaîne, et mélanger librement texte stylisé et variables Python.
Couleurs et styles : gras, italique, souligné
Rich expose un nuancier complet et tous les styles typographiques classiques. Le Console te donne un contrôle plus fin que print, notamment pour définir un style directement sur un appel :
from rich.console import Console
console = Console()
# Styles simples
console.print("Texte en gras", style="bold")
console.print("Texte en italique", style="italic")
console.print("Rouge sur fond blanc", style="red on white")
# Combinaisons inline
console.print("[bold underline red]Important[/bold underline red]")
# Couleur precise en RGB
console.print("[rgb(255,192,203)]Rose bonbon[/rgb(255,192,203)]")Les couleurs disponibles couvrent les huit couleurs de base et leurs variantes, plus des teintes hexadécimales et RGB. La syntaxe couleur sur couleur (red on white) définit le texte et le fond en une fois. Pour une interface de ligne de commande, définis une convention cohérente : vert pour le succès, rouge pour l'erreur, jaune pour les avertissements.
Le Console : contrôle fin et journalisation
Le Console est l'objet central de Rich. Il sait écrire sur une sortie donnée, mesurer la largeur du terminal, et logger des messages avec un niveau de gravité. C'est aussi lui qui gère les couleurs quand la sortie est redirigée vers un fichier :
from rich.console import Console
console = Console()
# Niveaux de journalisation avec styles predefinis
console.log("Un simple message d'information")
console.log("Attention, quelque chose cloche", style="yellow")
console.log("Echec critique", style="bold red")
# Ecrire vers un fichier avec couleur desactivee automatiquement
with open("sortie.txt", "w", encoding="utf-8") as f:
fichier_console = Console(file=f)
fichier_console.print("Ce texte ira dans le fichier, sans code de couleur.")La méthode log préfixe chaque ligne avec l'heure, pratique pour tracer l'exécution d'un script long. Et le comportement avec un fichier est exemplaire : Rich détecte que la sortie n'est pas un terminal et retire les codes de couleur, ce qui évite les artefacts dans les logs.
Afficher du Markdown dans le terminal
Tu rédiges déjà du Markdown dans tes documents et tes issues GitHub. Rich le rend directement dans le terminal, avec titres, listes, gras et italique correctement mis en forme :
from rich.console import Console
from rich.markdown import Markdown
contenu = """# Rapport quotidien
## Points clés
- Le pipeline a traité **12 400** documents.
- Le taux d'erreur est de *0,4 %*.
- Trois modèles ont été mis à jour.
> Conclusion : tout est sous contrôle.
"""
Console().print(Markdown(contenu))C'est un moyen élégant d'afficher de la documentation, un rapport ou un résumé sans réinventer la mise en forme. Rich gère les titres, les listes, les citations, les blocs de code et les liens, le tout adapté à la largeur de ton terminal.
Des tableaux dignes d'un rapport
Le composant Table est sans doute le plus utile au quotidien : il aligne les colonnes, gère les titres, les styles par colonne et les totaux. Voici un tableau de comparaison de modèles :
from rich.console import Console
from rich.table import Table
table = Table(title="Comparatif de modèles IA")
table.add_column("Modèle", style="cyan", no_wrap=True)
table.add_column("Taille", justify="right", style="magenta")
table.add_column("Prix / 1M tokens", justify="right", style="green")
table.add_row("GPT-4o", "n/a", "2,50 $")
table.add_row("Claude Sonnet", "n/a", "3,00 $")
table.add_row("Mistral Large", "123B", "2,00 $")
table.add_row("Llama 3", "70B", "0,60 $")
Console().print(table)Chaque colonne peut avoir son alignement, sa couleur et un style. Le titre, les bordures et l'alignement sont calculés automatiquement à partir de la largeur du terminal. Pour un rapport ou un script d'analyse, c'est un bond qualitatif immédiat.
Barres de progression animées
Pour un script qui traite beaucoup d'éléments, une barre de progression transforme l'attente en information. Le helper track s'enroule autour d'un itérable et affiche une barre, un pourcentage et un débit :
from rich.progress import track
import time
# track enveloppe n'importe quel iterable
for i in track(range(100), description="Traitement des données..."):
time.sleep(0.02) # simule un travailPour des cas plus riches (plusieurs barres simultanées, étapes, colonnes personnalisées), la classe Progress offre un contrôle total. L'intérêt d'une barre n'est pas cosmétique : elle te dit immédiatement où en est un traitement long, et te permet de repérer une tâche anormalement lente.
Statuts et spinners pour les tâches longues
Quand une étape prend quelques secondes sans progression mesurable, un statut animé est plus adapté qu'une barre. Le gestionnaire de contexte status affiche un spinner avec un message, puis le remplace par un résultat à la sortie :
from rich.console import Console
import time
console = Console()
with console.status("Chargement du modèle...", spinner="dots"):
time.sleep(3) # simule un chargement
console.print("[green]Modèle chargé ![/green]")Plusieurs styles de spinner sont disponibles (dots, line, moon, etc.). Le statut est idéal pour les appels réseau, les chargements de fichiers ou toute opération dont tu ne peux pas mesurer la progression, mais dont tu veux signaler qu'elle est en cours.
Coloration syntaxique de code source
Si ton script affiche du code (extraits, erreurs, exemples), le composant Syntax le colore comme un éditeur, avec numéros de ligne et thème au choix :
from rich.console import Console
from rich.syntax import Syntax
source = """def bonjour(nom):
return f"Bonjour {nom} !"
"""
syntaxe = Syntax(source, "python", theme="monokai", line_numbers=True)
Console().print(syntaxe)Rich prend en charge des dizaines de langages (Python, JavaScript, SQL, JSON, Bash, et bien d'autres) et plusieurs thèmes. C'est un vrai plus pour les outils qui affichent des extraits de code, comme un linter ou un assistant de révision.
Arbres, panneaux et mises en page
Pour structurer une hiérarchie ou encadrer un contenu, Rich propose des composants dédiés. Tree dessine une arborescence, Panel encadre un bloc, et Columns organise plusieurs blocs côte à côte :
from rich.console import Console
from rich.tree import Tree
from rich.panel import Panel
console = Console()
# Une arborescence
projet = Tree("Mon projet IA")
rag = projet.add("Module RAG")
rag.add("Embeddings")
rag.add("Base vectorielle")
projet.add("API FastAPI")
console.print(projet)
# Un panneau encadre
console.print(Panel("Résumé du rapport", title="Synthese", border_style="blue"))Ces composants s'emboîtent : tu peux placer un tableau dans un panneau, un arbre dans une colonne, etc. C'est cette composabilité qui rend Rich si agréable à assembler : chaque brique est simple, et leur combinaison couvre la plupart des besoins d'affichage.
Alignement, padding et mises en forme fines
Au-delà des gros composants, Rich offre des briques de mise en forme élémentaires qui affinent n'importe quel affichage : Padding ajoute des marges, Align centre un bloc, et Text permet d'appliquer un style global à plusieurs lignes d'un coup :
from rich.console import Console
from rich.align import Align
from rich.padding import Padding
from rich.text import Text
console = Console()
message = Text("Titre centré", style="bold cyan")
console.print(Align.center(message))
encadre = Padding("Contenu avec marges", (1, 4))
console.print(encadre)Ces primitives composent bien avec le reste : un tableau centré dans un panneau avec des marges donne un rendu de rapport soigné. Quand le rendu par défaut te semble trop dense, c'est souvent Padding qu'il te faut.
Tout assembler : un script complet
Pour finir, voici un mini-script réaliste qui combine table, progression et statut dans un flux cohérent : il traite une liste d'articles, affiche un statut pendant le traitement, progresse avec une barre, puis résume le tout dans un tableau :
from rich.console import Console
from rich.table import Table
from rich.progress import track
import time
console = Console()
articles = ["Intro à Python", "DuckDB en 10 minutes", "Playwright", "edge-tts"]
resultats = []
with console.status("Initialisation du pipeline...", spinner="dots"):
time.sleep(1)
for article in track(articles, description="Traitement des articles"):
time.sleep(0.4) # simule le travail
resultats.append((article, "OK"))
table = Table(title="Résumé du traitement")
table.add_column("Article", style="cyan")
table.add_column("Statut", style="green")
for nom, statut in resultats:
table.add_row(nom, statut)
console.print(table)
console.print("[green]Traitement terminé :[/green]", len(resultats), "articles.")Ce script illustre la bonne façon d'agencer les composants : un statut pour l'initialisation, une barre pour la boucle, un tableau pour le bilan. Chaque brique répond à un besoin précis, et l'ensemble reste lisible.
Inspecter des objets Python
Le débogage passe souvent par l'observation d'un objet. La fonction inspect remplace avantageusement un print(variable) en affichant la structure, les types et même les méthodes d'un objet, le tout en couleur :
from rich import inspect
donnees = {
"nom": "iancr",
"articles": [1, 2, 3],
"actif": True,
}
# Vue structuree avec types et methodes
inspect(donnees, methods=True)inspect gère les dictionnaires, les listes, les objets et les classes. C'est un réflexe à adopter dans tes sessions interactives ou tes scripts de diagnostic : tu vois d'un coup d'œil la forme d'un objet là où un print() n'affiche qu'une ligne compacte et illisible.
Mise à jour en place avec Live
Parfois, tu veux rafraîchir une zone de l'écran au lieu d'empiler des lignes : un compteur, un tableau qui évolue, un moniteur en temps réel. Le gestionnaire Live réécrit son contenu sur place à intervalles réguliers :
from rich.live import Live
from rich.table import Table
import time
def construire_table(i):
t = Table()
t.add_column("Itération", justify="right")
t.add_column("Avancement")
t.add_row(str(i), "█" * (i % 30))
return t
with Live(construire_table(0), refresh_per_second=10) as live:
for i in range(50):
time.sleep(0.05)
live.update(construire_table(i + 1))Live est la brique des tableaux de bord en terminal : moniteur de tâches, affichage de métriques en direct, suivi d'un entraînement de modèle. Combiné à un Table ou à un Panel, il donne un rendu professionnel sans sortir du terminal.
Des messages d'erreur enfin lisibles
Le traceback par défaut de Python est dense et difficile à lire. Rich le reformate avec les variables locales, la coloration syntaxique et une mise en page claire. Une seule ligne suffit :
from rich.traceback import install
# Installe le gestionnaire de tracebacks Rich pour tout le script
install(show_locals=True)
# Cette ligne va lever une exception : observe le traceback ameliore
1 / 0L'option show_locals affiche les variables locales au moment de l'erreur, ce qui résout souvent le problème sans ajouter de print() de débogage. C'est le genre d'amélioration qu'on regrette de ne pas avoir adoptée plus tôt.
Bonnes pratiques et pièges à éviter
Quelques réflexes pour tirer le meilleur de Rich sans te tirer une balle dans le pied :
- Ne mélange pas print() et Console : utilise le Console pour tout ce qui est stylisé, et réserve print() standard aux cas où tu veux explicitement éviter le traitement.
- Pense à la redirection : Rich retire les couleurs quand la sortie n'est pas un terminal, mais un tableau très large peut être tronqué. Teste aussi en redirection.
- Garde un style cohérent : définis une petite convention (couleurs des succès/erreurs, format des tableaux) et tiens-t'y dans tout le projet.
- Désactive les barres de progression en environnement non interactif : dans un cron ou un CI, préfère un log simple à une animation.
- Attention aux très gros tableaux : afficher des milliers de lignes d'un coup reste lent et illisible. Pagine ou tronque.
Un dernier conseil : Rich est aussi la fondation de Textual, un framework complet d'interfaces de terminal. Si tu finis par vouloir plus qu'un affichage (des boutons, des formulaires, des applications interactives), c'est la suite naturelle de ta progression.
Conclusion
Tu sais désormais transformer un terminal terne en sortie riche : couleurs et styles, Markdown, tableaux alignés, barres de progression, statuts animés, coloration syntaxique, arbres et panneaux, inspection d'objets, affichage en temps réel et tracebacks lisibles. Le tout avec une bibliothèque légère et sans dépendance.
La prochaine fois que tu écriras un script, un outil CLI ou un rapport d'analyse, accorde quelques lignes à la présentation. Tes collègues, tes utilisateurs et ton futur toi en train de relire les logs te remercieront. Un terminal bien présenté, c'est un outil qu'on a envie d'utiliser.
Rich a aussi un effet secondaire agréable : il rend la programmation plus satisfaisante. Voir une barre avancer, un tableau s'aligner, une erreur s'expliquer clairement, ça transforme un script utilitaire en petit plaisir quotidien. Et un développeur qui prend plaisir à son outil écrit du meilleur code.
Pour aller plus loin
Le dépôt officiel : github.com/Textualize/rich, avec de nombreux exemples dans le README.
La documentation Rich couvre chaque composant en détail, ainsi que les API de Console et de Progress.






