一个用于多级cli的cli解析系统('cisco-like-cli')
multilevelcli的Python项目详细描述
多级cli
该模块支持复杂(多命令)和嵌套(多级)cli的命令行解析,如 "cisco"cli或gcpgcloudcli。
multilevelcli提供的主要功能是:
- 支持多个命令
- 命令分组
- 嵌套组
- 自动生成树
- 级别感知选项分析
- 数组(list)和结构(dict)参数和选项
- 嵌套参数和选项类型支持和分析
与argparse模块的比较
multilevelcli与argparse不兼容,也不完全是argparse的超集。它不是设计成 一般情况下为argparse替换。它旨在用于复杂的cli情况,其中 argparse很难使用并且缺少功能。对于大多数应用程序 使用argparse命令行解析可能更容易。实际上,multilevelcli不支持单个命令clis。
不过,在某些方面,多级cli通常会更好:
- 以编程方式使用更简单,即从其他结构化定义语言生成cli,例如 大摇大摆。
- 在大多数情况下,不需要嵌套解析器,因为解析器是按设计多级的
- 帮助生成和调用更简单
- 在大多数情况下,打字系统更简单、更强大
- 可以分阶段进行分析,即多次
不支持以下argparse功能(可能是部分列表):
- 动态参数数(如add_argument(narg=…)
- 操作(但在大多数情况下不需要这些操作)
- 特殊类型如"打开"
- 选择
- 必选选项(因为有一个"必选"选项有点奇怪,不是吗?)
- 元变量(multilevelcli使用arg类型)
- 目标(multilevelcli始终使用arg名称)
一般操作模式
基本上multilevelcli遵循argparse模型。需要定义一个解析器,所有的组, 在开始分析之前,必须定义命令、参数和选项。 调用解析器后,将返回命名空间对象。命名空间对象类似 原则上是argparse命名空间对象,但由于它支持级别、组,所以功能更强大 以及嵌套类型。
多级cli实体
分析器
解析器是主类。必须至少创建一个multilevelargparse实例并为其指定名称。 例如:
cli=multilevelcli.MultiLevelArgParse("testcli1")
命令
cli的整个用途是让用户发出带有参数和/或选项的命令。任何流 最后没有可解析命令的是一个未完成的流,默认情况下将显示帮助用法 引导用户添加缺少的部分。此行为可以更改(请参阅下面的默认处理)。 使用add_command()方法添加cli命令。可以在每个级别上添加任意数量的命令。 每个命令都可能有(必需的)位置参数和可选的非位置选项(见下文)。 命令至少需要一个名称(级别唯一)。描述是可选的 但是,如果需要有意义的帮助/使用屏幕,当然是非常需要的。 函数的作用是 命令对象。如果需要添加选项或参数,请存储该对象。 例如:
cli.add_command("version")list_cmd=cli.add_command("list",description="list all entities")
参数
使用add_argument()将位置参数添加到命令(对象)。参数顺序已确定 按创作顺序。所有参数都是必需的。 必须为每个参数提供(命令作用域唯一)名称,并用于检索参数值。 还可以提供可选的描述 AgType(S)参见下面的类型部分)。默认参数类型为"str"。
list_cmd.add_argument("name",description="The name of the item to be listed")
选项
使用add_option()向组和/或命令添加可选的非位置参数。 选项是级别感知的,必须在级别或命令中唯一命名。长短期权 支持,并且必须至少定义其中一个。 描述是可选的。如果未提供opttype,则该选项为布尔值(即标志选项)。 选项类型可以是任何受支持的类型(请参见下面的类型部分)。 例如:
cli.add_option('q','quiet',description="do not emit messages")# root (group) level option. short (-q) and long (--quiet)list_cmd.add_option(None,'id',description="id of the listed object")# command level option (only long - i.e., --id)
组
组用于创建新级别的命令。在大多数情况下,它聚集特定对象或主题的命令。 例如,gcp cligcloud有一个compute组,用于聚合"images"、"instances"、"ssh"等。 cli parser对象是根组,级别1组附加到它。 组级别是通过嵌套生成的。 在每个级别上,组和命令可以一起使用。生成的组对象需要 存储以便可以向其中添加选项、组和/或命令。 例如:
compute=cli.add_group("compute")instances=compute.add_group("instances")instances.add_command("list")instances.add_command("new")
cliresult
cliresult是运行时由cli解析器的cli.parse()
方法返回的对象。它包含解析结果
以及选定命令的最终值、命令参数和选项。单独的命名空间
(见下文)为每个级别进行维护。
最重要的方法是:
- 命令名()-返回用户选择的命令名(str)
- 参数()-返回选定的命令参数命名空间。每个参数都是一个键,解析后的用户输入是 它的价值。
- opt()-返回选定的命令选项命名空间。如果由用户和/或其设置,则出现在此命名空间中的选项 有一个默认值。
- ns)-返回一个全局命名空间,其中包含收集的所有选项和参数 从各个层面。选项和参数键以完整路径格式设置,其中组和命令 添加到名称中 被一个点隔开。例如,如果您有一个命令"vms instances new"<;id>;"名称空间中的id参数键 将是"vms.instances.new.name"。
- 命令()-返回与用户输入匹配的命令对象。
- 组()-返回命令所属的组对象。
- 未解析的令牌()-返回未解析的令牌。这在部分解析期间是必需的。
- 命令CTX()-获取用户定义的命令上下文(见下文)
命名空间
名称空间是一个python字典,它有一些方便的函数来允许访问字典键 作为成员,也支持嵌套名称查找(例如,您可以查找"vms.instances.new.name")。所以不是 使用标准的python dict查找a["key"]只需执行a.key
生成命令树
可以打印一个完整的命令树,列出所有组和每个组中的命令
通过调用cli.show_tree()
方法。没有默认绑定
对于此函数,程序必须显式调用此函数作为命令的实现
或选项。
这样的输出示例:
[./clitest2.py] - testcli2
tree
[vms]
[instances] - commands on vm instances
list - list instances
[networks]
list - list networks
默认命令处理
如果找不到命令,则会触发默认函数。默认设置为显示用法和退出,但是 这可以通过设置defaultfn或在组和/或命令期间传递defaultfn参数来更改 初始化和/或分析器。默认fn是接受 单个多级clibase.grouptype参数。 存在几个预定义的实用程序函数,例如引发no command的usage和raise no命令 异常而不是退出(这样程序就可以捕获这就是)。 例如:
# root level default handlingcli=MultiLevelArgParse("demo cli",defaultfn=usage_and_raise_no_command,help=usage_and_raise_help)# 'class' group defaultclass_group=cli.add_group("class",defaultfn=usage_and_raise_no_command)try:parsed_input=cli.parse()exceptNoCommand:print("No command was entered. Valid commands:")cli.show_tree()
帮助生成
默认情况下,选项'-h'和'--help'调用默认帮助函数defhelpfn,该函数设置为usage\u and_exit。 要更改此值,可以更改defhelpfn变量和/或在group/command期间传递help参数 初始化。帮助函数是接受单个multilevelclibase.parsebase参数的函数。 将"帮助"功能设置为"无"将禁用默认的帮助处理。 例如:
# group level help overridealpha_group=cli.add_group("alpha",help=usage_help_and_raise_nocommand)# command level help overridecmd=alpha_group.add_command("list",help=usage_help_and_raise_nocommand)
命令用户上下文
可以在命令初始化期间设置用户上下文。此上下文通过 cliresult中的命名空间(见上文)。可以为每个命令设置不同的上下文。这对于自动生成cli尤其有用,其中 可用于将命令连接到特定于操作的对象。例如:
beta_group.add_command("test",ctx="context")...ctx=cli.parse().command_ctx()
部分解析
为了允许解析器只解析其编程的令牌,而忽略其余的令牌,只需使用 部分旗。解析后,可以使用cliresult.unparsed_tokens()方法检索未解析的令牌数组(字符串列表)。 例如:
cli=multilevelcli.MultiLevelArgParse("testcli1")0
参数和选项类型
参数和选项值可以是任何类型。主要限制是类型必须支持simple(即 参数化)从简单文本(str)格式转换。这意味着大多数原生python简单类型都受支持 例如"str"、"int"、"double"、"float"等。 例如:
cli=multilevelcli.MultiLevelArgParse("testcli1")1
cli=multilevelcli.MultiLevelArgParse("testcli1")2
此外,通过数组(列表)和 结构(词典)。 数组是同一类型的可变大小列表,由"["<;type>;']'表示。例如一个int数组 变量定义为[int]。 结构是键和值的字典。键是字符串,值可以是任何类型。例如a 描述一个人的姓名和年龄的结构可以定义为{name:str,age:int}'。
示例(来自clitest2.py):
cli=multilevelcli.MultiLevelArgParse("testcli1")3
cli=multilevelcli.MultiLevelArgParse("testcli1")4
嵌套类型
类型可以嵌套。例如
cli=multilevelcli.MultiLevelArgParse("testcli1")5
cli=multilevelcli.MultiLevelArgParse("testcli1")6
示例
示例1:单个命令示例:
cli=multilevelcli.MultiLevelArgParse("testcli1")7
exampel 1用法
如果找不到任何命令,将生成并发送自动帮助/用法信息。 使用automatic-h/--help选项可以显示帮助屏幕。
cli=multilevelcli.MultiLevelArgParse("testcli1")8
示例2(基于testcli2.py):
cli=multilevelcli.MultiLevelArgParse("testcli1")9