Package: autofunccli
Python Command FunctionDescriptionThis project aims to build an easy to use package allowing to use a python function directly as a command line script using the argparse module.When building a software, deep learning algorithm or even simple script; most of the time you will end up with one function that do all the job. But when you want to try or use it quickly you will have to use the python in command line or just edit your script each time you want to change your parameters. The best actual way for now is to use the argparse module to wrap your function with a command line interface but you will have to update it each type you change your function.The point is that function is already what you want to call, and has already all the informations that you put in the argparse, so why not automate it ?And this what this project is about using the function signature directly to produce an argparser.InstallationVia PyPIThe project is available on PyPI and you can install using pip :pipinstallautofunccliUsing GithubIf you want to have the example and run the tests you can clone the repository from Github.gitclonehttps://github.com/CuadrosNicolas/Python-Command-FunctioncdpythonFunctionCommandTo run the test :chmod+x./setup.sh&&setup.shOnce you have done that you are ready to build your command function.You first need to import the class from the packagefromautofunccliimportcmdfuncThen you just have to use it to wrap your function and build a command function.How to useBasic usage#examples/basic.pyfromautofunccliimportcmdfunc#define a simple plus functiondefplus(a,b):returna+b#Use it as a main#.main test if __name__ == '__main__'# if it's the case, parse the command line inputout=cmdfunc(plus).main(__name__)if(out!=None):print(out)Then you can try by running the scriptpython3basic.py-hWhich will output :usage: basic.py [-h] a bpositional arguments:a           : <str>b           : <str>optional arguments:-h, --help  show this help message and exit[RETURN]If you try it by running the script with the right arguments like if you want to add 1 and 2python3basic.py12You will end up with :12But wait that's not 1+2 ! And it's normal, you have to specify that the arguments are integer to use them as integer. So let's modify the signature and add type annotationdefplus(a:int,b:int)->int:returna+bIf you run it again :3Now it's the right output !
autofunccli uses the type annotation for parsing the raw input allowing a great flexibility in time if you change your signature.Accepted type are the following :#Accepted types for function argumentacceptedTypes=[bool,int,float,str,List,Tuple]#Accepted types for generic type argumentacceptedTypeArgs=[bool,int,float,str]List,Tuple, Bool and Enum are special cases that you will know more about in the next section.Default ValuesWhen using default value for arguments, they becomes optional argument for your command.#examples/default.pyfromautofunccliimportcmdfuncdeff(must:int,optional:int=0):returnmust+optionalout=cmdfunc(f).main(__name__)if(out!=None):print(out)List arguments and choicesTo use List and Tuple you have to import the typing packagefromtypingimportList,TupleListIf you want to use list as arguments like using the nargs='+' in command argparse you have to specify your function argument as a List[T] type like in this example :#examples/list.pyfromautofunccliimportcmdfuncfromtypingimportListfromfunctoolsimportreducedefsum(l:List[int])->int:returnreduce(lambdaprev,act:prev+act,l)out=cmdfunc(sum).main(__name__)if(out!=None):print(out)Will create a command like this :usage: list.py [-h] l [l ...]positional arguments:l           : <List[int]>optional arguments:-h, --help  show this help message and exit[RETURN] : <int>The list type argument must be in the acceptedTypeArgs array.TupleTuple can be seen as a special case of array with a finite number of element.
In our cases if we want to have a function taking an array of 3 numbers for example to build a color, we need to proceed like this :#examples/tuple.pyfromautofunccliimportcmdfuncfromtypingimportTupledefcolor(c:Tuple[int,int,int])->str:return"RGB({},{},{})".format(c[0],c[1],c[2])out=cmdfunc(color).main(__name__)if(out!=None):print(out)Will create a command like this :usage: tuple.py [-h] c c cpositional arguments:c           : <int,int,int>optional arguments:-h, --help  show this help message and exit[RETURN] : <str>This command needs to have a exactly 3 integers as parameters.
Notice that you can also have different type in the Tuple type arguments.
The Tuple type arguments must be in the acceptedTypeArgs array.BooleanBoolean type can be use to produce the equivalent of the "action='store_true'" or "action='store_false'" arguments when adding argument to an arg parser.
When using a boolean type, it will automatically be an optional argument with the default False value and using the action store_true, if you specify True as a default value, the parser use the store_false action.
For example the following function :#examples/bool.pyfromautofunccliimportcmdfuncdefisItTrue(b:bool):if(b):return'yes'else:return'no'out=cmdfunc(isItTrue).main(__name__)if(out!=None):print(out)Produce this result :usage: bool.py [-h] [-b]optional arguments:-h, --help  show this help message and exit-b, --b     : <bool>(False)[RETURN] : <str>ChoicesChoices imply that the user can only use a set of value as argument.
In our case you have to first create a class deriving from the Enum type.
And use it as a type for your argument.
The only restriction is to have the same type for each values of the Enum.
And the type be in the acceptedTypeArgs array.#you have to import the Enum class first#examples/choices.pyfromautofunccliimportcmdfunc#you have to import the Enum class firstfromenumimportEnumclassLEFT_OR_RIGHT(Enum):LEFT='LEFT'RIGHT='RIGHT'defwhereAreYouGoing(d:LEFT_OR_RIGHT)->str:if(d==LEFT_OR_RIGHT.LEFT):return'GOING LEFT !'elif(d==LEFT_OR_RIGHT.RIGHT):return'GOING RIGHT'out=cmdfunc(whereAreYouGoing).main(__name__)if(out!=None):print(out)Produce the following command :usage: choices.py [-h] {LEFT,RIGHT}positional arguments:{LEFT,RIGHT}optional arguments:-h, --help    show this help message and exit[RETURN] : <str>Merging multiple function to build command line utilityIf you to build a command line utility that works like git for example. You need to use the cmdfusion class that allows to wrap multiple function and call them as one autofunccli.For example:#examples/multifunction.pyfromautofunccliimportcmdfusioncmd=cmdfusion("Test with multiple function.")@cmd.adddefplus(a:int,b:int)->int:"""plus operation:param a: first number:param b: second number:return: a+b"""returna+b@cmd.adddefminus(a:int,b:int)->int:"""minus operation:param a: first number:param b: second number:return: a-b"""returna-bout=cmd.main(__name__)if(out!=None):print(out)Output this help :usage: multifunction.py [-h] {plus,minus}Test with multiple function.positional arguments:{plus,minus}optional arguments:-h, --help    show this help message and exitdescription:plus            plus operationminus           minus operationIn this way, the first argument allow to choose one specific command, for each one of them you can use the '-h' to print the chosen one's help.Document your command functionIf you want to add information about your command or arguments you can use doc string that way :#examples/doc.pyfromautofunccliimportcmdfuncfromtypingimportListfromfunctoolsimportreducedefsum(l:List[int],n:bool)->int:"""Sum a list of integer.:param l: List of integer.:param n: if present, multiply the result by -1:return: The sum of the list"""o=reduce(lambdaprev,act:prev+act,l)if(n):o*=-1returnoout=cmdfunc(sum).main(__name__)if(out!=None):print(out)Produce the following command :usage: doc.py [-h] [-n] l [l ...]Sum a list of integer.positional arguments:l           List of integer. : <List[int]>optional arguments:-h, --help  show this help message and exit-n, --n     if present, multiply the result by -1 : <bool>(False)[RETURN] The sum of the list: <int>AuthorCuadros Nicolas