I\'ve read this http://docs.python.org/release/2.6.2/library/optparse.html
But I\'m not so clear how to make an option to be required in optparse?
I\'ve tried to
As the optparse module is deprecated since version 2.7, you will probably find some more up to date examples here: Dead simple argparse example wanted: 1 argument, 3 results
I'm forced to use python 2.6 for our solution so I'm stick to optparse module. Here is solution I found to check for required options that works without specifying second time list of required options. Thus when you add new option you don't have to add it's name into the list of options to check.
My criteria for required option - option value should be not None and this options doesn't have default (user didn't specified add_option(default="...",...).
def parse_cli():
"""parse and check command line options, shows help message
@return: dict - options key/value
"""
import __main__
parser = OptionParser(description=__main__.__doc__)
parser.add_option("-d", "--days", dest="days",
help="Number of days to process")
parser.add_option("-p", "--period", dest="period_length",default="2",
help="number or hours per iteration, default value=%default hours")
(options, args) = parser.parse_args()
"""get dictionary of options' default values.
in this example: { 'period_length': '2','days': None}"""
defaults = vars(parser.get_default_values())
optionsdict = vars(options)
all_none = False
for k,v in optionsdict.items():
if v is None and defaults.get(k) is None:
all_none = True
if all_none:
parser.print_help()
sys.exit()
return optionsdict
I would use argparse library that has this functionality embedded:
PARSER.add_argument("-n", "--namespace", dest="namespace", required=True,
help="The path within the repo to the data base")
argparse reference
I'm also stuck on python 2.6 (pining for python2.7 and argparse, which not only has required arguments, but lets me specify that one of a set must be supplied); my approach requires a second pass, but lets me prompt for missing arguments unless running in batch mode:
# from myscript
import helpers
import globalconfig
parser = optparse.OptionParser(usage=myheader,epilog=myfooter)
parser.add_option("-L","--last",
action="store",dest="last_name",default="",
help="User's last (family) name; prompted for if not supplied"
)
parser.add_option("-y","--yes",
action="store_true",dest="batch_flag",default=False,
help="don't prompt to confirm actions (batch mode)"
)
[...]
(options, args) = parser.parse_args()
globalconfig.batchmode = options.batch_flag
[...]
last = prompt_if_empty(options.last_name,
"Last name (can supply with \"-L\" or \"--last\" option):")
# from helpers.py
def prompt_if_empty(variable,promptstring):
if not variable:
if globalconfig.batchmode:
raise Exception('Required variable missing.')
print "%s" %promptstring
variable = raw_input(globalconfig.prompt)
return variable
(I'm thinking of making my own parser class that has common options for global configs baked in.)
Another answer to this question cited parser.error, which I was unfamiliar with when I wrote the code, but might have been a better choice.
You can implement a required option easily.
parser = OptionParser(usage='usage: %prog [options] arguments')
parser.add_option('-f', '--file',
dest='filename',
help='foo help')
(options, args) = parser.parse_args()
if not options.filename: # if filename is not given
parser.error('Filename not given')
On the help message of each required variable Im writting a '[REQUIRED]' string at the beggining, to tag it to be parsed later, then I can simply use this function to wrap it around:
def checkRequiredArguments(opts, parser):
missing_options = []
for option in parser.option_list:
if re.match(r'^\[REQUIRED\]', option.help) and eval('opts.' + option.dest) == None:
missing_options.extend(option._long_opts)
if len(missing_options) > 0:
parser.error('Missing REQUIRED parameters: ' + str(missing_options))
parser = OptionParser()
parser.add_option("-s", "--start-date", help="[REQUIRED] Start date")
parser.add_option("-e", "--end-date", dest="endDate", help="[REQUIRED] End date")
(opts, args) = parser.parse_args(['-s', 'some-date'])
checkRequiredArguments(opts, parser)