Files
Medios-Macina/SYS/result_table_renderers.py

68 lines
2.3 KiB
Python
Raw Normal View History

"""Renderers for the ResultTable API.
This module provides a Rich-based Renderer implementation that returns a
`rich.table.Table` renderable. The implementation is intentionally small and
focused on the command-line display use-case; keep logic side-effect-free where
possible and let callers decide whether to `Console.print()` or capture output.
"""
from __future__ import annotations
from typing import Any, Dict, Iterable, Optional
from SYS.result_table_api import ColumnSpec, ResultModel, Renderer
class RichRenderer(Renderer):
"""Rich renderer implementing the `Renderer` protocol.
Usage:
from rich.console import Console
table = RichRenderer().render(rows, columns, meta)
Console().print(table)
"""
def render(self, rows: Iterable[ResultModel], columns: Iterable[ColumnSpec], meta: Optional[Dict[str, Any]] = None) -> Any: # pragma: no cover - simple wrapper
try:
from rich.table import Table as RichTable
except Exception as exc:
raise RuntimeError("rich is required for RichRenderer") from exc
table = RichTable(show_header=True, header_style="bold")
cols = list(columns)
for col in cols:
table.add_column(col.header)
for r in rows:
cells = []
for col in cols:
try:
raw = col.extractor(r)
if col.format_fn:
try:
cell = col.format_fn(raw)
except Exception:
cell = str(raw or "")
else:
cell = str(raw or "")
except Exception:
cell = ""
cells.append(cell)
table.add_row(*cells)
return table
# Small convenience function
def render_to_console(rows: Iterable[ResultModel], columns: Iterable[ColumnSpec], meta: Optional[Dict[str, Any]] = None) -> None:
try:
from rich.console import Console
except Exception:
# If rich isn't present, fall back to simple text output
for r in rows:
print(" ".join(str((col.extractor(r) or "")) for col in columns))
return
table = RichRenderer().render(rows, columns, meta)
Console().print(table)