Tutorial#
This tutorial is intended as an introduction to working with petcmd.
Overview#
petcmd creates a CLI applications with many commands.
In general, the petcmd commands look like this:
$ app-name command-name [OPTIONS]
So to get it petcmd provides a petcmd.Commander.command decorator to mark specific functions as commands.
Basic usage#
Let’s create a simple functon to sum two numbers in app.py:
def sum_two_numbers(a, b):
print(a + b)
To create a CLI interface with this command let’s mark it as command with petcmd decorator and call the entrypoint:
from petcmd import Commander
commander = Commander()
@commander.command("sum")
def sum_two_numbers(a: int, b: int):
print(a + b)
if __name__ == "__main__":
commander.process()
Now we can try it:
$ python app.py sum 1 2
3
The CLI interface creating based on the command’s function signature.
It’s allowed to specify arguments both by position and keyword. It’s also supports *arga and *kwargs.
Let’s see some examples:
from petcmd import Commander
commander = Commander()
@commander.command("calc")
def calculate(a: int, b: int, operator: str = "+"):
print(eval(f"{a} {operator} {b}"))
if __name__ == "__main__":
commander.process()
$ python app.py calc 1 2
3
$ python app.py calc 10 2 /
5.0
$ python app.py calc 10 2 -o /
5.0
$ python app.py calc 10 2 --operator /
5.0
$ python app.py calc -a 10 -b 2 --operator /
5.0
Basically, you can pass values right as in the simple python function. There are some rules and restrictions for specifying command arguments:
Positional arguments#
You can specify arguments values by position of these arguments in the function signature, but it’s allowed only up to the first argument specified by the keyword - no mater positional or keyword by signature. Note that it’s related to arguments position in the function signature, not to the command values position, so you can first specify a keyword arguments and only then a positional:
$ python app.py calc -o / 10 2
5.0
$ python app.py calc 10 -o / 2
5.0
$ python app.py calc 10 2 /
5.0
$ python app.py calc 2 / -a 10
Invalid usage: positional argument follows keyword argument
Usage: calc a b [-operator]
a int
b int
Options:
--operator -o str [default: +]
$ python app.py calc 10 / -b 2
Invalid usage: unexpected number of positional arguments
Usage: calc a b [-operator]
a int
b int
Options:
--operator -o str [default: +]
It’s forbidden to specify keyword arguments by position in case *args presents in the function signature:
@commander.command("sum")
def calc_the_sum(init: int, *args: int, limit: int = -1):
result = init + sum(args)
if limit == -1 or result < limit:
print(result)
else:
print("Limit exceeded")
$ python app.py sum 1 2 3 4 5
15
$ python app.py sum 1 2 3 4 -l 5
Limit exceeded
You also can’t duplicate keyword arguments by specifying them both by position and by keyword:
$ python app.py calc 10 2 / -o +
Invalid usage: keyword argument operator have been specified as positional already
Usage: calc a b [-operator]
a int
b int
Options:
--operator -o str [default: +]