Rich Table Live Display CLI

Render dynamic CLI tables with Rich Live mode, updating rows in place as background tasks progress and finishing with a clean summary.

PythonCli Tooling

Code

snippet
import asyncio
import time

from rich.console import Console
from rich.live import Live
from rich.table import Table
from rich.text import Text

console = Console()


def build_table(rows: list[dict]) -> Table:
    table = Table(title='Deployment Progress')
    table.add_column('Service')
    table.add_column('Status')
    table.add_column('Duration', justify='right')

    status_style = {
        'pending': 'dim',
        'running': 'yellow',
        'done': 'green',
        'failed': 'red',
    }
    for row in rows:
        style = status_style.get(row['status'], 'white')
        table.add_row(
            row['name'],
            Text(row['status'], style=style),
            f"{row['elapsed']:.1f}s",
        )
    return table


async def deploy(rows: list[dict]) -> None:
    with Live(build_table(rows), console=console, refresh_per_second=4) as live:
        pending = [r for r in rows if r['status'] == 'pending']
        while pending:
            await asyncio.sleep(0.4)
            for row in rows:
                if row['status'] == 'running':
                    row['elapsed'] += 0.4
                    if row['elapsed'] >= 1.2:
                        row['status'] = 'done'
            live.update(build_table(rows))
            pending = [r for r in rows if r['status'] != 'done']


services = [
    {'name': 'api-gateway', 'status': 'running', 'elapsed': 0.0},
    {'name': 'billing', 'status': 'pending', 'elapsed': 0.0},
    {'name': 'search', 'status': 'pending', 'elapsed': 0.0},
]
services[1]['status'] = 'running'
services[2]['status'] = 'running'

asyncio.run(deploy(services))
console.print('deployment complete')