Advanced Tutorial
There are plenty of advanced topics available to us. Here, we will try to look at them with an emphasis on simplicity.
Multiple commands and execution
Once we start adding more capabilities to our program, we might find having multiple commands with their own arguments and options does make the interface cleaner. To make it simple, let's look at a small program that can install, run and uninstall itself:
$ ls -l netapplet
-rwxr-xr-x 1 admin admin 784 2025-09-17 16:32:58 netapplet
$ cat netapplet
#!/usr/bin/env python
from loadconfig import Config
from sys import argv
conf = """\
clg:
subparsers:
run: {help: 'run as: $prog run',
execute: {module: __main__, function: run}}
install: {help: 'run as: $prog install | bash',
execute: {module: __main__, function: install}}
uninstall: {help: 'run as: $prog uninstall | bash',
execute: {module: __main__, function: uninstall}}
"""
def install(clg_ns):
print(f'mkdir -p ~/bin; cp {argv[0]} ~/bin')
def uninstall(clg_ns):
print(f'rm -f {argv[0]}')
def run(clg_ns):
print(f'Running {argv[0]}')
def main(args):
c = Config(conf, args=args)
if __name__ == '__main__':
main(argv)
A couple of runs will show:
# Our program is not installed in $PATH
netapplet
bash: netapplet: command not found
# To keep things simple, let's temporarely add ~/bin to the shell session
export PATH=~/bin:"$PATH"
# Running netapplet from the current directory
# ( ./ needs to be prepended to the command as . is not usually on $PATH )
$ ./netapplet
usage: netapplet [-h] {run,install,uninstall} ...
# Retrieving help
$ ./netapplet --help
usage: netapplet [-h] {run,install,uninstall} ...
positional arguments:
{run,install,uninstall}
run run as: ./netapplet run
install run as: ./netapplet install | bash
uninstall run as: ./netapplet uninstall | bash
options:
-h, --help show this help message and exit
# Looking the output of install
./netapplet install
mkdir -p ~/bin; cp ./netapplet ~/bin
# Sounds good. Lets install it according to the help.
$ ./netapplet install | bash
# Checking our program is now available
$ ls -la ~/bin/netapplet
-rwxr-xr-x 1 admin admin 784 2025-09-17 16:38:58 /data/admin/bin/netapplet
# and working... (notice no ./) Yeey!
$ netapplet run
Running /data/admin/bin/netapplet
# Time to uninstall it
$ ./netapplet uninstall
rm -f ./netapplet
$ netapplet uninstall | bash
# And... it's gone
$ netapplet run
/bin/ash: netapplet: not found
The program is clean, self-installable and self-documented.
The first line is a typical unix shebang to look for the system or virtualenv python shell. (Note: $VIRTUAL_ENV could had been used to optionally autoinstall within the virtualenv). It follows a couple import lines and the conf global variable. The install, uninstall and run functions are simple print statements that will be leveraged by a shell in our program, though these functions can be as complex as wanted, being part of other modules, etc. They receive clg namespace configuration as the first argument. The main function is called if our program is executed directly. This is a good programming and testing practice. Having main as a function with parameters allows to test it with handcrafted arguments. Lets now focus on the conf and the functions.
conf is a clg key with subparsers. This is an argparse concept which basically means a subcommand. In our case we have three of them with their documentation. If you are wondering why the quotes in the help of the subparsers keys, this is to escape the usual yaml meaning of the colon (:) char on these help strings. As we are using a clg key, loadconfig (through clg) assigns args[0] to the $prog attribute, decoupling the program name from sys.argv[0]. Once Config(conf, args=args) is called, clg creates a configuration based on the command line arguments and passes it to the function requested. After the function finishes, loadconfig return a Config object like {prog: ./netapplet, command0: run}.
loadconfig CLG features
One key feature of loadconfig is its CLG integration. We saw in cli interface some of its features. Here, we mention extra features that loadconfig adds to CLG
default command
This feature is used to add a default command to loadconfig cli. In [Multiple commands and execution][], a clg subparsers example was presented. Lets show again how it runs:
# Using the conf variable as in the original example
$ ./netapplet run
Running ./netapplet
$ ./netapplet
usage: netapplet [-h] {run,install,uninstall} ...
If instead we introduce default_cmd to conf, it now renders:
conf = """\
clg:
default_cmd: run
subparsers:
run: {help: 'run as: $prog run',
...
$ ./netapplet
Running ./netapplet
Closing
The netapplet program succinctly highlights very important needs in a program lifecycle (configuration, interface, documentation, deployment) and it can easily be used as a base for more complex ones.