Files
Medios-Macina/SYS/rich_display.py
2026-01-11 01:14:45 -08:00

96 lines
2.4 KiB
Python

"""Central Rich output helpers.
Opinionated: `rich` is a required dependency.
This module centralizes Console instances so tables/panels render consistently and
so callers can choose stdout vs stderr explicitly (important for pipeline-safe
output).
"""
from __future__ import annotations
import contextlib
import sys
from typing import Any, Iterator, Sequence, TextIO
from rich.console import Console
from rich.panel import Panel
from rich.text import Text
# Configure Rich pretty-printing to avoid truncating long strings (hashes/paths).
# This is version-safe: older Rich versions may not support the max_* arguments.
try:
from rich.pretty import install as _pretty_install
try:
_pretty_install(max_string=100_000, max_length=100_000)
except TypeError:
_pretty_install()
except Exception:
pass
_STDOUT_CONSOLE = Console(file=sys.stdout)
_STDERR_CONSOLE = Console(file=sys.stderr)
def stdout_console() -> Console:
return _STDOUT_CONSOLE
def stderr_console() -> Console:
return _STDERR_CONSOLE
def console_for(file: TextIO | None) -> Console:
if file is None or file is sys.stdout:
return _STDOUT_CONSOLE
if file is sys.stderr:
return _STDERR_CONSOLE
return Console(file=file)
def rprint(renderable: Any = "", *, file: TextIO | None = None) -> None:
console_for(file).print(renderable)
@contextlib.contextmanager
def capture_rich_output(*, stdout: TextIO, stderr: TextIO) -> Iterator[None]:
"""Temporarily redirect Rich output helpers to provided streams.
Note: `stdout_console()` / `stderr_console()` use global Console instances,
so `contextlib.redirect_stdout` alone will not capture Rich output.
"""
global _STDOUT_CONSOLE, _STDERR_CONSOLE
previous_stdout = _STDOUT_CONSOLE
previous_stderr = _STDERR_CONSOLE
try:
_STDOUT_CONSOLE = Console(file=stdout)
_STDERR_CONSOLE = Console(file=stderr)
yield
finally:
_STDOUT_CONSOLE = previous_stdout
_STDERR_CONSOLE = previous_stderr
def show_provider_config_panel(
provider_name: str,
keys: Sequence[str] | None = None,
*,
config_hint: str = "config.conf"
) -> None:
"""Show a Rich panel explaining how to configure a provider."""
pass
def show_store_config_panel(
store_type: str,
keys: Sequence[str] | None = None,
*,
config_hint: str = "config.conf"
) -> None:
"""Show a Rich panel explaining how to configure a storage backend."""
pass