Typer:用 Python 类型注解写 CLI

Typer 在 GitHub 上已经拿到 19.5K Star 了。

FastAPI 作者 Sebastián Ramírez 写的这个库,让 Python 开发者用类型注解就能把普通函数变成命令行工具。自动 help 文档、自动 shell 补全、无限层级子命令,全都有了。

1、Typer 解决什么问题

Python 标准库有 argparse,社区有 Click,都能写 CLI。但它们有个共同的毛病:需要学一套新的 API 语法。参数怎么声明、选项怎么配、help 文本怎么加,每个库都有一套规矩。

Typer 把这件事简化到了极致。你写一个普通 Python 函数,加上类型注解,它就自动变成命令行工具:

def main(name: str, age: int = 0, happy: bool = False):
    print(f"Hello {name}, age {age}, happy {happy}")

name 变成必填参数,age 是可选选项,happy 自动生成 --happy--no-happy 两个 flag。一行 add_argument 都不用写。

正文顶部截图

2、为什么选择 Typer

构建 CLI 工具时,大量时间花在了重复劳动上:参数校验、help 排版、错误提示美化、shell 补全脚本的生成。这些活跟业务逻辑没关系,但又绕不开。

Typer 靠三样东西把这些全自动化了:

第一是 Python 类型系统。name: str 既是参数声明也是类型校验规则,编辑器能给你补全和类型检查,不用翻文档查参数格式。

第二是 Rich 库集成。错误提示和 help 输出自带格式化与彩色高亮,不需要额外配置。

第三是 shellingham 库。自动检测当前 shell(Bash、Zsh、Fish、PowerShell),一键安装补全脚本。

零行配置,help 输出长这样:

Usage: main.py [OPTIONS] NAME

 Arguments:
 *    name      TEXT  [default: None] [required]

 Options:
 --help          Show this message and exit.

3、从最简单到任意复杂

Typer 的入门代码就两行,一行 import,一行调用:

import typer

def main(name: str):
    print(f"Hello {name}")

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

更妙的是,脚本里完全不 import Typer,也能直接用 typer 命令运行:

$ typer main.py run Camila
Hello Camila

这个特性让 Typer 可以当一个通用脚本运行器。写个简单脚本,不加任何框架代码,typer run 一下就有 help、补全和错误提示。

当项目变大后,装饰器模式能组织多级子命令:

import typer

app = typer.Typer()

@app.command()
def hello(name: str):
    print(f"Hello {name}")

@app.command()
def goodbye(name: str, formal: bool = False):
    if formal:
        print(f"Goodbye Ms. {name}.")
    else:
        print(f"Bye {name}!")

if __name__ == "__main__":
    app()

命令层级可以无限嵌套,每个子命令都是一个 typer.Typer() 实例,挂到父级 app 上。参数声明方式完全一样,不管命令藏得多深。

README区域截图

4、依赖和架构变化

Typer 的依赖很少:

  • rich 负责终端输出格式化和错误渲染
  • shellingham 自动检测 shell 类型
  • annotated-doc 从类型注解生成文档

从 0.26.0 版本开始,Typer 把 Click 的源码内嵌(vendor)进了自己仓库,不再作为外部依赖安装。这意味着团队可以直接控制底层 CLI 框架的行为,维护路径更短。

之前还有一个精简版 typer-slim,去掉了 Rich 和 shellingham。从 0.22.0 起这个版本不再维护,typer-slim 现在直接安装完整版 Typer。如果确实不需要 Rich,设环境变量 TYPER_USE_RICH=False 即可。

5、适合什么人用

  • 用 Python 写运维脚本和内部工具的开发者,想让命令行体验更专业但不想花时间学 CLI 框架
  • FastAPI 用户,同样的类型注解思路,从 Web API 到 CLI 零切换成本
  • 数据团队,把 Notebook 里的分析逻辑快速封装成带参数的命令行工具
  • 需要交付 CLI 工具的 Python 项目,参数校验、help 文档和 shell 补全开箱即用

Typer 做的事情不大,但恰好踩在 CLI 开发中最烦人的那部分上。用 Python 类型注解这种已经会的东西来声明接口,不用再学一套 API,这个思路值 19.5K Star。

elp 文档和 shell 补全开箱即用

Typer 做的事情不大,但恰好踩在 CLI 开发中最烦人的那部分上。用 Python 类型注解这种已经会的东西来声明接口,不用再学一套 API,这个思路值 19.5K Star。

更多推荐