Rich & Textual
Rich torna a saída do terminal legível - cores, tabelas, barras de progresso, tracebacks com realce de sintaxe. Textual é construído sobre Rich para criar interfaces de usuário de terminal (TUIs) completas com widgets, layouts e eventos assíncronos. Juntos, eles substituem a depuração print frágil e o boilerplate do curses.
Receita
from rich.console import Console
from rich.table import Table
console = Console()
table = Table(title="Status da Implantação")
table.add_column("Serviço")
table.add_column("Versão")
table.add_row("api", "2.1.0")
table.add_row("worker", "2.1.0")
console.print(table)Quando usar isso:
- Ferramentas de CLI que os operadores executam diariamente (implantação, migração, correções de dados)
- Scripts de longa duração que precisam de feedback de progresso
- Dashboards internos sem orçamento para interface web
- Saída de erro bonita durante o desenvolvimento local
Exemplo de Trabalho
from __future__ import annotations
import time
from dataclasses import dataclass
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TaskProgressColumn
@dataclass
class Job:
name: str
rows: int
def process_jobs(jobs: list[Job]) -> None:
console = Console(stderr=True)
with Progress(
SpinnerColumn(),
TextColumn("[bold blue]{task.description}"),
BarColumn(),
TaskProgressColumn(),
console=console,
) as progress:
task_id = progress.add_task("Processando", total=sum(j.rows for j in jobs))
for job in jobs:
progress.update(task_id, description=job.name)
for _ in range(job.rows):
time.sleep(0.01)
progress.advance(task_id)
console.print("[green]Concluído[/green]")
if __name__ == "__main__":
process_jobs([Job("users", 50), Job("orders", 30)])O que isso demonstra:
Console(stderr=True)mantém o stdout livre para pipingProgresscompõe colunas para spinner, rótulo, barra e porcentagem- A descrição da tarefa é atualizada por nome de trabalho
- Marcação de cor (
[green]) sem códigos de escape manuais
Mergulho Profundo
Como Funciona
- Console - Detecta a largura do terminal, suporte a cores e renderização de emojis; degrada graciosamente em logs de CI.
- Marcação - Tags no estilo
[bold red]erro[/];console.print(obj)imprime de forma bonita dataclasses e dicionários. - Exibição ao vivo -
rich.live.Liveatualiza tabelas ou logs no local sem piscar. - Textual - Framework TUI orientado a eventos; aplicativos herdam de
App, definemcompose()para widgets, lidam comon_button_pressedetc.
Rich vs Textual
| Ferramenta | Melhor Para |
|---|---|
| Rich | Saída de CLI única, progresso, embelezamento de logs |
| Textual | TUIs interativas: assistentes de configuração, rastreadores de logs, consoles de operações internas |
curses da stdlib | Dependências mínimas apenas em sistemas embarcados |
Notas de Python
# Instala tracebacks Rich globalmente em um ponto de entrada de CLI
from rich.traceback import install
install(show_locals=True)
# Esqueleto mínimo de aplicativo Textual
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static
class HelloApp(App):
def compose(self) -> ComposeResult:
yield Header()
yield Static("Olá do Textual")
yield Footer()
if __name__ == "__main__":
HelloApp().run()Armadilhas
- Imprimir tabelas no stdout em CLIs com pipe - Interrompe
jqougrepdownstream. Correção:Console(file=sys.stderr)para saída humana. - Assumir cor em CI - Alguns runners removem ANSI. Correção:
Console(force_terminal=True)apenas quando necessário; teste em modo simples. - Textual sem disciplina assíncrona -
time.sleepbloqueante em manipuladores congela a UI. Correção:await asyncio.sleepourun_worker. - Tabelas enormes em terminais estreitos - As colunas são truncadas de forma confusa. Correção:
table.add_column(..., overflow="fold")ou exportar CSV. - Rich em código de biblioteca incondicionalmente - Força Rich como uma dependência rígida para os consumidores. Correção: saída bonita opcional por trás de uma flag
--verbose. - Duplicação de manipulador de log -
LoggingHandlerdo Rich mais um manipulador stdlib duplica linhas. Correção: configure uma árvore de manipuladores.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
click + print simples | CLIs simples com formatação mínima | Operadores precisam de tabelas, progresso ou status ao vivo |
typer | Substituição de argparse tipada | Você precisa de UIs interativas em tela cheia |
blessed / prompt_toolkit | REPLs com muitas entradas | Você deseja layouts de widget declarativos (Textual) |
| UI Web (FastAPI + HTMX) | Usuários não técnicos precisam de acesso | Servidores apenas SSH ou ambientes isolados |
FAQs
Rich funciona em terminais Windows?
Sim - Rich detecta limitações de console legadas e degrada graciosamente. O Windows Terminal suporta cores completas.
Posso usar Rich dentro do pytest?
Sim - Console(record=True) captura a saída para asserções; evite barras de progresso em execuções de teste padrão.
Quando devo escolher Textual em vez de um pequeno aplicativo web?
Quando os operadores vivem em sessões SSH e você precisa de fluxos de trabalho controlados por teclado sem hospedar outro serviço.
Como faço para registrar JSON e ainda ter uma aparência bonita localmente?
Mantenha os logs de produção como JSON no stdout; anexe o manipulador Rich apenas quando LOG_FORMAT=pretty em desenvolvimento.
Textual suporta cliques do mouse?
Sim em terminais suportados - habilite nas configurações do aplicativo; ainda forneça alternativas de teclado.
Como testo um aplicativo Textual?
Use o harness de teste assíncrono textual.pilot para simular pressionamentos de tecla e afirmar o estado do widget.
Rich pode renderizar Markdown?
rich.markdown.Markdown renderiza MD no terminal - útil para extensões de --help.
Como desativo as cores para scripting?
Defina NO_COLOR=1 no ambiente - Rich respeita o padrão.
Rich é lento para saídas grandes?
Renderizar 10k linhas inline é lento - pague, amostre ou escreva em um arquivo e abra um editor.
Posso incorporar Rich no FastAPI?
Rich tem como alvo terminais, não HTTP - use-o em comandos de gerenciamento e CLIs de worker, não em respostas de API.
Relacionados
- Noções Básicas de Ferramentas CLI - pontos de entrada argparse/typer
- Noções Básicas de Erros e Logging - padrões de log estruturado
- Configuração do pytest - testando ferramentas CLI
- Produtividade do Shell - fluxo de trabalho do terminal
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.