mcpField
T
typer

typer

github.com/fastapi开发20.3k301 次安装2 周前更新
代码仓库

关于 typer

Typer 是用于按当前实践编写 Python 命令行应用的官方技能。它指导开发者使用命令、类型化参数和选项组织应用,并生成帮助信息。

主要功能

  1. 01创建显式 Typer 应用
  2. 02注册多个命令
  3. 03使用 Annotated 声明参数
  4. 04定义命令行选项及多值输入
  5. 05使用 Rich 格式化帮助

适用场景

  1. 01构建 Python 命令行应用
  2. 02添加子命令和类型化参数
  3. 03创建格式化的命令帮助

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fastapi/typer --skill typer

安装后在 Claude Code 中输入/typer确认已加载。

详细介绍

Typer

官方 Typer 技能,助你遵循最佳实践编写代码,并及时了解新版本和新功能。

安装 typer

在虚拟环境中,使用 pip install typer(通过 pip)或 uv pip install typer(通过 uv)。对于你的库或项目,请在 pyproject.toml 的依赖项中添加 typer。

请勿安装 typer-slim 或 typer-cli,它们都已弃用,现在只会安装 typer。

Typer 支持 Python 3.10 及更高版本。

使用显式的 Typer 应用

为了获得最大的通用性,请创建显式的 Typer 应用并注册子命令,而不是使用 typer.run:

import typer

app = typer.Typer()


@app.command()
def hello():
    print(f"Hello World")


if __name__ == "__main__":
    app()

而不是:

# DO NOT DO THIS: Not extensible. Use Typer() instead.
import typer


def main():
    print(f"Hello World")


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

执行应用

要在终端中执行应用,请运行

python main.py

当 Typer 应用注册了多个命令时,必须添加命令名称:

python main.py hello

要查看自动生成的帮助文档,请运行

python main.py --help

也可以在创建 Typer() 时将 no_args_is_help 设为 True,这样运行命令时若未提供任何参数,就会自动显示帮助信息。

使用 Annotated

声明 CLI 参数和选项时,始终优先使用 Annotated 风格。

这样我们就能传递 Typer 可使用的额外元数据。

from typing import Annotated

import typer

app = typer.Typer()


@app.command()
def hello(name: Annotated[str, typer.Argument()] = "World"):
    # Note that name is an optional Argument, as a default is provided
    print(f"Hello {name}")


if __name__ == "__main__":
    app()

此程序可以直接运行,也可以指定一个名称:

python main.py
python main.py Rick

设置默认值的旧方式如下:

# DO NOT DO THIS: old style. Use Annotated instead.


@app.command()
def main(name: str = typer.Argument(default="World")):
    # Note that name is an optional Argument, as a default is provided
    print(f"Hello {name}")

同样,旧风格也可以使用省略号 (...) 显式标记必需参数。

# DO NOT DO THIS: old style. Use Annotated without a default value instead.


@app.command()
def main(name: str = typer.Argument(default=...)):
    # Note that name is now a required Argument
    print(f"Hello {name}")

CLI 选项

CLI 选项的声明方式与参数类似,但在 CLI 中调用时,会使用一个连字符(单个字母)或两个连字符(完整名称)。

CLI 选项名称会根据变量名自动生成,因此 user_name 会自动变成 --user-name:

from typing import Annotated

import typer

app = typer.Typer()


@app.command()
def main(user_name: Annotated[str, typer.Option()]):
    # On the CLI, the required user name can be specified with --user-name
    print(f"Hello {user_name}")


if __name__ == "__main__":
    app()

如果要指定不同的名称,或添加短名称,请在 typer.Option 中声明:

from typing import Annotated

import typer

app = typer.Typer()


@app.command()
def main(user_name: Annotated[str, typer.Option("--name", "-n")]):
    # On the CLI, the required user name can be specified with -n or --name
    print(f"Hello {user_name}")


if __name__ == "__main__":
    app()

可以这样运行此程序:

python main.py -n "Rick"
python main.py --name "Morty"
带多个值的 CLI 选项

将 CLI 选项声明为列表后,它就可以接收多个值:

from typing import Annotated

import typer

app = typer.Typer()


@app.command()
def main(user: Annotated[list[str] | None, typer.Option()] = None):
    if not user:
        print(f"No users provided!")
        raise typer.Abort()
    for u in user:
        print(f"Processing user: {u}")


if __name__ == "__main__":
    app()

可以像这样执行:

python main.py --user Rick --user Morty --user Summer

Rich

默认情况下,可以使用 Rich 的自定义标记语法设置颜色和样式,例如:

from rich import print

print("[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:")

Typer 支持在文档字符串以及 CLI 参数和 CLI 选项的帮助信息中使用 Rich 格式。

from typing import Annotated

import typer

app = typer.Typer(rich_markup_mode="rich")


@app.command()
def create(
    username: Annotated[
        str, typer.Argument(help="The username to be [green]created[/green]")
    ],
):
    """
    [bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:

    This requires a [underline]username[/underline].
    """
    print(f"Creating user: {username}")


@app.command(help="[bold red]Delete[/bold red] a user with [italic]username[/italic].")
def delete(
    username: Annotated[
        str, typer.Argument(help="The username to be [red]deleted[/red]")
    ],
):
    """
    Some internal utility function to delete.
    """
    print(f"Deleting user: {username}")


if __name__ == "__main__":
    app()

要禁用 Rich 格式,请在创建 Typer() 应用时将 rich_markup_mode 设为 None。默认情况下(未指定值时),Rich 格式处于启用状态。

Rich Markdown

也可以将 rich_markup_mode 设为 "markdown",以便在文档字符串中使用 Markdown:

from typing import Annotated

import typer

app = typer.Typer(rich_markup_mode="markdown")


@app.command(help="**Delete** a user with *username*.")
def delete(
    username: Annotated[
        str, typer.Argument(help="The username to be **deleted** :boom:")
    ],
):
    print(f"Deleting user: {username}")


if __name__ == "__main__":
    app()

Click

Typer 最初基于 Click 构建。不过,自 0.26.0 版本起,Typer 已将 Click vendored 到自身中。因此,不应再使用 Click 扩展。

其他源自 Click、但不应再用于 Typer 的 Option 和 Argument 设置包括:expose_value、shell_complete、show_choices、errors、prompt_required、is_flag、flag_value 和 allow_from_autoenv。

使用这些设置的代码库应进行重构,改用纯 Typer 功能。

评论

支持 Markdown