コンテンツへスキップ

カスタム型

Typerアプリケーションでは、独自のカスタム型を簡単に使用できます。

その方法は、CLIの入力テキストのようなプレーンな形式から、独自の型を持つPythonオブジェクトに変換する(パースする)方法を提供することです。

これを実現する方法は2つあります。

  • パーサーを追加する
  • Clickのカスタム型を拡張する

型パーサー

typer.Argumenttyper.Optionは、パーサー 呼び出し可能オブジェクトを使用してカスタムパラメータ型を作成できます。

import typer
from typing_extensions import Annotated


class CustomClass:
    def __init__(self, value: str):
        self.value = value

    def __str__(self):
        return f"<CustomClass: value={self.value}>"


def parse_custom_class(value: str):
    return CustomClass(value * 2)


def main(
    custom_arg: Annotated[CustomClass, typer.Argument(parser=parse_custom_class)],
    custom_opt: Annotated[CustomClass, typer.Option(parser=parse_custom_class)] = "Foo",
):
    print(f"custom_arg is {custom_arg}")
    print(f"--custom-opt is {custom_opt}")


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

ヒント

可能な場合は、Annotatedバージョンを使用することを推奨します。

import typer


class CustomClass:
    def __init__(self, value: str):
        self.value = value

    def __str__(self):
        return f"<CustomClass: value={self.value}>"


def parse_custom_class(value: str):
    return CustomClass(value * 2)


def main(
    custom_arg: CustomClass = typer.Argument(parser=parse_custom_class),
    custom_opt: CustomClass = typer.Option("Foo", parser=parse_custom_class),
):
    print(f"custom_arg is {custom_arg}")
    print(f"--custom-opt is {custom_opt}")


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

パラメータパーサーに渡す関数(または呼び出し可能オブジェクト)は、入力値を文字列として受け取り、独自のカスタム型でパースされた値を返す必要があります。

Clickカスタム型

既にClickカスタム型がある場合は、typer.Argument()typer.Option()click_typeパラメータを使用してそれを使用できます。

import click
import typer
from typing_extensions import Annotated


class CustomClass:
    def __init__(self, value: str):
        self.value = value

    def __repr__(self):
        return f"<CustomClass: value={self.value}>"


class CustomClassParser(click.ParamType):
    name = "CustomClass"

    def convert(self, value, param, ctx):
        return CustomClass(value * 3)


def main(
    custom_arg: Annotated[CustomClass, typer.Argument(click_type=CustomClassParser())],
    custom_opt: Annotated[
        CustomClass, typer.Option(click_type=CustomClassParser())
    ] = "Foo",
):
    print(f"custom_arg is {custom_arg}")
    print(f"--custom-opt is {custom_opt}")


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

ヒント

可能な場合は、Annotatedバージョンを使用することを推奨します。

import click
import typer


class CustomClass:
    def __init__(self, value: str):
        self.value = value

    def __repr__(self):
        return f"<CustomClass: value={self.value}>"


class CustomClassParser(click.ParamType):
    name = "CustomClass"

    def convert(self, value, param, ctx):
        return CustomClass(value * 3)


def main(
    custom_arg: CustomClass = typer.Argument(click_type=CustomClassParser()),
    custom_opt: CustomClass = typer.Option("Foo", click_type=CustomClassParser()),
):
    print(f"custom_arg is {custom_arg}")
    print(f"--custom-opt is {custom_opt}")


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