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 -, like find’s -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 sed inplace.

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 8.8.8.8

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 8.8.8.8

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.

I then tried using the Click package, but it’s paradigm made things even more confusing for me. Even after trying to tweak the example in Advanced Patterns, I was helplessly lost.

But eventually, I found a way to have multiple levels of sub-commands, and even wrapped their enumeration in for loops:

I hope this helps someone out there.

References

  • I wouldn’t have figured it out if it weren’t for this user and this gist:

This is a preview of Clap Button, a new feedback and analytics tools for Hydejack, built by yours truly. You can try it out on localhost for free, but it will be removed (together with this message) when building with JEKYLL_ENV=production. To use Clap Button on your site, get a subscription
and set clap_button: true in your config file.


© 2021. All rights reserved.