动态指定选项和参数

2023-11-27

我想从数据库加载参数和选项。我允许用户定义自己的选项和参数。用户可以通过命令行调用远程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
    }
]

这些参数与远程端点的需求一致。每个 API 端点都有不同的参数,因此它们需要是动态的。这是命令行的外观。

command run www.mysite.com/api/get -a testparam --bravo testpara2 -c item1 item2

参数和值将映射到 URL 中。有没有办法在click中设置动态参数?


这可以通过构建一个调用的自定义装饰器来完成click.option将给定的数据结构转换为点击等价物后多次装饰器。

Code:

import click

def options_from_db(options):
    map_to_types = dict(
        array=str,
        number=float,
        string=str,
    )
    def decorator(f):
        for opt_params in reversed(options):
            param_decls = (
                '-' + opt_params['short'],
                '--' + opt_params['long'],
                opt_params['name'])
            attrs = dict(
                required=opt_params['required'],
                type=map_to_types.get(
                    opt_params['type'], opt_params['type'])
            )
            if opt_params['type'] == 'array':
                attrs['cls'] = OptionEatAll
                attrs['nargs'] = -1

            click.option(*param_decls, **attrs)(f)
        return f
    return decorator

使用options_from_db装饰器:

要使用新的装饰器,请装饰命令,并从数据库传递选项数据,如下所示:

@options_from_db(run_options)
def command(*args, **kwargs):
    ....

这是如何运作的?

The @click.option()与所有装饰器一样,装饰器是一个函数。在这种情况下,它注释了修饰函数,并返回相同的函数。所以我们可以简单地多次调用它来注释我们的装饰函数。

Note: your array参数违反点击要求不允许nargs选项 另一个答案这使得这一点成为可能,并且这个答案使用the code从那里。

代码来自其他答案:

class OptionEatAll(click.Option):

    def __init__(self, *args, **kwargs):
        self.save_other_options = kwargs.pop('save_other_options', True)
        nargs = kwargs.pop('nargs', -1)
        assert nargs == -1, 'nargs, if set, must be -1 not {}'.format(nargs)
        super(OptionEatAll, self).__init__(*args, **kwargs)
        self._previous_parser_process = None
        self._eat_all_parser = None

    def add_to_parser(self, parser, ctx):

        def parser_process(value, state):
            # method to hook to the parser.process
            done = False
            value = [value]
            if self.save_other_options:
                # grab everything up to the next option
                while state.rargs and not done:
                    for prefix in self._eat_all_parser.prefixes:
                        if state.rargs[0].startswith(prefix):
                            done = True
                    if not done:
                        value.append(state.rargs.pop(0))
            else:
                # grab everything remaining
                value += state.rargs
                state.rargs[:] = []
            value = tuple(value)

            # call the actual process
            self._previous_parser_process(value, state)

        retval = super(OptionEatAll, self).add_to_parser(parser, ctx)
        for name in self.opts:
            our_parser = parser._long_opt.get(
                name) or parser._short_opt.get(name)
            if our_parser:
                self._eat_all_parser = our_parser
                self._previous_parser_process = our_parser.process
                our_parser.process = parser_process
                break
        return retval

测试代码:

run_options = [
    {
        "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
    }
]

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

@cli.command()
@options_from_db(run_options)
@click.argument('url')
def run(*args, **kwargs):
    click.echo('args: {}'.format(args) )
    click.echo('kwargs: {}'.format(kwargs))


if __name__ == "__main__":
    commands = (
        'run www.mysite.com/api/get -a testparam --bravo 5 -c item1 item2',
        '',
        '--help',
        'run --help',
    )

    import sys, time

    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for cmd in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + cmd)
            time.sleep(0.1)
            cli(cmd.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise

Results:

Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> run www.mysite.com/api/get -a testparam --bravo 5 -c item1 item2
args: ()
kwargs: {'thename1': 'testparam', 'thename2': 5.0, 'thename3': ('item1', 'item2'), 'url': 'www.mysite.com/api/get'}
-----------
> 
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  run
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  run
-----------
> run --help
Usage: test.py run [OPTIONS] URL

Options:
  -a, --ace TEXT
  -b, --bravo FLOAT  [required]
  -c, --candy TEXT   [required]
  --help             Show this message and exit.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态指定选项和参数 的相关文章

随机推荐

  • 检查返回的文件是否为XML

    我需要检查网站输出的返回值 如果登录详细信息有效 它会返回一个 XML 文件 如果登录详细信息无效 它只会返回一个字符串 显示 您输入了无效 ID 我的问题是我用这个代码来检查 ch curl init curl setopt ch CUR
  • C# - 从特定应用程序捕获 Windows 消息

    我正在编写一个需要拦截的 C 应用程序窗口消息另一个应用程序正在发送 编写我正在监视的应用程序的公司向我发送了一些示例代码 但它是用 C 编写的 我不太了解 在 C 示例代码中 我得到了它们使用以下代码 UINT uMsg Register
  • 在 AXIOS 中发送 GET 方法的请求正文会引发错误

    我有一个 React 应用程序 我将 POST 方法更改为 GET 并按原样请求正文 它适用于 POST 请求 但是当我将方法更改为 GET 时 它给了我错误 message org springframework http convert
  • 基于gradle构建更新IntelliJ中的单一依赖

    是否可以让 IntelliJ 更新单个依赖项 而不必通过 Gradle 侧选项卡中的 刷新所有 Gradle 项目 按钮刷新所有依赖项 我问的原因是 我们的项目的完全刷新需要几分钟 足够长的时间让我写这个问题 我只想更新对我正在本地更新的另
  • 是否可以获得转换后的绘图数据? (例如点图中的点坐标、密度曲线)

    我想知道是否可以在 ggplot2 图中获取转换后的数据 特别是 我有兴趣获取点图中点的坐标和大小 以便在另一个绘图库中使用它们 d3 js 我怎样才能提取这些信息 这是情节 g ggplot data frame x rnorm 100
  • 控制台应用程序 - 当前工作线上方的 WriteLine

    我看过其他一些与此非常相似的帖子 但他们给出的答案并没有正确回答问题 抱歉 如果有什么隐藏的东西我找不到 我想使用 Console WriteLine 打印当前 Console ReadLine 上方的内容 例如 我的应用程序打印 Hell
  • 将变量编号分配给复数数组

    我想将复杂数组分配为变量 我的代码就像 complex indx 3 3 integer i j do i 1 3 do j 1 3 indx i j i j write indx i j end do end do 在这种情况下我收到类似
  • 在后面的代码中设置显示属性

    如何将显示属性设置为在后面的代码中阻止
  • 升级到 Gradle 7 后 Android Gradle Javadoc 损坏

    几天前 我升级到了新的 Android Studio Arctic Fox 版本 现在也需要 Gradle 7 在升级之前 我有以下 javadoc 任务 它运行得很好 def javaDocsAllowList com mycompany
  • 根据外部值有条件地应用管道步骤

    鉴于 dplyr 工作流程 require dplyr mtcars gt tibble rownames to column var model gt filter grepl x model pattern Merc gt group
  • “谓词下推”和“投影下推”有什么区别?

    我找到了多种信息来源 例如发现的一个here 将 谓词下推 解释为 如果您可以将部分查询 下推 到数据存储的位置 从而过滤掉大部分数据 那么您可以大大减少网络流量 但是 我还在其他文档中看到了术语 投影下推 例如here 这似乎是同一件事
  • Android每5秒拍照一次

    使用相机 API 我能够成功拍摄照片并将其保存到文件夹中 这是我正在使用的代码 主要 xml
  • Amazon APi 网关无法生成转换后的请求

    我正在尝试将 Amazon API gateway 与 Lambda 函数集成 我成功地实现了这一目标 但是当我尝试使用curl 时 它失败了 设置 Lambda 方法 API 网关集成以及集成请求下的模板映射 当我从控制台运行 测试 时
  • 将鼠标悬停在子级上时如何禁用父级悬停

    我将尝试用一些简单的例子来展示我的问题 我拥有的 http jsfiddle net JGzSh 3 这是一些简单的按钮 稍后会有 onclick 事件 当我将鼠标悬停在绿色 div 父级 上时 hover可以稍微改变它的颜色 有什么问题
  • 如何重命名 tSQLt 测试类?

    我正在使用以下方法开发数据库红门 SQL 开发人员 tools SQL Test运行 tSQLt 测试的 SSMS 加载项缺少重命名测试类的方法 我有一个测试叫 BackendLayerCustomerAdministrationTests
  • 未捕获 无法从 URL 哈希获取父源

    我正在尝试为我的网络应用程序设置谷歌登录 目前 它处于开发状态并运行在http localhost 8080 auth 我使用 Google 提供的默认登录按钮进行用户登录 每当打开新的 iFrame 进行用户身份验证时 它就会无限挂起 当
  • TypeScript 扩展 String Static

    有没有办法将 isNullOrEmpty str string 添加到静态字符串对象 这样我就可以称之为 String isNullOrEmpty myobj 我找到了一种将其放在实现中的方法 但这对这样的方法没有帮助 String定义于l
  • Javascript:抑制 onbeforeunload 上的“此页面要求您确认是否要离开”弹出窗口

    当用户离开页面时 我需要在离开之前询问他是否想执行特定操作
  • Jquery - 遍历所有 xml 标签

    如何循环遍历xml中的所有标签 我有一个 php 可以生成类似于下一个的 xml
  • 动态指定选项和参数

    我想从数据库加载参数和选项 我允许用户定义自己的选项和参数 用户可以通过命令行调用远程api 它们指定端点的 URL 和参数 这是数据库中的数据的样子 name thename1 short a long ace type string r