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.
Code
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')Report a problem with this exampleOpens a pre-filled issue on GitHub.