Python

Goto Main Page

Python Toolkit

The Python is a Python wrapper over the XMLSERVICE open source project from IBM. This python .whl/.egg is now jointly maintained by IBM and the KrengelTech Litmis team.

Python toolkit source

IBM project link

Download .whl (test only).

Versions:
2017–12–18 - python3-itoolkit-1.3.zip - change iLibCall - fix UnicodeDecodeError: ascii codec cannot decode byte 0xc3
pip3 install dist/*cp34m*.whl

Download .whl/.egg (or use IBM PTFs).

Versions:
2016–05–27 - python-itoolkit-1.2.zip

Interesting learning example with QTEMP.

A person using python iLibCall() in-memory driver to call RPG programs with ExecSql and native access mixed noticed after call python ibm_db the program did not work. The reason for the failure is QTEMP ‘moved’ to a different job after python ibm_db.

Why?

  1. Python ibm_db uses CLI ‘server mode’ to allow multiple translations with multiple user profiles. In fact, all new IBM i languages use CLI ‘server mode’ (php, nodejs, etc.). Briefly, CLI ‘server mode’ uses proxy QSQSRVR jobs attached to the main python job to process all DB2 work. Therein, QTEMP, moves away from python job #1 and into proxy QSQSRVR job #2.
  2. RPG ExecSql programs follow ‘sever mode’. That is. after ibm_db entered server mode, any ExecSql actions in a called RPG program in job #1 also went to the QSQSRVR job #2. However, natvive access like setll, chain, remained in the main job #1.
  3. Under these conditions, RPG ExecSql inserted into QTEMP in QSQSRVR job #2, but, RPG native access continued to look for QTEMP results in main job #1. There was no QTEMP date in job #1, so the iLibCall in-memory call to the RPG program failed.
  4. The fix was to use the iDb2Call transport protocol, so all of operations RPG ExecSql and native could share same QTEMP with ibm_db in QSQSRVR job #2.

Quick link classes and samples

Index
Classes Sample

iBase iCmd iSh iCmd5250 iPgm iSrvPgm iParm iRet iDS iData iSqlQuery iSqlPrepare iSqlExecute iSqlFetch iSqlParm iSqlFree iXml iToolKit iDB2Call iLibCall iRestCall

config.py icmd5250_dspsyssts.py icmd_rtvjoba.py ipase_ps.py ipgm_bad_trace_db2.py ipgm_bad_trace_file.py ipgm_bad_trace_rest.py ipgm_bad_trace_terminal.py ipgm_zzcall.py isleep_rest_async.py isql_callproc.py isql_prepare.py isql_query.py isql_rest_async.py isrvpgm_qgyrhrl.py isrvpgm_zzarray.py istop_msg_qsysopr_before_pgm_call.py ixml_diag.py ixml_zzvary.py

Overview


IBM i python toolkit. 

The toolkit runs both local and remote to IBM i using iDB2Call or iRestCall. 
However, class iLibCall process local calls will only work on IBM i (similar to IBM i CL).

Transport classes:
  class iLibCall:             Transport XMLSERVICE direct job call (within job/process calls).
  class iDB2Call:             Transport XMLSERVICE calls over DB2 connection.
  class iRestCall:            Transport XMLSERVICE calls over standard HTTP rest.

XMLSERVICE classes:
  Base:
  class iToolKit:             Main iToolKit XMLSERVICE collector and output parser.
  class iBase:                IBM i XMLSERVICE call addable operation(s).

  *CMDs:
  class iCmd(iBase):          IBM i XMLSERVICE call *CMD not returning *OUTPUT.

  PASE:
  class iSh(iBase):           IBM i XMLSERVICE call 5250 *CMD returning *OUTPUT.
  class iCmd5250(iSh):        IBM i XMLSERVICE call PASE utilities.

  *PGM or *SRVPGM:
  class iPgm (iBase):         IBM i XMLSERVICE call *PGM.
  class iSrvPgm (iPgm):       IBM i XMLSERVICE call *SRVPGM.
  class iParm (iBase):        Parameter child node for iPgm or iSrvPgm
  class iRet (iBase):         Return structure child node for iSrvPgm
  class iDS (iBase):          Data structure child node for iPgm, iSrvPgm,
                              or nested iDS data structures.
  class iData (iBase):        Data value child node for iPgm, iSrvPgm,
                              or iDS data structures.

  DB2:
  class iSqlQuery (iBase):    IBM i XMLSERVICE call DB2 execute direct SQL statment.
  class iSqlPrepare (iBase):  IBM i XMLSERVICE call DB2 prepare SQL statment.
  class iSqlExecute (iBase):  IBM i XMLSERVICE call execute a DB2 prepare SQL statment.
  class iSqlFetch (iBase):    IBM i XMLSERVICE call DB2 fetch results/rows of SQL statment.
  class iSqlParm (iBase):     Parameter child node for iSqlExecute.
  class iSqlFree (iBase):     IBM i XMLSERVICE call DB2 free open handles.

  Anything (XMLSERVICE XML, if no class exists):
  class iXml(iBase):          IBM i XMLSERVICE raw xml input.

Import:
  1) XMLSERVICE direct call (current job) - local only
  from itoolkit import *
  from itoolkit.lib.ilibcall import *
  itransport = iLibCall()

  2) XMLSERVICE db2 call (QSQSRVR job) - local/remote
  from itoolkit import *
  from itoolkit.db2.idb2call import *
  itransport = iDB2Call(user,password)
  -- or -
  conn = ibm_db.connect(database, user, password)
  itransport = iDB2Call(conn)

  3) XMLSERVICE http/rest/web call (Apache job) - local/remote
  from itoolkit import *
  from itoolkit.rest.irestcall import *
  itransport = iRestCall(url,user,password)

Samples (itoolkit/sample):
  > cd /QOpenSys/QIBM/ProdData/OPS/Python3.4/lib/python3.4/site-packages/itoolkit/sample
  > python3 icmd5250_dspsyssts.py

  > cd /QOpenSys/QIBM/ProdData/OPS/Python2.7/lib/python2.7/site-packages/itoolkit/sample
  > python2 icmd5250_dspsyssts.py

Install:
  =====
  IBM pythons (PTF):
  =====
  pip3 uninstall itoolkit
  pip3 install dist/itoolkit*34m-os400*.whl
  pip2 uninstall itoolkit
  pip2 install dist/itoolkit*27m-os400*.whl
  ======
  perzl pythons
  ======
  rm  -R /opt/freeware/lib/python2.6/site-packages/itoolkit*
  easy_install dist/itoolkit*2.6-os400*.egg
  rm  -R /opt/freeware/lib/python2.7/site-packages/itoolkit*
  easy_install-2.7 dist/itoolkit*2.7-os400*.egg
  ======
  laptop/remote pythons
  ======
  pip uninstall itoolkit
  pip install dist/itoolkit-lite*py2-none*.whl
  -- or --
  easy_install dist/itoolkit-lite*2.7.egg

Configure:
  Requires XMLSERVICE library installed.
  1) IBM i DGO PTFs ship QXMLSERV library (Apache PTFs)
  -- or --
  2) see following link installation 
     http://yips.idevcloud.com/wiki/index.php/XMLService/XMLSERVICE
     (use crtxml for XMLSERVICE library)

Environment variables (optional):
  export XMLSERVICE=QXMLSERV  (default)
  -- or --
  export XMLSERVICE=XMLSERVICE
  -- or --
  export XMLSERVICE=ZENDSVR6
  -- so on --

License: 
  BSD (LICENSE)
  -- or --
  http://yips.idevcloud.com/wiki/index.php/XMLService/LicenseXMLService

Links:
  https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM%20i%20Technology%20Updates/page/Python


class iBase


    IBM i XMLSERVICE call addable operation(s).

      Args:
        iopt (dict): user options (see descendents)
        idft (dict): default options (see descendents)

      Example:
        itransport = iLibCall()
        itool = iToolKit()
        itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
        itool.add(iSh('ps', 'ps -ef'))
        ... so on ...
        itool.call(itransport)

      Returns:
        iBase (obj)

      Notes:
        iopt  (dict): XMLSERVICE elements, attributes and values
                      'k' - element <x>
                      'v' - value <x>value</x>
                      'i' - attribute <x var='ikey'>
                      'c' - iBase children
                      ... many more idft + iopt ...
                      'error' - <x 'error'='fast'>


    def __init__(self, iopt={}, idft={}):


    def add(self, obj):
        Additional mini dom xml child nodes.

        Args:
          obj (iBase) : additional child object 

        Example:
          itool = iToolKit()
          itool.add(
            iPgm('zzcall','ZZCALL')             <--- child of iToolkit
            .addParm(iData('INCHARA','1a','a')) <--- child of iPgm 
            )

        Returns:
          (void)


    def xml_in(self):
        Return XML string of collected mini dom xml child nodes.

        Args:
          none

        Returns:
          XML (str)


    def make(self):
        Assemble coherent mini dom xml, including child nodes.

        Args:
          none

        Returns:
          xml.dom.minidom (obj)

class iCmd(iBase)


    IBM i XMLSERVICE call *CMD not returning *OUTPUT.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      icmd  (str): IBM i command no output (see 5250 command prompt).
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'}   : optional - XMLSERVICE error choice {'error':'fast'}
        {'exec':cmd|system|rexx'} : optional - XMLSERVICE command execute choice {'exec':'cmd'}
                                                              RTVJOBA CCSID(?N)      {'exec':'rex'}
    Example:
      iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)')
      iCmd('rtvjoba', 'RTVJOBA CCSID(?N) OUTQ(?)')

    Returns:
      iCmd (obj)

    Notes:
      Special commands returning output parameters are allowed.
       (?)  - indicate string return
       (?N) - indicate numeric return

      <cmd [exec='cmd|system|rexx'                        (default exec='cmd')
            hex='on' before='cc1/cc2/cc3/cc4' after='cc4/cc3/cc2/cc1'  (1.6.8)
            error='on|off|fast'                                        (1.7.6)
            ]>IBM i command</cmd>


    def __init__(self, ikey, icmd, iopt={}):

class iSh(iBase)


    IBM i XMLSERVICE call PASE utilities.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      icmd  (str): IBM i PASE script/utility (see call qp2term).
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'}  : optional - XMLSERVICE error choice {'error':'fast'}
        {'row':'on|off'}         : optional - XMLSERVICE <row>line output</row> choice {'row':'off'}

    Example:
      iSh('ls /home/xml/master | grep -i xml')

    Returns:
      iSh (obj)

    Notes:
      XMLSERVICE perfoms standard PASE shell popen calls,
      therefore, additional job will be forked,
      utilities will be exec'd, and stdout will
      be collected to be returned.

      Please note, this is a relatively slow operation,
      use sparingly on high volume web sites.   

      <sh [rows='on|off' 
           hex='on' before='cc1/cc2/cc3/cc4' after='cc4/cc3/cc2/cc1' (1.7.4)
           error='on|off|fast'                                       (1.7.6)
           ]>(PASE utility)</sh>


    def __init__(self, ikey, icmd, iopt={}):

class iCmd5250(iSh)


    IBM i XMLSERVICE call 5250 *CMD returning *OUTPUT.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      icmd  (str): IBM i PASE script/utility (see call qp2term).
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'}  : optional - XMLSERVICE error choice {'error':'fast'}
        {'row':'on|off'}         : optional - XMLSERVICE <row>line output</row> choice {'row':'off'}

    Example:
      iCmd5250('dsplibl','dsplibl')
      iCmd5250('wrkactjob','wrkactjob')

    Returns:
      iCmd5250 (obj)

    Notes:
      This is a subclass of iSh, therefore XMLSERVICE perfoms 
      standard PASE shell popen fork/exec calls.

      /QOpenSys/usr/bin/system 'wrkactjob'

      Please note, this is a relatively slow operation,
      use sparingly on high volume web sites.   

      <sh [rows='on|off' 
           hex='on' before='cc1/cc2/cc3/cc4' after='cc4/cc3/cc2/cc1' (1.7.4)
           error='on|off|fast'                                       (1.7.6)
           ]>(PASE utility)</sh>


    def __init__(self, ikey, icmd, iopt={}):

class iPgm (iBase)


    IBM i XMLSERVICE call *PGM.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      iname (str): IBM i *PGM or *SRVPGM name
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'func':'MYFUNC'}       : optional - IBM i *SRVPGM function export.
        {'lib':'mylib'}         : optional - IBM i library name
        {'mode':'opm|ile'}      : optional - XMLSERVICE error choice {'mode':'ile'} 

    Example:
     iPgm('zzcall','ZZCALL')
     .addParm(iData('var1','1a','a'))
     .addParm(iData('var2','1a','b'))
     .addParm(iData('var3','7p4','32.1234'))
     .addParm(iData('var4','12p2','33.33'))
     .addParm(
      iDS('var5')
      .addData(iData('d5var1','1a','a'))
      .addData(iData('d5var2','1a','b'))
      .addData(iData('d5var3','7p4','32.1234'))
      .addData(iData('d5var4','12p2','33.33'))
      )

    Returns:
      iPgm (obj)

    Notes:
      pgm:
        <pgm name='' 
          [lib='' 
           func='' 
           mode='opm|ile' 
           error='on|off|fast'                        (1.7.6)
           ]> ... </pgm>


    def __init__(self, ikey, iname, iopt={}):


    def addParm(self, obj):
        Add a parameter child node.

        Args:
          obj   (obj): iData object or iDs object.

        Returns:
          (void)

class iSrvPgm (iPgm)


    IBM i XMLSERVICE call *SRVPGM.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      iname (str): IBM i *PGM or *SRVPGM name
      ifunc (str): IBM i *SRVPGM function export.
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'lib':'mylib'}         : optional - IBM i library name
        {'mode':'opm|ile'}      : optional - XMLSERVICE error choice {'mode':'ile'} 

    Example:
      see iPgm

    Returns:
      iSrvPgm (obj)

    Notes:
      pgm:
        <pgm name='' 
          [lib='' 
           func='' 
           mode='opm|ile' 
           error='on|off|fast'                        (1.7.6)
           ]> ... </pgm>


    def __init__(self, ikey, iname, ifunc, iopt={}):


    def addRet(self, obj):
        Add a return structure child node.

        Args:
          obj   (obj): iData object or iDs object.

        Returns:
          (void)

class iParm (iBase)


    Parameter child node for iPgm or iSrvPgm (see iPgm.addParm)

    Args:
      ikey  (str): ikey  (str): XML <parm ... var="ikey"> for parsing output.
      iopt (dict): option - dictionay of options (below)
        {'io':'in|out|both|omit'} : optional - XMLSERVICE param type {'io':both'}.

    Example:
      see iPgm

    Returns:
      iParm (obj)

    Notes:
      This class is not used directly, but is used by iPgm.addParm
      or iSrvPgm.addParm.

      pgm parameters:
        <pgm>
        <parm [io='in|out|both|omit'                  (omit 1.2.3)
               by='val|ref'
               ]>(see <ds> and <data>)</parm>
        </pgm>


    def __init__(self, ikey, iopt={}):

class iRet (iBase)


    Return structure child node for iSrvPgm (see iSrvPgm.addRet)

    Args:
      ikey  (str): XML <return ... var="ikey"> for parsing output.

    Example:
      see iPgm

    Returns:
      iRet (obj)

    Notes:
      This class is not used directly, but is used by iSrvPgm.addRet.

      pgm return:
        <pgm>
        <return>(see <ds> and <data>)</return>
        </pgm>


    def __init__(self, ikey):

class iDS (iBase)


    Data structure child node for iPgm, iSrvPgm,
    or nested iDS data structures.

    Args:
      ikey  (str): XML <ds ... var="ikey"> for parsing output.
      iopt (dict): option - dictionay of options (below)
        {'dim':'n'}     : optional - XMLSERVICE dimension/occurs number.
        {'dou':'label'} : optional - XMLSERVICE do until label.
        {'len':'label'} : optional - XMLSERVICE calc length label.

    Example:
      see iPgm

    Returns:
      iDS (obj)

    Notes:
      pgm data structure:
        <ds [dim='n' dou='label'
             len='label'                                 (1.5.4) 
             data='records'                              (1.7.5)
             ]>(see <data>)</ds>


    def __init__(self, ikey, iopt={}):


    def addData(self, obj):
        Add a iData or iDS child node.

        Args:
          obj   (obj): iData object or iDs object.

        Returns:
          (void)

class iData (iBase)


    Data value child node for iPgm, iSrvPgm,
    or iDS data structures.

    Args:
      ikey  (str): XML <data ... var="ikey"> for parsing output.
      itype (obj): data type [see XMLSERVICE types, '3i0', ...].
      ival  (obj): data type value.
      iopt (dict): option - dictionay of options (below)
        {'dim':'n'}               : optional - XMLSERVICE dimension/occurs number.
        {'varying':'on|off|2|4'}  : optional - XMLSERVICE varying {'varying':'off'}.
        {'hex':'on|off'}          : optional - XMLSERVICE hex chracter data {'hex':'off'}.
        {'enddo':'label'}         : optional - XMLSERVICE enddo until label.
        {'setlen':'label'}        : optional - XMLSERVICE set calc length label.
        {'offset':'n'}            : optional - XMLSERVICE offset label.
        {'next':'label'}          : optional - XMLSERVICE next offset label (value).

    Example:
      see iPgm

    Returns:
      iData (obj)

    Notes:
      pgm data elements:
        <data type='data types' 
           [dim='n' 
            varying='on|off|2|4' 
            enddo='label' 
            setlen='label'                                                (1.5.4)
            offset='label'
            hex='on|off' before='cc1/cc2/cc3/cc4' after='cc4/cc3/cc2/cc1' (1.6.8)
            trim='on|off'                                                 (1.7.1)
            next='nextoff'                                                (1.9.2)
            ]>(value)</data>

      C types          RPG types                     XMLSERVICE types                                   SQL types
      ===============  ============================  ================================================   =========
      int8/byte        D myint8    3i 0              <data type='3i0'/>                                 TINYINT   (unsupported DB2)
      int16/short      D myint16   5i 0 (4b 0)       <data type='5i0'/>                                 SMALLINT
      int32/int        D myint32  10i 0 (9b 0)       <data type='10i0'/>                                INTEGER
      int64/longlong   D myint64  20i 0              <data type='20i0'/>                                BIGINT
      uint8/ubyte      D myuint8   3u 0              <data type='3u0'/>
      uint16/ushort    D myuint16  5u 0              <data type='5u0'/>
      uint32/uint      D myuint32 10u 0              <data type='10u0'/>
      uint64/ulonglong D myuint64 20u 0              <data type='20u0'/>
      char             D mychar   32a                <data type='32a'/>                                 CHAR(32)
      varchar2         D myvchar2 32a   varying      <data type='32a' varying='on'/>                    VARCHAR(32)
      varchar4         D myvchar4 32a   varying(4)   <data type='32a' varying='4'/>
      packed           D mydec    12p 2              <data type='12p2'/>                                DECIMAL(12,2)
      zoned            D myzone   12s 2              <data type='12s2'/>                                NUMERIC(12,2)
      float            D myfloat   4f                <data type='4f2'/>                                 FLOAT
      real/double      D myreal    8f                <data type='8f4'/>                                 REAL
      binary           D mybin    (any)              <data type='9b'>F1F2F3</data>                      BINARY
      hole (no out)    D myhole   (any)              <data type='40h'/>
      boolean          D mybool    1n                <data type='4a'/>                                  CHAR(4)
      time             D mytime     T   timfmt(*iso) <data type='8A'>09.45.29</data>                    TIME
      timestamp        D mystamp    Z                <data type='26A'>2011-12-29-12.45.29.000000</data> TIMESTAMP
      date             D mydate     D   datfmt(*iso) <data type='10A'>2009-05-11</data>                 DATE


    def __init__(self, ikey, itype, ival, iopt={}):

class iSqlQuery (iBase)


    IBM i XMLSERVICE call DB2 execute direct SQL statment.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      isql  (str): IBM i query (see 5250 strsql).
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'conn':'label'}        : optional - XMLSERVICE connection label
        {'stmt':'label'}        : optional - XMLSERVICE stmt label
        {'options':'label'}     : optional - XMLSERVICE options label

    Example:
      iSqlQuery('custquery', "select * from QIWS.QCUSTCDT where LSTNAM='Jones' or LSTNAM='Vine'")
      iSqlFetch('custfetch')

    Returns:
      iSqlQuery (obj)

    Notes:
      <sql><query [conn='label' stmt='label' options='label' error='on|off|fast']></sql>


    def __init__(self, ikey, isql, iopt={}):

class iSqlPrepare (iBase)


    IBM i XMLSERVICE call DB2 prepare SQL statment.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      isql  (str): IBM i query (see 5250 strsql).
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'conn':'label'}        : optional - XMLSERVICE connection label
        {'stmt':'label'}        : optional - XMLSERVICE stmt label
        {'options':'label'}     : optional - XMLSERVICE options label

    Example:
      iSqlPrepare('callprep', "call mylib/mycall(?,?,?)")
      iSqlExecute('callexec')
       .addParm(iSqlParm('var1','a'))
       .addParm(iSqlParm('var2','b'))
       .addParm(iSqlParm('var3','32.1234'))
      iSqlFetch('callfetch')
      iSqlFree('alldone')

    Returns:
      iSqlPrepare (obj)

    Notes:
      <sql><prepare [conn='label' stmt='label' options='label' error='on|off|fast']></sql>


    def __init__(self, ikey, isql, iopt={}):

class iSqlExecute (iBase)


    IBM i XMLSERVICE call execute a DB2 prepare SQL statment.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'conn':'label'}        : optional - XMLSERVICE connection label
        {'stmt':'label'}        : optional - XMLSERVICE stmt label
        {'options':'label'}     : optional - XMLSERVICE options label

    Example:
      see iSqlPrepare

    Returns:
      iSqlExecute (obj)

    Notes:
      <sql><execute [stmt='label'  error='on|off|fast']></sql>


    def __init__(self, ikey, iopt={}):


    def addParm(self, obj):
        Add a iSqlParm child node.

        Args:
          obj   (obj): iSqlParm object.

        Returns:
          (void)

class iSqlFetch (iBase)


    IBM i XMLSERVICE call DB2 fetch results/rows of SQL statment.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'stmt':'label'}        : optional - XMLSERVICE stmt label
        {'block':'all|n'}       : optional - XMLSERVICE block records {'block':'all'}
        {'desc':'on|off'}       : optional - XMLSERVICE block records {'desc':'on'}
        {'rec':'n'}             : optional - XMLSERVICE block records

    Example:
      see iSqlPrepare or iSqlQuery

    Returns:
      none

    Notes:
      <sql>
      <fetch [stmt='label' block='all|n' rec='n' desc='on|off' error="on|off|fast"/>
                          (default=all)         (default=on)  (default='off')
      </sql>


    def __init__(self, ikey, iopt={}):

class iSqlParm (iBase)


    Parameter child node for iSqlExecute (see iSqlExecute.addParm)

    Args:
      ikey  (str): XML <parm ... var="ikey"> for parsing output.
      ival  (str): data value.
      iopt (dict): option - dictionay of options (below)
        {'io':'in|out|both|omit'} : optional - XMLSERVICE param type {'io':both'}.

    Example:
      see iSqlPrepare

    Returns:
      iSqlParm (obj)

    Notes:
      This class is not used directly, but is used by iSqlExecute.addParm.

      <sql>
      <execute>
      <parm [io='in|out|both']>val</parm>
      </execute>
      <sql>


    def __init__(self, ikey, ival, iopt={}):

class iSqlFree (iBase)


    IBM i XMLSERVICE call DB2 free open handles.

    Args:
      ikey  (str): XML <ikey>...operation ...</ikey> for parsing output.
      iopt (dict): option - dictionay of options (below)
        {'error':'on|off|fast'} : optional - XMLSERVICE error choice {'error':'fast'}
        {'conn':'all|label'}    : optional - XMLSERVICE free connection label
        {'cstmt':'label'}       : optional - XMLSERVICE free connection label statements
        {'stmt':'all|label'}    : optional - XMLSERVICE free stmt label
        {'options':'all|label'} : optional - XMLSERVICE free options label

    Example:
      see iSqlPrepare

    Returns:
      iSqlFree (obj)

    Notes:
      <sql>
      <free [conn='all|label' 
        cstmt='label' 
        stmt='all|label' 
        options='all|label' 
        error='on|off|fast']/>
      </sql>


    def __init__(self, ikey, iopt={}):

class iXml(iBase)


    IBM i XMLSERVICE raw xml input.

    Args:
      ixml  (str): custom XML for XMLSERVICE operation.

    Example:
      iXml("<cmd>CHGLIBL LIBL(XMLSERVICE)</cmd>")
      iXml("<sh>ls /tmp</sh>")

    Returns:
      iXml (obj)

    Notes:
      Not commonly used, but ok when other classes fall short.


    def __init__(self, ixml):


    def add(self, obj):
        add input not allowed.

        Returns:
          raise except


    def make(self):
        Assemble coherent mini dom xml.

        Args:
          none

        Returns:
          xml.dom.minidom (obj)

class iToolKit


    Main iToolKit XMLSERVICE collector and output parser. 

    Args:
      iparm (num): include xml node parm output (0-no, 1-yes).
      iret  (num): include xml node return output (0-no, 1-yes).
      ids   (num): include xml node ds output (0-no, 1-yes).
      irow  (num): include xml node row output (0-no, 1-yes).

    Returns:
      iToolKit (obj)


    def __init__(self, iparm=0, iret=0, ids=1, irow=1):


    def clear(self):
        Clear collecting child objects.

        Args:
          none

        Returns:
          (void)

        Notes:
          <?xml version='1.0'?>
          <xmlservice>


    def add(self, obj):
        Add additional child object.

        Args:
          none

        Returns:
          none

        Notes:
          <?xml version='1.0'?>
          <xmlservice>


    def xml_in(self):
        return raw xml input.

        Args:
          none

        Returns:
          xml


    def xml_out(self):
        return raw xml output.

        Args:
          none

        Returns:
          xml


    def list_out(self,ikey=-1):
        return list output.

        Args:
          ikey  (num): select list from index [[0],[1],,,,].

        Returns:
          list [value]


    def dict_out(self,ikey=0):
        return dict output.

        Args:
          ikey  (str): select 'key' from {'key':'value'}.

        Returns:
          dict {'key':'value'}


    def hybrid_out(self,ikey=0):
        return hybrid output.

        Args:
          ikey  (str): select 'key' from {'key':'value'}.

        Returns:
          hybrid {key:{'data':[list]}}


    def trace_open(self,iname='*terminal'):
        Open trace *terminal or file /tmp/python_toolkit_(iname).log (1.2+)

        Args:
          iname  (str): trace *terminal or file /tmp/python_toolkit_(iname).log

        Returns:
          (void)


    def trace_write(self,itext):
        Write trace text (1.2+)

        Args:
          itext  (str): trace text

        Returns:
          (void)


    def trace_hexdump(self,itext):
        Write trace hexdump (1.2+)
        Args:
          itext  (str): trace text
        Returns:
          (void)


    def trace_close(self):
        End trace (1.2+)

        Args:
          none

        Returns:
          (void)


    def call(self, itrans):
        Call xmlservice with accumulated input XML.

        Args:
          itrans (obj): XMLSERVICE transport (iRestCall, iDB2Call, etc.)

        Returns:
          none


    def _dom_out(self):
        return xmlservice dom output.

        Args:
          none

        Returns:
          xml.dom


    def _parseXmlList(self, parent, values):
        return dict output.

        Args:
          parent (obj): parent xml.dom
          values (obj): accumulate list []

        Returns:
          list [value]


    def _parseXmlDict(self, parent, values):
        return dict output.

        Args:
          parent (obj): parent xml.dom
          values (obj): accumulate dict{}

        Returns:
          dict {'key':'value'}


    def _parseXmlHybrid(self, parent, values):
        return dict output.

        Args:
          parent (obj): parent xml.dom
          values (obj): accumulate hybrid{}

        Returns:
          hybrid {key:{'data':[list]}}

class iDB2Call


    Transport XMLSERVICE calls over DB2 connection.

    Args:
      iuid   (str): Database user profile name or database connection
      ipwd   (str): optional - Database user profile password
                               -- or --
                               env var PASSWORD (export PASSWORD=mypass) 
      idb2   (str): optional - Database (WRKRDBDIRE *LOCAL)
      ictl   (str): optional - XMLSERVICE control ['*here','*sbmjob'] 
      ipc    (str): optional - XMLSERVICE xToolkit job route for *sbmjob ['/tmp/myunique42'] 
      isiz   (int): optional - XMLSERVICE expected max XML output size, required for DB2 
      ilib   (str): optional - XMLSERVICE library compiled (default QXMLSERV)

    Example:
      from itoolkit.db2.idb2call import *
      itransport = iDB2Call(user,password)
      -- or --
      conn = ibm_db.connect(database, user, password)
      itransport = iDB2Call(conn)

    Returns:
       (obj)


    def __init__(self, iuid, ipwd=0, idb2=0, ictl=0, ipc=0, isiz=0, ilib=0):


    def trace_data(self):
        Return trace driver data.

        Args:
          none

        Returns:
          initialization data


    def call(self, itool):
        Call xmlservice with accumulated input XML.

        Args:
          itool  - iToolkit object

        Returns:
          xml

class iLibCall


    Transport XMLSERVICE direct job call (within job/process calls).

    Args:
      ictl   (str): optional - XMLSERVICE control ['*here','*sbmjob'] 
      ipc    (str): optional - XMLSERVICE xToolkit job route for *sbmjob ['/tmp/myunique42'] 
      iccsid (int): optional - XMLSERVICE EBCDIC CCSID [0,37,...] 0 = default jobccsid (1.2+)
      pccsid (int): optional - XMLSERVICE ASCII CCSID [0,1208, ...] 0 = default 1208 (1.2+)

    Returns:
      none


    def __init__(self, ictl=0, ipc=0, iccsid=0, pccsid=0):


    def trace_data(self):
        Return trace driver data.

        Args:
          none

        Returns:
          initialization data


    def call(self, itool):
        Call xmlservice with accumulated input XML.

        Args:
          itool  - iToolkit object

        Returns:
          xml

class iRestCall


    Transport XMLSERVICE calls over standard HTTP rest.

    Args:
      iurl   (str): XMLSERVICE url (https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm).
      iuid   (str): Database user profile name
      ipwd   (str): optional - Database user profile password
                               -- or --
                               env var PASSWORD (export PASSWORD=mypass) 
      idb2   (str): optional - Database (WRKRDBDIRE *LOCAL)
      ictl   (str): optional - XMLSERVICE control ['*here','*sbmjob'] 
      ipc    (str): optional - XMLSERVICE xToolkit job route for *sbmjob ['/tmp/myunique42'] 
      isiz   (str): optional - XMLSERVICE expected max XML output size, required for DB2 

    Example:
      from itoolkit.rest.irestcall import *
      itransport = iRestCall(url,user,password)

    Returns:
      none


    def __init__(self, iurl, iuid, ipwd=0, idb2=0, ictl=0, ipc=0, isiz=0):


    def trace_data(self):
        Return trace driver data.

        Args:
          none

        Returns:
          initialization data


    def call(self, itool):
        Call xmlservice with accumulated input XML.

        Args:
          itool  - iToolkit object

        Returns:
          xml

itoolkit/sample/config.py

"""
Configure:
  Requires XMSLERVICE library installed, see following link installation 
  http://yips.idevcloud.com/wiki/index.php/XMLService/XMLSERVICE

Transports:
  1) XMLSERVICE direct call (current job)
  from itoolkit.lib.ilibcall import *
  itransport = iLibCall()

  2) XMLSERVICE db2 call (QSQSRVR job)
  from itoolkit.db2.idb2call import *
  itransport = iDB2Call(config.user,config.password)
  -- or --
  conn = ibm_db.connect(database, user, password)
  itransport = iDB2Call(conn)

  3) XMLSERVICE http/rest/web call (Apache job)
  from itoolkit.rest.irestcall import *
  itransport = iRestCall(url, user, password)
"""
from itoolkit.lib.ilibcall import *
itransport = iLibCall()
# itransport = iLibCall("*here *cdata *debug") # i will stop, inquiry message qsysopr


itoolkit/sample/icmd5250_dspsyssts.py

#                                                                         Bottom
# Type command, press Enter.
# ===> dspsyssts                                                                 
#                             Display System Status                     LP0364D
#                                                             06/22/15  15:22:28
# % CPU used . . . . . . . :         .1    Auxiliary storage:
# Elapsed time . . . . . . :   00:00:01      System ASP . . . . . . :    176.2 G
# Jobs in system . . . . . :        428      % system ASP used  . . :    75.6481
import config
from itoolkit import *

itool = iToolKit()
itool.add(iCmd5250('dspsyssts', 'dspsyssts'))

# xmlservice
itool.call(config.itransport)

# output
dspsyssts = itool.dict_out('dspsyssts')
if 'error' in dspsyssts:
  print (dspsyssts['error'])
  exit()
else:
  print (dspsyssts['dspsyssts'])


itoolkit/sample/icmd_rtvjoba.py

# RTVJOBA can't issue from command line,
# but works with itoolkit
import config
from itoolkit import *

# modify iToolKit not include row node
itool = iToolKit(iparm=0, iret=0, ids=1, irow=0)
itool.add(iCmd('rtvjoba', 'RTVJOBA USRLIBL(?) SYSLIBL(?) CCSID(?N) OUTQ(?)'))

# xmlservice
itool.call(config.itransport)

# output
rtvjoba = itool.dict_out('rtvjoba')
print (rtvjoba)
if 'error' in rtvjoba:
  print (rtvjoba['error'])
  exit()
else:
  print('USRLIBL = ' + rtvjoba['USRLIBL'])
  print('SYSLIBL = ' + rtvjoba['SYSLIBL'])
  print('CCSID   = ' + rtvjoba['CCSID'])
  print('OUTQ    = ' + rtvjoba['OUTQ'])


itoolkit/sample/ipase_ps.py

# > ps -ef
#      UID   PID  PPID   C    STIME    TTY  TIME CMD
#  qsecofr    12    11   0   May 08      -  8:33 /QOpenSys/QIBM/ProdData/JavaVM/jdk60/32bit/jre/lib/ppc/jvmStartPase 566 
# qtmhhttp    31     1   0   May 08      -  0:00 /usr/local/zendsvr/bin/watchdog -c /usr/local/zendsvr/etc/watchdog-monitor.ini -s monitor 
import config
from itoolkit import *

itool = iToolKit()
itool.add(iSh('ps', 'ps -ef'))

# xmlservice
itool.call(config.itransport)

# output
ps = itool.dict_out('ps')
if 'error' in ps:
  print (ps['error'])
  exit()
else:
  print (ps['ps'])


itoolkit/sample/ipgm_bad_trace_db2.py

from itoolkit import *
from itoolkit.db2.idb2call import *

itransport = iDB2Call('adc') # export PASSWORD=mypass

itool = iToolKit()
itool.add(
 iPgm('zzcall','ZZCALLNOT')
 .addParm(iData('INCHARA','1a','a'))
 )

# xmlservice write trace log to *terminal
itool.trace_open()
itool.call(itransport)
itool.trace_close()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/ipgm_bad_trace_file.py

import config
from itoolkit import *
itool = iToolKit()
itool.add(
 iPgm('zzcall','ZZCALLNOT')
 .addParm(iData('INCHARA','1a','a'))
 )

# xmlservice write trace log to /tmp/python_toolkit_(tonyfile).log
itool.trace_open('tonyfile')
itool.call(config.itransport)
itool.trace_close()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/ipgm_bad_trace_rest.py

from itoolkit.rest.irestcall import *
from itoolkit import *

itransport = iRestCall('http://yips.idevcloud.com/cgi-bin/xmlcgi.pgm','*NONE','*NONE')

itool = iToolKit()
itool.add(
 iPgm('zzcall','ZZCALLNOT')
 .addParm(iData('INCHARA','1a','a'))
 )

# xmlservice write trace log to *terminal
itool.trace_open()
itool.call(itransport)
itool.trace_close()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/ipgm_bad_trace_terminal.py

import config
from itoolkit import *
itool = iToolKit()
itool.add(
 iPgm('zzcall','ZZCALLNOT')
 .addParm(iData('INCHARA','1a','a'))
 )

# xmlservice write trace log to *terminal
itool.trace_open()
itool.call(config.itransport)
itool.trace_close()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/ipgm_zzcall.py

import config
from itoolkit import *
# XMLSERVICE/ZZCALL:
#     D  INCHARA        S              1a
#     D  INCHARB        S              1a
#     D  INDEC1         S              7p 4        
#     D  INDEC2         S             12p 2
#     D  INDS1          DS                  
#     D   DSCHARA                      1a
#     D   DSCHARB                      1a           
#     D   DSDEC1                       7p 4      
#     D   DSDEC2                      12p 2            
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#      * main(): Control flow
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#     C     *Entry        PLIST                   
#     C                   PARM                    INCHARA
#     C                   PARM                    INCHARB
#     C                   PARM                    INDEC1
#     C                   PARM                    INDEC2
#     C                   PARM                    INDS1
itool = iToolKit()
itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
itool.add(
 iPgm('zzcall','ZZCALL')
 .addParm(iData('INCHARA','1a','a'))
 .addParm(iData('INCHARB','1a','b'))
 .addParm(iData('INDEC1','7p4','32.1234'))
 .addParm(iData('INDEC2','12p2','33.33'))
 .addParm(
  iDS('INDS1')
  .addData(iData('DSCHARA','1a','a'))
  .addData(iData('DSCHARB','1a','b'))
  .addData(iData('DSDEC1','7p4','32.1234'))
  .addData(iData('DSDEC2','12p2','33.33'))
  )
 )

# xmlservice
itool.call(config.itransport)

# output
chglibl = itool.dict_out('chglibl')
if 'success' in chglibl:
  print (chglibl['success'])
else:
  print (chglibl['error'])
  exit()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
  print ("    INCHARA      : " + zzcall['INCHARA'])
  print ("    INCHARB      : " + zzcall['INCHARB'])
  print ("    INDEC1       : " + zzcall['INDEC1'])
  print ("    INDEC2       : " + zzcall['INDEC2'])
  print ("    INDS1.DSCHARA: " + zzcall['INDS1']['DSCHARA'])
  print ("    INDS1.DSCHARB: " + zzcall['INDS1']['DSCHARB'])
  print ("    INDS1.DSDEC1 : " + zzcall['INDS1']['DSDEC1'])
  print ("    INDS1.DSDEC2 : " + zzcall['INDS1']['DSDEC2'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/isleep_rest_async.py

try:
  import queue
except ImportError:
  import Queue as queue
import threading
import urllib
from itoolkit.rest.irestcall import *
from itoolkit import *
class iShSleep():
  def __init__(self, icmd):
      self.itran = iRestCall('http://yips.idevcloud.com/cgi-bin/xmlcgi.pgm','*NONE','*NONE')
      self.itool = iToolKit()
      self.itool.add(iSh('igo',icmd))
  def go(self):
      self.itool.call(self.itran)
      return self.itool.dict_out('igo')
def get_url(q, icmd):
    q.put(iShSleep(icmd).go())
theshs = ["echo 'thing 1==>';date;sleep 10;date", 
          "echo 'thing 2==>';date;sleep 5;date"]
q = queue.Queue()
for u in theshs:
    t = threading.Thread(target=get_url, args = (q,u))
    t.daemon = True
    t.start()
# q.join()
for u in theshs:
    s = q.get()
    print(s)


itoolkit/sample/isql_callproc.py

import config
from itoolkit import *

itool = iToolKit(iparm=1)
sql  = "DROP PROCEDURE XMLSERVICE/FLUBBER\n"
itool.add(iSqlQuery('crt', sql))
itool.add(iSqlFree('free0'))
sql = "CREATE PROCEDURE XMLSERVICE/FLUBBER(IN first_name VARCHAR(128), INOUT any_name VARCHAR(128))\n"
sql += "LANGUAGE SQL\n"
sql += "BEGIN\n"
sql += "SET any_name = 'Flubber';\n"
sql += "END\n"
itool.add(iSqlQuery('crt', sql))
itool.add(iSqlFree('free1'))
itool.add(iSqlPrepare('callflubber', "call XMLSERVICE/FLUBBER(?,?)"))
itool.add(
 iSqlExecute('exec')
 .addParm(iSqlParm('myin','Jones'))
 .addParm(iSqlParm('myout','jjjjjjjjjjjjjjjjjjjjjuuuuuuuuuuuuuuuunnnnnnnnnkkkkkkkkkkkk'))
)
itool.add(iSqlFree('free2'))
# print(itool.xml_in())
# exit()

# xmlservice
itool.call(config.itransport)
# print(itool.xml_out())

# output
FLUBBER = itool.dict_out('exec')
if 'error' in FLUBBER:
  print (FLUBBER['error'])
  exit()
else:
  print ('myout = ' + FLUBBER['myout']['data'])


itoolkit/sample/isql_prepare.py

# strsql
#
# ===> select * from QIWS/QCUSTCDT where LSTNAM='Jones' or LSTNAM='Vine'
#   
#                                  Display Data    
#                                              Data width . . . . . . :     102
# Position to line  . . . . .              Shift to column  . . . . . .        
# ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....
#  CUSNUM   LSTNAM    INIT  STREET         CITY    STATE  ZIPCOD   CDTLMT   CHGCO
# 839,283   Jones     B D   21B NW 135 St  Clay     NY    13,041      400      1
# 392,859   Vine      S S   PO Box 79      Broton   VT     5,046      700      1
# ********  End of data  ********
import config
from itoolkit import *

itool = iToolKit()
itool.add(iSqlPrepare('cust2prep', "select * from QIWS/QCUSTCDT where LSTNAM=? or LSTNAM=?"))
itool.add(
 iSqlExecute('cust2exec')
 .addParm(iSqlParm('pm1','Jones'))
 .addParm(iSqlParm('pm2','Vine'))
)
itool.add(iSqlFetch('cust2fetch'))
itool.add(iSqlFree('cust2free'))

# xmlservice
itool.call(config.itransport)

# output
QCUSTCDT = itool.dict_out('cust2fetch')
# print(QCUSTCDT)
if 'error' in QCUSTCDT:
  print (QCUSTCDT['error'])
  exit()
else:
  for row in QCUSTCDT['row']:
    print('row:')
    print(' CDTDUE :' + row['CDTDUE'])
    print(' CDTLMT :' + row['CDTLMT'])
    print(' CUSNUM :' + row['CUSNUM'])
    print(' CHGCOD :' + row['CHGCOD'])
    print(' STREET :' + row['STREET'])
    print(' INIT   :' + row['INIT'])
    print(' BALDUE :' + row['BALDUE'])
    print(' LSTNAM :' + row['LSTNAM'])
    print(' ZIPCOD :' + row['ZIPCOD'])
    print(' CITY   :' + row['CITY'])
    print(' STATE  :' + row['STATE'])


itoolkit/sample/isql_query.py

# strsql
#
# ===> select * from QIWS/QCUSTCDT where LSTNAM='Jones' or LSTNAM='Vine'
#   
#                                  Display Data    
#                                              Data width . . . . . . :     102
# Position to line  . . . . .              Shift to column  . . . . . .        
# ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....
#  CUSNUM   LSTNAM    INIT  STREET         CITY    STATE  ZIPCOD   CDTLMT   CHGCO
# 839,283   Jones     B D   21B NW 135 St  Clay     NY    13,041      400      1
# 392,859   Vine      S S   PO Box 79      Broton   VT     5,046      700      1
# ********  End of data  ********
import config
from itoolkit import *

itool = iToolKit()
itool.add(iSqlQuery('custquery', "select * from QIWS/QCUSTCDT where LSTNAM='Jones' or LSTNAM='Vine'"))
itool.add(iSqlFetch('custfetch'))
itool.add(iSqlFree('custfree'))

# xmlservice
itool.call(config.itransport)

# output
QCUSTCDT = itool.dict_out('custfetch')
# print(QCUSTCDT)
if 'error' in QCUSTCDT:
  print (QCUSTCDT['error'])
  exit()
else:
  for row in QCUSTCDT['row']:
    print('row:')
    print(' CDTDUE :' + row['CDTDUE'])
    print(' CDTLMT :' + row['CDTLMT'])
    print(' CUSNUM :' + row['CUSNUM'])
    print(' CHGCOD :' + row['CHGCOD'])
    print(' STREET :' + row['STREET'])
    print(' INIT   :' + row['INIT'])
    print(' BALDUE :' + row['BALDUE'])
    print(' LSTNAM :' + row['LSTNAM'])
    print(' ZIPCOD :' + row['ZIPCOD'])
    print(' CITY   :' + row['CITY'])
    print(' STATE  :' + row['STATE'])


itoolkit/sample/isql_rest_async.py

try:
  import queue
except ImportError:
  import Queue as queue
import threading
import urllib
from itoolkit.rest.irestcall import *
from itoolkit import *
class iDB2Async():
  def __init__(self, isql):
      self.itran = iRestCall('http://yips.idevcloud.com/cgi-bin/xmlcgi.pgm','*NONE','*NONE')
      self.itool = iToolKit()
      self.itool.add(iSqlQuery('iqry', isql))
      self.itool.add(iSqlFetch('ifch'))
      self.itool.add(iSqlFree('ifre'))
  def go(self):
      self.itool.call(self.itran)
      return self.itool.dict_out('ifch')
def get_url(q, icmd):
    q.put(iDB2Async(icmd).go())
thedb2s = ["select CUSNUM from QIWS/QCUSTCDT where LSTNAM='Jones'", 
          "select CUSNUM from QIWS/QCUSTCDT where LSTNAM='Johnson'"]
q = queue.Queue()
for u in thedb2s:
    t = threading.Thread(target=get_url, args = (q,u))
    t.daemon = True
    t.start()
# q.join()
for u in thedb2s:
    s = q.get()
    print(s)


itoolkit/sample/isrvpgm_qgyrhrl.py

import config
from itoolkit import *
# Retrieve Hardware Resource List (QGYRHRL, QgyRtvHdwRscList) API
# Service Program: QGYRHR
# Default Public Authority: *USE
# Threadsafe: No
# Required Parameter Group:
#  Output Char(*)..............Receiver variable (RHRL0100, RHRL0110)
#  Input Binary(4).............Length of receiver variable
#  Input Char(8)...............Format name
#  Input Binary(4).............Resource category (see hardware resource category)
#  I/O Char(*).................Error code
# RHRL0100 Format
#  BINARY(4)...................Bytes returned
#  BINARY(4)...................Bytes available
#  BINARY(4)...................Number of resources returned
#  BINARY(4)...................Length of resource entry
#  CHAR(*).....................Resource entries
#  These fields repeat for each resource.
#  BINARY(4)...................Resource category
#  BINARY(4)...................Family level
#  BINARY(4)...................Line type
#  CHAR(10)....................Resource name
#  CHAR(4).....................Type number
#  CHAR(3).....................Model number
#  CHAR(1).....................Status
#  CHAR(8).....................System to which adapter is connected
#  CHAR(12)....................Adapter address
#  CHAR(50)....................Description
#  CHAR(24)....................Resource kind (liar, liar, pants on fire ... binary, not char)
#  hardware resource category:
#  1  All hardware resources (does not include local area network resources)
#  2  Communication resources
#  3  Local work station resources
#  4  Processor resources
#  5  Storage device resources
#  6  Coupled system adapter resources
#  7  Local area network resources
#  8  Cryptographic resources
#  9  Tape and optical resources
#  10 Tape resources
#  11 Optical resources
itool = iToolKit()
itool.add(
 iSrvPgm('qgyrhr','QGYRHR','QgyRtvHdwRscList')
 .addParm(
  iDS('RHRL0100_t',{'len':'rhrlen'})
  .addData(iData('rhrRet','10i0',''))
  .addData(iData('rhrAvl','10i0',''))
  .addData(iData('rhrNbr','10i0','',{'enddo':'mycnt'}))
  .addData(iData('rhrLen','10i0',''))
  .addData(iDS('res_t',{'dim':'999','dou':'mycnt'})
           .addData(iData('resCat','10i0',''))
           .addData(iData('resLvl','10i0',''))
           .addData(iData('resLin','10i0',''))
           .addData(iData('resNam','10a',''))
           .addData(iData('resTyp','4a',''))
           .addData(iData('resMod','3a',''))
           .addData(iData('resSts','1a',''))
           .addData(iData('resSys','8a',''))
           .addData(iData('resAdp','12a',''))
           .addData(iData('resDsc','50a',''))
           .addData(iData('resKnd','24b',''))
           )
 )
 .addParm(iData('rcvlen','10i0','',{'setlen':'rhrlen'}))
 .addParm(iData('fmtnam','10a','RHRL0100'))
 .addParm(iData('rescat','10i0','3')) #  3  Local work station resources
 .addParm(
  iDS('ERRC0100_t',{'len':'errlen'})
  .addData(iData('errRet','10i0',''))
  .addData(iData('errAvl','10i0',''))
  .addData(iData('errExp','7A','',{'setlen':'errlen'}))
  .addData(iData('errRsv','1A',''))
 )
)
# xmlservice
itool.call(config.itransport)
#output
qgyrhr = itool.dict_out('qgyrhr')
if 'success' in qgyrhr:
  print (qgyrhr['success'])
  print ("    Length of receiver variable......" + qgyrhr['rcvlen'])
  print ("    Format name......................" + qgyrhr['fmtnam'])
  print ("    Resource category................" + qgyrhr['rescat'])
  RHRL0100_t = qgyrhr['RHRL0100_t']
  print ('    RHRL0100_t:')
  print ("      Bytes returned................." + RHRL0100_t['rhrRet'])
  print ("      Bytes available................" + RHRL0100_t['rhrAvl'])
  print ("      Number of resources returned..." + RHRL0100_t['rhrNbr'])
  print ("      Length of resource entry......." + RHRL0100_t['rhrLen'])
  if int(RHRL0100_t['rhrNbr']) > 0:
    res_t = RHRL0100_t['res_t']
    for rec in res_t:
      print ("        --------------------------------------------------------")
      keys = rec.keys()
      print ("        Resource category............" + rec['resCat'])
      print ("        Family level................." + rec['resLvl'])
      print ("        Line type...................." + rec['resLin'])
      print ("        Resource name................" + rec['resNam'])
      print ("        Type number.................." + rec['resTyp'])
      print ("        Model number................." + rec['resMod'])
      print ("        Status......................." + rec['resSts'])
      print ("        System adapter connected....." + rec['resSys'])
      print ("        Adapter address.............." + rec['resAdp'])
      print ("        Description.................." + rec['resDsc'])
      print ("        Resource kind................" + rec['resKnd'])
else:
  print (qgyrhr['error'])
  exit()




itoolkit/sample/isrvpgm_zzarray.py

import config
from itoolkit import *
#     D ARRAYMAX        c                   const(999)
#     D dcRec_t         ds                  qualified based(Template)
#     D  dcMyName                     10A
#     D  dcMyJob                    4096A
#     D  dcMyRank                     10i 0
#     D  dcMyPay                      12p 2
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#      * zzarray: check return array aggregate 
#      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#     P zzarray         B                   export
#     D zzarray         PI                  likeds(dcRec_t) dim(ARRAYMAX)
#     D  myName                       10A
#     D  myMax                        10i 0
#     D  myCount                      10i 0
itool = iToolKit()
itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
itool.add(
 iSrvPgm('zzarray','ZZSRV','ZZARRAY')
 .addParm(iData('myName','10a','ranger'))
 .addParm(iData('myMax','10i0','8'))
 .addParm(iData('myCount','10i0','',{'enddo':'mycnt'}))
 .addRet(
  iDS('dcRec_t',{'dim':'999','dou':'mycnt'})
  .addData(iData('dcMyName','10a',''))
  .addData(iData('dcMyJob','4096a',''))
  .addData(iData('dcMyRank','10i0',''))
  .addData(iData('dcMyPay','12p2',''))
  )
 )

# xmlservice
itool.call(config.itransport)

# output
# print(itool.xml_out())
chglibl = itool.dict_out('chglibl')
if 'success' in chglibl:
  print (chglibl['success'])
else:
  print (chglibl['error'])
  exit()

zzarray = itool.dict_out('zzarray')
# print(zzarray)
if 'success' in zzarray:
  print (zzarray['success'])
  print ("    myName       : " + zzarray['myName'])
  print ("    myMax        : " + zzarray['myMax'])
  print ("    myCount      : " + zzarray['myCount'])
  dcRec_t = zzarray['dcRec_t']
  for rec in dcRec_t:
    print ('    dcRec_t:')
    print ("      dcMyName : " + rec['dcMyName'])
    print ("      dcMyJob  : " + rec['dcMyJob'])
    print ("      dcMyRank : " + rec['dcMyRank'])
    print ("      dcMyPay  : " + rec['dcMyPay'])
else:
  print (zzarray['error'])
  exit()



itoolkit/sample/istop_msg_qsysopr_before_pgm_call.py

from itoolkit import *
from itoolkit.lib.ilibcall import *

print("********************")
print("********************")
print("Hey user,")
print("Using '*debug' transport parameter allows debug halt before run.")
print ("\n  itransport = iLibCall('*here *debug')\n")
print("Expect qsysopr inquire message, you must answer to continue script.")
print("You may attach a debugger before you answer the inquiry.")
print("\n  dspmsg qsysopr\n")
print("  Reply inquiry message any character.")
print("    From  . . . :   ADC            06/25/15   14:08:07")
print("    Debug client 362262/QSECOFR/QP0ZSPWP")
print("      Reply . . :   c\n")
print("Script continues to run after answer (call PGM, etc.)")
print("********************")
print("********************")

itransport = iLibCall("*here *debug") # i will stop, inquiry message qsysopr
itool = iToolKit()
itool.add(iCmd('chglibl', 'CHGLIBL LIBL(XMLSERVICE)'))
itool.add(
 iPgm('zzcall','ZZCALL')
 .addParm(iData('INCHARA','1a','a'))
 .addParm(iData('INCHARB','1a','b'))
 .addParm(iData('INDEC1','7p4','32.1234'))
 .addParm(iData('INDEC2','12p2','33.33'))
 .addParm(
  iDS('INDS1')
  .addData(iData('DSCHARA','1a','a'))
  .addData(iData('DSCHARB','1a','b'))
  .addData(iData('DSDEC1','7p4','32.1234'))
  .addData(iData('DSDEC2','12p2','33.33'))
  )
 )

# xmlservice
itool.call(itransport)

# output
chglibl = itool.dict_out('chglibl')
if 'success' in chglibl:
  print (chglibl['success'])
else:
  print (chglibl['error'])
  exit()

zzcall = itool.dict_out('zzcall')
if 'success' in zzcall:
  print (zzcall['success'])
  print ("    INCHARA      : " + zzcall['INCHARA'])
  print ("    INCHARB      : " + zzcall['INCHARB'])
  print ("    INDEC1       : " + zzcall['INDEC1'])
  print ("    INDEC2       : " + zzcall['INDEC2'])
  print ("    INDS1.DSCHARA: " + zzcall['INDS1']['DSCHARA'])
  print ("    INDS1.DSCHARB: " + zzcall['INDS1']['DSCHARB'])
  print ("    INDS1.DSDEC1 : " + zzcall['INDS1']['DSDEC1'])
  print ("    INDS1.DSDEC2 : " + zzcall['INDS1']['DSDEC2'])
else:
  print (zzcall['error'])
  exit()



itoolkit/sample/ixml_diag.py

import config
from itoolkit import *

# from itoolkit.lib.ilibcall import *
# itransport = iLibCall("*here *debug") # i will stop, inquiry message qsysopr

itool = iToolKit()
itool.add(iCmd('chglibl2', 'CHGLIBL LIBL(QTEMP XMLSERVICE)'))
itool.add(iCmd('chglibl3', 'CHGLIBL LIBL(SOMEBAD42)'))
myxml  = "<diag/>"
itool.add(iXml(myxml))

print(itool.xml_in())


# xmlservice
itool.call(config.itransport)
# itool.call(itransport)

# output
print(itool.xml_out())
diag = itool.dict_out()
if 'version' in diag: 
  print ("version   : "+diag['version'])
print ("job       : "+diag['jobnbr']+'/'+diag['jobuser']+'/'+diag['jobname'])
print ("jobipc    : "+diag['jobipc'])
print ("curuser   : "+diag['curuser'])
print ("ccsid     : "+diag['ccsid'])
print ("dftccsid  : "+diag['dftccsid'])
print ("paseccsid : "+diag['paseccsid'])
print ("syslibl   : "+diag['syslibl'])
print ("usrlibl   : "+diag['usrlibl'])
joblog = diag['joblog'].replace("\n"," ")
cpflist = ""
for word in joblog.split(' '):
  if word[:3] == 'CPF' or word[:3] == 'MCH':
    cpflist += word + " "
    if diag['jobcpf'] == "":
       diag['jobcpf'] = word
print ("jobcpf    : "+diag['jobcpf'] + " ( " + cpflist + ")")
print ("joblog    :\n" + diag['joblog'])


itoolkit/sample/ixml_zzvary.py

import config
from itoolkit import *
# XMLSERVICE/ZZSRV.ZZVARY:
#     P zzvary          B                   export
#     D zzvary          PI            20A   varying
#     D  myName                       10A   varying
itool = iToolKit()
itool.add(iXml("<cmd var='chglibl'>CHGLIBL LIBL(XMLSERVICE)</cmd>"))
myxml  = "<pgm name='ZZSRV' func='ZZVARY' var='zzvary'>"
myxml += "<parm io='in'>"
myxml += "<data var='myName' type='10A' varying='on'><![CDATA[<Ranger>]]></data>"
myxml += "</parm>"
myxml += "<return>"
myxml += "<data var='myNameis' type='20A' varying='on'><![CDATA[<Mud>]]></data>"
myxml += "</return>"
myxml += "</pgm>"
itool.add(iXml(myxml))

# xmlservice
itool.call(config.itransport)

# output
chglibl = itool.dict_out('chglibl')
if 'success' in chglibl:
  print (chglibl['success'])
else:
  print (chglibl['error'])
  exit()

zzvary = itool.dict_out('zzvary')
if 'success' in zzvary:
  print (zzvary['success'])
  # print ("    myName       : " + zzvary['myName']) ... input only, no output
  print ("    myNameis     : " + zzvary['myNameis'])
else:
  print (zzvary['error'])
  exit()