Does python argparse have a solution for this case where we have unknown argument names and need to match them to values?

Viewed 95

I am receiving arguments to my script such that the argument vector available to the script looks like the example below.

sys.argv = ["the/script/path.py", "--key1='value1'", "--key2='value2'", ... "--keyN='valueN'"]

I have no way of knowing what the key names will be. The end goal is to get a JSON map of all the key names to value name. I'm trying to figure out if there's a way to have the built in argparse library help with this. I understand that I can just do this manually by splitting the string in the list on equals, and removing the extra quote and dash characters.

As far as I can tell, you can use argparse to get unknown arguments, but I'm not seeing a clear way to automatically match the argument by name to the proper value after doing this. I just get a list of strings similar to the contents of sys.argv

Is there a clear method using the argparse library to convert the contents of my argument list to a JSON map of arguments to values?

2 Answers

I don't think you can use argparse for this, but I also don't see why you would need to unless you need to take additional options or positional arguments. Like @hpaulj said in a comment, argparse is meant to define what arguments are valid, so where you're expecting anything, don't bother.

Instead, since the arguments are super consistent, do it manually like you're saying.

BTW, if you need to parse the single-quoted strings, there are libraries that can help with that, like shlex.

(This is assuming you can't control the arguments that the script receives.)

You can use parse_known_args to parse the arguments you do know about, and leave the unknown ones in a list to be passed to a parser that does now about them.

import argparse

p1 = argparse.ArgumentParser()
p1.add_argument("--key1")

p2 = argparse.ArgumentParser()
p2.add_argument("--key2")

args1, others = p1.parse_known_args()
args2 = p.parse_args(others)

print(args1)
print(args2)

This produces

$ python tmp.py --key1=3 --key2=5
Namespace(key1='3')
Namespace(key2='5')
Related