Skip to content

rich

Rich is a Python library for rich text and beautiful formatting in the terminal.

Installation

pip install rich

Usage

Progress display

Rich can display continuously updated information regarding the progress of long running tasks / file copies etc. The information displayed is configurable, the default will display a description of the ‘task’, a progress bar, percentage complete, and estimated time remaining.

Rich progress display supports multiple tasks, each with a bar and progress information. You can use this to track concurrent tasks where the work is happening in threads or processes.

It's beautiful, check it out with python -m rich.progress.

Basic Usage

For basic usage call the track() function, which accepts a sequence (such as a list or range object) and an optional description of the job you are working on. The track method will yield values from the sequence and update the progress information on each iteration. Here’s an example:

from rich.progress import track

for n in track(range(n), description="Processing..."):
    do_work(n)

Tables

from rich.console import Console
from rich.table import Table

table = Table(title="Star Wars Movies")

table.add_column("Released", justify="right", style="cyan", no_wrap=True)
table.add_column("Title", style="magenta")
table.add_column("Box Office", justify="right", style="green")

table.add_row("Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$952,110,690")
table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347")
table.add_row("Dec 15, 2017", "Star Wars Ep. V111: The Last Jedi", "$1,332,539,889")
table.add_row("Dec 16, 2016", "Rogue One: A Star Wars Story", "$1,332,439,889")

console = Console()
console.print(table)

Adding a footer is not easy task. This answer doesn't work anymore as table doesn't have the add_footer. You need to create the footer in the add_column so you need to have the data that needs to go to the footer before building the rows.

You would do something like:

table = Table(title="Star Wars Movies", show_footer=True)
table.add_column("Title", style="magenta", footer='2342')

Rich text

from rich.console import Console
from rich.text import Text

console = Console()
text = Text.assemble(("Hello", "bold magenta"), " World!")
console.print(text)

Live display text

import time

from rich.live import Live

with Live("Test") as live:
    for row in range(12):
        live.update(f"Test {row}")
        time.sleep(0.4)

If you don't want the text to have the default colors, you can embed it all in a Text object.

Tree

Rich has a Tree class which can generate a tree view in the terminal. A tree view is a great way of presenting the contents of a filesystem or any other hierarchical data. Each branch of the tree can have a label which may be text or any other Rich renderable.

The following code creates and prints a tree with a simple text label:

from rich.tree import Tree
from rich import print

tree = Tree("Rich Tree")
print(tree)

With only a single Tree instance this will output nothing more than the text “Rich Tree”. Things get more interesting when we call add() to add more branches to the Tree. The following code adds two more branches:

tree.add("foo")
tree.add("bar")
print(tree)

The tree will now have two branches connected to the original tree with guide lines.

When you call add() a new Tree instance is returned. You can use this instance to add more branches to, and build up a more complex tree. Let’s add a few more levels to the tree:

baz_tree = tree.add("baz")
baz_tree.add("[red]Red").add("[green]Green").add("[blue]Blue")
print(tree)

Configure the logging handler

Rich supplies a logging handler which will format and colorize text written by Python’s logging module.

Here’s an example of how to set up a rich logger:

import logging
from rich.logging import RichHandler

FORMAT = "%(message)s"
logging.basicConfig(
    level="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
)

log = logging.getLogger("rich")
log.info("Hello, World!")

If you want to use different levels with the verbose use:

def load_logger(verbose: bool = False) -> None: 
    """Configure the Logging logger.

    Args:
        verbose: Set the logging level to Debug.
    """

    if verbose:
        level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(
        format="%(message)s",
        level=level,
        handlers=[RichHandler()],
    )

References