コンテンツへスキップ

数値

intfloatの*CLIパラメータ*に対して、maxminの値で数値検証を定義できます。

import typer
from typing_extensions import Annotated


def main(
    id: Annotated[int, typer.Argument(min=0, max=1000)],
    age: Annotated[int, typer.Option(min=18)] = 20,
    score: Annotated[float, typer.Option(max=100)] = 0,
):
    print(f"ID is {id}")
    print(f"--age is {age}")
    print(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、Annotatedバージョンを使用することをお勧めします。

import typer


def main(
    id: int = typer.Argument(..., min=0, max=1000),
    age: int = typer.Option(20, min=18),
    score: float = typer.Option(0, max=100),
):
    print(f"ID is {id}")
    print(f"--age is {age}")
    print(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

*CLI引数*と*CLIオプション*の両方で、これらの検証を使用できます。

minmax、またはその両方を指定できます。

確認してください

$ python main.py --help

// Notice the extra RANGE in the help text for --age and --score
Usage: main.py [OPTIONS] ID

Arguments:
  ID  [required]

Options:
  --age INTEGER RANGE   [default: 20]
  --score FLOAT RANGE   [default: 0]
  --help                Show this message and exit.

// Pass all the CLI parameters
$ python main.py 5 --age 20 --score 90

ID is 5
--age is 20
--score is 90.0

// Pass an invalid ID
$ python main.py 1002

Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for 'ID': 1002 is not in the range 0<=x<=1000.

// Pass an invalid age
$ python main.py 5 --age 15

Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for '--age': 15 is not in the range x>=18.

// Pass an invalid score
$ python main.py 5 --age 20 --score 100.5

Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for '--score': 100.5 is not in the range x<=100.

// But as we didn't specify a minimum score, this is accepted
$ python main.py 5 --age 20 --score -5

ID is 5
--age is 20
--score is -5.0

数値のクランピング

エラーを表示する代わりに、最も近い最小値または最大値を使用したい場合があります。

clampパラメータを使用して実行できます

import typer
from typing_extensions import Annotated


def main(
    id: Annotated[int, typer.Argument(min=0, max=1000)],
    rank: Annotated[int, typer.Option(max=10, clamp=True)] = 0,
    score: Annotated[float, typer.Option(min=0, max=100, clamp=True)] = 0,
):
    print(f"ID is {id}")
    print(f"--rank is {rank}")
    print(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、Annotatedバージョンを使用することをお勧めします。

import typer


def main(
    id: int = typer.Argument(..., min=0, max=1000),
    rank: int = typer.Option(0, max=10, clamp=True),
    score: float = typer.Option(0, min=0, max=100, clamp=True),
):
    print(f"ID is {id}")
    print(f"--rank is {rank}")
    print(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

有効範囲外のデータを渡すと、「クランピング」され、最も近い有効値が使用されます。

// ID doesn't have clamp, so it shows an error
$ python main.py 1002

Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for 'ID': 1002 is not in the range 0<=x<=1000.

// But --rank and --score use clamp
$ python main.py 5 --rank 11 --score -5

ID is 5
--rank is 10
--score is 0

カウンター *CLIオプション*

counterパラメータを使用して、*CLIオプション*をカウンターとして機能させることができます。

import typer
from typing_extensions import Annotated


def main(verbose: Annotated[int, typer.Option("--verbose", "-v", count=True)] = 0):
    print(f"Verbose level is {verbose}")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、Annotatedバージョンを使用することをお勧めします。

import typer


def main(verbose: int = typer.Option(0, "--verbose", "-v", count=True)):
    print(f"Verbose level is {verbose}")


if __name__ == "__main__":
    typer.run(main)

つまり、*CLIオプション*はブール型のフラグ(例:--verbose)のように動作します。

そして、関数で受け取る値は、--verboseが追加された回数になります。

// Check it
$ python main.py

Verbose level is 0

// Now use one --verbose
$ python main.py --verbose

Verbose level is 1

// Now 3 --verbose
$ python main.py --verbose --verbose --verbose

Verbose level is 3

// And with the short name
$ python main.py -v

Verbose level is 1

// And with the short name 3 times
$ python main.py -v -v -v

Verbose level is 3

// As short names can be put together, this also works
$ python main.py -vvv

Verbose level is 3