argparse 解决方案 requested for commands and subcommands with subcommands
argparse solution requested for commands and subcommands with subcommands
希望这会转化为一个优雅的解决方案,但我自己无法弄清楚。我一直在阅读大量示例和解释,但我似乎无法让它发挥作用。
我正在编写一个需要以下选项的程序:
myprogram:
-h help
--DEBUG debugging on
Commands are: dashboard / promote / deploy / auto-tag / dbquery
Some commands have sub-commands.
Dashboard prosesing:
dashboard <ALL | DEBUG | AAA [sub1-aaa | ...] >
Promoting:
promote <environment> [to environment] <system> [version]
Deployment
deploy <system> [version] <in environment>
Auto-tagging
auto-tag <repo> <project> [--days-back]
Database queries (--tab is optional)
(system or env or both are required)
dbquery lock set <system | environment> [--tab]
dbquery lock clear <system | environment> [--tab]
dbquery lock show <system | environment | before-date | after-date> [--tab]
dbquery promote list <system| version| environment | before-date | after-date> [--tab]
dbquery deploy list <system| version| environment | before-date | after-date> [--tab]
如果使用命令,则需要一些子命令或选项。
我很难使用 argparse 库完成这项工作。我尝试使用 add_argument_group、子解析器等。但我想我在这里遗漏了一些基本的东西。我发现接近的所有示例都是关于 svn 的,但它们似乎只在 svn 之后进入 1 级。我需要更多,或者不同的方法。
如果可能,我想将 dbquery deploy list 之后的所有参数设为可选,至少需要 1 个选项。但是区分系统名称和环境名称可能会变得棘手,因此最好更改此名称:
dbquery lock set <system | environment>
进入
dbquery lock set <system=system | env=environment>
p.s。 [] 之间的选项是可选的,<> 之间的选项是必需的。
提前致谢。
针对提供我的代码的评论,让我们关注 dbquery,因为其余部分可能是重复的:
import argparse
parser = argparse.ArgumentParser(description="Main cli tool for processing in the CD pipeline (%s)" % VERSION)
subparsers = parser.add_subparsers(help='additional help',title='subcommands')
dbq_parser=subparsers.add_parser("dbqueue", aliases=['dbq'])
dbq_group_lock = dbq_parser.add_argument_group('lock', 'lock desc')
dbq_group_promote =dbq_parser.add_argument_group('promote')
dbq_group_deploy = dbq_parser.add_argument_group('deploy','Deployment description')
dbq_group_lock.add_argument('set', help="Sets lock")
dbq_group_lock.add_argument('clear', help='Clears lock')
dbq_group_lock.add_argument('show', help='Show lock status')
dbq_group_deploy.add_argument('name system etc')
执行结果:
# python3 main.py -h
usage: main.py [-h] [--debug] {dbqueue,dbq} ...
Main cli tool for processing in the CD pipeline (cdv3, Jun 2019, F.IJskes)
optional arguments:
-h, --help show this help message and exit
--debug Generate debug output and keep temp directories
subcommands:
{dbqueue,dbq} additional help
这看起来不错,但是:
#python3 main.py dbq -h
usage: main.py dbqueue [-h] set clear show name system etc
optional arguments:
-h, --help show this help message and exit
lock:
lock desc
set Sets lock
clear Clears lock
show Show lock status
显示预期参数不是锁定、提升或部署。
好的,反馈有助于我的理解。我现在明白解析器可以获得子解析器,而那些可以获得解析器。所以一个人可以去的深度可能没有限制。
这个新见解让我想到了这一点:(我的工作示例的部分副本)
import argparse
main_parser = argparse.ArgumentParser(description="Main cli tool for processing in the CD pipeline (%s)" % VERSION)
main_subparsers = main_parser.add_subparsers(help='',title='Possible commnds')
dashbrd_subparser = main_subparsers.add_parser('dashboard', help="Proces specified dashboards", allow_abbrev=True)
dashbrd_subparser.add_argument('who?',help='Proces dashboard for ALL, Supplier or DEBUG what should happen.')
dashbrd_subparser.add_argument('-subsystem', help='Select subsystem to proces for given supplier')
dbq_main=main_subparsers.add_parser("dbquery", help="Query database for locks,deployments or promotes")
dbq_main_sub=dbq_main.add_subparsers(help="additions help", title='sub commands for dbquery')
dbq_lock=dbq_main_sub.add_parser('lock', help='query db for lock(s)')
dbq_lock_sub=dbq_lock.add_subparsers(help='', title='subcommands for lock')
dbq_lock_sub_set=dbq_lock_sub.add_parser('set', help='sets a lock')
dbq_lock_sub_set.add_argument('-env', required=True)
dbq_lock_sub_set.add_argument('--tab',required=False, action="store_true" )
dbq_lock_sub_clear=dbq_lock_sub.add_parser('clear', help='clears a lock')
# dbq_lock_sub_set.add_argument('-env', required=True)
# dbq_lock_sub_set.add_argument('--tab', required=False)
dbq_lock_sub_show=dbq_lock_sub.add_parser('show', help='shows a lock/locks')
# dbq_lock_sub_set.add_argument('-env', required=True)
# dbq_lock_sub_set.add_argument('--tab', required=False)
print( vars(main_parser.parse_args()))
exit(1)
我现在似乎只有在不同子命令中使用“-env”和“-subsystem”参数时才会遇到问题。因为当我将它们添加到另一个解析器时存在冲突。
我也没有关于选择了哪些选项的数据。这也是需要的东西。
差不多了,我现在拥有的东西在很大程度上是有用的,所以我会 post 这样其他用户可能会从我的工作中受益,而 hpaulj 的评论让我受益匪浅到可以澄清其他部分的其他文件。
# see: https://pymotw.com/3/argparse/
# BLOCK FOR SHARED options used at more places,
# see also:
env_shared = argparse.ArgumentParser(add_help=False)
env_shared.add_argument('-env', action="store", help='name of environment <tst|acc|acc2|prod|...>', metavar='<environment>', required=True)
ds_shared = argparse.ArgumentParser(add_help=False)
ds_shared.add_argument('-ds', action="store", help='name of subsystem to use <ivs-gui|ivs-vpo|...>', metavar='<system name>', required=True)
version_shared = argparse.ArgumentParser(add_help=False)
version_shared.add_argument('-version', action="store", help='version to use. If used, specify at least sprint as in 1.61', metavar='<version>')
tab_shared=argparse.ArgumentParser(add_help=False)
tab_shared.add_argument('--tab', required=False, action="store_true", help='Use nice tabulation for output')
# END OF SHARED options
# MAIN
main_p = argparse.ArgumentParser(description="Main cli tool for use in the CD v3 pipeline (%s)" % VERSION, epilog='Defaults are taken from the configuration file, which is pulled from git when needed.', )
# Change formatting of help output for main-parser
main_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=30, width=80)
main_p.add_argument("--debug", action="store_true", help="Generate debug output and keep temp directories")
# MAIN-SUB
main_s_p = main_p.add_subparsers(title='Commands', dest='main_cmd')
# MAIN-SUB-DASHBOARD
dashbrd_p = main_s_p.add_parser('dashboard', aliases=['db'], help="Proces specified dashboards", parents=[ds_shared])
dashbrd_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=40, width=80)
dashbrd_p.add_argument('which', help='Proces dashboard for <ALL|Supplier|DEBUG what would happen>. If supplier is specified an optional subsystem to be processed can be passed using -ds')
# MAIN-SUB-QUERY
query_p = main_s_p.add_parser("query", aliases=['qry'], help="Query database for locks,deployments or promotes")
query_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=40, width=80)
# MAIN-SUB-QUERY-SUB
query_s_p = query_p.add_subparsers(help="additions help", title='sub commands for query', dest='query_cmd')
# MAIN-SUB-QUERY-LOCK
q_lock_p = query_s_p.add_parser('lock', help='query db for lock(s)', )
# MAIN-SUB-QUERY-LOCK-SUB
q_lock_sub = q_lock_p.add_subparsers(help='', title='subcommands for dbquery lock', dest='lock_cmd')
# MAIN-SUB-QUERY-LOCK-SUB-SET
q_lock_set_p = q_lock_sub.add_parser('set', help='sets a lock', parents=[env_shared, ds_shared])
# MAIN-SUB-QUERY-LOCK-SUB-CLEAR
q_lock_clear_p = q_lock_sub.add_parser('clear', help='clears a lock', parents=[env_shared, ds_shared], )
# MAIN-SUB-QUERY-LOCK-SUB-SHOW
q_lock_show_p = q_lock_sub.add_parser('show', help='shows a lock/locks', parents=[env_shared, tab_shared])
# MAIN-SUB-QUERY-PROMOTE
q_promote_p = query_s_p.add_parser('promote', help='query db for promotions', parents=[env_shared,ds_shared] )
# MAIN-SUB-QUERY-DEPLOY
q_deploy_p = query_s_p.add_parser('deploy', help='query db for deployments')
# MAIN-SUB-PROMOTE
promote_p = main_s_p.add_parser('promote', help='Do a promotion.', parents=[env_shared, ds_shared, version_shared])
promote_p.add_argument('-dest', required=False, action="store", help='If used specifies the destination, otherwise defaults are used. (-dest is optional, -env is not)', metavar='<dest_env>')
# MAIN-SUB-DEPLOY
deploy_p = main_s_p.add_parser('deploy', help='Deploy software', parents=[ds_shared, env_shared])
# MAIN-SUB-AUTOTAG
autotag_p = main_s_p.add_parser('autotag', help="Autotags specified repository", parents=[ds_shared])
print("------------arguments-----------")
print(vars(main_p.parse_args()))
这创建了许多我想要的功能。
希望这会转化为一个优雅的解决方案,但我自己无法弄清楚。我一直在阅读大量示例和解释,但我似乎无法让它发挥作用。
我正在编写一个需要以下选项的程序:
myprogram:
-h help
--DEBUG debugging on
Commands are: dashboard / promote / deploy / auto-tag / dbquery
Some commands have sub-commands.
Dashboard prosesing:
dashboard <ALL | DEBUG | AAA [sub1-aaa | ...] >
Promoting:
promote <environment> [to environment] <system> [version]
Deployment
deploy <system> [version] <in environment>
Auto-tagging
auto-tag <repo> <project> [--days-back]
Database queries (--tab is optional)
(system or env or both are required)
dbquery lock set <system | environment> [--tab]
dbquery lock clear <system | environment> [--tab]
dbquery lock show <system | environment | before-date | after-date> [--tab]
dbquery promote list <system| version| environment | before-date | after-date> [--tab]
dbquery deploy list <system| version| environment | before-date | after-date> [--tab]
如果使用命令,则需要一些子命令或选项。
我很难使用 argparse 库完成这项工作。我尝试使用 add_argument_group、子解析器等。但我想我在这里遗漏了一些基本的东西。我发现接近的所有示例都是关于 svn 的,但它们似乎只在 svn 之后进入 1 级。我需要更多,或者不同的方法。
如果可能,我想将 dbquery deploy list 之后的所有参数设为可选,至少需要 1 个选项。但是区分系统名称和环境名称可能会变得棘手,因此最好更改此名称:
dbquery lock set <system | environment>
进入
dbquery lock set <system=system | env=environment>
p.s。 [] 之间的选项是可选的,<> 之间的选项是必需的。
提前致谢。
针对提供我的代码的评论,让我们关注 dbquery,因为其余部分可能是重复的:
import argparse
parser = argparse.ArgumentParser(description="Main cli tool for processing in the CD pipeline (%s)" % VERSION)
subparsers = parser.add_subparsers(help='additional help',title='subcommands')
dbq_parser=subparsers.add_parser("dbqueue", aliases=['dbq'])
dbq_group_lock = dbq_parser.add_argument_group('lock', 'lock desc')
dbq_group_promote =dbq_parser.add_argument_group('promote')
dbq_group_deploy = dbq_parser.add_argument_group('deploy','Deployment description')
dbq_group_lock.add_argument('set', help="Sets lock")
dbq_group_lock.add_argument('clear', help='Clears lock')
dbq_group_lock.add_argument('show', help='Show lock status')
dbq_group_deploy.add_argument('name system etc')
执行结果:
# python3 main.py -h
usage: main.py [-h] [--debug] {dbqueue,dbq} ...
Main cli tool for processing in the CD pipeline (cdv3, Jun 2019, F.IJskes)
optional arguments:
-h, --help show this help message and exit
--debug Generate debug output and keep temp directories
subcommands:
{dbqueue,dbq} additional help
这看起来不错,但是:
#python3 main.py dbq -h
usage: main.py dbqueue [-h] set clear show name system etc
optional arguments:
-h, --help show this help message and exit
lock:
lock desc
set Sets lock
clear Clears lock
show Show lock status
显示预期参数不是锁定、提升或部署。
好的,反馈有助于我的理解。我现在明白解析器可以获得子解析器,而那些可以获得解析器。所以一个人可以去的深度可能没有限制。 这个新见解让我想到了这一点:(我的工作示例的部分副本)
import argparse
main_parser = argparse.ArgumentParser(description="Main cli tool for processing in the CD pipeline (%s)" % VERSION)
main_subparsers = main_parser.add_subparsers(help='',title='Possible commnds')
dashbrd_subparser = main_subparsers.add_parser('dashboard', help="Proces specified dashboards", allow_abbrev=True)
dashbrd_subparser.add_argument('who?',help='Proces dashboard for ALL, Supplier or DEBUG what should happen.')
dashbrd_subparser.add_argument('-subsystem', help='Select subsystem to proces for given supplier')
dbq_main=main_subparsers.add_parser("dbquery", help="Query database for locks,deployments or promotes")
dbq_main_sub=dbq_main.add_subparsers(help="additions help", title='sub commands for dbquery')
dbq_lock=dbq_main_sub.add_parser('lock', help='query db for lock(s)')
dbq_lock_sub=dbq_lock.add_subparsers(help='', title='subcommands for lock')
dbq_lock_sub_set=dbq_lock_sub.add_parser('set', help='sets a lock')
dbq_lock_sub_set.add_argument('-env', required=True)
dbq_lock_sub_set.add_argument('--tab',required=False, action="store_true" )
dbq_lock_sub_clear=dbq_lock_sub.add_parser('clear', help='clears a lock')
# dbq_lock_sub_set.add_argument('-env', required=True)
# dbq_lock_sub_set.add_argument('--tab', required=False)
dbq_lock_sub_show=dbq_lock_sub.add_parser('show', help='shows a lock/locks')
# dbq_lock_sub_set.add_argument('-env', required=True)
# dbq_lock_sub_set.add_argument('--tab', required=False)
print( vars(main_parser.parse_args()))
exit(1)
我现在似乎只有在不同子命令中使用“-env”和“-subsystem”参数时才会遇到问题。因为当我将它们添加到另一个解析器时存在冲突。 我也没有关于选择了哪些选项的数据。这也是需要的东西。
差不多了,我现在拥有的东西在很大程度上是有用的,所以我会 post 这样其他用户可能会从我的工作中受益,而 hpaulj 的评论让我受益匪浅到可以澄清其他部分的其他文件。
# see: https://pymotw.com/3/argparse/
# BLOCK FOR SHARED options used at more places,
# see also:
env_shared = argparse.ArgumentParser(add_help=False)
env_shared.add_argument('-env', action="store", help='name of environment <tst|acc|acc2|prod|...>', metavar='<environment>', required=True)
ds_shared = argparse.ArgumentParser(add_help=False)
ds_shared.add_argument('-ds', action="store", help='name of subsystem to use <ivs-gui|ivs-vpo|...>', metavar='<system name>', required=True)
version_shared = argparse.ArgumentParser(add_help=False)
version_shared.add_argument('-version', action="store", help='version to use. If used, specify at least sprint as in 1.61', metavar='<version>')
tab_shared=argparse.ArgumentParser(add_help=False)
tab_shared.add_argument('--tab', required=False, action="store_true", help='Use nice tabulation for output')
# END OF SHARED options
# MAIN
main_p = argparse.ArgumentParser(description="Main cli tool for use in the CD v3 pipeline (%s)" % VERSION, epilog='Defaults are taken from the configuration file, which is pulled from git when needed.', )
# Change formatting of help output for main-parser
main_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=30, width=80)
main_p.add_argument("--debug", action="store_true", help="Generate debug output and keep temp directories")
# MAIN-SUB
main_s_p = main_p.add_subparsers(title='Commands', dest='main_cmd')
# MAIN-SUB-DASHBOARD
dashbrd_p = main_s_p.add_parser('dashboard', aliases=['db'], help="Proces specified dashboards", parents=[ds_shared])
dashbrd_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=40, width=80)
dashbrd_p.add_argument('which', help='Proces dashboard for <ALL|Supplier|DEBUG what would happen>. If supplier is specified an optional subsystem to be processed can be passed using -ds')
# MAIN-SUB-QUERY
query_p = main_s_p.add_parser("query", aliases=['qry'], help="Query database for locks,deployments or promotes")
query_p.formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=40, width=80)
# MAIN-SUB-QUERY-SUB
query_s_p = query_p.add_subparsers(help="additions help", title='sub commands for query', dest='query_cmd')
# MAIN-SUB-QUERY-LOCK
q_lock_p = query_s_p.add_parser('lock', help='query db for lock(s)', )
# MAIN-SUB-QUERY-LOCK-SUB
q_lock_sub = q_lock_p.add_subparsers(help='', title='subcommands for dbquery lock', dest='lock_cmd')
# MAIN-SUB-QUERY-LOCK-SUB-SET
q_lock_set_p = q_lock_sub.add_parser('set', help='sets a lock', parents=[env_shared, ds_shared])
# MAIN-SUB-QUERY-LOCK-SUB-CLEAR
q_lock_clear_p = q_lock_sub.add_parser('clear', help='clears a lock', parents=[env_shared, ds_shared], )
# MAIN-SUB-QUERY-LOCK-SUB-SHOW
q_lock_show_p = q_lock_sub.add_parser('show', help='shows a lock/locks', parents=[env_shared, tab_shared])
# MAIN-SUB-QUERY-PROMOTE
q_promote_p = query_s_p.add_parser('promote', help='query db for promotions', parents=[env_shared,ds_shared] )
# MAIN-SUB-QUERY-DEPLOY
q_deploy_p = query_s_p.add_parser('deploy', help='query db for deployments')
# MAIN-SUB-PROMOTE
promote_p = main_s_p.add_parser('promote', help='Do a promotion.', parents=[env_shared, ds_shared, version_shared])
promote_p.add_argument('-dest', required=False, action="store", help='If used specifies the destination, otherwise defaults are used. (-dest is optional, -env is not)', metavar='<dest_env>')
# MAIN-SUB-DEPLOY
deploy_p = main_s_p.add_parser('deploy', help='Deploy software', parents=[ds_shared, env_shared])
# MAIN-SUB-AUTOTAG
autotag_p = main_s_p.add_parser('autotag', help="Autotags specified repository", parents=[ds_shared])
print("------------arguments-----------")
print(vars(main_p.parse_args()))
这创建了许多我想要的功能。