Command Line Interface (cli)
Notes
positional args
optional =
[arg]required =
<arg>
prefer flags (
tool --url="http://") over args (tool <url>) when building complex clialways show something to the user, in addition to the error code
show progress visually if possible (progress bar if downloading)
if a command has a side effect, provide a
--dry-runoptionwrite to stdout for useful information (and for other programs), stderr for warnings and errors
use error return codes (not just 0 and 1/-1)
use trackable, human-readable and actionable errors
avoid interactivity, or make it possible to disable it (think about scripting and continuous integration pipelines without user interaction)
keep security in mind (avoid asking for password as a flag or arg for example)
commonly used args, be creative, but not for these ones
use the XDG Base Directory
where to put user data, cache data etc...
$XDG_CONFIG_HOME(defaults to~/.config/)$XDG_DATA_HOME(defaults to~/.local/share/)XDG Base Directory compliant applications should first attempt to read these values from the environment variables, or fallback to the default paths if these variables aren’t set in the runtime environment.
example of an issue on the symfony project : https://github.com/symfony/cli/issues/56
be aware of
option-like argumentslike for example a negative integer. If you want to pass a negative integer as an argument, you need to use--before the arg. For example to enter-4, a user user must use-- -4. (https://click.palletsprojects.com/en/6.x/arguments/#option-like-arguments)
Libs
argparse (from the stdlib) : https://docs.python.org/3/library/argparse.html
How to design a good cli
Examples
the classic sysargv
To build a complex cli with it, you'll have to code a lot to parser the args, validate etc...
Please use argparse or click.
argparse
example of a parser, a subparser, and an inherited verbose mode
click
a simple example :
grouping commands