rami300
rami300

Reputation: 69

adding arguments to an argument parser python using a a dictionary type variable

I have a CLI argument parser and I'm trying to build the parts that adds the specifications of the arguments dynamically with a pre defined dictionary that contains those details. This is dictionary with the details:

paramsDetails = {
'inputpath': {
    '-': 'i',
    '--': '--inputpath',
    'dest': 'userinputpath',
   'type': 'str',
   'metavar': 'PATH',
   'help': 'REQUIRED, input path of base folder of the files in which to scan. ',
   'required': True
},

'depth': {
    '-': 'd',
    '--': '--depth',
    'dest': 'directorydepth',
   'type': 'int',
   'metavar': 'INT',
   'help': 'depth to do down in path. ',
}

}

The "paramsDetails" dictionary details are retrieved from a external source out of my control and it might change without my knowledge at any time so I can't be manually hard coding it in my code. I need to be able to build the "parser.add_argument" call dynamically without knowing the content of "paramsDetails". I don't necessarily need to "parser.add_argument" for this buy DO need to use the "paramsDetails" dict.

This is what I got so far:

from argparse import ArgumentParser

parser = ArgumentParser(description='My test')

for currentParamDetails in paramsDetails:
    parser.add_argument(currentParamDetails)

args = parser.parse_args()

the "parser.add_argument(currentParamDetails)" doesn't work. I get:

usage: tests.py [-h] -i PATH [-d INT] inputpath depth
tests.py: error: the following arguments are required: inputpath, depth

which means it all went wrong.

of course typing the arguments manually works as so:

from argparse import ArgumentParser

parser = ArgumentParser(description='My test')

parser.add_argument("-i", "--inputpath", dest="userinputpath", type=str, metavar="PATH", help="REQUIRED, input path of base folder of the files in which to scan. ", required=True)

parser.add_argument("-d", "--depth", dest="directorydepth", type=int, metavar="INT", default=2, help="depth to do down in path. ")

args = parser.parse_args()

but that's not what I want, I want to use the dict.

How can this be done?

The Python version I'm using is 3.6.

Upvotes: 0

Views: 136

Answers (1)

Tzane
Tzane

Reputation: 3462

Here's something you can do. Missing the "-" on the short flag seems kinda strange to me but it is not a big deal. Having the "type" as a string instead of an object is more problematic, but assuming they are always builtin types (like in your examples) this should work:

parser = ArgumentParser(description='My test')

for definition in paramsDetails.values():
    flags = []
    flag_short = definition.pop("-", None)
    if flag_short:
        flags.append(f"-{flag_short}")
    flag_long = definition.pop("--", None)
    if flag_long:
        flags.append(flag_long)
    if "type" in definition:
        definition["type"] = getattr(__builtins__, definition["type"])
    parser.add_argument(*flags, **definition)
args = parser.parse_args(["-h"])

Upvotes: 1

Related Questions