Skip to content

Rich Textual Formatting in Python: A Comprehensive Guide

[

The Python Rich Package: Unleash the Power of Console Text

Python’s Rich package is a tool kit that helps you generate beautifully formatted and highlighted text in the console. More broadly, it allows you to build an attractive text-based user interface (TUI).

Why would you choose a TUI over a graphical user interface, or GUI? Sometimes a text display feels more appropriate. Why use a full-blown GUI for a simple application, when an elegant text interface will do? It can be refreshing to work with plain text. Text works in almost any hardware environment, even on an SSH terminal or a single-board computer display. And many applications don’t need the complexity of a full graphical windowing system.

In this tutorial, you’ll learn how Rich can help you:

  • Enhance the user interface of command-line tools
  • Improve the readability of console output
  • Create attractive dashboard displays for real-time tabular data
  • Generate well-formatted reports

Will McGugan, the author of Rich, has also developed the Textual package. Whereas Rich is a rich-text tool kit, Textual is a full application framework built on Rich. It provides application base classes, an event-driven architecture, and more.

There’s a lot you can do with Rich on its own, and its support for engaging, dynamic displays may well be sufficient for your app. By following this tutorial, you’ll experiment with many of the cool features of Rich, and you’ll finish up by using your skills to build a dynamically scrolling tabular display of crypto prices.

To fully understand Rich’s syntax for animations, you should have a good grasp of context managers. But if you’re a bit rusty, don’t worry! You’ll get a quick refresher in this tutorial.

Installing Rich

You can start using Rich very quickly. As always when starting a new project or investigation, it’s best to create a virtual environment first, to avoid polluting your system’s Python installation.

It’s quite possible to install Rich and use it with the built-in Python REPL, but for a better developer experience, you may want to include support for Jupyter notebooks. Here’s how you can install Rich so that it’ll work with either the REPL or Jupyter:

Windows:

Terminal window
pip install rich jupyter-console

Linux + macOS:

Terminal window
pip install rich jupyter-console

Using Rich for Python Development

Once you have Rich installed, you can start using its powerful features to enhance your Python development experience.

Syntax Highlighting

Rich provides syntax highlighting for multiple programming languages. This feature is particularly useful when working in a console environment where code readability is important. Let’s see an example:

from rich import print
code = '''
def greet(name):
print(f"Hello, {name}!")
'''
print(code, "python")

In this example, we import the print function from the rich module and use it to print the code block with syntax highlighting specified as python. This will make the code more readable and visually appealing.

Code Object Inspection

Rich also allows you to inspect Python code objects and display them in a formatted and easily understandable way. This can be useful when debugging or exploring Python objects. Here’s an example:

from rich import inspect
# Define a simple class
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Create an instance of the class
person = Person("John", 30)
# Inspect the object
inspect(person)

In this example, we create a simple Person class and an instance of that class. We then use the inspect function from Rich to display the object in a readable format.

The Console Class

Rich provides the Console class, which allows you to create rich text output in a more flexible way. You can use this class to create custom console displays with various styling and formatting options. Here’s an example:

from rich.console import Console
# Create a new console
console = Console()
# Output text with different styles
console.print("Hello, world!", style="bold underline")
console.print("This is a warning message.", style="bold yellow")

In this example, we create a new Console object and use its print method to output text with different styles. This allows us to create visually appealing and informative console output.

Logging and Tracebacks

Rich provides a logging handler that outputs formatted log messages with various levels of severity. This can be useful when debugging or logging information during the execution of your Python code.

Rich also improves the formatting of Python tracebacks, making them more readable and easier to understand. This can be a time-saver when troubleshooting issues in your code.

Keeping Your User Engaged Through Animation

Rich allows you to create engaging animations in the console, keeping your users interested and entertained. This section will cover how to use context managers and various animation features provided by Rich.

Understanding Context Managers

Before diving into animations, it’s important to have a good understanding of context managers. Context managers allow you to allocate and release resources automatically, ensuring that resources are properly managed and cleaned up.

Rich provides a context manager called ProgressBar. This context manager can be used to create progress bars for tracking the progress of a process or task. Let’s see an example:

from rich.progress import Progress
# Create a progress bar
with Progress() as progress:
task = progress.add_task("[cyan]Progress:", total=100)
while not progress.finished:
progress.advance(task, 10)
progress.refresh()
time.sleep(0.1)

In this example, we create a Progress object and use it as a context manager. Inside the with block, we add a task to the progress bar and then use a loop to increment the progress. The refresh method is called to update the progress bar in the console.

Displaying Dynamic Status With Animations

Rich allows you to display dynamic statuses in the console using animations. These animations can be helpful for showing the user that a process is ongoing or that something is happening in the background. Let’s take a look at an example:

from rich.live import Live
# Create a live object
with Live(auto_refresh=False) as live:
for i in range(10):
live.update(f"Processing item {i}...")
time.sleep(0.1)

In this example, we create a Live object and use it as a context manager. Inside the with block, we use the update method to update the live status message in the console. By default, the Live object automatically refreshes the console, but we can disable this with the auto_refresh parameter set to False.

Animating Activities With Progress Bars

Rich allows you to animate activities in the console using progress bars. This can be useful for tasks that take a long time to complete and for displaying the progress to the user. Here’s an example:

from rich.progress import Progress
# Create a progress bar
with Progress() as progress:
task = progress.add_task("[cyan]Downloading...", total=100)
for i in range(1, 101):
time.sleep(0.1)
progress.update(task, completed=i)

In this example, we create a Progress object and use it as a context manager. Inside the with block, we add a task to the progress bar and then use a loop to update the progress. The update method is called to increment the completion of the task.

Bringing Tables to Life

Rich provides powerful features for creating and animating tables in the console. This can be useful for displaying tabular data, such as real-time data feeds or data from APIs. In this section, we’ll explore how to create static tables, animate scrolling displays, and create live tables.

Building a Static Table

Rich allows you to create static tables in the console with various formatting options. This can be useful for presenting data in a tabular format. Let’s see an example:

from rich.console import Console
from rich.table import Table
# Create a new console
console = Console()
# Create a table
table = Table(show_header=True, header_style="bold")
table.add_column("Name", style="dim", width=12)
table.add_column("Age", style="dim", width=8)
table.add_row("John Doe", "30")
table.add_row("Jane Smith", "25")
# Render the table
console.print(table)

In this example, we create a new Console object and a Table object. We add columns and rows to the table, specifying styles and width. Finally, we use the print method of the console to render the table in the console.

Animating a Scrolling Display

Rich allows you to create scrolling displays in the console, which can be useful for showing a large amount of data without taking up too much space. Let’s see an example:

from rich.console import Console
from rich.table import Table
# Create a new console
console = Console()
# Create a table
table = Table(show_header=True, header_style="bold")
table.add_column("Name", style="dim", width=12)
table.add_column("Age", style="dim", width=8)
# Add rows to the table
for i in range(100):
table.add_row(f"Person {i}", str(i))
# Render the table with a scrolling display
console.print(table, overflow="fold")

In this example, we create a new Console object and a Table object. We add columns to the table and then use a loop to add rows. Finally, we use the print method of the console to render the table with a scrolling display. The overflow="fold" parameter specifies that the table should be folded if it exceeds the height of the console.

Accessing the Crypto Data

Rich allows you to access real-time data sources, such as cryptocurrency APIs, to retrieve data and display it in a table. This can be useful for creating live displays of real-time data. Here’s an example:

import requests
from rich.console import Console
from rich.table import Table
# Create a new console
console = Console()
# Fetch crypto data from an API
response = requests.get("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=bitcoin,ethereum")
data = response.json()
# Create and populate the table
table = Table(show_header=True, header_style="bold")
table.add_column("Name", style="dim", width=12)
table.add_column("Price", style="dim", width=12)
for crypto in data:
name = crypto["name"]
price = crypto["current_price"]
table.add_row(name, price)
# Render the table
console.print(table)

In this example, we use the requests library to fetch crypto data from a cryptocurrency API. We then create a new Console object and a Table object. We add columns to the table and populate it with data from the API response. Finally, we use the print method of the console to render the table in the console.

Coding the Live Table

Rich allows you to create live tables that update in real-time. This can be useful for displaying continuously changing data, such as stock prices or live statistics. Here’s an example:

import requests
from datetime import datetime
from rich.console import Console
from rich.live import Live
from rich.table import Table
# Create a new console
console = Console()
# Create the table
table = Table(show_header=True, header_style="bold")
table.add_column("Time", style="dim", width=16)
table.add_column("Price", style="dim", width=12)
# Create a live table
with Live(table, auto_refresh=True, console=console) as live:
while True:
now = datetime.now().strftime("%H:%M:%S")
response = requests.get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd")
price = response.json()["bitcoin"]["usd"]
table.rows = [[now, str(price)]]
time.sleep(1)

In this example, we import the necessary libraries and create a new Console object, a Table object, and a Live object. Inside the with block, we use a loop to continuously update the table with the current time and the price of Bitcoin fetched from a cryptocurrency API.

Conclusion

In this tutorial, you learned how to use the Python Rich package to enhance command-line tools, improve console output readability, create attractive dashboard displays, and generate well-formatted reports. You explored various features of Rich, such as syntax highlighting, code object inspection, the Console class, logging and tracebacks, animations, and table creation. With Rich, you can create visually appealing and informative text-based user interfaces in Python.

Next Steps

Remember to experiment and have fun with Rich. It’s a powerful tool that can bring your command-line applications to life with attractive and engaging text-based interfaces. Happy coding!