User Tools

Site Tools


Sidebar

Table Of Contents

endurox-python:v8.0.x:guides:getting_started_tutorial

Enduro/X Python Getting Started Tutorial

Enduro/X Python Getting Started Tutorial


1. About the guide

This document guides users on how to quickly start using Enduro/X for Python3 module. It contains step-by-step actions that need to be taken to write and start the basic XATMI server and client process.

2. Operating System configuration

Certain operating system configuration is required to get Enduro/X running, see Enduro/X Administration Manual, Setup System section, the steps are crucial to be executed for the chosen operating system before continuing.

3. Preparing the Python 3 installation

After the system configuration is done, Enduro/X and Python packages can be installed. This document assumes that your operating system has already Python version 3.6 or later installed. If not, follow the standard installation procedure for CPython.

3.1. Installing a binary version of Enduro/X Python module

Binary wheel release can be downloaded from https://www.mavimax.com/downloads Mavimax provides binary builds for selected operating systems. The Python Wheel release files are packaged in ZIP files which are labeled according to the release platform. ZIP file which contains the original WHL file. Example of the ZIP file name: "endurox-python-8.0.1-1.solaris11_cp36m.x86_64.whl.zip".

The name encodes the following data:

  • endurox-python-<version>-<release>.<os_ver>_<py_abi>.<arch>.whl.zip

To install wheel release on the target operating system use the following commands:

$ unzip <package_name>.whl.zip

$ pip3 install *.whl --user

3.2. Installing Enduro/X Python module from sources

To install the module from source code, the following dependencies must be installed in the system:

  • CMake build system
  • PKG Config
  • C++ 11 capable compiler

When dependencies are met, download the source distribution from https://www.mavimax.com/downloads

$ tar -xzvf endurox-<version>.tar.gz

$ cd endurox-<version>

$ python3 ./setup.py install --user

or

$ pip3 install . --user

Note, that if the installation process fails, see the troubleshooting section of the module_developer_guide(guides).

4. Configuring the application environment

This tutorial will prepare "python-app" application. It will be prepared from the new unix user "user1". Application (Enduro/X instance) will be located in /opt/app-python folder.

To create creating base environment, Enduro/X "provision" tool is used. This generates the base layout of the application.

# sudo -s
# useradd -m user1
# mkdir -p /opt/app-python
# chown user1 /opt/app-python
# su - user1
$ bash
$ cd /opt/app-python
$ xadmin provision -d \
    -v qprefix=setapppy \
    -v addubf=test.fd
....
Provision succeed!

The above script uses defaults, and for some parameters, values are specified:

Table 1. Parameters applied to provision script above

ParameterValue appliedDescription

qprefix

app-python

Application prefix

addubf

test.fd

Additional Key-value field table/UBF field to be configured, used by sample later


The final directory structure built for the application is:

  • /opt/app-python/conf - will contain configuration files.
  • /opt/app-python/conf/setapppy - environment configuration file.
  • /opt/app-python/conf/ndrxconfig.xml - XATMI server process configuration file.
  • /opt/app-python/conf/app.ini - application settings.
  • /opt/app-python/bin - for executables / Python scripts.
  • /opt/app-python/ubftab - for tables for field definitions.
  • /opt/app-python/tmp - temp dir
  • /opt/app-python/log - for logging
  • /opt/app-python/test - test data
  • /opt/tmlogs/rm1 - transaction manager log files (used for persistent queue space)

The initial configuration file can be found in /opt/app-python/conf/ndrxconfig.xml. Let’s register our Python XATMI server named testsv.py here first. Do this in <servers/> section add following <server /> block in the file:

<?xml version="1.0" ?>
<endurox>
...
        </defaults>
        <servers>
...
        <server name="testsv.py">
            <min>1</min>
            <max>1</max>
            <srvid>200</srvid>
            <sysopt>-e ${NDRX_ULOG}/testsv.log -r</sysopt>
        </server>
...
        </servers>
</endurox>

Also we are about to add logging settings for Python scripts, add following lines to the [@debug] section in application ini file (/opt/app-python/conf/app.ini):

[@debug]
..
python3= ndrx=2 ubf=0 tp=5 file=

[@debug/PYCLT]
python3= file=${NDRX_ULOG}/testcl.log

This makes any Python3 script to log to stderr. The testsv.py will log The other option is to use tplogconfig(3) during the process init phase to select required logfile name. Or use NDRX_CCTAG env variable for process to specify sub-section of the @debug section.

5. Adding source code

This tutorial will use Enduro/X built-in feature of generating the source code. Generators can create simple XATMI client/server processes. In this example, the client process makes request to "TESTSV" service with one field in UBF buffer (T_STRING_FLD) and the server provides the original value back in T_STRING_2_FLD field.

The development process will be following:

  • Define UBF tables
  • Create Python server process
  • Create Python client process

5.1. Define UBF tables

Enduro/X Exfields table in folder /opt/app-python/ubftab is already added by the provision command. In this folder, we will add an additional test.fd (already included in configuration).

$ cd /opt/app-python/ubftab

$ xadmin gen ubf tab  -d -vgenmake=n
Enduro/X 8.0.6, build Jun 15 2022 00:45:31, using epoll for LINUX (64 bits)

Enduro/X Middleware Platform for Distributed Transaction Processing
Copyright (C) 2009-2016 ATR Baltic Ltd.
Copyright (C) 2017-2022 Mavimax Ltd. All Rights Reserved.

This software is released under one of the following licenses:
AGPLv3 (exceptions for Java, Go, Python) or Mavimax license for commercial use.

Logging to ./ULOG.20220619

*** Review & edit configuration ***

 0: Edit table_name   :UBF Table name (.fd will be added) [test]:
 1: Edit base_number  :Base number [6000]:
 2: Edit testfields   :Add test fields [y]:
 3: Edit genexfields  :Gen Exfields [y]:
 4: Edit genmake      :Gen makefile [n]:
Gen ok!

5.2. Define Python ATMI server process

Let’s generate a simple Python server process that provides some fields in response to the service calls. We will do this by using Enduro/X generators:

$ cd /opt/app-python/bin

$ xadmin gen python server -d
Enduro/X 8.0.6, build Jun 15 2022 00:45:31, using epoll for LINUX (64 bits)

Enduro/X Middleware Platform for Distributed Transaction Processing
Copyright (C) 2009-2016 ATR Baltic Ltd.
Copyright (C) 2017-2022 Mavimax Ltd. All Rights Reserved.

This software is released under one of the following licenses:
AGPLv3 (exceptions for Java, Go, Python) or Mavimax license for commercial use.

 0: svname       :XATMI Server Name (script) [testsv]:
 1: svcname      :Service name [TESTSV]:
 2: useubf       :Use UBF? [y]:
 3: config       :INI File section (optional, will read config if set) []:

*** Review & edit configuration ***

 0: Edit svname       :XATMI Server Name (script) [testsv]:
 1: Edit svcname      :Service name [TESTSV]:
 2: Edit useubf       :Use UBF? [y]:
 3: Edit config       :INI File section (optional, will read config if set) []:
c: Cancel
w: Accept, write
Enter the choice [0-3, c, w]: w
Python server gen ok!

The source code for basic Python XATMI server is quite simple, Check the testsv.py:

#!/usr/bin/env python3

import sys
import endurox as e

class Server:

    def tpsvrinit(self, args):
        e.tplog_info("Doing server init...");
        e.tpadvertise("TESTSV", "TESTSV", self.TESTSV)
        return 0

    def tpsvrdone(self):
        e.log_info("Server shutdown")

    def TESTSV(self, args):
        e.tplogprintubf(e.log_info, "Incoming request:", args.data)
        args.data["data"]["T_STRING_2_FLD"]="Hello World from XATMI server"
        return e.tpreturn(e.TPSUCCESS, 0, args.data)

if __name__ == "__main__":
    e.tprun(Server(), sys.argv)

This is a basic XATMI single-threaded server. The tpsvrinit() advertises service "TESTSV". Method tpsvrdone() is called during XATMI server shutdown.

5.3. Define Python client process

Client process in the same way as server process for demo purposes will be generated by Enduro/X generator.

$ cd /opt/app-python/bin

$ xadmin gen python client
Enduro/X 8.0.6, build Jun 15 2022 00:45:31, using epoll for LINUX (64 bits)

Enduro/X Middleware Platform for Distributed Transaction Processing
Copyright (C) 2009-2016 ATR Baltic Ltd.
Copyright (C) 2017-2022 Mavimax Ltd. All Rights Reserved.

This software is released under one of the following licenses:
AGPLv3 (exceptions for Java, Go, Python) or Mavimax license for commercial use.

 0: cltname      :XATMI Client Name (script) [testcl]:
 1: useubf       :Use UBF? [y]:
 2: config       :INI File section (optional, will read config if set) []:

*** Review & edit configuration ***

 0: Edit cltname      :XATMI Client Name (script) [testcl]:
 1: Edit useubf       :Use UBF? [y]:
 2: Edit config       :INI File section (optional, will read config if set) []:
c: Cancel
w: Accept, write
Enter the choice [0-2, c, w]: w
Python client gen ok!

For the generator, the defaults are used, but you may choose your own identifiers as well. The simple Python XATMI client process looks like this (testcl.py):

#!/usr/bin/env python3

import sys
import endurox as e

def run():

    # Do some work here

    buf = dict()
    buf["data"] = dict()
    buf["data"]["T_STRING_FLD"] = "Hello world!"

    tperrno, tpurcode, buf = e.tpcall("TESTSV", buf)

    if 0!=tperrno:
        e.tplog_error("Failed to get configuration: %d" % tperrno)
        raise AtmiExcept(e.TPESVCFAIL, "Failed to call TESTSV")

    e.tplogprintubf(e.log_info, "Got server reply", buf);

def appinit():
    e.tplog_info("Doing client init...");
    e.tpinit()

def unInit():
    e.tpterm()

if __name__ == '__main__':
    try:
        appinit()
        run()
        unInit()
    except Exception as ee:
        e.tplog_error("Exception: %s occurred: %s" % (ee.__class__, str(ee)))

Generate source is a simple XATMI client process that prepares the key/value UBF buffer (dictionary), adds data to it and performs call to service.

6. Running the example

After this, we are ready to boot up the application, thus load the environment and start-up.

$ cd /opt/app-python/conf

$ . setapppy

$ xadmin start -y
Enduro/X 8.0.6, build Jun 15 2022 00:45:31, using epoll for LINUX (64 bits)

Enduro/X Middleware Platform for Distributed Transaction Processing
Copyright (C) 2009-2016 ATR Baltic Ltd.
Copyright (C) 2017-2022 Mavimax Ltd. All Rights Reserved.

This software is released under one of the following licenses:
AGPLv3 (exceptions for Java, Go, Python) or Mavimax license for commercial use.

* Shared resources opened...
* Enduro/X back-end (ndrxd) is not running
* ndrxd PID (from PID file): 277319
* ndrxd idle instance started.
exec cconfsrv -k 0myWI5nu -i 1 -e /opt/app-python/log/cconfsrv.log -r --  :
        process id=277325 ... Started.
exec cconfsrv -k 0myWI5nu -i 2 -e /opt/app-python/log/cconfsrv.log -r --  :
        process id=277326 ... Started.
exec tpadmsv -k 0myWI5nu -i 10 -e /opt/app-python/log/tpadmsv.log -r --  :
        process id=277327 ... Started.
exec tpadmsv -k 0myWI5nu -i 11 -e /opt/app-python/log/tpadmsv.log -r --  :
        process id=277328 ... Started.
exec tpevsrv -k 0myWI5nu -i 20 -e /opt/app-python/log/tpevsrv.log -r --  :
        process id=277329 ... Started.
exec tmsrv -k 0myWI5nu -i 40 -e /opt/app-python/log/tmsrv-rm1.log -r -- -t1 -l/opt/app-python/tmlogs/rm1 --  :
        process id=277330 ... Started.
exec tmsrv -k 0myWI5nu -i 41 -e /opt/app-python/log/tmsrv-rm1.log -r -- -t1 -l/opt/app-python/tmlogs/rm1 --  :
        process id=277342 ... Started.
exec tmsrv -k 0myWI5nu -i 42 -e /opt/app-python/log/tmsrv-rm1.log -r -- -t1 -l/opt/app-python/tmlogs/rm1 --  :
        process id=277354 ... Started.
exec tmqueue -k 0myWI5nu -i 60 -e /opt/app-python/log/tmqueue-rm1.log -r -- -s1 --  :
        process id=277366 ... Started.
exec tpbridge -k 0myWI5nu -i 150 -e /opt/app-python/log/tpbridge_2.log -r -- -f -n2 -r -i 127.0.0.1 -p 21003 -tA -z30 :
        process id=277399 ... Started.
exec testsv.py -k 0myWI5nu -i 200 -e /opt/app-python/log/testsv.log -r --  :
        process id=277406 ... Started.
exec tmrecoversv -k 0myWI5nu -i 9900 -e /opt/app-python/log/tmrecoversv.log --  --  :
        process id=277407 ... Started.
exec cpmsrv -k 0myWI5nu -i 9999 -e /opt/app-python/log/cpmsrv.log -r -- -k3 -i1 --  :
        process id=277408 ... Started.
Startup finished. 13 processes started.

As it could be seen Python server process testsv.py is booted. Let’s check services:

$ xadmin psc

Nd Service Name Routine Name Prog Name SRVID #SUCC #FAIL      MAX     LAST STAT
-- ------------ ------------ --------- ----- ----- ----- -------- -------- -----
 1 @CCONF       CCONF        cconfsrv      1     0     0      0ms      0ms AVAIL
 1 @CCONF       CCONF        cconfsrv      2     0     0      0ms      0ms AVAIL
 1 .TMIB        MIB          tpadmsv      10     0     0      0ms      0ms AVAIL
 1 .TMIB-1-10   MIB          tpadmsv      10     0     0      0ms      0ms AVAIL
 1 .TMIB-1      MIB          tpadmsv      10     0     0      0ms      0ms AVAIL
 1 .TMIB        MIB          tpadmsv      11     0     0      0ms      0ms AVAIL
 1 .TMIB-1-11   MIB          tpadmsv      11     0     0      0ms      0ms AVAIL
 1 .TMIB-1      MIB          tpadmsv      11     0     0      0ms      0ms AVAIL
 1 @TPEVSUBS001 TPEVSUBS     tpevsrv      20     0     0      0ms      0ms AVAIL
 1 @TPEVUNSUBS+ TPEVUNSUBS   tpevsrv      20     0     0      0ms      0ms AVAIL
 1 @TPEVPOST001 TPEVPOST     tpevsrv      20     0     0      0ms      0ms AVAIL
 1 @TPEVDOPOST+ TPEVDOPOST   tpevsrv      20     0     0      0ms      0ms AVAIL
 1 @TM-1        TPTMSRV      tmsrv        40     1     0      0ms      0ms AVAIL
 1 @TM-1-1      TPTMSRV      tmsrv        40     0     0      0ms      0ms AVAIL
 1 @TM-1-1-40   TPTMSRV      tmsrv        40     0     0      0ms      0ms AVAIL
 1 @TM-1        TPTMSRV      tmsrv        41     0     0      0ms      0ms AVAIL
 1 @TM-1-1      TPTMSRV      tmsrv        41     0     0      0ms      0ms AVAIL
 1 @TM-1-1-41   TPTMSRV      tmsrv        41     0     0      0ms      0ms AVAIL
 1 @TM-1        TPTMSRV      tmsrv        42     0     0      0ms      0ms AVAIL
 1 @TM-1-1      TPTMSRV      tmsrv        42     0     0      0ms      0ms AVAIL
 1 @TM-1-1-42   TPTMSRV      tmsrv        42     0     0      0ms      0ms AVAIL
 1 @TMQ-1-60    TMQUEUE      tmqueue      60     0     0      0ms      0ms AVAIL
 1 @QSPSAMPLES+ TMQUEUE      tmqueue      60     0     0      0ms      0ms AVAIL
 1 @TPBRIDGE002 TPBRIDGE     tpbridge    150     0     0      0ms      0ms AVAIL
 1 TESTSV       TESTSV       testsv.py   200     0     0      0ms      0ms AVAIL
 1 @CPMSVC      CPMSVC       cpmsrv     9999     0     0      0ms      0ms AVAIL

Script instance 200 provides TESTSV service. Now lets perform the test by calling the Python client process:

$ cd /opt/app-python/bin

$ ./testcl.py
t:USER:4:c9e5ad48:278711:7fde17b4e740:000:20220619:172802477430:tplog       :/tplog.c:0582:Doing client init...
t:USER:4:c9e5ad48:278711:7fde17b4e740:001:20220619:172802478349:plogprintubf:bf/ubf.c:1790:Got server reply
T_STRING_FLD    Hello world!
T_STRING_2_FLD  Hello World from XATMI server


-- To redirect client process output, CCTAG may be used:

$ NDRX_CCTAG="PYCLT" ./testcl.py

$ cat ${NDRX_ULOG}/testscl.log
t:USER:4:c9e5ad48:281668:7f64e79f7740:000:20220619:173453057883:tplog       :/tplog.c:0582:Doing client init...
t:USER:4:c9e5ad48:281668:7f64e79f7740:001:20220619:173453058520:plogprintubf:bf/ubf.c:1790:Got server reply
T_STRING_FLD    Hello world!
T_STRING_2_FLD  Hello World from XATMI server

7. Conclusions

In the end, we see that it is quite simple to create XATMI Python client and server processes. The good thing is that this API is consistent with Go, Java, and C/C++ languages. Any of these four programming languages can be mixed into a single high-performance application solution.

This tutorial shows only the basic features of the Enduro/X. There is more to study as async calls, tpforward(3), persistent queues, events, distributed transactions and more. For full API consult the Enduro/X API Pydoc pages at https://www.endurox.org/dokuwiki Also, unit tests can give a clue for the full functionality use (at https://github.com/endurox-dev/endurox-python/tree/master/tests).