Command-line Utilities for Everybody Else

16 Jul 2015 // programming

Here's a common problem: you've written a beautiful command-line utility - it's clean, it's refactored, it frankly sparkles. You tell folks about it, they want it, you send it to them. But, they won't use it. Why?

Because there's no GUI and people love their GUIs. The people hates the command-line.

What you need to do is wrap a GUI around your command-line utility. Not only that but for a minimum level of usability, your GUI better be:

  • cross-platform: works in any of the holy triumvirate of Windows, Unix or Mac
  • native look-and-feel: so people don't get put off opening files
  • easy-to-install: should not require esoteric knowledge

Now there are existing solutions that are close but not quite there. For example, gooey is a clever library that wraps a GUI around Python command-line utilities. The downside of gooey is that it uses wxPython. Installing wxPython is difficult for end-users. If you have a standard Python distribution (and that's a big if), then you can install wxPython from the website, but you need to know the exact binary version of your Python. Otherwise, you need a C-compiler ecosystem. Trivial, right?

Another solution might be to run a local web-server, which serves a local web-app to talk to your command-line utility. Sadly, webbrowsers are limited by a security feature, whereby open file dialogs are prevented from sending full pathnames to your webapp. This will cripple your command-line utility.

Well it turns there is a solution using plain old standard Python. Every Python install comes with a GUI library tkinter that is native to a certain extent. tkinter is not very powerful, but offers just enough features to build a GUI for a command-line utility. Since tkinter comes standard with Python on all 3 major platforms, your only requirement is to install Python (which is easy), and you get a cross-platform solution with native file dialogs for free!

So I wrote a module - tkform (http://github.com/boscoh/tkform) - that can wrap a tkinter GUI around command-line utilities. It's work flow is inspired by HTML forms. You construct the GUI in a linear fashion that will populate a single flowable page. There is a submit button at the bottom. When clicked with submit, your 'run' hook will get a JSON compatible parameter list that you can send to your command-line utility.

You get a bunch of widgets (checkbox, radio buttions, text labels, file lists) and some decorators (size-adjustable text, lines, spaces), and buttons for extra actions. You get a nice output area to display logging information. It even gracefuly handles Python exceptions. There are links to click on to send your user to the ouput.

I've even included a reoderable list widget that can display a list of filenames and elements that can be reordered and renamed, before the 'submit' button is pressed. This way your command-line utility can receive a list of filenames, ordered to your end-user's content. Imagine asking your end-user to do that on the command-line?

And it's easy to install. Just ask your end-user to install Python, then download your package which includes the tkform library with your Python command-line utility. Add an '-i' interactive option to your utility to trigger the GUI. Include a clickable shell/command/batch file and tell your user to click that. Easy as.