Python Rich Library - 豐富 Terminal 視覺化效果的函式庫

2020-07-08

GitHub Trending 意外發現的神好用函式庫,提供解決目前 Python Terminal 顯示上的兩個痛點,分別是 Syntax Highlighting 以及 Progress Bar,原本要實現這兩項功能都是仰賴自己手動刻寫,完全是重造輪子的疲憊感。而 Rich 除實現了目前的痛點,並且帶來更多 Terminal 上視覺效果的呈現,實在是相見恨晚 😎

logo

函式庫介紹

使用 Rich 之前必須先透過 pip install

pip install rich --user

而在使用上除可以將函式直接引入外,也可以藉由創造 console object 來進行,建議用這個 consle 的方式避免和既有的函式混淆。

from rich.console import Console

console = Console()
console.print("Hello World")

Rich Print

使用 Rich 就可以和以往使用的 coloroma library 整合,更為便利,而同樣受限 Cmder 僅支援 8bit color,未來對於彩色文字的應用潛力無窮。

console = Console()

for color in ['red', 'blue', 'green', 'yellow', 'white', 'black', 'magenta', 'cyan']:
    console.print(f"Hello World! {color} bold", style= f"{color} bold")
    console.print(f"Hello World! {color}", style= f"{color}")

渲染效果

Docs - style colors

支援 bbcode 的標籤方式,要組合彩色字串更為方便

console.input("[lime bold]What[/] is [green bold]your[/] [bold red]name[/]?")

Docs - bbcode

也自帶 python objects 的顏色渲染

fruits = {
    'apple' : { 'price' : 20, 'color' : 'red'},
    'banana' : { 'price' : 10, 'color' : 'yellow'},
}

console.print(fruits)
console.print(locals())

要做到 Jusfity 也是易如反掌,當然要更精準的對齊還是要仰賴 format string

console = Console(width = 50) # width 控制輸出螢幕寬度

style = "bold white on green"
console.print("Rich", justify="left")
console.print("Rich", justify="center")
console.print("Rich", justify="right")

Syntax Highlighting

Rich 使用 pygments 來實踐 Syntax Highlighting,所支援的 themes 包括:

abap, algol, algol_nu, arduino, autumn, borland, bw, colorful, default, emacs, friendly, fruity, igor, inkpot, lovelace, manni, monokai, murphy, native, paraiso_dark, paraiso_light, pastie, perldoc, rainbow_dash, rrt, sas, solarized, stata_dark, stata_light, tango, trac, vim, vs, xcode

其中最常使用的就是 monokai

而支援的語言也相當豐富,基本上常見的都有支援,例如 c_like, python, javascript, sql。

from rich.console import Console
from rich.syntax import Syntax

console = Console()

syntax = Syntax(codeString, "python", theme = "monokai", line_numbers = True)
console.print(syntax)

New Windows Terminal 上渲染的成果令人感動萬分 😂

Progress Bar

藉由將要迭代的集合 (sequence) 當作參數傳給 track ,Rich 就會自動計算已迭代的數量並顯示於 Termianl

from rich.progress import track

for step in track(range(100)):
    lst = []
    for i in range(100_000):
        lst.append(i)

實作成果

同時 Rich 也支援多個 ProgressBar 顯示,其中 total 表示的是任務完成所需要的總量,advance 則是每次 update 時累積的完成度, Rich 會根據兩者的比值自動渲染 Multiple ProgressBar。

from rich.progress import Progress


with Progress() as progress:
    task1 = progress.add_task("[red]Downloading...", total=1000)
    task2 = progress.add_task("[green]Processing...", total=1000)
    task3 = progress.add_task("[cyan]Cooking...", total=1000)

    while not progress.finished:
        progress.update(task1, advance=0.5)
        progress.update(task2, advance=0.3)
        progress.update(task3, advance=0.9)
        time.sleep(0.02)

實作成果

Docs - Progress

Tables

容易使用的程度與 prettytable 不相上下,而 Rich Table 強項在顏色控制、Emoji 等支援,prettytable 強項則是表格的欄位、格線等客製。

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

table = Table(title="Python Versions")

table.add_column("Release Date", justify="right", style="cyan", no_wrap=True)
table.add_column("Version", style="magenta")
table.add_column("Latest Micro Version", justify="left", style="green")

table.add_row("Oct 10, 2020", "3.9", "3.9.0")
table.add_row("Oct 14, 2019", "3.8", "3.8.3")
table.add_row("Jun 27, 2018", "3.7", "3.7.7")
table.add_row("Dec 23, 2016", "3.6", "3.6.10")
table.add_row("Sep 13, 2015", "3.5", "3.5.9")
table.add_row("Mar 16, 2014", "3.4", "3.4.10")

console = Console()
console.print(table)

Docs - Tables

Logs / Logging Handler / Tracebacks

console.log("Hello, World!")
#[19:05:53] Hello, World!                test.py:25

小結

Rich 完全是激起重新整合 CLI 環境的神兵利器,因為對於豐富文字色彩、 Emoji 支援的需求改採 New Windows Terminal 來作為 shell 工具;同時 Cmder 的便利性也不能割捨,於是整合 Cmder 以及New Windows Terminal 並使用 Rich 改寫既有的 CLI tools 成為現下最熱血想做的事情。

參考資料