Search Rocket site

Python for the Rocket MultiValue Developer - Part 3 of 3 - Leveraging the Power of Python

Michael Rajkowski

April 26, 2017

In part one of the series “Python for the Rocket MultiValue Developer – Part 1 of 3 – An Introduction” we discussed how the Rocket MultiValue application platforms ( UniData and UniVerse ) added Python as a programming language which sits at the same level as the other access methods.

In part two of the series, we discussed the u2py module, and how the Python programmer could leverage MultiValue applications and data. See: “Python for the Rocket MultiValue Developer – Part 2 of 3 – Getting Started with the u2py module

In this final section of this series, I’ll cover how the MultiValue developer can leverage Python from ECL/TCL and new BASIC Python APIs.

ACCESSING PYTHON FROM BASIC APIS AND ECL /TCL

Rocket UniData and UniVerse developers have access to Python through the following:

  • Two ECL/TCL commands RUNPY and PYTHON
    • RUNPY runs a Python program from TCL.
    • PYTHON launches Python’s interactive shell and can execute Python commands.
  • Rocket MultiValue BASIC APIs for Python
  • A new BASIC variable type, PYOBJECT is available.
    • PYOBJECT is used internally to receive a Python object.
  • Three new @variables:
    • @PYEXCEPTIONMSG
    • @PYEXCEPTIONTRACEBACK
    • @PYEXCEPTIONTYPE.
  • Several U2 BASIC API functions have been added, including
    • PyCall
    • PyCallFunction
    • PyCallMethod
    • PyGetAttr
    • PyImport
    • PySetAttr

ECL/TCL Commands to access Python

To run/execute a Python program from an ECL/TCL prompt, use the RUNPY command.

: RUNPY PP Greeting.py
Type your name: Mike
Hello Mike

The Greeting.py program is a simple program with just two lines code:

Greeting.py
0001 hello_name = input ('Type your name: ')
0002 print("Hello", hello_name)

Another way of executing the code is from the Python interactive shell:

import Greeting
Type your name: Mike
Hello Mike

Note that for the import to work, the path to the directory containing the code must be defined in the Python path. In this case since the PP (Python Program) directory in the XDEMO account is included in the u2.pth file, the import succeeds.The BASIC Python API for Rocket MultiValue

The U2 BASIC API functions allow the developer to access his/her Python code from within his/her MultiValue BASIC programs. We’ve added the following functions:

  • PyCall
  • PyCallFunction
  • PyCallMethod
  • PyGetAttr
  • PyImport
  • PySetAttr

To continue with our previous example, you’ll see that we can execute the simple lines of Python code by importing it, just as we did in the interactive Python Shell.

moduleName = "Greeting.py"
pyResults = PyImport(moduleName)

While the example demonstrates the import, it is not the most “Pythonic” of examples. Python purists look for their Python code to be object oriented, while the language gives the flexibility to deviate from a pure OO model. The next example shows how you can instantiate a Python object from MultiValue, and call methods on that object.

First from the interactive Python shell:

1. Import the module

import AddressToCoordObj

2. Instantiate an object that has the decoded address

my_location = AddressToCoordObj.decodeAddressToGeocode("2 Venture Plaza, Irvine, CA, 92618")

3. Take a look at the object

my_location
<AddressToCoordObj.Point object at 0x000000000502FEB8>

4. Call a method on the object that returns the results as a string

my_coords = my_location.str()
my_coords
'33.6593895, -117.7511262'

The same can be done programmatically:

ModuleName = "AddressToCoordObj"
FuncName = "decodeAddressToGeocode"
my_address   = "2 Venture Plaza, Irvine, CA, 92618"
*
* 1. Import the module
AddressObj = PyImport(ModuleName)
*
* 2. Instantiate an object that has the decoded address
my_location = PyCallMethod(AddressObj, FuncName, my_address )
PRINT "Using the ":FuncName:" function in the ":ModuleName:" module."
* 3. take a look at the object
this_obj = PyCallMethod(my_location, '__repr__')
PRINT "printable version of obj: ":this_obj
*
* 4. Call a method on the obhect tat returns the results as a string
my_coords = PyCallMethod(my_location, "str")
PRINT my_coords

Note that in step 3 we are executing the ‘__repr__’ method on the my_location variable, which contains a Python object. The ‘__repr__’ method is part of the base object class and thus inherited by our object.Compiling and running the program we get the following.

: BASIC PBP example
Compiling: Source = 'PBP/example', Object = 'PBP.O/example'
*
Compilation Complete.

Run the program

RUN PBP example
Using the decodeAddressToGeocode function in the AddressToCoordObj module.
printable version of obj: <AddressToCoordObj.Point object at 0x00000000036DFEF0>
33.6593895, -117.7511262

The above is a simple example, for another example with the AddressToCoordObj module see the “FINDWAREHOUSE_PYFUNC” program in the PBP file of the XDEMO account.If you examine the “FINDWAREHOUSE_PYFUNC” program you will notice that it is checking for thrown exceptions from the Python API.

.
.
.
IF @PYEXCEPTIONTYPE NE '' THEN
GOSUB CRT.EXCEPTION.INFO
STOP
END
.
.
.
CRT.EXCEPTION.INFO:
CRT "EXCEPTION TYPE IS " :@PYEXCEPTIONTYPE
CRT "EXCEPTION MESSAGE IS " :@PYEXCEPTIONMSG
CRT "EXCEPTIONTRACEBACK IS " :@PYEXCEPTIONTRACEBACK
RETURN

The following is a simple program that shows one way to check the exception:

>CT PBP bad_import
bad_import
0001 badmod = "notAValidPythonModule"
0002 st = PyImport(badmod)
0003 IF @PYEXCEPTIONTYPE NE '' THEN
0004   CRT "EXCEPTION TYPE IS " :@PYEXCEPTIONTYPE
0005   CRT "EXCEPTION MESSAGE IS " :@PYEXCEPTIONMSG
0006   CRT "EXCEPTIONTRACEBACK IS " :@PYEXCEPTIONTRACEBACK
0007 END

>RUN PBP bad_import
EXCEPTION TYPE IS ImportError
EXCEPTION MESSAGE IS No module named 'notAValidPythonModule'
EXCEPTIONTRACEBACK IS

While this concludes this introductory series of posts on “Python for the Rocket MultiValue Developer”, please visit the “U2 Python Community Resources” page if you would like to know more.