Building Command Line Applications using the click-shell Library
Tags: shell, automation, python, tutorial
Published: 2023-03-01 13:00:57

The **[click-shell](https://click-shell.readthedocs.io/en/latest/index.html)** is a Python library that’s built on top of the standard **cmd** library. It is an extension of the **click** library that’s used for building command-line applications. These command-line applications are programs that use a command-line interface(CLI) for receiving commands from users. These commands are in the form of text, and they are for instructing the computer to do a specific task. One thing that’s notable about command-line applications is that they do not have a graphical user interface(GUI), it’s just the console with some background and the user is prompted to enter commands. Have you ever wondered how a popular command line application like **Git** works? if you are curious and want to know how it works and you fancy the idea of building your own command line application then this tutorial is for you.


These is what we will cover:
  - Installing the **click-shell** Library
  - Creating the Shell
  - Adding a Command to the Shell
  - Getting Advanced
  - Conclusion 


## Installing the click-shell Library
To use the **click-shell** library you need to install it on your machine, enter this command in your terminal:
`$ pip install click-shell`

## Creating the Shell
Now that we have installed **click-shell**, let us create a new Python file and call it **automation_shell.py**. Make it look like this:
```python
from click_shell import shell

message = """
Welcome to Ninja Shell!!!Please enter a command below.
"""
# creating the shell
@shell(prompt='ninjashell/>', intro=message)
def my_shell():
    pass
    
# executing the shell 
if __name__ == '__main__':
    my_shell()
```
In the code, we are importing the **shell** from **click_shell**, then we are creating a string that will be the shell’s welcoming message. 

To create the **shell**, use the **[@shell()](https://dev.to/khumbolamulungu/)** decorator which takes **prompt** and **intro** as arguments, both these arguments are strings.

After the shell’s definition, create its function with a **pass** statement inside, and finally, we are executing the function inside the **if** block.


## Adding a Command to the Shell
Let’s add the first command to the **shell**, this command will just print a hello word text. To do that, below the **shell** paste this code:
```python
# adding a command to print hello world message
@my_shell.command() # adds a shell’s command
def hello_world():
    print("Hello World!")
```
To add a command to the **shell**, use the **command()** method. Create the command which is a Python function, then inside this function define what you want the command to do when executed. Note, the command that we will enter is the **hello-world**.

To run the program, use:
`$ python automation_shell.py`


Make sure you get this output:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqmlxpnvx6imv39ud9y0.png)

Enter the **hello-world** command and the output will be this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xcxugxl10tibvq1hqqf.png)

The **click-shell** library handles so much under the hood, like exception handling and keeping the **shell** running even when an error occurs and it has some inbuilt commands like the **exit** command. 

Try to enter a command that does not exist, you will get this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyqwzuhiscwwzqwy223m.png)
And to break out of the shell, just enter the exit command.


## Getting Advanced
We will now modify the **shell** to do meaningful tasks like listing the available **shell** commands, printing the current date and time, and creating a file. Open the file and replace the current code with this code:
```python
from click_shell import shell
from datetime import datetime

message = """
Welcome to Ninja Shell!!!Please enter a command below. If you want to
see a list of all the available commands, enter "help".
"""

# creating the shell
@shell(prompt='ninjashell/>', intro=message)
def my_shell():
    pass

# adding command to the shell to list available commands
@my_shell.command()
def help(): # the command will be help
    print(
        """Here is a list of all commands:
*******************************
help: List all the available commands
date-time: Prints current date and time
create-file: Creates a new file and write to it
exit: Exits the shell
        """
        )
    
@my_shell.command()
def date_time(): # the command will be date-time
    now = datetime.now().strftime("%d/%m/%Y %H:%M:%S") # getting the formatted current date and time
    print(f"The current date&time is: {now}")

@my_shell.command()
def create_file(): # the command will be create-file
    filename = input("Enter the file name and extension:") # getting the filename from user
    content = input("Enter the file content:") # getting the file contents from user
    # creating the new file, opening it in write mode
    with open(filename, "w") as f:
        f.write(content) # writing content to the file

# executing the shell 
if __name__ == '__main__':
    my_shell()
```
To be on the same page, let’s do some code breakdown. This code is not different from the previous code, here we have a few additions. 

We have imported the **datetime** library, extended the message string, and added 3 commands, **help**, **date-time**, and **create-file**.

The **help** command will list all the available commands for the **shell**, the **date-time** command will print the current date and time and lastly, the **create-file** command will assist the user in creating a basic file. 

Run the program and enter the help command to get this output:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6j675n698fuoprynyb8.png)

If you enter the **date-time** command, you get this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltv978gq6lwl8klqawf9.png)

To create a file, enter the **create-file** command:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3nxz4x7vec09477to4a.png)

You will find the file in your current working directory:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06efh44irec3id1b16x6.png)

With this content:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7extrkkp5qj10cczsjb2.png)


## Conclusion
 
That’s it, geeks!!! I hope you have learned so much from this piece. Remember there is so much that you could do with **click-shell**. I have only shown you a few things you could do with the library in this piece. But you can go the extra mile by building advanced commandline applications. Thanks for reading!!!! and do let me know in the comment section how you have benefitted from this piece.