I want to be able to run different functions from the command line in this way:
python my_parser.py myfunction1 arg1 arg2
and then again be able to run another function
python my_parser.py myfunction2 arg1 arg2 arg3
How do you do this in a clean manner? At the moment I can do it but in a very cumbersome way:
I have my code organized like this: A python file1 with all my functions
A second python file2 where I define the arguments to parse for the functions in file1.
It seems very inefficient because every time that I write a new function on file1 I have to add it to file2.
file1.py:
def my_func1(arg1, arg2):
return arg1*arg2
def my_func2(arg1, arg2, arg3):
return arg1*arg2*arg3
def my_func3(arg1)
return print(arg1)
file2.py (the parser)
import argparse
FUNCTION_MAP = {'myfunc1': file1.my_func1,
'myfunc2': file1.my_func2,
'myfunc3': file1.my_func3}
# create the top-level parser
parser = argparse.ArgumentParser(prog='PROG')
# Just add the subparser, no need to add any other argument.
# Pass the "dest" argument so that we can figure out which parser was used.
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')
# create the parser for the "a" command
parser_a = subparsers.add_parser('my_func1', help='func1 help')
# Keep the names here in sync with the argument names of the FUNCTION_MAP
parser_a.add_argument("-arg1", "--arg1", required=True)
parser_a.add_argument("-arg2", "--arg2", required=True)
# create the parser for the "b" command
parser_b = subparsers.add_parser('my_func2', help='func2 help')
# Keep the names here in sync with the argument names of the FUNCTION_MAP
parser_b.add_argument("-arg1", "--arg1", required=True)
parser_b.add_argument("-arg2", "--arg2", required=True)
parser_b.add_argument("-arg3", "--arg3", required=True)
# create the parser for the "c" command
parser_c = subparsers.add_parser('my_func3', help='func3 help')
# Keep the names here in sync with the argument names of the FUNCTION_MAP
parser_c.add_argument("-arg1", "--arg1", required=True)
#parse args
args = parser.parse_args()
# subparser_name has either "tiff2avif" or "ometiff2bigtiff".
func = FUNCTION_MAP[args.subparser_name]
# the passed arguments can be taken into a dict like this
func_args = vars(args)
# remove "subparser_name" - it's not a valid argument
del func_args['subparser_name']
# now call the function with its arguments
func(**func_args)
It would be great if I could just write the functions in file1.py and a parser would take arguments for the functions without having to manually add a new parser_x and each argument as parser_x_add_argument(). I bet this is possible, but could not figure out how.
Ideally I would like to have the parser on file1 under
if __name__ == "__main__":
So that I can run my functions directly from there, and I can get rid of file2.
Thank you very much in advance.
Related question: Parse different inputs into different Python functions