Typer 回调
当你创建一个 app = typer.Typer()
时,它作为一个命令组工作。
你可以使用它创建多个命令。
每个命令都可以有自己的CLI 参数。
但由于这些CLI 参数由每个命令处理,它们不允许我们为 CLI 应用程序本身创建CLI 参数。
但我们可以为此使用 @app.callback()
。
它非常类似于 @app.command()
,但它声明了主 CLI 应用程序的CLI 参数(在命令之前)
import typer
app = typer.Typer()
state = {"verbose": False}
@app.command()
def create(username: str):
if state["verbose"]:
print("About to create a user")
print(f"Creating user: {username}")
if state["verbose"]:
print("Just created a user")
@app.command()
def delete(username: str):
if state["verbose"]:
print("About to delete a user")
print(f"Deleting user: {username}")
if state["verbose"]:
print("Just deleted a user")
@app.callback()
def main(verbose: bool = False):
"""
Manage users in the awesome CLI app.
"""
if verbose:
print("Will write verbose output")
state["verbose"] = True
if __name__ == "__main__":
app()
这里我们使用一个CLI 选项 --verbose
创建一个回调
。
提示
获取 --verbose
标志后,我们会修改全局状态
,并在其他命令中使用它。
还有其他方法可以实现相同的效果,但这对于本示例来说已经足够了。
而且由于我们在回调函数中添加了文档字符串,因此默认情况下它将被提取并用作帮助文本。
检查它
// Check the help
$ python main.py --help
// Notice the main help text, extracted from the callback function: "Manage users in the awesome CLI app."
Usage: main.py [OPTIONS] COMMAND [ARGS]...
Manage users in the awesome CLI app.
Options:
--verbose / --no-verbose [default: False]
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.
Commands:
create
delete
// Check the new top level CLI option --verbose
// Try it normally
$ python main.py create Camila
Creating user: Camila
// And now with --verbose
$ python main.py --verbose create Camila
Will write verbose output
About to create a user
Creating user: Camila
Just created a user
// Notice that --verbose belongs to the callback, it has to go before create or delete ⛔️
$ python main.py create --verbose Camila
Usage: main.py create [OPTIONS] USERNAME
Try "main.py create --help" for help.
Error: No such option: --verbose
在创建时添加回调¶
在创建 typer.Typer()
应用程序时也可以添加回调
import typer
def callback():
print("Running a command")
app = typer.Typer(callback=callback)
@app.command()
def create(name: str):
print(f"Creating user: {name}")
if __name__ == "__main__":
app()
这与使用 @app.callback()
实现的效果相同。
检查它
$ python main.py create Camila
Running a command
Creating user: Camila
覆盖回调¶
如果你在创建 typer.Typer()
应用程序时添加了回调,则可以使用 @app.callback()
覆盖它
import typer
def callback():
print("Running a command")
app = typer.Typer(callback=callback)
@app.callback()
def new_callback():
print("Override callback, running a command")
@app.command()
def create(name: str):
print(f"Creating user: {name}")
if __name__ == "__main__":
app()
现在将使用 new_callback()
。
检查它
$ python main.py create Camila
// Notice that the message is the one from new_callback()
Override callback, running a command
Creating user: Camila
仅为文档添加回调¶
你还可以添加回调只是为了在文档字符串中添加文档。
它很方便,尤其是在你有多行文本时,因为缩进将自动为你处理
import typer
app = typer.Typer()
@app.callback()
def callback():
"""
Manage users CLI app.
Use it with the create command.
A new user with the given NAME will be created.
"""
@app.command()
def create(name: str):
print(f"Creating user: {name}")
if __name__ == "__main__":
app()
现在回调将主要用于提取帮助文本的文档字符串。
检查它
$ python main.py --help
// Notice all the help text extracted from the callback docstring
Usage: main.py [OPTIONS] COMMAND [ARGS]...
Manage users CLI app.
Use it with the create command.
A new user with the given NAME will be created.
Options:
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.
Commands:
create
// And it just works as normally
$ python main.py create Camila
Creating user: Camila
单击组¶
如果你来自 Click,此Typer 回调等效于 Click 组 中的函数。
例如
import click
@click.group()
def cli():
pass
原始函数 cli
等效于 Typer 回调。
技术细节
使用 Click 时,它会将 cli
变量转换为 Click Group
对象。然后原始函数不再存在于该变量中。
Typer 不会这样做,回调函数不会被修改,只会注册在 typer.Typer
应用程序中。这是故意的,这是Typer 设计的一部分,以允许编辑器自动完成和类型检查。