コンテンツへスキップ

サブコマンド名とヘルプ

Typerアプリを別のアプリに追加する場合、コマンドに使用する`name`を設定する方法を見てきました。

例えば、コマンドを`users`に設定するには

app.add_typer(users.app, name="users")

ヘルプテキストの追加

Typerを追加する際に`help`も設定できます。

import typer

app = typer.Typer()

users_app = typer.Typer()
app.add_typer(users_app, name="users", help="Manage users in the app.")


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

そして、CLIプログラムでそのコマンドのヘルプテキストが表示されます。

// Check the main help
$ python main.py --help

Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  users  Manage users in the app.

// Check the help for the users command
$ python main.py users --help

Usage: main.py users [OPTIONS] COMMAND [ARGS]...

  Manage users in the app.

Options:
  --help  Show this message and exit.

Commands:
  create

`name`と`help`は複数の場所で設定でき、それぞれが前の値を上書きします。

それらの場所を見てみましょう。

ヒント

次に示すのと同じ場所で、同じように設定できる他の属性もあります。

しかし、それらは別のセクションで後ほど説明します。

コールバックからの名前とヘルプの推論

コマンドの名前とヘルプの推論

@app.command()でコマンドを作成する場合、デフォルトでは関数名から名前が生成されます。

また、デフォルトでは、ヘルプテキストは関数のdocstringから抽出されます。

例:

@app.command()
def create(item: str):
    """
    Create an item.
    """
    typer.echo(f"Creating item: {item}")

…は、ヘルプテキストが「アイテムを作成する」であるコマンド`create`を作成します。

@app.callback()からの名前とヘルプの推論

同様に、`typer.Typer()`でコールバックを定義する場合、ヘルプテキストはコールバック関数のdocstringから抽出されます。

そして、そのTyperアプリが別のTyperアプリに追加されると、コマンドのデフォルト名はコールバック関数名から生成されます。

例を以下に示します。

import typer

app = typer.Typer()

users_app = typer.Typer()
app.add_typer(users_app)


@users_app.callback()
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

ここでは、`name`も`help`も指定せずにサブTyperを追加しました。

これらは、コールバック関数から推論されます。

コマンド名は、同じコールバック関数名になります:`users`。

そして、`users`コマンドのヘルプテキストは、コールバック関数のdocstringになります:「アプリでユーザーを管理します。」

確認してください

// Check the main help
$ python main.py --help

// Notice the command name "users" and the help text "Manage users in the app."
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  users  Manage users in the app.

// Check the help for the users command
$ python main.py users --help

// Notice the main description: "Manage users in the app."
Usage: main.py users [OPTIONS] COMMAND [ARGS]...

  Manage users in the app.

Options:
  --help  Show this message and exit.

Commands:
  create

typer.Typer()のコールバックパラメータからの名前とヘルプ

`typer.Typer(callback=some_function)`を作成する際に`callback`パラメータを渡すと、名前とヘルプテキストの推論に使用されます。

これは優先順位が最も低く、後で優先順位が高く、上書きできるものを見ていきます。

コードを確認してください

import typer

app = typer.Typer()


def users():
    """
    Manage users in the app.
    """


users_app = typer.Typer(callback=users)
app.add_typer(users_app)


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

これは、前の例と同じことを実現します。

確認してください

// Check the main help
$ python main.py --help

// Notice the command name "users" and the help text "Manage users in the app."
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  users  Manage users in the app.

// Check the help for the users command
$ python main.py users --help

// Notice the main description: "Manage users in the app."
Usage: main.py users [OPTIONS] COMMAND [ARGS]...

  Manage users in the app.

Options:
  --help  Show this message and exit.

Commands:
  create

typer.Typer()で設定されたコールバックを@app.callback()でオーバーライドする

通常の**Typer**アプリと同様に、`typer.Typer(callback=some_function)`に`callback`を渡して`@app.callback()`でオーバーライドすると、名前とヘルプテキストは新しいコールバックから推論されます。

import typer

app = typer.Typer()


def old_callback():
    """
    Old callback help.
    """


users_app = typer.Typer(callback=old_callback)
app.add_typer(users_app)


@users_app.callback()
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

これで、コマンド名は`users`になり(`old-callback`ではなく)、ヘルプテキストは「アプリでユーザーを管理します。」になります(「古いコールバックのヘルプ」ではなく)。

確認してください

// Check the main help
$ python main.py --help

// Notice the command name "users" and the help text "Manage users in the app."
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  users  Manage users in the app.

// Check the help for the users command
$ python main.py users --help

// Notice the main description: "Manage users in the app."
Usage: main.py users [OPTIONS] COMMAND [ARGS]...

  Manage users in the app.

Options:
  --help  Show this message and exit.

Commands:
  create

app.add_typer()のコールバックから名前とヘルプを推論する

サブアプリを含める際に`app.add_typer()`でコールバックをオーバーライドすると、名前とヘルプは、このコールバック関数から推論されます。

これは、`@sub_app.callback()`と`typer.Typer(callback=sub_app_callback)`で設定されたコールバックからの名前とヘルプの推論よりも優先されます。

コードを確認してください

import typer

app = typer.Typer()


def old_callback():
    """
    Old callback help.
    """


users_app = typer.Typer(callback=old_callback)


def new_users():
    """
    I have the highland! Create some users.
    """


app.add_typer(users_app, callback=new_users)


@users_app.callback()
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

これで、コマンドは`new-users`になります(`users`ではなく)。ヘルプテキストは「ハイランドを手に入れた!ユーザーを作成しましょう。」になります(以前のものとは異なります)。

確認してください

// Check the main help
$ python main.py --help

// Check the command new-users and its help text
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  new-users  I have the highland! Create some users.

// Now check the help for the new-users command
$ python main.py new-users --help

// Notice the help text
Usage: main.py new-users [OPTIONS] COMMAND [ARGS]...

  I have the highland! Create some users.

Options:
  --help  Show this message and exit.

Commands:
  create

推論はここまで

そのため、名前とヘルプテキストを推論する場合、優先順位(優先順位が低い順)は次のとおりです。

  • sub_app = typer.Typer(callback=some_function)
  • @sub_app.callback()
  • app.add_typer(sub_app, callback=new_function)

これは、関数から名前とヘルプテキストを推論する場合です。

しかし、名前とヘルプテキストを明示的に設定すると、これらよりも優先されます。

名前とヘルプの設定

それでは、コマンドの名前とヘルプテキストを設定できる場所を、優先順位が低い順に見ていきましょう。

ヒント

名前とヘルプテキストを明示的に設定すると、常にコールバック関数からの推論よりも優先されます。

typer.Typer()での名前とヘルプ

これまでに定義したすべてのコールバックとオーバーライドを使用できますが、名前とヘルプテキストは関数名とdocstringから推論されていました。

明示的に設定すると、推論よりも優先されます。

新しい`typer.Typer()`を作成する際に設定できます。

import typer

app = typer.Typer()


def old_callback():
    """
    Old callback help.
    """


users_app = typer.Typer(callback=old_callback, name="exp-users", help="Explicit help.")


def new_users():
    """
    I have the highland! Create some users.
    """


app.add_typer(users_app, callback=new_users)


@users_app.callback()
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

情報

残りのコールバックとオーバーライドは、名前とヘルプテキストを明示的に設定した場合は影響しないことを示すためだけに存在します。

明示的な名前`exp-users`と明示的なヘルプ`Explicit help.`を設定しました。

そのため、これが優先されます。

確認してください

// Check the main help
$ python main.py --help

// Notice the command name is exp-users and the help text is "Explicit help."
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  exp-users  Explicit help.

// Check the help for the exp-users command
$ python main.py exp-users --help

// Notice the main help text
Usage: main.py exp-users [OPTIONS] COMMAND [ARGS]...

  Explicit help.

Options:
  --help  Show this message and exit.

Commands:
  create

@app.callback()での名前とヘルプ

`typer.Typer()`アプリの作成時に使用するパラメータは、`@app.callback()`のパラメータでオーバーライドできます。

前の例を続けると、ここでは`@user_app.callback()`の値をオーバーライドします。

import typer

app = typer.Typer()


def old_callback():
    """
    Old callback help.
    """


users_app = typer.Typer(callback=old_callback, name="exp-users", help="Explicit help.")


def new_users():
    """
    I have the highland! Create some users.
    """


app.add_typer(users_app, callback=new_users)


@users_app.callback("call-users", help="Help from callback for users.")
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

これで、コマンド名は`call-users`になり、ヘルプテキストは「ユーザーのコールバックからのヘルプ」になります。

確認してください

// Check the help
$ python main.py --help

// The command name now is call-users and the help text is "Help from callback for users.".
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  call-users  Help from callback for users.

// Check the call-users command help
$ python main.py call-users --help

// Notice the main help text
Usage: main.py call-users [OPTIONS] COMMAND [ARGS]...

  Help from callback for users.

Options:
  --help  Show this message and exit.

Commands:
  create

app.add_typer()での名前とヘルプ

最後に、最も高い優先順位で、上記の最初の例のように`app.add_typer()`で`name`と`help`を明示的に設定することで、すべてをオーバーライドできます。

import typer

app = typer.Typer()


def old_callback():
    """
    Old callback help.
    """


users_app = typer.Typer(callback=old_callback, name="exp-users", help="Explicit help.")


def new_users():
    """
    I have the highland! Create some users.
    """


app.add_typer(
    users_app,
    callback=new_users,
    name="cake-sith-users",
    help="Unlimited powder! Eh, users.",
)


@users_app.callback("call-users", help="Help from callback for users.")
def users():
    """
    Manage users in the app.
    """


@users_app.command()
def create(name: str):
    print(f"Creating user: {name}")


if __name__ == "__main__":
    app()

そして、これらすべての中で最も高い優先順位で、コマンド名は`cake-sith-users`になり、ヘルプテキストは「無限のパウダー!え、ユーザー。」になります。

確認してください

// Check the help
$ python main.py --help

// Notice the command name cake-sith-users and the new help text "Unlimited powder! Eh, users."
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or customize the installation.
  --help                Show this message and exit.

Commands:
  cake-sith-users  Unlimited powder! Eh, users.

// And check the help for the command cake-sith-users
$ python main.py cake-sith-users --help

// Notice the main help text
Usage: main.py cake-sith-users [OPTIONS] COMMAND [ARGS]...

  Unlimited powder! Eh, users.

Options:
  --help  Show this message and exit.

Commands:
  create

要約

コマンドの名前とヘルプを生成する優先順位(優先順位が低い順)は次のとおりです。

  • `sub_app = typer.Typer(callback=some_function)`から暗黙的に推論される
  • `@sub_app.callback()`の下のコールバック関数から暗黙的に推論される
  • `app.add_typer(sub_app, callback=some_function)`から暗黙的に推論される
  • `sub_app = typer.Typer(name="some-name", help="Some help.")`で明示的に設定される
  • `@sub_app.callback("some-name", help="Some help.")`で明示的に設定される
  • `app.add_typer(sub_app, name="some-name", help="Some help.")`で明示的に設定される

そのため、`app.add_typer(sub_app, name="some-name", help="Some help.")`が常に優先されます。