Agent skill
rich
Terminal rendering library for styled text, tables, progress bars, prompts, markdown, syntax highlighting, and tracebacks.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/skills-skilldoai-skilldo
SKILL.md
Imports
import rich
from rich import print, print_json, inspect
from rich.console import Console, Group
from rich.prompt import Prompt, IntPrompt, FloatPrompt, Confirm
from rich.table import Table
from rich.progress import track
from rich.markdown import Markdown
from rich.syntax import Syntax
from rich import traceback, pretty
Core Patterns
Styled printing with rich.print ✅ Current
from rich import print
def main() -> None:
print("Hello, [bold magenta]World[/]!")
print("[green]OK[/] [dim](dim text)[/]")
print("A whole line styled via markup, plus an emoji: [bold]Done[/] ✅")
if __name__ == "__main__":
main()
- Use
from rich import printas a drop-in replacement for built-inprint. - Inline styling uses Rich markup tags (BBCode-like), e.g.
[bold magenta]...[/].
Use a shared Console for app-wide output ✅ Current
from __future__ import annotations
from rich.console import Console
from rich.table import Table
def build_table() -> Table:
table = Table(title="Build Summary")
table.add_column("Step", style="bold")
table.add_column("Status", justify="right")
table.add_row("Lint", "[green]pass[/]")
table.add_row("Tests", "[green]pass[/]")
table.add_row("Package", "[yellow]skipped[/]")
return table
def main() -> None:
console = Console()
console.print("Starting build...", style="bold cyan")
console.print(build_table())
console.log("Build finished", log_locals=False)
if __name__ == "__main__":
main()
- Prefer a single
rich.console.Consoleinstance for consistent width/color/logging configuration. - Use
console.print(..., style="...")to style an entire renderable/line (and markup for parts).
JSON pretty printing with print_json ✅ Current
from __future__ import annotations
from rich import print_json
def main() -> None:
payload: dict[str, object] = {
"name": "example",
"ok": True,
"count": 3,
"items": ["a", "b", "c"],
"meta": {"source": "unit-test"},
}
print_json(data=payload, indent=2, highlight=True, sort_keys=True)
if __name__ == "__main__":
main()
print_json(json=...)prints a JSON string;print_json(data=...)encodes Python data then prints.- Useful for debugging structured output with syntax highlighting.
Progress over an iterable with track ✅ Current
from __future__ import annotations
import time
from rich.progress import track
def main() -> None:
for _ in track(range(50), description="Working..."):
time.sleep(0.01)
if __name__ == "__main__":
main()
rich.progress.track(sequence, description=...)is the quick pattern for a single progress bar.
Prompts with validation (Prompt.ask, Confirm.ask) ✅ Current
from __future__ import annotations
from rich.prompt import Prompt, IntPrompt, Confirm
def main() -> None:
name: str = Prompt.ask("Name", default="Ada")
color: str = Prompt.ask(
"Favorite color",
choices=["red", "green", "blue"],
default="green",
case_sensitive=False,
)
age: int = IntPrompt.ask("Age", default=30)
proceed: bool = Confirm.ask("Proceed?", default=True)
from rich import print
print(f"Hello [bold]{name}[/], age={age}, color={color}, proceed={proceed}")
if __name__ == "__main__":
main()
Prompt.ask(..., choices=[...])loops until valid input; setcase_sensitive=Falseif desired.Confirm.ask(...)is for yes/no prompts;IntPrompt/FloatPromptparse numeric input.
Pretty printing with pretty.pprint ✅ Current
from __future__ import annotations
from rich.pretty import pprint
def main() -> None:
data = {
"name": "example",
"items": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"nested": {"foo": "bar", "baz": [True, False]},
}
# Basic pretty print
pprint(data)
# With max_length to truncate sequences/dicts
pprint(data, max_length=3)
# With max_string to truncate long strings
pprint({"long": "Hello" * 50}, max_string=20)
if __name__ == "__main__":
main()
pprint(obj, ...)pretty prints objects with automatic layout and syntax highlighting.- Use
max_length=Nto limit items shown in sequences/dicts; usemax_string=Nto truncate strings. - Use
expand_all=Trueto force multi-line layout even for small objects.
Trees for hierarchical data ✅ Current
from __future__ import annotations
from rich.tree import Tree
from rich.console import Console
def main() -> None:
console = Console()
tree = Tree("Project Root")
tree.add("README.md")
src = tree.add("src/", style="bold blue")
src.add("main.py")
src.add("utils.py")
tree.add("tests/", style="bold green")
console.print(tree)
if __name__ == "__main__":
main()
Tree(label)creates a tree structure for hierarchical data visualization.- Use
.add(item, style=..., guide_style=...)to add branches; returns aTreefor nesting.
Columns for multi-column layout ✅ Current
from __future__ import annotations
from rich.columns import Columns
from rich.console import Console
from rich.panel import Panel
def main() -> None:
console = Console()
panels = [Panel(f"Item {i}", expand=True) for i in range(6)]
columns = Columns(panels, equal=True, expand=True)
console.print(columns)
if __name__ == "__main__":
main()
Columns(renderables, ...)arranges items in columns.- Use
equal=Truefor equal-width columns;expand=Trueto fill available width. - Use
align="left","center", or"right"to control alignment.
Configuration
- Console configuration
- Prefer constructing a
Console()and passing it through your app. - If you rely on Rich's global console, you can access it via:
rich.get_console() -> Consolerich.reconfigure(*args, **kwargs) -> None(reconfigures the global console)
- Prefer constructing a
- Environment variables (behavior change in 14.0.0)
NO_COLOR: if set to a non-empty value, disables color output; empty is treated as disabled (i.e., does not disable colors).FORCE_COLOR: if set to a non-empty value, forces color output; empty is treated as disabled.UNICODE_VERSION: control Unicode version used for cell width calculations (added in 14.3.0).TTY_COMPATIBLE: override auto-detection of TTY support (added in 14.0.0).
- Unicode width handling
- Rich has internal support for Unicode cell width tables; avoid relying on internal loaders.
- If using
rich.cells.cell_len, prefer keyword args (not positional), especially after signature changes in 14.3.0.
- Pretty printing in REPL / IPython
rich.pretty.install()enables pretty-printing in the Python REPL.- On 14.3.0+, IPython respects a
Consolepassed topretty.install(console=...).
Pitfalls
Wrong: Using built-in print and expecting Rich markup to render
def main() -> None:
# Built-in print will output markup tags literally.
print("Hello, [bold magenta]World[/]!")
if __name__ == "__main__":
main()
Right: Import rich.print (or use Console.print)
from rich import print
def main() -> None:
print("Hello, [bold magenta]World[/]!")
if __name__ == "__main__":
main()
Wrong: Prompt.ask choices are case-sensitive by default
from rich.prompt import Prompt
def main() -> None:
# User typing "paul" will be rejected.
name = Prompt.ask(
"Enter your name",
choices=["Paul", "Jessica", "Duncan"],
default="Paul",
)
from rich import print
print(name)
if __name__ == "__main__":
main()
Right: Set case_sensitive=False when appropriate
from rich.prompt import Prompt
def main() -> None:
name = Prompt.ask(
"Enter your name",
choices=["Paul", "Jessica", "Duncan"],
default="Paul",
case_sensitive=False,
)
from rich import print
print(name)
if __name__ == "__main__":
main()
Wrong: Passing multiple renderables where a single renderable is expected (e.g., Panel)
from rich import print
from rich.panel import Panel
def main() -> None:
# Panel expects a single renderable as its content.
print(Panel("Hello", "World"))
if __name__ == "__main__":
main()
Right: Combine multiple renderables with Group
from rich import print
from rich.console import Group
from rich.panel import Panel
def main() -> None:
content = Group(
"Hello",
"World",
)
print(Panel(content, title="Greeting"))
if __name__ == "__main__":
main()
Wrong: Relying on exact traceback formatting in snapshot tests across versions
from rich import traceback
def main() -> None:
traceback.install()
raise ValueError("boom")
if __name__ == "__main__":
main()
Right: Assert on stable substrings / exception types, not exact rendered frames
from __future__ import annotations
from rich import traceback
def main() -> None:
traceback.install()
try:
raise ValueError("boom")
except ValueError as exc:
# In tests, assert on message/type rather than exact terminal rendering.
assert "boom" in str(exc)
if __name__ == "__main__":
main()
Wrong: Expecting empty environment variables to enable features
from __future__ import annotations
import os
def main() -> None:
# Empty NO_COLOR will NOT disable colors in Rich 14.0.0+
os.environ["NO_COLOR"] = ""
from rich import print
print("[red]This will still be colored[/]")
if __name__ == "__main__":
main()
Right: Set environment variables to non-empty values
from __future__ import annotations
import os
def main() -> None:
# Set to non-empty value to disable colors
os.environ["NO_COLOR"] = "1"
from rich import print
print("[red]This will not be colored[/]")
if __name__ == "__main__":
main()
References
Migration from v13.x
- 14.0.0: Environment variable semantics changed
- Empty
NO_COLORis now considered disabled (does not disable colors). - Empty
FORCE_COLORis now considered disabled (does not force colors). - Migration: ensure CI/container environments either unset these variables or set them to a non-empty value to activate behavior.
- Empty
from __future__ import annotations
import os
from rich.console import Console
def main() -> None:
# Prefer explicit configuration over relying on possibly-empty env vars.
os.environ.pop("NO_COLOR", None)
os.environ.pop("FORCE_COLOR", None)
console = Console()
console.print("Color behavior is now consistent with env var semantics.")
if __name__ == "__main__":
main()
-
14.0.0: Traceback rendering output changed
- Notes (Py3.11+), Exception Groups, and formatting differences may break snapshot tests.
- Migration: update golden files or switch to assertions on stable content.
-
13.9.0: Python 3.7 dropped
- Migration: run on Python 3.8+ (or pin Rich < 13.9.0 if you must stay on 3.7).
-
14.3.0:
rich.cells.cell_lensignature changed- Migration: prefer keyword arguments when calling
cell_lento avoid positional mismatch.
- Migration: prefer keyword arguments when calling
-
14.3.0: IPython Console support
pretty.install(console=...)now respects the Console instance in IPython environments.- Migration: if you pass a custom Console to
pretty.install(), it will now be used in IPython.
-
14.3.0: Markdown styling changes
- Markdown headers, tables, and rules have updated styling.
- New styles added:
markdown.table.headerandmarkdown.table.border. - Migration: review Markdown rendering output; customize styles if needed to match previous appearance.
API Reference
- *rich.print(objects, sep=" ", end="\n", file=None, flush=False) - Rich-enhanced print with markup rendering.
- *rich.print_json(json=None, , data=None, indent=2, highlight=True, skip_keys=False, ensure_ascii=False, check_circular=True, allow_nan=True, default=None, sort_keys=False) - Pretty-print JSON (string or data) with optional highlighting.
- *rich.inspect(obj, , console=None, title=None, help=False, methods=False, docs=True, private=False, dunder=False, sort=True, all=False, value=True) - Introspect and render object details to the console.
- rich.get_console() - Get the global
Consoleinstance used by top-level helpers. - **rich.reconfigure(*args, kwargs) - Reconfigure the global
Console(use sparingly; prefer explicitConsole()). - rich.console.Console(...) - Primary output object; controls width, color system, recording, etc.
- *rich.console.Console.print(renderables, style=None, markup=True, highlight=None, emoji=True, ...)
- Print renderables (strings, Tables, Markdown, Syntax, Panels, etc.) with styling.
- *rich.console.Console.log(objects, log_locals=False, ...)
- Log with timestamps and optional locals capture for debugging.
- rich.console.Console.status(status, spinner="dots")
- Context manager for a live status spinner while work runs.
- *rich.console.Group(renderables) - Combine multiple renderables into one for containers expecting a single renderable.
- *rich.prompt.Prompt.ask(prompt, , choices=None, default=None, case_sensitive=True, ...)
- Prompt for text input with optional validation and looping.
- rich.prompt.IntPrompt.ask(...) / rich.prompt.FloatPrompt.ask(...)
- Prompt for numeric input with parsing and validation.
- *rich.prompt.Confirm.ask(prompt, , default=False, ...)
- Prompt for yes/no input.
- rich.table.Table(title=None, ...) - Build tables for console rendering.
- **rich.table.Table.add_column(header, , style=None, justify=None, ...) / Table.add_row(cells, ...)
- Define columns and add rows.
- rich.progress.track(sequence, description=None, total=None, ...)
- Iterate with a progress bar.
- rich.markdown.Markdown(markdown_text) - Render Markdown as a Rich renderable.
- rich.syntax.Syntax(code, lexer, theme="monokai", line_numbers=False, ...) - Render syntax-highlighted code.
- rich.pretty.install(console=None, ...)
- Enable Rich pretty-printing in REPL/IPython contexts.
- *rich.pretty.pprint(obj, , console=None, indent_guides=True, max_length=None, max_string=None, max_depth=None, expand_all=False, ...)
- Pretty print an object to the console with Rich formatting.
- *rich.pretty.pretty_repr(obj, , max_width=80, indent_size=4, max_length=None, max_string=None, max_depth=None, expand_all=False, ...)
- Generate a pretty string representation of an object.
- rich.traceback.install(...)
- Install Rich traceback handler (note output format changed in 14.0.0).
- *rich.tree.Tree(label, , guide_style="tree.line", ...)
- Create a tree structure for hierarchical data.
- *rich.tree.Tree.add(label, , style=None, guide_style=None, ...)
- Add a branch to the tree; returns a
Treefor nesting.
- Add a branch to the tree; returns a
- *rich.columns.Columns(renderables, , equal=False, expand=False, align="left", ...)
- Arrange renderables in columns.
- *rich.filesize.decimal(size, , precision=1, separator=" ")
- Format file size in decimal units (base 1000: bytes, kB, MB, etc.).
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?