コンテンツへスキップ

コンテキストの使用

Typerアプリケーションを作成すると、内部的にClickが使用されます。そして、すべてのClickアプリケーションには、通常は非表示の"コンテキスト"と呼ばれる特別なオブジェクトがあります。

しかし、`typer.Context`型の関数パラメータを宣言することで、コンテキストにアクセスできます。

CLIオプションコールバックとコンテキストでそれを読んだことがあるかもしれません。

同様に、コマンド内またはメインのTyperコールバック内で、`typer.Context`型の関数パラメータを宣言することでコンテキストにアクセスできます。

コンテキストの取得

例えば、呼び出されているサブコマンドに応じて、Typerコールバックで何らかのロジックを実行したいとします。

コンテキストからサブコマンドの名前を取得できます。

import typer

app = typer.Typer()


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


@app.command()
def delete(username: str):
    print(f"Deleting user: {username}")


@app.callback()
def main(ctx: typer.Context):
    """
    Manage users in the awesome CLI app.
    """
    print(f"About to execute command: {ctx.invoked_subcommand}")


if __name__ == "__main__":
    app()

確認してください

$ python main.py create Camila

// We get the message from the callback
About to execute command: create
Creating user: Camila

$ python main.py delete Camila

// We get the message from the callback, this time with delete
About to execute command: delete
Deleting user: Camila

実行可能コールバック

デフォルトでは、コールバックはコマンドの実行直前にのみ実行されます。

そして、コマンドが提供されない場合、ヘルプメッセージが表示されます。

しかし、`invoke_without_command=True` を使用して、サブコマンドなしでも実行させることができます。

import typer

app = typer.Typer()


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


@app.command()
def delete(username: str):
    print(f"Deleting user: {username}")


@app.callback(invoke_without_command=True)
def main():
    """
    Manage users in the awesome CLI app.
    """
    print("Initializing database")


if __name__ == "__main__":
    app()

確認してください

$ python main.py

// The callback is executed, we don't get the default help message
Initializing database

// Try with a command
$ python main.py create Camila

// The callback is still executed
Initializing database
Creating user: Camila

排他的実行可能コールバック

既に実行される他のコマンドがある場合に、コールバックが実行されないようにしたい場合があります。

`typer.Context`を取得し、`ctx.invoked_subcommand`に呼び出されたコマンドがあるかどうかを確認できます。

それが`None`の場合、サブコマンドではなく、メインプログラム(コールバック)が直接呼び出されていることを意味します。

import typer

app = typer.Typer()


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


@app.command()
def delete(username: str):
    print(f"Deleting user: {username}")


@app.callback(invoke_without_command=True)
def main(ctx: typer.Context):
    """
    Manage users in the awesome CLI app.
    """
    if ctx.invoked_subcommand is None:
        print("Initializing database")


if __name__ == "__main__":
    app()

確認してください

$ python main.py

// The callback is executed
Initializing database

// Check it with a subcommand
$ python main.py create Camila

// This time the callback is not executed
Creating user: Camila

コンテキストの設定

コマンドまたはコールバックを作成する際に、コンテキストの設定を渡すことができます。

使用可能な設定の詳細については、ClickのContextのドキュメントを参照してください。

例えば、`ignore_unknown_options` と `allow_extra_args` を使用して、CLIプログラムで宣言されていない追加のCLIパラメータを保持することができます。

その後、それらの追加の生のCLIパラメータを`ctx.args`で`str`の`list`としてアクセスできます。

import typer

app = typer.Typer()


@app.command(
    context_settings={"allow_extra_args": True, "ignore_unknown_options": True}
)
def main(ctx: typer.Context):
    for extra_arg in ctx.args:
        print(f"Got extra arg: {extra_arg}")


if __name__ == "__main__":
    app()
$ python main.py --name Camila --city Berlin

Got extra arg: --name
Got extra arg: Camila
Got extra arg: --city
Got extra arg: Berlin

ヒント

すべての追加のCLIパラメータが、CLIオプション名と値を含めて、生の`str`の`list`として保存されることに注意してください。