Getting started

Nothing fancy here, we just create a simple cli calculator with argparse_action.

Single function

"Simple calculator"

import argparse
import argparse_action

def add(a, b):
    print(a + b)

parser = argparse.ArgumentParser(description=__doc__)
argparse_action.add_action(parser, add)

namespace = parser.parse_args()
namespace.action(namespace)

The argparse_action.add_action does two things:

  • defines cli arguments from the function signature of calc

  • register a wrapped function from calc into the parser as action so namespace.action(namespace) will unwrap the paramaters from namespace and calls calc as a normal python function.

So a usual argparse help is available:

$ python3 calc.py -h
usage: calc.py [-h] a b

Simple calculator

positional arguments:
  a
  b

  optional arguments:
    -h, --help  show this help message and exit

Let see how the script works:

$ python3 calc.py 1 2
12

This is stranger! We should handle the arguments as numbers instead of strings.

The type annotation will help:

def add(a: int, b: int):
    print(a + b)

argparse_action registers the type annotation of the parameters as the type of the cli argument.

$ python3 calc.py 1 2
3

Remark: You should use such types which accept str as input.

Multiple commands

We should extend calc.py with multiplication:

"Simple calculator"
import argparse
import argparse_action

parser = argparse.ArgumentParser(description=__doc__)
action = argparse_action.Action(parser)

@action.add()
def add(a: int, b: int):
    "Add two numberss together"
    print(a + b)

@action.add()
def mul(a: int, b: int):
    "Multiply two numbers"
    print(a * b)

namespace = parser.parse_args()
namespace.action(namespace)

The argparse_action.Action is used here to register a subparser for the functions. So the usage help will differ a bit:

$ python3 calc.py -h
usage: calc.py [-h] command ...

Simple calculator

positional arguments:
  command
    add       Add two numbers together
    mul       Multiply two numbers

optional arguments:
  -h, --help  show this help message and exit
$ python3 calc.py mul -h
usage: calc.py mul [-h] a b

positional arguments:
  a
  b

optional arguments:
  -h, --help  show this help message and exit

It works as it expected:

$ python3 calc.py mul 12 2
24

Command aliases

It’s tedious to type so much: add, mul. How about some command aliases:

@action.add("a", "+")
def add(a: int, b: int):
    print(a + b)

action.add() registers arbitrary number of aliases from its parameters.

$ python3 calc.py + 4 3
7

CLI options

We should add some other arithmetics like square:

@action.add()
def square(a: int):
    print(a ** at)
$ python3 calc.py square 3
9

It’s dull. How about a more generic option:

@action.add()
def pow(a: int, at: int = 2):
    print(a ** at)

argparse_action will create cli options from default values:

$ python3 calc.py pow 3
9

$ python3 calc.py pow 3 --at 3
27

That’s it.