Implementing sub-commands in Python with argparse
Long chains of easier-to-read sub-commands have come to be all the rage these days, or maybe it’s just me. To fit into contemporary parlance, I feel like most programs historically used prefixes for sub-commands like
-exec. These days, calling an application with
docker volume ls or
kubectl get all --all-namespaces is an everyday thing. Nowadays
sed -i would be written like
Anyways, I have this Python Project where I originally used a complex web of one-dimensional optional arguments (all prefixed with
--) for circumstances that were sometimes optional, and sometimes required.
My first go was ugly. It mucks up the
--help because nothing had any context relative to other options. Example:
--add --cf --dns --record --type A --name subdomain.domain.com --content 220.127.116.11
When enumerating additional arguments within the context of a sub-command, the
--help is a lot more helpful. The equivalent of the above, but with greater elegance:
add cf dns record --type A --name subdomain.domain.com --content 18.104.22.168
Any sub-command not prefixed with
-- is required until the last sub-command. Anything prefixed with
-- is optional and/or non-sequential. It makes things much more clear and readable. Hence why it’s becoming more common.
I had found some
argparse tutorials where I could implement one sub-command, but it just didn’t make sense to me.
But eventually, I found a way to have multiple levels of sub-commands, and even wrapped their enumeration in
I hope this helps someone out there.
- I wouldn’t have figured it out if it weren’t for this user and this gist: