你好,
我实际上正在学习如何使用点击包中的一些元素,并且我希望能够使用该prompt命令从用户那里获取有效日期。
我尝试查找文档,并在http://click.pocoo.org/5/prompts/下找到了这个:
要手动请求用户输入,可以使用prompt()函数。默认情况下,它接受任何 Unicode 字符串,但您可以要求任何其他类型。
所以我编写了这段代码并尝试将类 datetime.datetime 作为所需的输入类型传递:
import datetime
value = click.prompt("Enter a date", type=datetime.datetime)
Run Code Online (Sandbox Code Playgroud)
当我执行此代码时,会出现提示,但在插入有效日期并按 Enter 键后,我收到此错误消息:
回溯(最近一次调用):文件“”,第 1 行,文件“/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/termui.py”,第 98 行,在提示 result = value_proc(value) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/types.py",第 38 行,在调用 return self.convert (value, param, ctx) 文件“/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/types.py”,第 87 行,在转换中返回 self.func(value )类型错误:需要一个整数(得到类型 str)
请您告诉我我在这段代码中做错了什么吗?
基本上我想通过编写类似这段(部分虚构的)代码的内容来获得正确格式化的日期值:
import datetime
value = click.prompt("Enter a date",
type=datetime.datetime,
format="%d/%m/%Y",
default=datetime.datetime.now())
Run Code Online (Sandbox Code Playgroud)
非常感谢
我用来click定义一个 CLI,它采用datetimes 和逗号分隔的参数列表。
import click
def valid_date(s):
try:
return dt.strptime(s, "%Y-%m-%d")
except ValueError:
msg = "Not a valid date: '{0}'.".format(s)
raise Exception(msg)
except TypeError:
return None
split_parameter = lambda _, __, s: s.split(",")
check_date = lambda _, __, s: valid_date(s)
@click.command()
@click.argument('symbols', callback=split_parameter)
@click.option('--start_date', callback=check_date)
@click.option('--end_date', callback=check_date)
@click.option('--file_name')
def f(symbols, start_date, end_date, file_name):
return None
Run Code Online (Sandbox Code Playgroud)
它有效,但 s 周围的逻辑callback有点尴尬。拆分列表和转换都datetime中断了单击的简单结构。有没有一种Python式的方法可以做到这一点?
我正在尝试用Click完成CLI解析方面不是很标准的事情,并且只能部分工作:
样品:
import click
@click.group()
@click.argument('hostname', required=False)
@click.pass_context
def cli(ctx, hostname=None):
""""""
ctx.obj = hostname
click.echo("cli: hostname={}".format(hostname))
@cli.command()
@click.pass_obj
def check(hostname):
click.echo("check: hostname={}".format(hostname))
@cli.command()
@click.pass_obj
def show(hostname):
click.echo("check: hostname={}".format(hostname))
if __name__ == '__main__':
cli()
Run Code Online (Sandbox Code Playgroud)
具有主机名的部分起作用:
> pipenv run python cli.py localhost check
cli: hostname=localhost
check: hostname=localhost
> pipenv run python cli.py localhost show
cli: hostname=localhost
check: hostname=localhost
Run Code Online (Sandbox Code Playgroud)
但是没有主机名的那部分却没有:
> pipenv run python cli.py show
Usage: cli.py [OPTIONS] [HOSTNAME] COMMAND [ARGS]...
Error: Missing command.
Run Code Online (Sandbox Code Playgroud)
有人对我应该开始研究的方向有所了解吗?
如果有命令组并且每个子命令都可能引发异常,我如何在一个地方一起处理它们?
鉴于以下示例:
import click
@click.group()
def cli():
pass
@cli.command()
def foo():
pass
if __name__ == '__main__':
cli()
Run Code Online (Sandbox Code Playgroud)
双方cli并foo可能会提高。我知道,一个可能的解决方案是将try-except各地cli()的在if条款。但是当你分发一个包时这不起作用。在setup.py 中,您必须指定一个入口点(在本例中为cli)。该if条款将不会被执行。
我用click这样的:
import click
@click.command(name='foo')
@click.option('--bar', required=True)
def do_something(bar):
print(bar)
Run Code Online (Sandbox Code Playgroud)
因此选项的名称和函数参数的名称是相同的.当它不相同时(例如,当你想要--id而不是--bar)时,我得到:
TypeError: do_something() got an unexpected keyword argument 'id'
Run Code Online (Sandbox Code Playgroud)
我不希望调用该参数,id因为这是一个Python函数.我不希望将CLI参数调用为不同,因为它会更麻烦/更不直观.我该如何解决?
我想从数据库加载参数和选项。我允许用户定义他们自己的选项和参数。用户可以在命令行上调用远程 api。它们指定到终点的 URL 和参数。这是来自数据库的数据的样子
[
{
"name": "thename1",
"short": "a",
"long": "ace"
"type": "string",
"required": false
},
{
"name": "thename2",
"short": "b",
"long": "bravo"
"type": "number",
"required": true
},
{
"name": "thename3",
"short": "c",
"long": "candy"
"type": "array",
"required": true
}
]
Run Code Online (Sandbox Code Playgroud)
这些参数与远程端点的需要一致。每个 API 端点都有不同的参数,因此它们需要是动态的。这是命令行的外观。
command run www.mysite.com/api/get -a testparam --bravo testpara2 -c item1 item2
Run Code Online (Sandbox Code Playgroud)
参数和值将映射到 URL 中。有没有办法在点击中设置动态参数?
我想自定义我的 Python Click CLI 程序的 BASH 完成功能,不仅包括脚本的命令/子命令,还包括脚本创建的对象。
假设我的程序被调用cli-tool,它可以foo使用以下命令创建对象:
cli-tool object create foo
Run Code Online (Sandbox Code Playgroud)
为简单起见,假设该命令只是将参数字符串(foo在本例中)连接到位于~/.cli-tool/objects/foo. 这样做cat ~/.cli-tool/objects/foo,然后将打印foo在你的终端。
我希望该工具做的是当我输入:
cli-tool object get <TAB><TAB>
Run Code Online (Sandbox Code Playgroud)
终端然后将名单foo及任何其他文件里面住~/.cli-tool/objects。
作为记录,我已阅读Python Click 6.x stable 文档,其中明确指出:
目前,Bash 补全是一个不可定制的内部功能。这在未来的版本中可能会放宽。
我希望有一种方法可以从以下命令中提取完整的BASH 完成脚本:
eval "$(_CLI_TOOL_COMPLETE=source cli-tool)"
Run Code Online (Sandbox Code Playgroud)
然后自己定制。我也看过点击完成项目,但我不确定它除了扩展 Zsh 和 Fish shell 的完成之外还有什么作用。
有没有人达到我上面提到的完成类型?
我正在尝试click从配置文件生成命令。本质上,这种模式:
import click
@click.group()
def main():
pass
commands = ['foo', 'bar', 'baz']
for c in commands:
def _f():
print("I am the '{}' command".format(c))
_f = main.command(name=c)(_f)
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
该--help文本看起来不错:
Usage: test_click.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
bar
baz
foo
Run Code Online (Sandbox Code Playgroud)
但是,所有命令似乎都路由到生成的最后一个命令:
$ ./test_click.py foo
I am the 'baz' command
$ ./test_click.py bar
I am the 'baz' command
$ ./test_click.py baz
I am the 'baz' command
Run Code Online (Sandbox Code Playgroud)
我正在尝试的实际上可能吗?
我想在我的配置中使用一个值(我加载到我的上下文中)作为单击命令选项的默认值。我已经阅读了文档的这一部分,但我认为我不明白我需要做什么。
这是我的示例脚本:
import sys
import click
@click.group()
@click.pass_context
def cli(ctx):
"""
CLI
"""
ctx.ensure_object(dict)
ctx.obj['DEFAULT_ENVIRONMENT'] = "dev"
@cli.command()
@click.option('-e', '--environment', required=True, default=click.get_current_context().obj['DEFAULT_ENVIRONMENT'])
def show_env(environment):
click.echo(environment)
if __name__ == '__main__':
cli()
Run Code Online (Sandbox Code Playgroud)
如果我运行python cli.py show-env,目标是让它输出dev(因为我没有传递参数,因为它是从上下文加载的)。
这失败了
Traceback (most recent call last):
File "testcli.py", line 15, in <module>
@click.option('-e', '--environment', required=True, default=click.get_current_context().obj['DEFAULT_ENVIRONMENT'])
File "/home/devuser/.virtualenvs/cli/lib/python3.6/site-packages/click/globals.py", line 26, in get_current_context
raise RuntimeError('There is no active click context.')
RuntimeError: There is no active click context.
Run Code Online (Sandbox Code Playgroud)
我也尝试过@pass_context在我的show_env命令上使用,如下所示: …
我正在尝试通过使用Click 包实现的命令来测试异常的引发。
这是我的命令:
@click.option(
'--bucket_name',
...)
@click.option(
'--group_id',
...)
@click.option(
'--artifact_id',
...)
@click.option(
'--version',
...)
@click.option(
'--artifact_dir',
required=False,
default='downloads/artifacts/',
...)
@click.command()
def download_artifacts(
bucket_name,
group_id, artifact_id, version,
artifact_dir
):
logger.info(
f"bucket_name: {bucket_name}, "
f"group_id: {group_id}, "
f"artifact_id: {artifact_id}, "
f"version: {version}, "
f"artifact_dir: {artifact_dir}, "
)
if not artifact_dir.endswith('/'):
raise ValueError(
"Enter artifact_dir ending with '/' ! artifact_dir: "
f"{artifact_dir}")
...
Run Code Online (Sandbox Code Playgroud)
这是我的测试代码,assertRaises它不起作用:
def test_download_artifacts_invalid_dir(
self,
):
runner = CliRunner()
with self.assertRaises(ValueError):
result = runner.invoke(
download_artifacts,
'--bucket_name my_bucket …Run Code Online (Sandbox Code Playgroud)