コンテンツにスキップ

パス

標準のPython pathlib.Path を _CLI パラメータ_ として宣言できます。

これは、ディレクトリパス、ファイルパスなどに対して行うことです。

from pathlib import Path
from typing import Optional

import typer
from typing_extensions import Annotated


def main(config: Annotated[Optional[Path], typer.Option()] = None):
    if config is None:
        print("No config file")
        raise typer.Abort()
    if config.is_file():
        text = config.read_text()
        print(f"Config file contents: {text}")
    elif config.is_dir():
        print("Config is a directory, will use all its config files")
    elif not config.exists():
        print("The config doesn't exist")


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

ヒント

可能な場合は、注釈付きバージョンを使用することをお勧めします。

from pathlib import Path
from typing import Optional

import typer


def main(config: Optional[Path] = typer.Option(None)):
    if config is None:
        print("No config file")
        raise typer.Abort()
    if config.is_file():
        text = config.read_text()
        print(f"Config file contents: {text}")
    elif config.is_dir():
        print("Config is a directory, will use all its config files")
    elif not config.exists():
        print("The config doesn't exist")


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

繰り返しますが、型注釈と同じ標準の Python Path オブジェクトを受け取るので、エディターはすべての属性とメソッドの自動補完を提供します。

確認してください

// No config
$ python main.py

No config file
Aborted!

// Pass a config that doesn't exist
$ python main.py --config config.txt

The config doesn't exist

// Now create a quick config
$ echo "some settings" > config.txt

// And try again
$ python main.py --config config.txt

Config file contents: some settings

// And with a directory
$ python main.py --config ./

Config is a directory, will use all its config files

パス検証

Path _CLI パラメータ_ に対して、いくつかの検証を実行できます。

  • exists: true に設定されている場合、この値が有効であるためには、ファイルまたはディレクトリが存在する必要があります。これが必須ではなく、ファイルが実際に存在しない場合、それ以降のすべてのチェックはサイレントにスキップされます。
  • file_okay: ファイルが有効な値かどうかを制御します。
  • dir_okay: ディレクトリが有効な値かどうかを制御します。
  • writable: true の場合、書き込み可能チェックが実行されます。
  • readable: true の場合、読み取り可能チェックが実行されます。
  • resolve_path: これが true の場合、値が渡される前にパスが完全に解決されます。これは、絶対パスであり、シンボリックリンクが解決されることを意味します。

技術的な詳細

チルダプレフィックス (~ の付いたもの、例: ~/Documents/) は展開されません。これはシェルのみが行うことになっているためです。

ヒント

これらすべてのパラメータは、Click から直接取得されます。

例えば

from pathlib import Path

import typer
from typing_extensions import Annotated


def main(
    config: Annotated[
        Path,
        typer.Option(
            exists=True,
            file_okay=True,
            dir_okay=False,
            writable=False,
            readable=True,
            resolve_path=True,
        ),
    ],
):
    text = config.read_text()
    print(f"Config file contents: {text}")


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

ヒント

可能な場合は、注釈付きバージョンを使用することをお勧めします。

from pathlib import Path

import typer


def main(
    config: Path = typer.Option(
        ...,
        exists=True,
        file_okay=True,
        dir_okay=False,
        writable=False,
        readable=True,
        resolve_path=True,
    ),
):
    text = config.read_text()
    print(f"Config file contents: {text}")


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

確認してください

$ python main.py --config config.txt

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

Error: Invalid value for '--config': File 'config.txt' does not exist.

// Now create a quick config
$ echo "some settings" > config.txt

// And try again
$ python main.py --config config.txt

Config file contents: some settings

// And with a directory
$ python main.py --config ./

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

Error: Invalid value for '--config': File './' is a directory.

高度なパス設定

詳細

最初はこれらの設定は必要ないでしょう。スキップしても構いません。

これらは、より高度なユースケースで使用されます。

  • allow_dash: これが True に設定されている場合、標準ストリームを示す単一のダッシュが許可されます。
  • path_type: オプションで、パスを表すために使用する文字列型。デフォルトは None で、これは Click が扱う入力データに応じて、戻り値がバイトまたはユニコードのいずれかになることを意味します。