Exporting SVGs of terminal output with Rich
Rich recently added two interesting new features.
The first feature is SVG support. Anything printed to the terminal with Rich can be captured and exported to an SVG file. The output is somewhat like a screenshot but generated within Rich itself (it doesn't peek at your desktop).
I think these SVGs will be useful for sharing terminal output, particularly for documentation.
The API to save SVGs works in the same way as the methods to save / export text and HTML. Here's the code that generated the above image:
from rich.console import Console
from rich.table import Table
table = Table(title="Star Wars Movies")
table.add_column("Released", 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(record=True)
console.print(table, justify="center")
console.save_svg("table.svg", title="save_table_svg.py")
import os
import webbrowser
webbrowser.open(f"file://{os.path.abspath('table.svg')}")
The second new feature was contributed by Martin Larralde who often has to process large datasets where you might want to see a progress bar. Integrating Rich's progress bars was difficult to do if the code reading the file is not in your control. For example, if you are using json.load
from the standard library -- there is no easy hook to update the progress bar.
Martin's solution was to wrap file-like objects to that reads and seeks update the progress bar accordingly. That way when you pass a file-like object to a third-party API, you will get a progress bar that tracks how much of the file has been read.
Here's how you would read and decode a large JSON file and display progress:
import json
import rich.progress
with rich.progress.open("cats.json") as cats_file:
data = json.load(cats_file)
Now adding a progress bar can be as simple as replacing open
with rich.progress.open
.
See the Rich Repository for more details. You may also want to check out Rich's sister project, Textual.