Spaces:
Sleeping
Sleeping
Download cli/formatters.py from JuanCS-Dev/twitch-byte-bot: direct link, hf CLI and curl.
- Browser
- Download file 7.31 kB
-
https://huggingface.co/spaces/JuanCS-Dev/twitch-byte-bot/resolve/main/cli/formatters.py
- Command line
-
hf download hf://spaces/JuanCS-Dev/twitch-byte-bot/cli/formatters.py
-
curl -L -o formatters.py https://huggingface.co/spaces/JuanCS-Dev/twitch-byte-bot/resolve/main/cli/formatters.py
7.31 kB
| # SPDX-License-Identifier: MIT | |
| """Output formatters for the Byte Agent CLI. | |
| Provides human-readable (tables, key-value, colored) and machine-readable (JSON) | |
| output modes. All output goes through these formatters so the --json flag works | |
| consistently across every command. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import sys | |
| from datetime import UTC, datetime, timezone | |
| from typing import Any, Final, TextIO | |
| # --------------------------------------------------------------------------- | |
| # ANSI Color Constants | |
| # --------------------------------------------------------------------------- | |
| _SUPPORTS_COLOR: Final[bool] = hasattr(sys.stdout, "isatty") and sys.stdout.isatty() | |
| _RESET: Final[str] = "\033[0m" if _SUPPORTS_COLOR else "" | |
| _BOLD: Final[str] = "\033[1m" if _SUPPORTS_COLOR else "" | |
| _DIM: Final[str] = "\033[2m" if _SUPPORTS_COLOR else "" | |
| _GREEN: Final[str] = "\033[32m" if _SUPPORTS_COLOR else "" | |
| _RED: Final[str] = "\033[31m" if _SUPPORTS_COLOR else "" | |
| _YELLOW: Final[str] = "\033[33m" if _SUPPORTS_COLOR else "" | |
| _CYAN: Final[str] = "\033[36m" if _SUPPORTS_COLOR else "" | |
| _MAGENTA: Final[str] = "\033[35m" if _SUPPORTS_COLOR else "" | |
| # --------------------------------------------------------------------------- | |
| # Primitive Formatters | |
| # --------------------------------------------------------------------------- | |
| def print_success(message: str, *, file: TextIO = sys.stdout) -> None: | |
| """Print a success message in green.""" | |
| file.write(f"{_GREEN}β{_RESET} {message}\n") | |
| file.flush() | |
| def print_error(message: str, *, file: TextIO = sys.stderr) -> None: | |
| """Print an error message in red to stderr.""" | |
| file.write(f"{_RED}β{_RESET} {message}\n") | |
| file.flush() | |
| def print_warning(message: str, *, file: TextIO = sys.stderr) -> None: | |
| """Print a warning message in yellow.""" | |
| file.write(f"{_YELLOW}β {_RESET} {message}\n") | |
| file.flush() | |
| def print_info(message: str, *, file: TextIO = sys.stdout) -> None: | |
| """Print an informational message in cyan.""" | |
| file.write(f"{_CYAN}βΉ{_RESET} {message}\n") | |
| file.flush() | |
| def print_header(title: str, *, file: TextIO = sys.stdout) -> None: | |
| """Print a bold section header.""" | |
| file.write(f"\n{_BOLD}{title}{_RESET}\n") | |
| file.write(f"{_DIM}{'β' * min(len(title) + 4, 60)}{_RESET}\n") | |
| file.flush() | |
| # --------------------------------------------------------------------------- | |
| # JSON Output | |
| # --------------------------------------------------------------------------- | |
| def print_json(data: Any, *, file: TextIO = sys.stdout) -> None: | |
| """Pretty-print data as indented JSON.""" | |
| output = json.dumps(data, indent=2, ensure_ascii=False, default=str) | |
| file.write(output) | |
| file.write("\n") | |
| file.flush() | |
| # --------------------------------------------------------------------------- | |
| # Table Output | |
| # --------------------------------------------------------------------------- | |
| def print_table( | |
| headers: list[str], | |
| rows: list[list[str]], | |
| *, | |
| file: TextIO = sys.stdout, | |
| max_col_width: int = 50, | |
| ) -> None: | |
| """Print an ASCII table with auto-sized columns. | |
| Columns are sized to fit the widest value (capped at max_col_width). | |
| """ | |
| if not headers: | |
| return | |
| # Compute column widths | |
| col_count = len(headers) | |
| widths = [len(h) for h in headers] | |
| for row in rows: | |
| for i, cell in enumerate(row[:col_count]): | |
| widths[i] = max(widths[i], len(str(cell))) | |
| widths = [min(w, max_col_width) for w in widths] | |
| def _truncate(text: str, width: int) -> str: | |
| text = str(text) | |
| if len(text) <= width: | |
| return text.ljust(width) | |
| return text[: width - 1] + "β¦" | |
| # Header row | |
| header_line = " β ".join(_truncate(h, widths[i]) for i, h in enumerate(headers)) | |
| separator = "ββΌβ".join("β" * w for w in widths) | |
| file.write(f" {_BOLD}{header_line}{_RESET}\n") | |
| file.write(f" {_DIM}{separator}{_RESET}\n") | |
| # Data rows | |
| if not rows: | |
| file.write(f" {_DIM}(empty){_RESET}\n") | |
| else: | |
| for row in rows: | |
| padded = [ | |
| _truncate(row[i] if i < len(row) else "", widths[i]) for i in range(col_count) | |
| ] | |
| file.write(f" {' β '.join(padded)}\n") | |
| file.flush() | |
| # --------------------------------------------------------------------------- | |
| # Key-Value Output | |
| # --------------------------------------------------------------------------- | |
| def print_kv( | |
| data: dict[str, Any], | |
| *, | |
| file: TextIO = sys.stdout, | |
| label_width: int = 0, | |
| ) -> None: | |
| """Print key-value pairs aligned vertically. | |
| If label_width is 0, it auto-sizes to the longest key. | |
| """ | |
| if not data: | |
| return | |
| width = label_width or max(len(str(k)) for k in data) | |
| for key, value in data.items(): | |
| label = f"{_CYAN}{str(key).ljust(width)}{_RESET}" | |
| formatted_value = _format_value(value) | |
| file.write(f" {label} {formatted_value}\n") | |
| file.flush() | |
| def _format_value(value: Any) -> str: | |
| """Format a single value for display with semantic coloring.""" | |
| if value is None: | |
| return f"{_DIM}β{_RESET}" | |
| if isinstance(value, bool): | |
| return f"{_GREEN}yes{_RESET}" if value else f"{_RED}no{_RESET}" | |
| if isinstance(value, list | tuple): | |
| if not value: | |
| return f"{_DIM}(none){_RESET}" | |
| return ", ".join(str(v) for v in value) | |
| if isinstance(value, dict): | |
| if not value: | |
| return f"{_DIM}{{}}{_RESET}" | |
| return json.dumps(value, ensure_ascii=False, default=str) | |
| return str(value) | |
| # --------------------------------------------------------------------------- | |
| # Timestamp Formatter | |
| # --------------------------------------------------------------------------- | |
| def format_timestamp(iso_or_float: str | float | None) -> str: | |
| """Convert an ISO timestamp or Unix float into a human-readable string. | |
| Returns "β" for None/empty values. | |
| """ | |
| if iso_or_float is None: | |
| return "β" | |
| if isinstance(iso_or_float, int | float): | |
| if iso_or_float <= 0: | |
| return "β" | |
| try: | |
| dt = datetime.fromtimestamp(iso_or_float, tz=UTC) | |
| return dt.strftime("%Y-%m-%d %H:%M:%S UTC") | |
| except (OSError, ValueError, OverflowError): | |
| return str(iso_or_float) | |
| text = str(iso_or_float).strip() | |
| if not text: | |
| return "β" | |
| # Try to parse ISO format | |
| for fmt in ("%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S+00:00", "%Y-%m-%dT%H:%M:%S"): | |
| try: | |
| dt = datetime.strptime(text, fmt).replace(tzinfo=UTC) | |
| return dt.strftime("%Y-%m-%d %H:%M:%S UTC") | |
| except ValueError: | |
| continue | |
| return text | |
| # --------------------------------------------------------------------------- | |
| # Dispatcher Helper | |
| # --------------------------------------------------------------------------- | |
| def output( | |
| data: Any, | |
| *, | |
| json_mode: bool = False, | |
| human_fn: Any = None, | |
| ) -> None: | |
| """Universal output dispatcher. | |
| In JSON mode: prints raw JSON. | |
| In human mode: calls the provided human_fn callback, or falls back to print_json. | |
| """ | |
| if json_mode: | |
| print_json(data) | |
| elif callable(human_fn): | |
| human_fn(data) | |
| else: | |
| print_json(data) | |