Python command line application

How to create a command-line utility using Python

Today I’ll show you how to make a command-line utility using Python. So maybe you are wondering what is a command-line utility? Right? So, let’s get started!

What is a command-line utility?

A command-line utility is a app that runs on the command-line. It does not have a GUI. It uses the command line interface or CLI to run and execute itself. If you want to read more about this, go here on wikipedia.

Prerequisites

I am going to be using Windows but the code will remain same for macOS and Linux as well. But the process for making a command-line utility are different. So, I guess I’ll make another post soon, for macOS and Linux. I am going to be using Visual Studio Code. You can use any code editor or text editor or IDE of your choice. Like, Sublime Text, Atom, Vim, etc. I will be using Command Prompt(CMD) as my Terminal, you can use Windows Powershell as well.

Terms that will be used

  • CMD — Command Prompt
  • CLI — Command Line Interface
  • CLU — Command Line Utility
  • VSCode — Visual Studio Code
  • py — python3
  • conda — anaconda3
  • editor, code editor, text editor, ide — Your editor

Modules

All modules used in this project are from the stdlib. No modules need to be installed seperately. Modules used are:

Project 1

What are we creating?

We are going to be making two utilities rather than one. The first one is going to be a file search utility that will search for a given keyword in file names in a specific directory, say, D: Drive. Then the utility lists all the files with the given word in their filename. And finally print the total no. of files that matched say, 23. And the fun part is we are not going to be taking these keyword and directory as input. Instead they should be passed as arguments after the utility name. And we are also going to take a look at Error and Exception Handling. For e.g. — Input:

C:\Users\username> search.py .py D:\Programming 
 D:\Programming\CLI-Utilities\search.py D:\Programming\CLI-Utilities\calc.py D:\Programming\etc.py No. of files matched = 3 
C:\Users\username> search.py python D:\Programming 
 No matching files in the given directory! Try another directory! 

Did you see that even though our file is in D:\Programming , we were access it from C:\Users\username ?

  1. Create a new folder named cli-utilities
  2. cd into that directory.
  3. Open it in your code editor. Type code . to open that directory in VSCode(if you are using VSCode).
  4. Make a new file named search.py .
  5. Now open search.py .

Actual Code

Ok, so let’s get into the fun stuff now.

First we are going to be importing the required modules.

# search.py - CLI-Utilities - play4Tutorials.hashnode.dev, github.com/play4Tutorials import os # stdlib import sys # stdlib 

Next we are gonna check if the modules were imported successfully. If not we are gonna handle the error or exception and print out some useful details. We are going to be using try/except for that.

try: import os # stdlib import sys # stdlib # Error and Exception Handling except ImportError as e: print("Some modules could not be imported from stdlib('sys' and 'os')") 

Next, we are going to be getting the arguments passed along with the filename. We are going to be using sys.argv for that. We are going to be storing them in variables. sys.argv returns a list of all the arguments passed. Among them the first one is the file name itself. So we are going to be starting from sys.argv[1].

keyword = sys.argv[1] # Get the keyword that is to be searched for 

Now, we have the keyword stored in the variable keyword . So, let’s get the path as well. But some times paths contain spaces, right? So, how do we deal with them? Since sys.argv splits arguments on spaces. Let’s see.

path = " ".join(sys.argv[2:]) # Get the path where to search for the keyword # Alright, so what we just did here is we used py's in-built `join()` function and joined # all the strings from index 2 to n with a space. So that now if the path contained # spaces, it will be joined with them. fileMatched = 0 # Initialize filesMatched as 0. I'll explain this later. 

Finally, we will now start creating the main function named search_files(keyword, path)

def search_files(keyword, path): filesFound = filesMatched for root, dirs, files in os.walk(path): # Use os.walk(path) to loop through the given directory and get the root, dirs, and files for file in files: # Loop through all the files in the given directory. if keyword in file: # Check if keyword is in filename filesFound += 1 # Counter to see how many files matched print(" "+root+'\\'+str(file)+"\n") # Print out the full file path for every matching file if filesFound == 0: # Check if no files matched the given keyword and print the same print("No matching files in the given directory! Try another directory!") # If 1 or more files are matched then print the same print(f"No. of files matched: ") 

The above code kind of explains itself, however I’ll explain it. First, we define a function named search_files(keyword, path) . Next, we create a new variable named filesFound which is equal to filesMatched . we can’t use filesMatched directly because then py would give an that it is an Unbound Variable . Ok, next up we create a for loop using os.walk(path)

for root, dirs, files in os.walk(path): 

So, what is os.walk() in Python? os.walk() is an in-built python method from the os module we imported at the beginning, remember? And it gives you back a list with all the names of the files in the given directory. And root, dirs, files is passed because it will return the root or the directory passed, then all the folders in the directory and then all the files in the directory. So we pass it store the values in the specific variables.

Читайте также:  Excel to html table vba

Then, we have another loop in the files list or array

for file in files: if keyword in file: filesFound += 1 print(" " + root + '\\' + str(file) + "\n") if filesFound == 0: print("No matching files in the given directory! Try another directory!") 

This simply loops through all the files. And checks if the given keyword is present in the filename. If it is present, then filesFound is incremented by 1 and the whole path to the file is printed. The » «, «\n» are just make it look abit better in the CLI. And the «\\» (double back-slash) is used because single back-slash is used to escape the quotes but double back-slash escapes the slash. Finally, another if condition checks whether the no. of matched files is 0 or not? If iit is zero, we print the same. Else, we go out of the if statement, then out the if statement, then out of the loop, and again out of the loop.

print(f"No. of files matched: ") 

Over here, I am using f string to print out how many files matched the search. Using the filesFound variable. You can also use .format()

After that, we have another block of code for error and exception handling, which doesn’t require any explanation.

try: search_files(keyword, path) # Calling the function # Error and Exception Handling except FileNotFoundError as e: print("Error: FileNotFoundError occured! Make sure you entered the correct path and entered it correctly.") except Exception as e: print(f"Error: Some Error occured! \nDetails: ") 

Again, I am using f strings . You can use .format() as well.

Читайте также:  What are regular expressions in python

And finally, the finished code looks like this.

# search.py - CLI-Utilities - play4Tutorials.hashnode.dev, github.com/play4Tutorials try: import os # stdlib import sys # stdlib # Exception and Error Handling except ImportError as e: print("Error: Some modules could not be imported from stdlib('sys' and 'os')") keyword = sys.argv[1] # Get the keyword that is to be searched for path = " ".join(sys.argv[2:]) # Get the path where to search for the keyword filesMatched = 0 # Initialize filesMatched as 0 # Function to search the keyword in a given directory def search_files(keyword, path): filesFound = filesMatched for root, dirs, files in os.walk(path): # Use os.walk(path) to loop through the given directory and get the root, dirs, and files for file in files: # Loop through all the files in the given directory. if keyword in file: # Check if keyword is in filename filesFound += 1 # Counter to see how many files matched print(" "+root+'\\'+str(file)+"\n") # Print out the full file path for every matching file if filesFound == 0: # Check if no files matched the given keyword and print the same print("No matching files in the given directory! Try another directory!") # If 1 or more files are matched then print the same print(f"No. of files matched: ") try: search_files(keyword, path) # Call the function # Error and Exception Handling except FileNotFoundError as e: print("Error: FileNotFoundError occured! Make sure you entered the correct path and entered it correctly.") except Exception as e: print(f"Error: Some Error occured! \nDetails: ") 

Moving on to the 2nd Project, which is super simple and easy and not as fun as the previous one.

Project 2

What are we making?

We are going to be making a simple CLI calculator. It will print out the result of the expression passed to it. For e.g. — Input:

C:\Users\username> calc.py 2 +10 * 5 

Источник

Читайте также:  Html table header text size

Command-line Applications¶

https://d33wubrfki0l68.cloudfront.net/b6a8e99951ff1577e83f05367cb44cf2e327dfd9/08dbe/_images/34435690330_11930b5987_k_d.jpg

Command-line applications, also referred to as Console Applications, are computer programs designed to be used from a text interface, such as a shell. Command-line applications usually accept various inputs as arguments, often referred to as parameters or sub-commands, as well as options, often referred to as flags or switches.

Some popular command-line applications include:

  • grep — A plain-text data search utility
  • curl — A tool for data transfer with URL syntax
  • httpie — A command-line HTTP client, a user-friendly cURL replacement
  • Git — A distributed version control system
  • Mercurial — A distributed version control system primarily written in Python

Click¶

click is a Python package for creating command-line interfaces in a composable way with as little code as possible. This “Command-Line Interface Creation Kit” is highly configurable but comes with good defaults out of the box.

docopt¶

docopt is a lightweight, highly Pythonic package that allows creating command-line interfaces easily and intuitively, by parsing POSIX-style usage instructions.

Plac¶

Plac is a simple wrapper over the Python standard library argparse, which hides most of its complexity by using a declarative interface: the argument parser is inferred rather than written down imperatively. This module targets unsophisticated users, programmers, sysadmins, scientists, and in general people writing throw-away scripts for themselves, who choose to create a command-line interface because it is quick and simple.

Cliff¶

Cliff is a framework for building command-line programs. It uses setuptools entry points to provide subcommands, output formatters, and other extensions. The framework is meant to be used to create multi-level commands such as svn and git , where the main program handles some basic argument parsing and then invokes a sub-command to do the work.

Cement¶

Cement is an advanced CLI Application Framework. Its goal is to introduce a standard and feature-full platform for both simple and complex command line applications as well as support rapid development needs without sacrificing quality. Cement is flexible, and its use cases span from the simplicity of a micro-framework to the complexity of a mega-framework.

Python Fire¶

Python Fire is a library for automatically generating command-line interfaces from absolutely any Python object. It can help debug Python code more easily from the command line, create CLI interfaces to existing code, allow you to interactively explore code in a REPL, and simplify transitioning between Python and Bash (or any other shell).

Источник

Оцените статью