使用许多可选的子参数设计argparse

时间:2016-11-26 11:14:37

标签: python python-3.x argparse

我正在为我的库编写一个脚本,我最终陷入了如何设计argparse的问题,这将有很多选项和子参数。

目前我正在设计搜索功能,它具有以下选项,一些是必需的,一些不是:

  • search_session_id - 必填
  • user_session_id - 必填
  • discover_fields - 可选
  • start_time - 可选
  • end_time - 可选
  • summary_fields - 可选
  • field_summary - 可选
  • local_search - 可选

我的问题是:

如果所有选项需要一起工作,我如何制作argparse和if语句,如果只定义了其中一个,那么它也可以工作吗?

如果我需要检查每一个组合,我最终会得到这样的结果:

#!/usr/bin/env python3

"""Script to generate searches on the ArcSight Logger"""

import arcsightrest
import argparse

parser = argparse.ArgumentParser(description='Script used to send search '
                                             'queries to ArcSight Logger API')
parser.add_argument('-t', '--target',
                    help='IP Address of the Loggger', required=True)
parser.add_argument('-u', '--username',
                    help='Username to access the logger', required=True)
parser.add_argument('-p', '--password',
                    help='Password to access the logger', required=True)
parser.add_argument('-ussl', '--unsecuressl', action='store_true',
                    help='Disable ssl warnings', )
parser.add_argument('-w', '--wait', action='store_true',
                    help='Wait for query to finish', )
parser.add_argument('-q', '--query',
                    help='Query to be used in the search')
parser.add_argument('-st', '--starttime',
                    help='From which time the query should look')
parser.add_argument('-et', '--endtime',
                    help='To which time the query should look')
parser.add_argument('-e', '--event',
                    help='Events based input search id')
parser.add_argument('-s', '--status',
                    help='Status of running search')
args = (parser.parse_args())

"""
Sets the target Logger Server
"""
arcsightrest.ArcsightLogger.TARGET = args.target

"""
Gets login token from the Logger API
"""
arc = arcsightrest.ArcsightLogger(args.username, args.password,
                                  args.unsecuressl)
"""
Checks if query is used, and starts a search
"""
if args.query:
    if args.starttime:
        search_id, response = arc.search(args.query, start_time=args.starttime,
                                         end_time=args.endtime)
    search_id, response = arc.search(args.query)

    if args.starttime and args.discover_fields:
        search_id, response = arc.search(args.query, start_time=args.starttime,
                                         end_time=args.endtime,
                                         discover_fields=args.discover_fields)
    print('The search id is {}'.format(search_id))
    if response:
        print('The search has successfully started')

正如你所看到的,我可以继续没有结束,使if语句具有可选参数的每一个组合。必须有一种更简单的方法来设计它?如果我只是将其解析为kwargs,它们将不会以正确的格式发送,或者我会要求使用该脚本的人编写end_time=SOMETIME之类的内容,而不仅仅是--endtime TIME。现在这似乎是一个很小的代价,但如果我需要将所有参数都添加到脚本中,那么这将会变得更长,更乏味。

1 个答案:

答案 0 :(得分:2)

您可以将传递给arc.search的所有可选关键字参数收集到dict,然后在调用该函数时将其解压缩:

import argparse

parser = argparse.ArgumentParser(description='Script used to send search '
                                             'queries to ArcSight Logger API')
parser.add_argument('-t', '--target',
                    help='IP Address of the Loggger', required=True)
parser.add_argument('-u', '--username',
                    help='Username to access the logger', required=True)
parser.add_argument('-p', '--password',
                    help='Password to access the logger', required=True)
parser.add_argument('-q', '--query',
                    help='Query to be used in the search')
parser.add_argument('-st', '--starttime',
                    help='From which time the query should look')
parser.add_argument('-et', '--endtime',
                    help='To which time the query should look')
args = (parser.parse_args())

# Mock search
def search(query, start_time=None, end_time=None, discover_fields=None):
    return 'Id', ', '.join(str(x) for x in [start_time, end_time, discover_fields])

"""
Checks if query is used, and starts a search
"""
if args.query:
    # {name used in argparse: search parameter name}
    query_args = {
        'starttime': 'start_time',
        'endtime': 'end_time',
        'discover_fields': 'discover_fields'
    }
    d = vars(args)
    real_args = {v: d[k] for k, v in query_args.items() if k in d}
    search_id, response = search(args.query, **real_args)

    print('The search id is {}'.format(search_id))
    print('Response is {}'.format(response))

输出:

>python test.py -t foo -u user -p pass -q
query -st start -et end
The search id is Id
Response is start, end, None

由于解析器使用的某些参数名称与传递给search的参数名称不同,因此需要重新映射名称。 vars用于从dict返回的Namespace对象创建parse_args()。然后字典理解迭代映射的参数名称,选择给定用户的名称并创建一个具有arc.search理解的键名称的新字典。最后**real_args解包函数调用中名为parameters的字典。