Pythonライブラリ Rich ✨:ターミナル出力を華やかにする魔法

プログラミング

はじめに:Richとは?

Pythonを使ってコマンドラインアプリケーション(CLI)を開発していると、ターミナルの地味なテキスト出力に物足りなさを感じることがありませんか? 🤔 デバッグ情報や処理結果をもっと分かりやすく、視覚的に魅力的に表示したいと思ったことはありませんか?

そんな悩みを解決してくれるのが、PythonライブラリRichです。Richは、ターミナル出力に色やスタイルを付けたり、テーブル、プログレスバー、マークダウン、シンタックスハイライトされたコードなど、高度なコンテンツを驚くほど簡単に追加できるライブラリです。

Richを使うことで、あなたのCLIアプリケーションは単なるツールから、視覚的に魅力的で、ユーザーにとって格段に使いやすいものへと変貌します。また、データ構造をきれいに表示したり、構文をハイライトしたりすることで、デバッグ作業の効率も大幅に向上させることが可能です。🚀

このブログ記事では、Richの基本的な使い方から、応用的な機能まで、具体的なコード例を交えながら詳しく解説していきます。さあ、Richの世界を探検し、あなたのコンソール出力を次のレベルへと引き上げましょう!

インストール

Richのインストールは非常に簡単です。Pythonのパッケージインストーラであるpipを使って、以下のコマンドを実行するだけです。

pip install rich

もし既にインストール済みで、最新バージョンにアップデートしたい場合は、-Uオプションを追加します。

pip install -U rich

Jupyter NotebookやJupyter LabでRichを利用する場合は、追加の依存関係が必要です。以下のコマンドでインストールできます。

pip install "rich[jupyter]"

インストールが完了したら、以下のコマンドを実行して、お使いのターミナルでRichの出力テストができます。

python -m rich

これでRichを使う準備が整いました!🎉

互換性について: RichはLinux, macOS, Windowsで動作します。True colorや絵文字は新しいWindows Terminalなどでサポートされますが、古いターミナル(Windowsのcmd.exeなど)では色数が制限される場合があります。Python 3.8以上が必要です。(一部古いドキュメントでは3.6.3や3.7.0と記載されている場合もありますが、最新版では3.8が推奨されています。)PyCharmなどのIDEのコンソールで利用する場合、設定で「ターミナルをエミュレートする」オプションの有効化が必要な場合があります。

基本的な使い方:print関数とConsoleオブジェクト

Richを使い始める最も簡単な方法は、組み込みのprint関数の代わりにRichのprint関数をインポートすることです。

from rich import print

print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", {"name": "Rich", "version": "latest"})

これを実行すると、”World”の部分が太字のマゼンタ色で表示され、絵文字:vampire:が表示され、辞書オブジェクトが整形されてシンタックスハイライト付きで出力されます。通常のprint関数と同じ感覚で使えますが、自動的にリッチな表現が加わります。

より高度な制御を行いたい場合は、Consoleオブジェクトを使用します。

from rich.console import Console

console = Console()

console.print("これはConsoleオブジェクトからの出力です。", style="bold green")
console.print("複数の引数も", "扱えます。", style="underline blue")

data = {"key1": "value1", "key2": [1, 2, 3], "key3": {"nested": True}}
console.print("データ構造もきれいに表示:", data)

Consoleオブジェクトのprintメソッドは、組み込み関数と同様のインターフェースを持ちつつ、style引数で出力全体のスタイルを指定したり、自動でテキストをワードラップ(ターミナルの幅に合わせて折り返す)したりする機能があります。

リッチな表現力:主な機能紹介

Richが提供する多彩な機能の中から、特に代表的なものをいくつか紹介します。

1. テキストスタイリングとコンソールマークアップ

Richでは、BBCodeに似たシンプルなマークアップを使って、テキストに色やスタイル(太字、斜体、下線など)を簡単に適用できます。

from rich import print

print("[bold]これは太字です[/bold]")
print("[italic red]これは斜体の赤文字です[/italic red]")
print("[underline cyan on white]これはシアン色の下線付き文字(白背景)です[/underline cyan on white]")
print("スタイルは[bold blue]ネスト[/bold blue]することも[i]可能[/i]です。")
print("絵文字も使えます :rocket: :star:")

利用可能な色やスタイルは非常に豊富です。詳細は公式ドキュメント(Style)を参照してください。

2. 美しいテーブル表示

データのリストや辞書などを、整形された美しいテーブル形式で表示できます。カラムの幅調整、テキスト揃え、罫線のスタイルなどをカスタマイズ可能です。

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

console = Console()

table = Table(title="Star Wars Movies", show_header=True, header_style="bold magenta")
table.add_column("Released", style="dim", width=12)
table.add_column("Title", style="cyan")
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. VIII: The Last Jedi", "$1,332,539,889")
table.add_row("Dec 16, 2016", "Rogue One: A Star Wars Story", "$1,056,057,273")

console.print(table)

上記コードを実行すると、ターミナルに次のような見やすいテーブルが表示されます。

                  Star Wars Movies
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Released     ┃ Title                                ┃     Box Office ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ Dec 20, 2019 │ Star Wars: The Rise of Skywalker     │   $952,110,690 │
│ May 25, 2018 │ Solo: A Star Wars Story              │   $393,151,347 │
│ Dec 15, 2017 │ Star Wars Ep. VIII: The Last Jedi    │ $1,332,539,889 │
│ Dec 16, 2016 │ Rogue One: A Star Wars Story         │ $1,056,057,273 │
└──────────────┴──────────────────────────────────────┴────────────────┘

(注:実際のターミナルではスタイル(色など)が適用されます)

3. プログレスバー

時間のかかる処理の進捗状況を視覚的に表示するプログレスバーを簡単に実装できます。複数のタスクの進捗を同時に表示したり、表示項目をカスタマイズしたりすることも可能です。

import time
from rich.progress import track

total_items = 100
for item in track(range(total_items), description="[cyan]処理中..."):
    # 何らかの重い処理を実行
    time.sleep(0.05)

print("[green]処理完了![/green]")

track関数でイテラブルをラップするだけで、ETA(推定残り時間)なども表示される便利なプログレスバーが表示されます。

より複雑なシナリオ(複数のタスク、カスタム表示など)に対応するには、Progressクラスを使用します。

import time
from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn, TimeElapsedColumn, TimeRemainingColumn

with Progress(
    SpinnerColumn(),
    TextColumn("[progress.description]{task.description}"),
    BarColumn(),
    TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
    TimeRemainingColumn(),
    TimeElapsedColumn(),
    transient=True  # 完了したらプログレスバーを消す
) as progress:
    task1 = progress.add_task("[red]ダウンロード中...", total=1000)
    task2 = progress.add_task("[green]処理中...", total=500)
    task3 = progress.add_task("[cyan]コピー中...", total=None) # 不定

    while not progress.finished:
        progress.update(task1, advance=10.5)
        progress.update(task2, advance=5.3)
        # task3 は進捗不明なので advance しない
        time.sleep(0.02)

print("[bold green]すべてのタスクが完了しました![/bold green]")

これにより、複数のタスクの進捗が同時に、かつ詳細な情報と共に表示されます。

4. シンタックスハイライト

ソースコードを指定した言語の構文に従って色付け表示できます。対応言語も豊富です。

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

console = Console()

my_code = """
def hello(name: str) -> str:
    '''これはサンプル関数です。'''
    greeting = f"こんにちは、{name}さん!"
    print(greeting) # コンソールにも出力
    return greeting

if __name__ == "__main__":
    hello("Rich")
"""

syntax = Syntax(my_code, "python", theme="native", line_numbers=True)
console.print(syntax)

Pythonコードはもちろん、他の多くの言語にも対応しており、テーマも複数から選択可能です。

5. マークダウンレンダリング

マークダウン形式のテキストを解釈し、ターミナルに適した形式で表示します。見出し、リスト、コードブロック、引用、テーブルなどを表現できます。

from rich.console import Console
from rich.markdown import Markdown

console = Console()

MARKDOWN = """
# Richのマークダウン機能

これは**Rich**ライブラリの*マークダウン*レンダリング機能のデモです。

## 特徴

- 見出し
- **太字** や *斜体*
- 箇条書きリスト
  - ネストも可能
    - さらに深く
- 番号付きリスト
  1. 項目1
  2. 項目2
- `インラインコード`
- ```python
  def greet(name):
      print(f"Hello, {name}!")
  ```
- 引用
> Richは素晴らしい!
- 水平線
---
- [リンク](https://github.com/Textualize/rich)

テーブルも表示できます:

| ヘッダー1 | ヘッダー2 |
|---|---|
| セル1-1 | セル1-2 |
| セル2-1 | セル2-2 |

"""

md = Markdown(MARKDOWN)
console.print(md)

READMEファイルなどをCLIツール内で表示したい場合に便利です。

6. ログハンドラ

Python標準のloggingモジュールと連携し、ログ出力をリッチな形式(色分け、タイムスタンプ、ファイル名、行番号など)で行うことができます。

import logging
from rich.logging import RichHandler

FORMAT = "%(message)s"
logging.basicConfig(
    level="INFO", format=FORMAT, datefmt="[%X]", handlers=[RichHandler(rich_tracebacks=True)]
)

log = logging.getLogger("rich")

log.info("これは情報メッセージです。")
log.warning("これは警告メッセージです。")
log.error("これはエラーメッセージです。")
try:
    1 / 0
except ZeroDivisionError:
    log.exception("ゼロ除算エラーが発生しました!")

これにより、ログレベルに応じた色分けや、読みやすいトレースバック情報などが出力され、デバッグ効率が向上します。

7. トレースバックの改善

キャッチされなかった例外が発生した場合のトレースバック(エラー発生箇所の情報)を、非常に見やすく表示します。コードスニペットとシンタックスハイライト付きで表示されるため、エラーの原因特定が容易になります。

from rich.traceback import install

install(show_locals=True) # トレースバックハンドラをインストール(ローカル変数も表示)

def func_a(x, y):
    return func_b(x * 2, y / 2)

def func_b(a, b):
    # わざとエラーを発生させる
    result = a / (b - 5)
    return result

# 実行
func_a(10, 10)

上記のコードを実行すると、標準のトレースバックよりもはるかに多くの情報を含んだ、色付きの分かりやすいエラーレポートが表示されます。

8. Live Display(ライブ表示)

ターミナル画面の一部を継続的に更新し、アニメーションやリアルタイムで変化する情報を表示できます。スピナーや進捗バーと組み合わせたり、動的に変化するテーブルを表示したりするのに役立ちます。

import time
from rich.live import Live
from rich.table import Table
from datetime import datetime

table = Table()
table.add_column("時刻")
table.add_column("イベント")

with Live(table, refresh_per_second=4, screen=True) as live: # screen=Trueで画面をクリアしてから表示
    for i in range(10):
        time.sleep(1)
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        table.add_row(now, f"イベント {i+1} 発生")
        # live.update(table) # Liveコンテキスト内では明示的なupdateは不要な場合が多い
    live.update("[bold green]ライブ表示終了[/bold green]") # 最後にメッセージを表示

この例では、1秒ごとにテーブルに行が追加されていく様子がリアルタイムで表示されます。

9. その他

上記以外にも、Richには以下のような多くの機能があります。

  • Pretty Printing: Pythonオブジェクト(リスト、辞書など)を人間が読みやすい形に整形して表示します。
  • Tree表示: ファイル構造などの階層データをツリー形式で表示します。
  • Columns: コンテンツを複数のカラムに分割して表示します。
  • Panel: テキストや他の要素を枠線で囲んで表示します。
  • Layout: より複雑なターミナルUIを構築するためのレイアウト機能。
  • Inspect: Pythonオブジェクトの詳細情報(属性、メソッドなど)を分かりやすく表示します。

これらの機能を組み合わせることで、非常に高度で表現力豊かなCLIアプリケーションを構築できます。

Richを使うメリット ✨

  • 視認性の向上: 色やスタイル、テーブルなどを使うことで、情報が格段に見やすくなります。
  • 開発効率の向上: Pretty Printingや改善されたトレースバック、ログハンドラにより、デバッグ作業が捗ります。
  • ユーザーエクスペリエンスの向上: プログレスバーやLive Displayなどで、ユーザーに処理状況を分かりやすく伝えられます。
  • 表現力の豊かさ: マークダウンやシンタックスハイライトなど、多様なコンテンツをターミナルで表現できます。
  • 導入の容易さ: pipで簡単にインストールでき、基本的な機能はprintを置き換えるだけで使い始められます。

まとめ

PythonライブラリRichは、ターミナル出力を劇的に改善するための強力で多機能なツールです。基本的なテキストの装飾から、テーブル、プログレスバー、ログ、トレースバックの改善、さらにはLive Displayやレイアウト機能まで、CLIアプリケーション開発を豊かにする機能が満載です。

導入も簡単で、学習コストも比較的低いため、PythonでCLIツールを開発する際には、ぜひRichの導入を検討してみてください。きっとあなたの開発体験と、アプリケーションの品質を一段階引き上げてくれるはずです。👍

さあ、Richを使って、あなたのターミナルをもっとカラフルで、もっと便利に、もっとリッチにしましょう!

より詳しい情報や最新情報については、Richの公式ドキュメントGitHubリポジトリをご参照ください。

コメント

タイトルとURLをコピーしました