Skip to Content
Technical Articles
Author's profile photo Stefan Schnell

How To Use Python via External OS Commands and Embed the Scripts Seamlessly

It is not very exciting to bind an external command via TAC SM69 on an SAP system. It is also not very exciting to use the external command via the function module SXPG_COMMAND_EXECUTE. But it is interesting to combine different possibilities in this context.

The external OS command is a scripting language, in my case Python. After the configuration of the TAC SM69 we set with the TAC FILE a logical and physical path to the target directory where the Python files should be stored on the application server. And now we can use this customizing in a function module, which reads the Python script from an ABAP include, stores, executes and delete it.

  1. Customizing in TAC SM69
    /wp-content/uploads/2016/02/005_884423.jpg
  2. Customizing in TAC FILE (logical and physical path)
    /wp-content/uploads/2016/02/003_884424.jpg
    /wp-content/uploads/2016/02/004_884425.jpg
  3. Now we store the Python script as include.
    /wp-content/uploads/2016/02/006_884429.jpg

    # -*- coding: iso-8859-15 -*-
    #-Begin-----------------------------------------------------------------
    
    #-Imports---------------------------------------------------------------
    import platform, struct
    
    #-Sub Main--------------------------------------------------------------
    def main():
      print("Hello World from Python", platform.python_version(), "on",
        platform.system(), "(" + platform.architecture()[0] + ")")
    
    #-Main------------------------------------------------------------------
    if __name__ == "__main__":
      main()
    
    #-End-------------------------------------------------------------------
    
  4. Now we can use the Python script from the include and the Python interpreter from the external command to executes the script and to use the result in our ABAP environment,
    Function ZEXECUTEPYTHONSCRIPT.
    *"----------------------------------------------------------------------
    *"*"Lokale Schnittstelle:
    *"  IMPORTING
    *"     VALUE(I_INCLNAME) TYPE  SOBJ_NAME
    *"     VALUE(I_FILENAME) TYPE  STRING
    *"  EXPORTING
    *"     VALUE(E_EXECPROT) TYPE  Z_TAB_BTCXPGLOG
    *"  EXCEPTIONS
    *"      NO_FILE_NAME
    *"      NO_INCLUDE_AVAILABLE
    *"      CAN_NOT_WRITE_SCRIPT
    *"      ERROR_IN_SCRIPT_EXECUTION
    *"      CAN_NOT_DELETE_SCRIPT
    *"----------------------------------------------------------------------
    
      "-Variables-----------------------------------------------------------
        Data lv_FileName(255) Type c.
        Data lv_TADIR Type TADIR.
        Data lt_Incl Type Table Of String.
        Data lv_lineIncl Type String.
        Data lv_strIncl Type String.
        Data lv_Status Type EXTCMDEXEX-STATUS.
        Data lv_ExitCode Type EXTCMDEXEX-EXITCODE.
    
      "-Main----------------------------------------------------------------
    
        "-Gets directory path-----------------------------------------------
          Call Function 'FILE_GET_NAME'
            Exporting
              CLIENT = sy-mandt
              LOGICAL_FILENAME = 'ZPYTHON'
              OPERATING_SYSTEM = sy-opsys
              PARAMETER_1  = i_FileName
              ELEMINATE_BLANKS = 'X'
            Importing
              FILE_NAME = lv_FileName
            Exceptions
              FILE_NOT_FOUND   = 1
              Others           = 2.
          If sy-subrc <> 0.
            Raise NO_FILE_NAME.
          EndIf.
    
        "-Gets script content-----------------------------------------------
          Select Single * From TADIR Into lv_TADIR
            Where OBJ_NAME = i_InclName.
          If sy-subrc = 0.
            Read Report i_InclName Into lt_Incl.
            If sy-subrc = 0.
              Loop At lt_Incl Into lv_lineIncl.
                lv_strIncl = lv_strIncl && lv_lineIncl &&
                  cl_abap_char_utilities=>cr_lf.
              EndLoop.
            EndIf.
          Else.
            Raise NO_INCLUDE_AVAILABLE.
          EndIf.
    
        "-Writes script-----------------------------------------------------
          Open Dataset lv_FileName For Output In Text Mode
            Encoding Non-Unicode With Windows Linefeed.
          If sy-subrc = 0.
            Transfer lv_strIncl To lv_FileName.
            Close Dataset lv_FileName.
          Else.
            Raise CAN_NOT_WRITE_SCRIPT.
          EndIf.
    
        "-Executes script---------------------------------------------------
          Call Function 'SXPG_STEP_COMMAND_START'
            Exporting
              COMMANDNAME = 'ZPYTHON'
              ADDITIONAL_PARAMETERS = lv_FileName
              OPERATINGSYSTEM = sy-opsys
              STDINCNTL = 'R'
              STDOUTCNTL = 'M'
              STDERRCNTL = 'M'
              TRACECNTL = '0'
              TERMCNTL = 'C'
            Tables
              LOG = e_ExecProt
            Exceptions
              COMMAND_NOT_FOUND = 1
              PARAMETER_EXPECTED = 2
              PARAMETERS_TOO_LONG = 3
              SECURITY_RISK = 4
              WRONG_CHECK_CALL_INTERFACE = 5
              NO_PERMISSION = 6
              UNKNOWN_ERROR = 7
              COMMUNICATION_ERROR = 8
              SYSTEM_ERROR = 9
              CANNOT_GET_RFC_DESTS = 10
              JOB_UPDATE_FAILED = 11
              JOB_DOES_NOT_EXIST = 12
              PROGRAM_START_ERROR = 13
              Others = 14.
            If sy-subrc <> 0.
              Raise ERROR_IN_SCRIPT_EXECUTION.
            EndIf.
    
        "-Deletes script----------------------------------------------------
          Delete Dataset lv_FileName.
          If sy-subrc <> 0.
            Raise CAN_NOT_DELETE_SCRIPT.
          EndIf.
    
    EndFunction.
    

    /wp-content/uploads/2016/02/001_884430.jpg
    /wp-content/uploads/2016/02/002_884431.jpg
    Hint: In this case I use the same method as the program SAPLSXPT. In a normal case you should use the function module SXPG_COMMAND_EXECUTE.

The tiny idea behind this method is that is not necessary to store the script files permanently on the file system of your application server. You can save it as includes in your ABAP environment and transfer it on demand, if you need it.

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Tanaya Sachin Amdekar
      Tanaya Sachin Amdekar

      Hi Stefan,

      Thanks for sharing this blog. When I was working with Python 2 years back, I used to store python script on application server and had maintenance issues. Your solution looks better 🙂 !

      Regards,

      Tanaya

       

      Author's profile photo Sweta Gohil
      Sweta Gohil

      Hi Stefan,

      Can you please let us know in above example SAP is installed in Windows OS or UNIX OS?

      I have scenario where I want to access python from ABAP where SAP installed on UNIX OS.

      Thanks & Regards,

      Sweta Gohil.