Command Line Tool Creation

Unidata Python Workshop


Overview:

  • Teaching: 30 minutes
  • Exercises: 36 minutes

Create command line tools to do common jobs

  • Do common data manipulations
  • Make plots
  • Download data or batch process items

You are already used to using command line tools

  • ls
  • grep
  • git
  • GEMPAK

Command line tools take command line arguments

GREP(1)                   BSD General Commands Manual                  GREP(1)

NAME
     grep, egrep, fgrep, zgrep, zegrep, zfgrep -- file pattern searcher

SYNOPSIS
     grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color[=when]] [--colour[=when]]
          [--context[=num]] [--label] [--line-buffered] [--null] [pattern] [file ...]

DESCRIPTION
     The grep utility searches any given input files, selecting lines that match one or more patterns.  By default, a pattern matches an input line if the regular
     expression (RE) in the pattern matches the input line without its trailing newline.  An empty expression matches every line.  Each input line that matches at
     least one of the patterns is written to the standard output.

     grep is used for simple patterns and basic regular expressions (BREs); egrep can handle extended regular expressions (EREs).  See re_format(7) for more informa-
     tion on regular expressions.  fgrep is quicker than both grep and egrep, but can only handle fixed patterns (i.e. it does not interpret regular expressions).
     Patterns may consist of one or more lines, allowing any of the pattern lines to match a portion of the input.

     zgrep, zegrep, and zfgrep act like grep, egrep, and fgrep, respectively, but accept input files compressed with the compress(1) or gzip(1) compression utili-
     ties.

     The following options are available:

     -A num, --after-context=num
             Print num lines of trailing context after each match.  See also the -B and -C options.

     -a, --text
             Treat all files as ASCII text.  Normally grep will simply print ``Binary file ... matches'' if files contain binary characters.  Use of this option
             forces grep to output lines matching the specified pattern.

     -B num, --before-context=num
             Print num lines of leading context before each match.  See also the -A and -C options.

     -b, --byte-offset
             The offset in bytes of a matched pattern is displayed in front of the respective matched line.

     -C[num, --context=num]
             Print num lines of leading and trailing context surrounding each match.  The default is 2 and is equivalent to -A 2 -B 2.  Note: no whitespace may be
             given between the option and its argument.

Start by writing a "requirements document" for yourself

  • Describe the specific functionality of the tool
  • Describe the options that are available to the user
  • Include an expected set of outputs

You can also begin the design process

  • Functional blocks
  • Flow charts
  • Interface decisions

Let's design a tool to make a plot like this

Requirements - Let's design the tool

  • Plot super national visible satellite image
  • Contour a recent GFS field of the user's choice and a level specified by the user
  • Plot with a basemap containing coastlines, country, state, and provice borders
  • Make the plot for the current time or up to 24 hours in the past
  • Use the GFS and satellite data from the time closest to that requested (smallest delta t)
  • Indicate the model and satellite times on the plot
  • Show or save the output image
  • Have a sensible default behavior
  • Include help documentation to remind others and ourselves how to use the program

We'll use five command line arguments

  • --gfsfield GFSFIELD - CF field name of data to contour from the GFS model.
  • --gfslevel GFSLEVEL - Model level to plot (in hPa)
  • --hours HOURS - Time to plot (must be present or past)
  • --savefig - Save out figure instead of displaying it
  • --imgformat IMGFORMAT - Format to save the resulting image as.

We could write a parser ourselves, but there's no need

The argparse module has us covered!


In [ ]:
# For demo purposes only
import sys
sys.argv = ['greetme.py', '--name', 'John', '--greeting', 'Hola,']

In [ ]:
import argparse

# Create an instance
parser = argparse.ArgumentParser(description='A simple program that prints a greeting to the name specified')

In [ ]:
# Add a name argument
parser.add_argument('--name', type=str, required=True, help='Name of the person being greeted')

parser.add_argument('--greeting', type=str, default='Hello, ', help='Greeting to be used')

In [ ]:
# Parse the arguments
args = parser.parse_args()

In [ ]:
# Print the greeting
print(f'{args.greeting} {args.name}')

Let's run it all together!

  • Create using the editor in the notebook
  • Run from the command line