DEV Community

Cover image for Command Line Utility with Python
Fernando B 🚀
Fernando B 🚀

Posted on

Command Line Utility with Python

Introduction

What is a CLI, or why do we even need them? In my line of work which is industrial automation and controls there tends to be lots of repetition. Back this up, copy this folder to this other folder, are all machines pinging, run this bat file, etc. Things that fascinate us when we first learn how to do them, but gets old real quick after the 1000th time. Other tasks take too long with a graphical user interface, and so it takes quicker with a CLI tool, especially if you do this more than once a day. I won't go into specific tasks code but more of how to approach the design of a CLI.

Initial Idea

Whenever I repeat a task over and over, or if I think it will be less error prone if I was to automate it, I make a CLI tool for the task or related tasks. My job is to abstract as much as I can to make the tool configurable, and used by other people. Making it configurable can also help for non-programmers to help you tweak it here and there through customization, so that is always a plus.

Anybody can make a script to do one thing or things, but if you can design it where other people can use it is even better. i.e. copy folder A on machine X1, to folder B on machine X2. Those are hard coded paths on your script, and that is a big no no. In this case an ini file to configure those paths would be more suitable. (Using this just as an example yeah I know you can copy files without scripts on most OSes)

  • What if those paths change later?
  • What if you have another folder to copy?

You see where I am going with this? Having to modify a script over and over will give you headaches in the long run. Configuration ini files rule the world.

CLI Libraries

These are just a few modules that will make your life easier when it comes to CLIs, but there are tons of them depending on what you are trying to accomplish.

  • argparse (for arguments)
  • configparser (for ini files)
  • progress (progress bar)
  • ping3 (pinging duh!)
  • ftplib (connecting to an ftp site)
  • datetime
  • pathlib (useful for paths)
  • glob (find pathnames with patterns)
  • shutil (copy files operations)
  • subprocess (spawn new processes)
  • zipfile (zip file operations)
  • getpass (secure password input)
  • os (OS interfaces)

If you are using the utility in an environment where python is not installed you can use pyinstaller to create an executable. I use Python 3.4 with pyinstaller anything above I cannot get it to work, spent a lot of time on this with newer python until I settled for pyinstaller on 3.4 just so you are aware. Issue Details

Design

The way I approach the CLI design, is to write down the requirements. Do a bit of research to see what modules or libraries are available so I don't have to write unnecessary code. Then I begin chipping away small chunks at a time while testing. Usually version 1.0.0 has a few bugs so I distribute to users, and wait for feedback. After a few iterations, the tool would be stable enough and hopefully never to be recompiled or changed again.

  • Functions are divided by responsibility
  • Menu
  • Configuration
  • Error log
  • Exception handling
  • Feedback for the user (Progress bar, and results)
  • Customization through settings.ini

Exceptions and Errors

A very important step in designing a CLI is to take care of exceptions and error. What do you need to show the user as far as messages goes. What needs to be logged to a log.txt file are very important decisions you need to make. What can possibly crash your program, think of ways your user could give wrong input or wrong ini settings.

Feedback

Showing feedback to the user is another important step. Many people seem to think that because is a CLI feedback is not that important. The user should always know what's going on. Time elapsed, current time, progress, are just a few items to think about when it comes to user feedback in a CLI.

Conclusion

Let me know what's your take on CLI tools:

  • Do you use them at work, and enjoy using them?
  • Do you make them?
  • Don't use them, don't care I love GUI's.

Top comments (3)

Collapse
 
rhymes profile image
rhymes

Hi Fernando, thanks for the article!

These are just a few modules that will make your life easier when it comes to CLIs, but there are tons of them depending on what you are trying to accomplish

It's amazing how extensive Python's standard library is when it comes to utilities for the command line and the operating system.

I use Python 3.4 with pyinstaller anything above I cannot get it to work

oooh that's a pity, are there no alternatives to pyinstaller? Through the search engine I found nuitka which declares support up to Python 3.7, have you tried it?

Functions are divided by responsibility

A very important step in designing a CLI is to take care of exceptions and error. What do you need to show the user as far as messages goes.

Really good points :D

Many people seem to think that because is a CLI feedback is not that important. The user should always know what's going on. Time elapsed, current time, progress, are just a few items to think about when it comes to user feedback in a CLI

I log a lot about what's going on usually, I don't think I've actually used a progress bar but time elapsed, current time and text I do!

Collapse
 
thefern profile image
Fernando B 🚀

Hi rhymes, thanks on the suggestion about nuitka. I haven't tried that one yet, I did try py2exe, and I can't remember what went wrong with that one. Is always a fine line between spending way too much trying to figure out how to compile a python script vs actually writing code to fix a problem. For this I wish it was as easy as Java, can get a jar file really quick.

Progress bars are not required for most quick tasks, in the cli article image, I actually need to add time elapsed now that I think about it, but the progress bar is a nice visual feedback on how fast things are moving along nevertheless. Or not moving along, I've witnessed that too. : ) Thanks for the feedback!

Collapse
 
rhymes profile image
rhymes

Is always a fine line between spending way too much trying to figure out how to compile a python script vs actually writing code to fix a problem.

ahahha I hear you, well, see if you can get it work within a limited time frame, otherwise bye bye, until you'll need features from the more recent Python versions at least.

For this I wish it was as easy as Java, can get a jar file really quick.

Isn't a jar the same thing as a wheel package in Python? A zip with a manifest basically.