I am trying to figure out how to incorporate argparse into a python function I have created that accepts two arguments, so that it is executable in the command line.
For example in this function below:
def function(arg1, arg2):
print(arg1 * arg2)
How could I implement argparse to be able to execute the following in the command line:
% python3 pythonscript.py function arg1 arg2
I have tried to use argparse, but I have only found tutorials for how to use it on python scripts and not functions.
To run function you have to load script - and this script has to get arguments and use it to execute expected function with expected values.
To get arguments you can use sys.argv
, argparse
and it will need to recognize function's name and run it. Other modules - like click, google/python-fire, invoke - can make it simpler because they can recognize function automatically and execute it.
For the beginning I show example with sys.argv
import sys
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
if len(sys.argv) < 4:
print("Usage: python3 script.py function arg1 arg2")
exit(1)
name = sys.argv[1]
val1 = int(sys.argv[2])
val2 = int(sys.argv[3])
if name == "mul":
result = mul(val1, val2)
print(result)
elif name == "add":
result = add(val1, val2)
print(result)
else:
print("wrong function's name")
And the same with dictionary (instead of many if/else) to execute function:
import sys
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
if len(sys.argv) < 4:
print("Usage: python3 script.py function arg1 arg2")
exit(1)
name = sys.argv[1]
val1 = int(sys.argv[2])
val2 = int(sys.argv[3])
functions = {
"mul": mul,
"add": add,
}
if name in functions:
result = functions[name](val1, val2)
print(result)
else:
print("wrong function's name")
And simular for argparse
.
argparse
may use options which may allow to send more complex parameters - like skip parameters to use default values, etc. - so it is more useful than sys.argv
I added option --debug
to display extra information
import argparse
"""
% python3 script.py --help
% python3 script.py mul 1 2
% python3 script.py add 1 2
% python3 script.py -D mul 1 2
% python3 script.py -D add 1 2
% python3 script.py --debug mul 1 2
% python3 script.py --debug add 1 2
"""
def mul(arg1, arg2):
return arg1 * arg2
def add(arg1, arg2):
return arg1 + arg2
# --- main ---
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('name')
parser.add_argument('val1')
parser.add_argument('val2')
parser.add_argument('-D', '--debug', action='store_true', help='[default: %(default)s]')
args = parser.parse_args()
if args.debug:
print("args:", args)
name = args.name
val1 = int(args.val1)
val2 = int(args.val1)
functions = {
"mul": mul,
"add": add,
}
if name in functions:
if args.debug:
print("executing:", functions[name], "with", val1, val2)
result = functions[name](val1, val2)
print(result)
else:
print("wrong function's name")
With click it can be simpler but it needs to add decorators.
#!/usr/bin/env python3
import click
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
@click.group()
def cli():
pass
@click.command()
@click.argument('arg1', type=click.INT)
@click.argument('arg2', type=click.INT)
def mul(arg1, arg2):
print(arg1 * arg2)
@click.command()
@click.argument('arg1', type=click.INT)
@click.argument('arg2', type=click.INT)
def add(arg1, arg2):
print(arg1 + arg2)
cli.add_command(mul)
cli.add_command(add)
# --- main ---
cli()
The same with fire can be even simpler
import fire
"""
% python3 script.py mul 1 2
% python3 script.py add 1 2
"""
class Calculator:
def mul(self, arg1, arg2):
return arg1 * arg2
def add(self, arg1, arg2):
return arg1 + arg2
# --- main ---
fire.Fire(Calculator)