Modular multi-commands script with sub-commands

This script is a little more complicated anyway not so much. It will be modular. That means it will load commands at run time. We decided to create a script that can executes user commands and admin commands.

For convenience we will put the admin part in a module named admin.py and the user part in a module named user.py. And our modules will reside in the commands subfolder. (Actually we can have many modules into the commands sub folder)

Download this example zip.

Main script

In the main script we will just import all the commands, pass all desired arguments to the ArgParseInator and finally call the check_command method.

multicommand.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    Modular multi commands with subcommands example
"""
# If we specify here out version ArgParseInator will include it for us.
__version__ = "1.2.3"

import os
from argparseinator import ArgParseInator, import_commands


if __name__ == "__main__":
    # Let's import commands for the script which resides into the commands
    # package.
    import_commands('commands')
    # Ok, Istantiate ArgParseInator
    ArgParseInator(
        # Enable the --output if we want to write the result on file.
        add_output=True,
        # We will automatically exit from the script with the command return
        # code and message if any
        auto_exit=True,
        # Set up the phrase for commands that needs authorization
        auth_phrase="ok",
        # And set the default command for when we don't explicitally pass it
        default_cmd="user",
    # And finally tell to ArgParseInator to check command
    ).check_command()

Note

We also defined the __version__ at module level, ArgParseInator will handle it for us.

User commands

In this module we define our user commands. Its intended as example. It doesn’t really something useful.

commnds/user.py
# -*- coding: utf-8 -*-
"""
    User commands for multi commands example.
"""
from argparseinator import class_args, arg, ArgParseInated


@class_args
class User(ArgParseInated):
    """
    User commands.
    """
    __cmd_name__ = "user"

    @arg()
    def files(self):
        """
        List files.
        """
        self.writeln("Listing files...")
        # listing files code.
        return 0, "Files listed\n"

    @arg('name', help="Name to greet")
    def greet(self, name):
        """
        Greeting command.
        """
        self.writeln('Greeting person...')
        self.writeln('Ciao', name)
        return 0, "person greeted\n"

Admin commands

And here we have our Administrations command. As you can see we used the Authorize commands (@cmd_auth) decorator for the useradd() and userdelete() commands without the parameter, so ArgParseInator will use the global auth_phrase. For the deleteallusers() command, instead, we used a specif auth_phrase.

commands/admin.py
# -*- coding: utf-8 -*-
"""
    Administation commands for multi commands example.
"""
from argparseinator import class_args, arg, cmd_auth, ArgParseInated, ap_arg


class UserExistsError(Exception):
    """Fake user error"""
    pass

UserNotExistsError = UserExistsError


@class_args
class Admin(ArgParseInated):
    """Administrations commands."""
    # Our command name.
    __cmd_name__ = "admin"
    __shared_arguments__ = [
        ap_arg("-p", "--passwd", help="User parssword"),
        ap_arg("username", help="username"),
    ]

    @arg()
    def useradd(self, username, passwd):
        """Fake Create new user command."""
        self.writeln("Creating user", username, '...')
        try:
            # ... create user code.
            pass
        except UserExistsError:
            return 1, "User {} already exists".format(username)
        if passwd:
            # ... set password code.
            pass
        return 0, "User {} created".format(username)

    @arg()
    def userdelete(self, username):
        """Fake Delete user command."""
        self.writeln("Deleting user", username, '...')
        try:
            # ... delete user code.
            pass
        except UserNotExistsError:
            return 1, "User {} do not exists".format(username)
        return 0, "User {} deleted".format(username)

    @arg()
    @cmd_auth("yesiwantit")
    def deleteallusers(self):
        """Fake delete all users command"""
        self.writeln("Deleting ALL users...")
        # ... delete all users code
        return 0, "All users deleted"