Implementation code

The implementation code receives the parsed syntax and then performs the requested actions. The code (whether written in Python, R, or Java) must contain a function that is named Run with a single argument that accepts the parsed syntax.

The contents of the Python module for the example MYORG GETURL EXCEL extension command, which was discussed in the preceding section, is shown in the code sample that follows. The code includes import statements for the spssaux and extension Python modules that are used by the code and that are installed with SPSS® Statistics. The Python module itself must be named MYORG_GETURL_EXCEL.py, as required by the naming conventions that are described in what follows.

The module contains two functions: Run and geturlexcel. The Run function takes the parsed syntax, validates it, extracts the values of the keywords, and then calls geturlexcel to implement the requested actions. Separating the implementation code into a Run function that processes the submitted syntax and a main implementation function that performs the requested actions is a general feature of all extension commands that are created by IBM® SPSS.


import spssaux
from extension import Template, Syntax, processcmd
         
def Run(args):
    oobj = Syntax([
        Template("URL", subc="",  ktype="literal", var="url", islist=True),
        Template("FILETYPE", subc="OPTIONS", ktype="str", var="filetype", vallist=["xls","xlsx"]),
        Template("SHEETNUMBER", subc="OPTIONS", ktype="int", var="sheetnumber"),
        Template("READNAMES", subc="OPTIONS", ktype="str", var="readnames", vallist=["on","off"])])
    args = args[args.keys()[0]]
    processcmd(oobj, args, geturlexcel)

def geturlexcel(url, filetype="xls", sheetnumber=1, readnames="ON"):
    kwargs = {}
    url = "".join(url)
    kwargs["filetype"] = filetype
    kwargs["sheetid"] = sheetnumber 
    kwargs["readnames"] = readnames
    spssaux.openDataFileFromUrl(url, **kwargs)

The Run function uses the Template class, the Syntax class, and the processcmd function. These functions are designed to be used together and greatly simplify the task of working with the parsed syntax, which is contained in the args parameter to the Run function.

  • The Template class specifies how to process a particular keyword in the syntax for an extension command. Each keyword of each subcommand must have an associated instance of the Template class.
    • The first argument to the Template class constructor is the name of the keyword.
    • The argument subc specifies the name of the subcommand that contains the keyword. If the keyword belongs to the anonymous subcommand, the argument subc can be omitted or set to the empty string as shown here for the URL keyword.
    • The argument ktype specifies the type of keyword, such as whether the keyword specifies a variable name, a string, or a floating point number.
    • The argument var specifies the name of the argument to the implementation function (geturlexcel in this example) that receives the value that is specified for the keyword.
    • The argument vallist, that is used for FILETYPE and READNAMES, specifies the list of allowed values for the keyword. For keywords that are specified as ktype="str" in the Template constructor, submitted values of the keyword are converted to lowercase before validation, so the list of allowed values is specified in lowercase.
  • The Syntax class validates the syntax that is specified by the Template objects. The class is instantiated with a sequence of one or more Template objects as shown in this example.
  • The processcmd function extracts the values of the keywords from the submitted syntax and then calls the implementation function to carry out the requested actions.
    • The first argument to the processcmd function is the Syntax object for the command.
    • For Python, the parsed syntax is passed to the Run function in a complex nested Python dictionary that has a single top-level entry. The second argument to processcmd is this top-level entry, which is given by the expression args[args.keys()[0]].
    • The third argument to processcmd is the name of the implementation function. The values of the keywords that are specified by the Template objects are passed to the implementation function as a set of keyword arguments. In this example, the implementation function geturlexcel is called with the following signature:
      
      geturlexcel(URL=<URL>,filetype=<FILETYPE>,sheetnumber=<SHEETNUMBER>,readnames=<READNAMES>)
      

      where <URL> is the value that is specified for the URL keyword, and likewise for the other keywords.

      Note:
      • If a Python exception is raised in the implementation function, the Python traceback is suppressed, but the error message is displayed. To display tracebacks, set the SPSS_EXTENSIONS_RAISE environment variable to "true".
      • If the signature of the implementation function does not have a default value for a parameter, then an error is raised if the submitted syntax does not include a value for the parameter.

The geturlexcel function receives the values that were specified for the keywords in the submitted syntax, and then opens the requested Excel file. The function calls the openDataFileFromUrl function from the spssaux module, which is installed with SPSS Statistics, to open the file.

Help for the Template class, the Syntax class, and the processcmd function is provided with the extension module, which is installed with SPSS Statistics. You can access the help from help(extension) after you import the extension module.

Although the preceding example is for Python, the same approach for creating the implementation code can be used for extension commands in R or Java.
  • For an example of creating an extension command in R, see the tutorial "Working with R" in the IBM SPSS Statistics Help system. Help for the spsspkg.Template, spsspkg.Syntax, and spsspkg.processcmd functions in R (the equivalents of the Python functions used in the previous example) is available under Integration Plug-in for R Help > R Integration Package for IBM SPSS Statistics, in the Help system.
  • For Java, see the topic "Creating IBM SPSS Statistics extension commands in Java" under Integration Plug-in for Java User Guide > Getting started with the Integration Plug-in for Java, in the SPSS Statistics Help system. Help for the Template, Syntax, and processcmd functions in Java is included in the help for the Extension class under Integration Plug-in for Java API Reference, in the Help system.
  • Numerous implementation code files for extension commands are installed with SPSS Statistics, and might be useful as examples. The files are in the location where extension commands are installed on your computer. To view the location, run the SHOW EXTPATHS syntax command from within SPSS Statistics. The output displays a list of locations under the heading "Locations for extension commands". The files are installed to the first writable location in the list.

Naming conventions

The Python module, R source file, or Java class file (or JAR file) that contains the Run function for an extension command must adhere to the following naming conventions:

  • Python. The Run function must reside in a Python module file with the same name as the command--for instance, in the Python module file MYCOMMAND.py for an extension command that is named MYCOMMAND. The name of the Python module file must be in upper case, although the command name itself is case insensitive. For multi-word command names, replace the spaces between words with underscores. For example, for an extension command with the name MY COMMAND, the associated Python module is MY_COMMAND.py.
  • R. The Run function must reside in an R source file or R package with the same name as the command--for instance, in a source file named MYRFUNC.R for an extension command that is named MYRFUNC. The name of the R source file or package must be in upper case, although the command name itself is case insensitive. For multi-word command names, replace the spaces between words with underscores for R source files and periods for R packages. For example, for an extension command with the name MY RFUNC, the associated R source file is MY_RFUNC.R, whereas an R package that implements the command is named MY.RFUNC.R. The source file or package should include any library function calls required to load R functions that are used by the code.
  • Java. The Run function must reside in a Java class file or JAR file with the same name as the command--for instance, in a class file named MYCOMMAND.class for an extension command that is named MYCOMMAND. The name of the Java class file or JAR file must be in upper case, although the command name itself is case insensitive. For multi-word command names, replace spaces between words with underscores when constructing the name of the Java class file or JAR file. For example, for an extension command with the name MY COMMAND, the associated Java class file is MY_COMMAND.class.

Command syntax errors

Syntax errors, like not providing an integer for a parameter that is specified as Integer, are handled by IBM SPSS Statistics and stop the module from running. In that regard, the implementation code does not need to handle deviations from the XML specification of the syntax for the extension command.

Generating output

Generating and sending output to IBM SPSS Statistics is handled by the implementation code.

  • For Python and Java, the implementation code is responsible for specifying the procedure name (associated with the extension command) that labels pivot table output in the Viewer. In other words, unlike built-in IBM SPSS Statistics procedures such as FREQUENCIES, there is no automatic association of the extension command name with the name that labels pivot table output from the command. For Python, the procedure name is the first argument to the spss.StartProcedure function that wraps the statements that generate the output. For Java, the procedure name is the first argument to the StatsUtil.startProcedure function that wraps the statements that generate the output.
  • For R, the default name that is associated with pivot table output from an extension command is R. For IBM SPSS Statistics version 18 and higher, the name can be customized by wrapping the output statements in an spsspkg.StartProcedure - spsspkg.EndProcedure block. The procedure name is then the first argument to the spsspkg.StartProcedure function.

Globalization

You can globalize messages and output that is produced by the implementation code. For Python, see the topic "Localizing Output from Python Programs" under Integration Plug-in for Python Help > Python Integration Package for IBM SPSS Statistics > Introduction to Python Programs, in the SPSS Statistics Help system. For R, see the topic "Localizing Output from R" under Integration Plug-in for R Help > Using the R Integration Package for IBM SPSS Statistics, in the SPSS Statistics Help system.