Skip to content

Instantly share code, notes, and snippets.

@av8rgeek
Created October 26, 2023 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save av8rgeek/9852d4effe5ebbbbc944474d377f3bfd to your computer and use it in GitHub Desktop.
Save av8rgeek/9852d4effe5ebbbbc944474d377f3bfd to your computer and use it in GitHub Desktop.
Pass key/value pairs to a python script using CLI arguments using Argparse
"""
Sample script to parse arguments in the form of foo=bar and return a dict value
"""
import argparse
class ParseTags(argparse.Action):
"""
This class overrides the argparse.Action __call__ method to evaluate
the arguments, create a dict, and then return that dict as the argument's
value.
"""
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, {})
tags = [] # Temporary working variable
for value in values:
# The whole point of this loop is to split out multiple
# key/value pairs into their own list elements
# Example ['foo=bar', 'up=down']
if "," in value:
if value.strip() == ",":
# This covers the `foo=bar , sun=moon` situation
# because the ',' will be its own argument and cause
# a crash.
continue
if value.strip().endswith(","):
# This covers the ending of the argument being a ','
# such as `foo=bar,up=down,`
# by eliminating the ending ','
value = value.strip()[:-1]
if value.strip().startswith(","):
# This covers the scenario where the ',' is at the
# beginning of the paramenters, such as
# `,foo=bar,up=down`
value = value.strip()[1:]
# This needs to be a += to properly add to the tags list
# In `foo=bar,up=down`, using .append() here results in
# ['foo=bar','u','p','=','d','o','w','n']
tags += value.split(",")
else:
# The .append() works here because only 1 element is being added
tags.append(value)
for tag in tags:
# This loop is where we split the tags list and then "reassemble"
# the pieces into a dictionary.
key, value = tag.split("=")
getattr(namespace, self.dest)[key] = value
myparser = argparse.ArgumentParser(
description="Testing script for argument parsing of keys and values"
)
myparser.add_argument("--opt1", nargs="?", type=str, help="Option 1")
myparser.add_argument("--opt2", type=str, required=False, help="Option 2")
myparser.add_argument("-t", "--tags", nargs="*", action=ParseTags)
args = myparser.parse_args()
print(args)
@av8rgeek
Copy link
Author

My inspiration for this came from https://sumit-ghosh.com/posts/parsing-dictionary-key-value-pairs-kwargs-argparse-python/ and then I took it a step further to handle multiple key=value pairs separated by spaces and commas and crazy combinations thereof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment