Python clickの案外知られていない機能

# Python clickの案外知られていない機能

Pythonには[click](https://click.palletsprojects.com/en/latest/)というコマンドラインパーサとして使えるライブラリがあります。同様のライブラリとして以前から[argparse](https://docs.python.org/ja/3/howto/argparse.html)がありますが、clickはargparseよりももっと簡単に使えるライブラリです。
clickでコマンドラインパーサを書く例は以下になります。

```python
# main.py
import click

@click.command()
@click.option(
        "--count", 
        type=int,
        default=1,
        required=True,
        help="Number of greetings.",
)
@click.option(
        "--name", 
        type=str,
        default="Your name",
        required=True,
        help="The person to greet.",
)
def hello(
        count: int, 
        name: str,
):
        for _ in range(count):
                click.echo(f"Hello {name}!")

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

これで以下のように実行することで引数を与えてプログラムを実行することができます。

```python
$ python -m main --count 2 --name test
Hello test!
Hello test!
```

ここで注目したいのは `click.echo(f"Hello {name}!")` です。clickで標準出力しています。clickはコマンドラインパーサとしてargparseの代替と思われることが多いですが、実はその他にもいろいろ便利な機能が提供されています。本記事ではclickの知られざる便利な機能を紹介します。

https://click.palletsprojects.com/en/8.0.x/utils/


## 標準出力 `click.echo()` `click.secho()` `click.style()` `click. echo_via_pager()`

clickで標準出力することができます。Pythonの標準出力であれば`print`がありますが、`click.echo`系の標準出力はいろいろ高機能です。

```python
# click_echo.py
import click

def main():
        message="Hello World of 2021!"
        # 普通に標準出力
        click.echo(message)
        # エラーメッセージとして標準出力
        click.echo(message, err=True)
        # フォントの色を緑
        click.echo(click.style(message, fg="green"))
        # フォントの色を緑、バックグラウンドを青
        click.echo(click.style(message, fg="green", bg="blue"))
        # 太文字、下線を引く、フォント色とバックグラウンド色を反転
        click.echo(click.style(message,bold=True, underline=True, reverse=True))
        # 太文字、下線を引く、フォント色を緑、バックグラウンドを青にしてフォント色とバックグラウンド色を反転
        click.secho(message, bold=True, underline=True, reverse=True, fg="green", bg="blue")

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

`python -m click_echo`　で実行すると以下のような結果になります。`click`のコマンドラインパーサ機能と組み合わせてPythonでCLIを作る時にメッセージの表示で便利に使うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/2ac28203-7eb4-0d22-fe61-6a9a0027ea7d.png)

更にはpagerを加えて長い複数行の表示をスクロール表示することもできます。

```python
# click_pager.py

import click

def main():
        click.echo_via_pager("\n".join(f"Line {idx}" for idx in range(100)))

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

これで複数行表示されたメッセージを↑↓やスペースキーで上下移動することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/7d353141-1ad1-c7e7-bfa7-e72d38a5201c.png)


## 表示操作 `click.clear()` `click.pause()`

`click`ではターミナルの表示を操作することもできます。

`click.clear()`　で標準出力をクリア（clearコマンド）、`click.pause()`でキーボードが押されるまで停止することができます。


## エディタやアプリケーションを開く `click.edit()` `click.launch()`

`click`からエディタやアプリケーションを開くこともできます。
たとえばテキストファイル等を開く場合は`click.edit(filename="text.txt")`で開いて直接編集することができます。これでターミナルでPythonでファイル操作中にファイルの内容を書き換えたい場合にいちいちPythonから`quit()`してエディタを開く必要はなくなります。
更には`click.launch()`でアプリケーションを開くこともできます。
たとえば`click.launch("https://qiita.com/advent-calendar/2021/python")`を実行することで標準のWebブラウザで　https://qiita.com/advent-calendar/2021/python　が開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/2383274b-14c7-def8-a844-4bcc5fdb6488.png)

その他にもファイルパスを指定することでそのファイルを開くこともできます。`click.launch("./text.txt")`で以下のようにファイルを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55384/e8d5cb96-7ed5-d4b0-ac4f-ca9307a477e8.png)

## プログレスバー `click.progressbar()`

最後にプログレスバーです。`click.progressbar()`でプログレスバーを表示することができます。

```python
# click_progress.py

import click
import time

with click.progressbar([1, 2, 3]) as bar:
        for x in bar:
                msg=f"sleep({x})..."
                click.echo(msg)
                time.sleep(x)
```

```sh
$ python -m click_progress
sleep(1)...
  [############------------------------]   33%  00:00:02sleep(2)...
  [########################------------]   66%  00:00:01sleep(3)...
  [####################################]  100%
```

## まとめ
というわけで[click](https://click.palletsprojects.com/en/latest/api/)の知られざる便利な機能の紹介でした。
良いお年を〜。