PythonでターミナルをRichにする

# PythonでターミナルをRichにする

ターミナルは暗い。Pythonでバックエンド開発をしていると日々真っ暗な画面を凝視することになり、性格も人生も暗くなります。

![スクリーンショット 2020-12-04 6.50.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/44fb841c-e493-3c97-8a98-87410eb3dd9b.png)


そこに光明を差すライブラリを見つけました。[Rich](https://github.com/willmcgugan/rich)です。Richを使うことによって、真っ暗なターミナルを色とりどりのフォントと絵文字で明るい人生を送ることができるようになります。

## What is Rich?
Richはターミナルにリッチなテキストを美しく整形して出力するPythonライブラリです。
Pythonの標準出力、ログの両方をきれいに表示することができるようになります。しかも絵文字も使えます。

Richは以下で公開されています。

- [Github](https://github.com/willmcgugan/rich)
- [Documentation](https://rich.readthedocs.io/en/latest/index.html)

## Richになりましょう！
### Rich入門
インストールは簡単です。すぐRichになれます。

```sh
pip install rich
```

これでRichになれました。続いてRichな生き方を学びましょう。
以下でRichな生き方が示されます。

```sh
python -m rich
```

![スクリーンショット 2020-12-03 16.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/c9e9b097-dbca-6fa3-fdfa-3b6a31f3b5fa.png)

すごいRichです。

### Rich生活
もう少しRichになってみましょう。標準出力をRichにします。

```python
import rich
from rich import pretty, print
from rich.console import Console

console = Console()
pretty.install()

print(1, 0.4, "I am Rich!", "私はRich!", ":smiley:")
console.print(1, 0.4, "I am Rich!", "私はRich!", ":smiley:")

print([1, 2, 3])
print({"a": 0, "b": 1, "c": "a1<aa>", "rich": rich})
```

![スクリーンショット 2020-12-03 16.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/1f4af636-1270-5f0f-3cc4-780b99edf6b1.png)

とてもRichです！　絵文字が輝いています！
Richは更に、クラスや関数をフォーマットして表示してくれます。intをinspectして表示してみましょう。

```python
from rich import pretty, print, inspect
from rich.console import Console

console = Console()
pretty.install()

print(inspect(int, methods=True))
```

![スクリーンショット 2020-12-03 16.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/7ec85c96-1ddb-b0c6-6aad-2c22cd13f39b.png)

コンソールログを使えば更にRichなフォーマットで表示することができます。

```python
from rich import pretty, print
from rich.console import Console

console = Console()
pretty.install()

test_data = [
    {"jsonrpc": "2.0", "method": "sum", "params": [None, 1, 2, 4, False, True]},
    {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
    {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23]},
]

console.log("Hello from", console, "!")
console.log(test_data, log_locals=True)
```

![スクリーンショット 2020-12-03 17.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/b7e103ea-89c9-1865-0543-2f36288d645e.png)


# 本番で使うRich
本番でもRichになるために、例外やloggingフォーマットもRichにしたいと思います。

例外もRichに表示することができます。

```python
from rich import pretty, print
from rich.console import Console

console = Console()
pretty.install()

try:
    print(1 / 0)
except Exception as e:
    console.print_exception(extra_lines=5, show_locals=True)
```

![スクリーンショット 2020-12-03 17.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/61bf25b9-02ae-a177-9ce0-85e7bf6c7377.png)


エラー内容がすーぱーRichになっています。絶対に見落とすことは有りません。

そしてRichはLoggingHandlerもRichに提供しています。

```python
import rich
from rich import pretty, print
from rich.console import Console
import time
import logging
from rich.logging import RichHandler

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

log = logging.getLogger("rich")
log.info("Hello, World!")


def div(divisor: int, divident: int) -> float:
    return divisor / divident


def main():
    try:
        a = div(2, 1)
        log.info(f"2 / 1 = {a}")

        b = div(1, 0)
        log.info(f"1 / 0 = {b}")
    except Exception as e:
        log.exception("Rich error!")


if __name__ == "__main__":
    main()
```

![スクリーンショット 2020-12-03 17.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/d0ec08d7-aeef-0745-7a4e-279042358527.png)

ログがRichになりました！
エラーもRichログ仕様になり、可読性の高いエラーになっています。

## 終わRich
というわけでRichでした。みなさまもRichを使って年末年始をRichに過ごしてください。良いお年を！