Building Rich Console Interfaces in Python

Martín Lamas
Sep 28 · 6 min read
Image for post
Image for post
Photo by Cookie the Pom on Unsplash

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

pip install rich

Once installed we can try some of the features of the library.

Rich text printing

To do so, we must first import and build a Console object:

Now, we can style and print text on the console using the print method:

Image for post
Image for post
Console output of the previous example

In this example we can see that:

  • We can either style text fragments inline or style the whole text by passing the style keyword argument.
  • 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 (on blue).
  • If we pass a hash to print it will be automatically styled.
  • We can print emojis using colon notation.

This is a list with the available attributes to define styles:

  • bold or b for bold text.
  • blink for text that flashes (use this one sparingly).
  • blink2 for text that flashes rapidly (not supported by most terminals).
  • conceal for concealed text (not supported by most terminals).
  • italic or i for italic text (not supported on Windows).
  • reverse or r for text with reversed foreground and background colors.
  • strike or s for text with a line through it.
  • underline or u for underlined text.

It also supports the following attributes, which are not universally supported and may not work on your terminal:

  • underline2 or uu for doubly underlined text.
  • frame for framed text.
  • encircle for encircled text.
  • overline or o for 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.

Image for post
Image for post
Console output of the previous example

Tables

In the following example, we use the Table class to create a new table instance and then we call the add_column and add_row methods to define the table columns and add the data rows:

Image for post
Image for post
Console output of the table example

We define the table header style and the title passing the show_header, header_style and title keyword arguments in the constructor. For a headless table we have to set the keyword argument show_header to 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 (left, center or right).

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 Table constructor:

Image for post
Image for post
Console output of the table without borders

Progress bars

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.

Image for post
Image for post
A progress bar. As expected

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 update method.

Image for post
Image for post
An improved progress bar.

Markdown rendering

Take the following markdown:

We can render it in the terminal with ease:

Image for post
Image for post
The formatted markdown output

Other useful features

Columns

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 Columns object.

Image for post
Image for post
Files shown in columns

Syntax highlighting

Image for post
Image for post
Syntax highlighted Python code

Tracebacks

Image for post
Image for post
Beautiful tracebacks

Summing up

Trabe

We are a development studio.

Thanks to Clara Dopico

Martín Lamas

Written by

Software developer @trabe

Trabe

Trabe

We are a development studio. We use Java, Rails, and JavaScript. This is where we write about the technologies we use at Trabe.

Martín Lamas

Written by

Software developer @trabe

Trabe

Trabe

We are a development studio. We use Java, Rails, and JavaScript. This is where we write about the technologies we use at Trabe.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store