Rich: saída de terminal estilizada

1. Introdução ao Rich e seus diferenciais

Rich é uma biblioteca Python que transforma a saída do terminal em uma experiência visual rica e informativa. Enquanto o print() tradicional oferece apenas texto simples, Rich permite adicionar cores, tabelas, barras de progresso, realce de sintaxe e muito mais.

Por que usar Rich?
- Saída mais legível e profissional
- Código mais expressivo e conciso
- Suporte nativo a Markdown e syntax highlighting
- Barras de progresso animadas para operações longas
- Compatível com Windows, macOS e Linux

Instalação:

pip install rich

Primeiro exemplo:

from rich import print

print("[bold magenta]Olá, Mundo![/bold magenta]")
print("[green]Este[/green] [yellow]texto[/yellow] [red]é[/red] [blue]colorido[/blue]!")

2. Estilizando textos com cores e formatação

O Rich oferece diversas formas de estilizar texto, desde cores nomeadas até combinações complexas de atributos.

Console.print() vs print() do Rich:

from rich.console import Console

console = Console()
console.print("Texto normal")
console.print("[bold red]Texto em negrito e vermelho[/bold red]")
console.print("[on blue]Fundo azul[/on blue]")

Cores RGB e estilos combinados:

from rich.text import Text
from rich.style import Style

texto = Text("Python é incrível!")
texto.stylize("bold", 0, 6)  # "Python" em negrito
texto.stylize(Style(color="#FF5733", italic=True), 7, 9)  # "é" em laranja itálico
texto.stylize("underline bright_cyan", 10, 19)  # "incrível!" sublinhado ciano

console.print(texto)

Estilos predefinidos:

console.print("[bold italic underline]Todos os atributos combinados[/]")
console.print("[#00FF00]Verde neon com RGB[/]")
console.print("[on #0000FF white]Texto branco em fundo azul escuro[/]")

3. Trabalhando com tabelas elegantes

Tabelas são essenciais para exibir dados estruturados. O Rich permite criar tabelas altamente personalizáveis.

Criando uma tabela básica:

from rich.table import Table

tabela = Table(title="Funcionários")

tabela.add_column("Nome", style="cyan", no_wrap=True)
tabela.add_column("Cargo", style="magenta")
tabela.add_column("Salário", justify="right", style="green")

tabela.add_row("Alice Silva", "Desenvolvedora", "R$ 8.500")
tabela.add_row("Bruno Costa", "Analista", "R$ 6.200")
tabela.add_row("Carla Souza", "Gerente", "R$ 12.000")

console.print(tabela)

Personalização avançada:

from rich.table import Table
from rich.box import ROUNDED

tabela_avancada = Table(
    title="Vendas por Região",
    box=ROUNDED,
    header_style="bold blue",
    title_style="bold yellow",
    border_style="bright_black"
)

tabela_avancada.add_column("Região", style="white")
tabela_avancada.add_column("Q1", style="green", justify="right")
tabela_avancada.add_column("Q2", style="yellow", justify="right")
tabela_avancada.add_column("Total", style="bold cyan", justify="right")

dados = {
    "Norte": [120, 150, 270],
    "Sul": [200, 180, 380],
    "Leste": [90, 110, 200]
}

for regiao, valores in dados.items():
    tabela_avancada.add_row(regiao, str(valores[0]), str(valores[1]), str(sum(valores)))

console.print(tabela_avancada)

4. Barras de progresso e feedback visual

Para operações demoradas, as barras de progresso do Rich oferecem feedback visual imediato.

Uso básico com track():

from rich.progress import track
import time

for i in track(range(100), description="Processando..."):
    time.sleep(0.05)  # Simula trabalho

Progress customizado com múltiplas tarefas:

from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn, TimeElapsedColumn

progresso = Progress(
    SpinnerColumn(),
    TextColumn("[progress.description]{task.description}"),
    BarColumn(),
    TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
    TimeElapsedColumn(),
    console=console
)

with progresso:
    tarefa1 = progresso.add_task("[cyan]Download...", total=100)
    tarefa2 = progresso.add_task("[green]Instalação...", total=50)

    for i in range(100):
        progresso.update(tarefa1, advance=1)
        if i % 2 == 0:
            progresso.update(tarefa2, advance=1)
        time.sleep(0.03)

Simulação de carregamento:

from rich.progress import Progress, SpinnerColumn, TextColumn

with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as p:
    tarefa = p.add_task("[yellow]Carregando recursos...", total=None)
    # Simula carregamento indeterminado
    time.sleep(3)

5. Renderizando Markdown e código-fonte

Rich pode renderizar Markdown diretamente no terminal e destacar sintaxe de código.

Renderizando Markdown:

from rich.markdown import Markdown

markdown_texto = """
# Documentação do Projeto

## Funcionalidades
- **Autenticação** via JWT
- *Cache* com Redis
- `API REST` documentada

### Links úteis
[Documentação oficial](https://docs.python.org)
"""

md = Markdown(markdown_texto)
console.print(md)

Destaque de sintaxe com Syntax:

from rich.syntax import Syntax

codigo = '''
def fibonacci(n):
    """Retorna o n-ésimo número de Fibonacci."""
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))  # 55
'''

syntax = Syntax(codigo, "python", theme="monokai", line_numbers=True)
console.print(syntax)

6. Layouts e painéis para saída organizada

Painéis e layouts permitem criar interfaces organizadas no terminal.

Criando painéis:

from rich.panel import Panel

console.print(Panel("Conteúdo simples", title="Aviso", border_style="yellow"))
console.print(Panel.fit("[bold green]Mensagem importante[/]", border_style="red"))

Dashboard com Columns:

from rich.columns import Columns
from rich.panel import Panel

metricas = [
    Panel("[bold blue]Usuários Ativos[/]\n[green]1.234[/]", title="Métrica 1"),
    Panel("[bold blue]Vendas Hoje[/]\n[yellow]R$ 5.678[/]", title="Métrica 2"),
    Panel("[bold blue]Taxa de Conversão[/]\n[magenta]3.45%[/]", title="Métrica 3"),
    Panel("[bold blue]Tickets Abertos[/]\n[red]23[/]", title="Métrica 4")
]

console.print(Columns(metricas, equal=True, expand=True))

Layout avançado:

from rich.layout import Layout

layout = Layout()
layout.split(
    Layout(name="header", size=3),
    Layout(name="body"),
    Layout(name="footer", size=3)
)
layout["body"].split_row(
    Layout(name="sidebar", size=30),
    Layout(name="main")
)

layout["header"].update(Panel("Dashboard Principal", style="bold cyan"))
layout["sidebar"].update(Panel("Menu Lateral\n- Opção 1\n- Opção 2", style="blue"))
layout["main"].update(Panel("Conteúdo Principal\n\nGráficos e métricas aqui"))
layout["footer"].update(Panel("Última atualização: agora", style="dim"))

console.print(layout)

7. Dicas avançadas e boas práticas

Salvando saída em log:

from rich.console import Console

log_console = Console(file=open("saida.log", "w"))
log_console.print("[bold]Log do sistema[/bold]")
log_console.print("[red]Erro crítico[/red]")

Temas customizados:

from rich.theme import Theme

meu_tema = Theme({
    "info": "dim cyan",
    "warning": "magenta",
    "danger": "bold red",
    "sucesso": "bold green"
})

console_tema = Console(theme=meu_tema)
console_tema.print("Mensagem de info", style="info")
console_tema.print("Aviso importante!", style="warning")

Integração com Click para CLIs:

import click
from rich.console import Console

console = Console()

@click.command()
@click.option('--nome', prompt='Seu nome')
def saudacao(nome):
    console.print(f"[bold green]Olá, {nome}![/bold green]")

if __name__ == '__main__':
    saudacao()

Rich é uma ferramenta poderosa que transforma a experiência do terminal. Comece com exemplos simples e explore gradualmente os recursos avançados para criar interfaces de linha de comando profissionais e visualmente atraentes.

Referências