How to Create a Command Line Interface (CLI) with Python

How to Create a Command Line Interface (CLI) with Python

If you have ever interacted with a computer using the command prompt or terminal, then you have used a Command Line Interface (CLI). In this article, we will explore how to create a basic CLI using Python’s <span>cmd</span> module.

What is a CLI?

A CLI allows you to interact with a computer by entering text commands. You input a command, and the computer responds accordingly. Here’s how to create your own CLI.

Step 1: Import Necessary Modules

In Python, you can use the <span>cmd</span> module to build your CLI. First, import it:

import cmd

Step 2: Define Your CLI Class

Create a class that inherits from <span>cmd.Cmd</span>. This class will contain the functionality of your CLI.

class MyCLI(cmd.Cmd):
    pass

Step 3: Set Your Prompt and Welcome Message

You can customize the prompt and welcome message of the CLI:

class MyCLI(cmd.Cmd):
    prompt = '>> '
    intro = 'Welcome to MyCLI. Type "help" to see available commands.'

Step 4: Define Your Commands

Each command in the CLI is a method in the class. For example:

class MyCLI(cmd.Cmd):
    def do_hello(self, line):
        """Print a greeting"""
        print("Hello, World!")

    def do_quit(self, line):
        """Exit the CLI"""
        return True

In the example above, <span>do_hello</span> is a command that prints a greeting, while <span>do_quit</span> is a command that exits the CLI.

Step 5: Run Your CLI

To start your CLI, create an instance of the class and call the <span>cmdloop()</span> method:

if __name__ == '__main__':
    MyCLI().cmdloop()

Step 6: Use Your CLI

Now, when you run your Python script, your CLI will greet you with the welcome message and prompt. You can enter commands like <span>hello</span> and <span>quit</span> to interact with it.

Complete Code

import cmd

class MyCLI(cmd.Cmd):
    prompt = '>> '
    intro = 'Welcome to MyCLI. Type "help" to see available commands.'

    def do_hello(self, line):
        """Print a greeting"""
        print("Hello, World!")

    def do_quit(self, line):
        """Exit the CLI"""
        return True

if __name__ == '__main__':
    MyCLI().cmdloop()

Advanced Features

Step 1: <span>precmd(self, line)</span> – Command Pre-hook

<span>precmd</span> method is a hook that runs before command execution. You can use it to perform actions or checks before command handling. Here’s how to use it:

def precmd(self, line):
    print("Before command execution")
    return line

In this example, “Before command execution” will be printed every time before command handling.

Step 2: <span>postcmd(self, stop, line)</span> – Command Post-hook

<span>postcmd</span> method runs after command execution. It is useful for performing actions or checks after command handling. Here’s how to use it:

def postcmd(self, stop, line):
    print("After command execution")
    return stop

In this example, “After command execution” will be printed every time after command handling. The <span>stop</span> parameter is used to control whether the CLI continues running (return <span>False</span>) or exits (return <span>True</span>).

Step 3: <span>preloop(self)</span> – Custom Initialization

<span>preloop</span> method runs once before the CLI loop starts. You can use it to perform any setup or initialization tasks that need to be completed before command handling:

def preloop(self):
    print("Initialization before CLI loop starts")

This method is useful for preparing the environment or loading resources before the CLI starts.

Step 4: <span>postloop(self)</span> – Custom Cleanup or Finalization

<span>postloop</span> method runs once when the CLI is about to exit. It is useful for performing cleanup or finalization tasks, such as closing files, cleaning up resources, or performing necessary actions before the CLI exits:

def postloop(self):
    print("Cleanup after CLI loop ends")

Example

import cmd
import os

class FileManagerCLI(cmd.Cmd):
    prompt = 'FileMngr>> '
    intro = 'Welcome to FileManagerCLI. Type "help" to see available commands.'

    def __init__(self):
        super().__init__()
        self.current_directory = os.getcwd()

    def do_list(self, line):
        """List files and folders in the current directory"""
        files_and_dirs = os.listdir(self.current_directory)
        for item in files_and_dirs:
            print(item)

    def do_change_dir(self, directory):
        """Change the current directory"""
        new_dir = os.path.join(self.current_directory, directory)
        if os.path.exists(new_dir) and os.path.isdir(new_dir):
            self.current_directory = new_dir
            print(f"Current directory changed to {self.current_directory}")
        else:
            print(f"Directory '{directory}' does not exist.")

    def do_create_file(self, filename):
        """Create a new text file in the current directory"""
        file_path = os.path.join(self.current_directory, filename)
        try:
            with open(file_path, 'w') as new_file:
                print(f"File '{filename}' created in {self.current_directory}")
        except Exception as e:
            print(f"Error: {e}")

    def do_read_file(self, filename):
        """Read the contents of a text file in the current directory"""
        file_path = os.path.join(self.current_directory, filename)
        try:
            with open(file_path, 'r') as existing_file:
                print(existing_file.read())
        except FileNotFoundError:
            print(f"File '{filename}' not found.")
        except Exception as e:
            print(f"Error: {e}")

    def do_quit(self, line):
        """Exit the CLI"""
        return True

    def postcmd(self, stop, line):
        print()
        return stop

if __name__ == '__main__':
    FileManagerCLI().cmdloop()

Step Breakdown

Step 1: Import Modules

import cmd
import os
  • We first import two Python modules: <span>cmd</span> and <span>os</span>. These modules help us create the CLI and interact with the file system.

Step 2: Create CLI Class

class FileManagerCLI(cmd.Cmd):
  • We define a new class named <span>FileManagerCLI</span> that inherits from the <span>cmd.Cmd</span> class. This class will contain all the functionality of our CLI.

Step 3: Set Prompt and Welcome Message

prompt = 'FileMngr>> '
intro = 'Welcome to FileManagerCLI. Type "help" to see available commands.'
  • We customize the prompt (the text before user input) and provide a welcome message that is displayed when the CLI starts.

Step 4: Initialize Current Directory

def __init__(self):
    super().__init__()
    self.current_directory = os.getcwd()
  • We initialize the <span>FileManagerCLI</span> class and set the <span>current_directory</span> variable to the current working directory in its constructor (<span>__init__</span> method).

Step 5: Create Commands

def do_list(self, line):
    """List files and folders in the current directory"""
  • We create commands like <span>do_list</span> to list files and folders in the current directory. The command description is in triple quotes and will be shown to users when they type “help”.

Step 6: Implement Command Logic

files_and_dirs = os.listdir(self.current_directory)
for item in files_and_dirs:
    print(item)
  • In each command method, we execute logic related to that command. For example, in <span>do_list</span>, we use the <span>os.listdir</span> function to get a list of files and folders in the current directory, then iterate through the list and print each item.

Step 7: Change Directory Command

def do_change_dir(self, directory):
    """Change the current directory"""
    new_dir = os.path.join(self.current_directory, directory)
    if os.path.exists(new_dir) and os.path.isdir(new_dir):
        self.current_directory = new_dir
        print(f"Current directory changed to {self.current_directory}")
    else:
        print(f"Directory '{directory}' does not exist.")
  • We create a <span>do_change_dir</span> command that allows users to change the current directory. The user needs to provide the directory name as an argument.

Step 8: Create File Command

def do_create_file(self, filename):
    """Create a new text file in the current directory"""
    file_path = os.path.join(self.current_directory, filename)
    try:
        with open(file_path, 'w') as new_file:
            print(f"File '{filename}' created in {self.current_directory}")
    except Exception as e:
        print(f"Error: {e}")
  • We create a <span>do_create_file</span> command that allows users to create a new text file in the current directory. The user needs to provide the filename as an argument.

Step 9: Read File Command

def do_read_file(self, filename):
    """Read the contents of a text file in the current directory"""
    file_path = os.path.join(self.current_directory, filename)
    try:
        with open(file_path, 'r') as existing_file:
            print(existing_file.read())
    except FileNotFoundError:
        print(f"File '{filename}' not found.")
    except Exception as e:
        print(f"Error: {e}")
  • We create a <span>do_read_file</span> command to read the contents of a text file in the current directory. The user needs to provide the filename as an argument.

Step 10: Quit Command

def do_quit(self, line):
    """Exit the CLI"""
    return True
  • We create a <span>do_quit</span> command to exit the CLI. When this command is entered, it returns <span>True</span>, which tells the CLI to exit.

Step 11: Command Post-hook

def postcmd(self, stop, line):
    print()
    return stop
  • We use the <span>postcmd</span> method to add a blank line after each command execution to improve the readability of the CLI output.

Step 12: Run the CLI

if __name__ == '__main__':
    FileManagerCLI().cmdloop()
  • Finally, we start the CLI by creating an instance of the <span>FileManagerCLI</span> class and calling the <span>cmdloop()</span> method.

Leave a Comment