在 Python 的 'click' 提示下自动回答 'yes'(无人值守命令 运行)
Automatically answer 'yes' on Python's 'click' prompts (unattended command run)
我已经使用 Python's click library(版本 7.1.2)构建了一个命令行界面,它可以 运行 一个命令,要求(人类)用户在途中回答某些确认(井已知 "Are you sure you want to continue? Y/n"
)
现在,我正在尝试 运行 在 Kubernetes CronJob 上自动执行该命令,我需要一种“假装”向每个提示输入 Y
的方法。
我看到了click.confirmation_option
,但如果我没理解错的话,那似乎更像是对运行整个命令的确认,对吧? (也许我错了?)
我更想在下面的示例中寻找类似 assume_yes
的东西(可以传递给调用或在创建完整上下文时传递 ctx = cli.make_context...
):
from my_command import cli
ctx = cli.make_context(
'main_command_group', ["action", "--num_times", 3]
)
with ctx:
result = cli.invoke(ctx, assume_yes=True)
这可能吗?
我总是可以添加某种环境变量,或者将 extra boolean Option (a flag) 传递到我的 Click 命令并编辑我的代码,这样在尝试显示确认提示之前,它会检查环境变量 (或标志)是 True
,如果是,则假设是(甚至不显示提示),但它 感觉 像 Click
必须 有一些无人看管的东西 运行s.
编辑:(根据评论)
提示如下:
customer = CustomerManager.get_by_name(customer_name)
if (
not customer and
click.confirm(f"Create customer {customer_name}", default=True)
):
customer = CustomerManger.create(name=customer_name)
# more code
if not customer.address:
if click.confirm(
f"No address for customer {customer.name}. Leave blank?",
default=True):
# ...
至于 为什么 这样做:因为完全相同的代码将 运行 首先由人类(作为脚本。 .. 在命令行上),一旦人类用户“确定”了它,它就会被推送到一个 pod,它会被 CronJob 运行
运行 命令行上的脚本将填充本地数据库,运行 一些数据检查,一些验证...所以一旦人类在本地确认一切“良好” ,一个信号将被发送到 Kubernetes Cronjob,它将与人类完全一样。唯一的区别是,此时它可以假设所有提示的答案都是“是”。
所以是的:代码 可以 重构,但如果
不一定是(因为当 CLI 被 cronjob 运行 时,我们
已经知道每个确认提示的答案都是
成为 “是”)
您希望 Click_ 如何开箱即用地处理这个问题?系统需要知道你是机器人,而不是人。你怎么能做到这一点?一种方法是使用一些环境变量,另一种方法是为您的 cron 作业使用特殊的 API。尽管如此——你最终会得到一个针对这种情况的特殊选项。
您完全正确 – confirmation_option 没有涵盖您的案例,但它向您展示了您应该如何处理此类案例。
所以,我会做的是这样的:
@click.option('--yes', is_flag=True)
def my_method(customer_name, yes):
if not yes:
click.confirm(f"Create customer {customer_name}", default=False, abort=True)
customer = CustomerManger.create(name=customer_name)
您可以使用环境变量,但我看不出有任何理由这样做。您可以强制您的 cron 作业提供 --yes 选项。更简单也更明显。
我在这里尝试了 abort=True ,因为否则我需要再重复一次创建行,但它可能不适合你,如果你不想中止整个命令而只是想跳过客户的创建。
还有一些与您的问题无关的内容:我建议您在确认时默认为 False(这是默认情况下 Click_ 的工作方式),而不是 True。我可能会无意中按下回车键并搬起石头砸自己的脚。如果确认错误数据没有危险,您将不会有确认对话,所以最好不要以这种方式轻松确认:)
好的,如果你想全局执行此操作,而不是每个命令,你可以轻松覆盖 confirm() 行为:
def confirm(*args, **kwargs):
if not os.environ.get('yes'):
click.confirm(*args, **kwargs)
然后,您可以在代码中使用本地版本的 confirm
,而不是 click.confirm
:
@click.command()
def test():
confirm('Create customer', default=False, abort=True)
...
现在,如果导出 yes
环境变量,您将看到不同之处。
我已经使用 Python's click library(版本 7.1.2)构建了一个命令行界面,它可以 运行 一个命令,要求(人类)用户在途中回答某些确认(井已知 "Are you sure you want to continue? Y/n"
)
现在,我正在尝试 运行 在 Kubernetes CronJob 上自动执行该命令,我需要一种“假装”向每个提示输入 Y
的方法。
我看到了click.confirmation_option
,但如果我没理解错的话,那似乎更像是对运行整个命令的确认,对吧? (也许我错了?)
我更想在下面的示例中寻找类似 assume_yes
的东西(可以传递给调用或在创建完整上下文时传递 ctx = cli.make_context...
):
from my_command import cli
ctx = cli.make_context(
'main_command_group', ["action", "--num_times", 3]
)
with ctx:
result = cli.invoke(ctx, assume_yes=True)
这可能吗?
我总是可以添加某种环境变量,或者将 extra boolean Option (a flag) 传递到我的 Click 命令并编辑我的代码,这样在尝试显示确认提示之前,它会检查环境变量 (或标志)是 True
,如果是,则假设是(甚至不显示提示),但它 感觉 像 Click
必须 有一些无人看管的东西 运行s.
编辑:(根据评论)
提示如下:
customer = CustomerManager.get_by_name(customer_name) if ( not customer and click.confirm(f"Create customer {customer_name}", default=True) ): customer = CustomerManger.create(name=customer_name) # more code if not customer.address: if click.confirm( f"No address for customer {customer.name}. Leave blank?", default=True): # ...
至于 为什么 这样做:因为完全相同的代码将 运行 首先由人类(作为脚本。 .. 在命令行上),一旦人类用户“确定”了它,它就会被推送到一个 pod,它会被 CronJob 运行
运行 命令行上的脚本将填充本地数据库,运行 一些数据检查,一些验证...所以一旦人类在本地确认一切“良好” ,一个信号将被发送到 Kubernetes Cronjob,它将与人类完全一样。唯一的区别是,此时它可以假设所有提示的答案都是“是”。
所以是的:代码 可以 重构,但如果 不一定是(因为当 CLI 被 cronjob 运行 时,我们 已经知道每个确认提示的答案都是 成为 “是”)
您希望 Click_ 如何开箱即用地处理这个问题?系统需要知道你是机器人,而不是人。你怎么能做到这一点?一种方法是使用一些环境变量,另一种方法是为您的 cron 作业使用特殊的 API。尽管如此——你最终会得到一个针对这种情况的特殊选项。
您完全正确 – confirmation_option 没有涵盖您的案例,但它向您展示了您应该如何处理此类案例。
所以,我会做的是这样的:
@click.option('--yes', is_flag=True)
def my_method(customer_name, yes):
if not yes:
click.confirm(f"Create customer {customer_name}", default=False, abort=True)
customer = CustomerManger.create(name=customer_name)
您可以使用环境变量,但我看不出有任何理由这样做。您可以强制您的 cron 作业提供 --yes 选项。更简单也更明显。
我在这里尝试了 abort=True ,因为否则我需要再重复一次创建行,但它可能不适合你,如果你不想中止整个命令而只是想跳过客户的创建。
还有一些与您的问题无关的内容:我建议您在确认时默认为 False(这是默认情况下 Click_ 的工作方式),而不是 True。我可能会无意中按下回车键并搬起石头砸自己的脚。如果确认错误数据没有危险,您将不会有确认对话,所以最好不要以这种方式轻松确认:)
好的,如果你想全局执行此操作,而不是每个命令,你可以轻松覆盖 confirm() 行为:
def confirm(*args, **kwargs):
if not os.environ.get('yes'):
click.confirm(*args, **kwargs)
然后,您可以在代码中使用本地版本的 confirm
,而不是 click.confirm
:
@click.command()
def test():
confirm('Create customer', default=False, abort=True)
...
现在,如果导出 yes
环境变量,您将看到不同之处。