Lately, I have been working on a project in which I needed to pretty print some data on the console. That was how I discovered Rich, a Python library for rich text and beautiful formatting in the terminal.
In this story I will show you some of the features of this library, and how you can use it in your projects.
Installing the library
First, we need to install the library in our environment using pip.
pip install rich
Once installed we can try some of the features of the library.
Rich text printing
One of the features that I use the most is to print rich text.
To do so, we must first import and build a
Now, we can style and print text on the console using the
In this example we can see that:
- We can either style text fragments inline or style the whole text by passing the
- Inline styles are defined using strings. These strings contain keywords to set the colors and other attributes for the foreground styles (like
bold white) and for the background color (
- If we pass a hash to
- We can print emojis using colon notation.
This is a list with the available attributes to define styles:
bfor bold text.
blinkfor text that flashes (use this one sparingly).
blink2for text that flashes rapidly (not supported by most terminals).
concealfor concealed text (not supported by most terminals).
ifor italic text (not supported on Windows).
rfor text with reversed foreground and background colors.
sfor text with a line through it.
ufor underlined text.
It also supports the following attributes, which are not universally supported and may not work on your terminal:
uufor doubly underlined text.
framefor framed text.
encirclefor encircled text.
ofor overlined text.
We can choose colors between one of the 256 Standard Colors. But we can also set a custom color using RGB codes. In the following example we print the same color using both its standard name and its RGB code:
Another useful feature of the library is the logger. We use this feature calling the
log method on the
Console instance. This method prints an output with three columns: the current time, the data to print and the file and line from which the call to
log was made. As we have seen before, the library does pretty format Python structures and repr strings. If we log a collection (i.e. a dict or a list) the library pretty prints it so that it fits in the available terminal space.
Another useful feature of the library is the ability to render tables on the terminal.
In the following example, we use the
Table class to create a new table instance and then we call the
add_row methods to define the table columns and add the data rows:
We define the table header style and the title passing the
title keyword arguments in the constructor. For a headless table we have to set the keyword argument
False and skip the others.
The column definition is performed by calling the
add_column method. We simply call this method as many times as columns we want to create. We have to provide the title of the column and, optionally, the justification of the data cells (
Once the table structure is defined, we can insert a data row by calling the
add_row method. We must pass the data as arguments in the same order the columns were defined. Each cell can be styled individually.
You can also change the default border using the
box keyword in the
To track long-running tasks we can use a progress bar to improve the user experience. We need to import the
track function to use the basic progress bar API. Then, we can wrap any sequence in this function and iterate over the result.
In this example, we iterate over a list of remote files in order to download them. Each iteration a file is downloaded and the progress bar is updated.
We can use the advanced API if we need to further customize our progress bar. In the following example we have a customized version of the example above:
In this example we first instantiate a
Progress object to define the different columns that compose the progress bar: the task description, the bar, a live progress showing how many files have been downloaded and the remaining time.
Then, we add a task to the Progress instance using the
add_task method passing the description and the total steps (the number of the files).
Finally, we iterate the file list and for each iteration we update the progress status by calling the
Another awesome Rich feature is markdown rendering.
Take the following markdown:
We can render it in the terminal with ease:
Other useful features
There are other interesting functionalities of the library.
When we need to tabulate the data into columns we can create a
Columns instance and pass the list of elements to tabulate in the constructor.
The following example shows how to render a directory content using columns:
We are using a helper function
file_info to get the file info (name, type and file extension). We list the directory passed as command line argument and we wrap each found file into a
Panel object to show the info inside a box. And, in turn, we put each panel inside a
We can handle and print beautiful tracebacks in our programs. These tracebacks are easier to read and show more code than standard Python tracebacks.
Rich is a good choice to improve the user experience of our console applications. In this story we have learned how to use the most interesting features and how to apply them with some simple examples.