为 Python Click CLI 脚本提供 STDIN 或文件路径名选项

Jam*_*son 1 python python-click

我是第一次尝试 Click,但我遇到了绊脚石。

我希望我的(两个)子命令要么采用文件路径名选项,要么接受来自 STDIN 的文件内容。

  • 允许:使用 --compose-file 的路径

    ./docker-secret-helper.py secret-hash-ini --compose-file docker-compose-test.yml
    
    Run Code Online (Sandbox Code Playgroud)
  • 允许:使用文件内容作为标准输入

    cat docker-compose-test.yml | ./docker-secret-helper.py secret-hash-ini
    
    Run Code Online (Sandbox Code Playgroud)

    (是否应该有一个选项来指示标准输入,例如-i,,或其他什么?)

  • 不允许: --compose-file 和 stdin 都没有通过

    ./docker-secret-helper.py secret-hash-ini
    
    Run Code Online (Sandbox Code Playgroud)

    应该返回如下内容: You must either pass --compose-file or pipe in stdin.

当前脚本

我当前的脚本接受(仅)文件路径名(通过--compose-file):

#!/usr/bin/env python

import click
from DockerSecretHelper import DockerSecretHelper

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])

@click.group(context_settings=CONTEXT_SETTINGS)
def cli():
    pass

@cli.command(help="retrieves an ini-style file of variables to be used as env vars for docker-compose commmand")
@click.option('--compose-file', help='compose file to work with', required=True)
def secret_hash_ini(**kwargs):
    helper = DockerSecretHelper()
    print(helper.get_secret_hash_ini_format_from_compose_file(**kwargs))
    # will need some kind of if block to call helper.get_secret_hash_ini_format_from_compose_contents(**kwargs) in the
    #  case of stdin

@cli.command(help="retrieves names/values of external secrets; to be used by `docker secret set`")
@click.option('--compose-file', help='compose file to work with', required=True)
def external_secret_info_json(**kwargs):
    helper = DockerSecretHelper()
    print(helper.get_external_secret_info_as_json_from_compost_file(**kwargs))
    # will need some kind of if block to call helper.get_external_secret_info_as_json_from_compose_contents(**kwargs) in
    # the case of stdin

if __name__ == '__main__':
    cli()
Run Code Online (Sandbox Code Playgroud)

我如何实现和强制执行 STDIN文件路径名(但不是两者)。

我愿意更改我的命令的语法以更好地遵循潜在的约定。

这个问题类似于使用 Click 在 python 中创建命令行应用程序,因此它可能提供一些构建块(我在组装时遇到问题)。

lar*_*sks 7

我会使用点击的File选项类型:

import click
import sys


@click.group()
def cli():
    pass


@cli.command()
@click.option('--compose-file', 
              help='compose file to work with',
              type=click.File('r'),
              default=sys.stdin)
def secret_hash_ini(compose_file):
    with compose_file:
        data = compose_file.read()

    print(data)


if __name__ == '__main__':
    cli()
Run Code Online (Sandbox Code Playgroud)

假设我们有一个example.txt包含文本的文件:

This is a test.
Run Code Online (Sandbox Code Playgroud)

然后我们可以指定一个文件--compose-file

$ python docker-secret-helper.py secret-hash-ini --compose-file example.txt
This is a test.
Run Code Online (Sandbox Code Playgroud)

或者我们可以阅读stdin

$ python docker-secret-helper.py secret-hash-ini < example.txt
This is a test.
Run Code Online (Sandbox Code Playgroud)

在“既没有 --compose-file 也没有通过标准输入”的情况下,我们无法生成错误,因为stdin它始终可用。如果我们在docker-secret-helper.py没有提供--compose-file和重定向的情况下调用stdin,它只会挂起等待输入。