Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member182779
Active Contributor
6,847

A couple of days back srdjan.boskovic wrote a blog called Python / ABAP Stack. This for sure, bring me back memories as I already played a lot with sapnwrfc from piers.harding

After downloading the sapnwrfc2 package from the PyRFC project’s website and some email exchanges with Srdjan and jonas.kunze I was able to set up and start working with it.

(Actually, the problem were not related to installing the connector itself, which was really easy, but more related to the nwrfcsdk as I have the 64bit version on my Windows 7 laptop and I needed the 32 bits for the connector...in the end, I used my VMWare Windows XP to get rid of any possible conflicts).

You may ask...why another Python to SAP connector? Simply, while Pier's one is awesome, it lacked some features that SAP needed for internal development, so this guys take the hard work of making from the scratch exactly what they needed...one of the beauties of being a developer...you can grab an idea...a turn it into a full blown application or RFC connector in this case...

As a way to introduce PyRFC, the best example is always showing something with the flights tables...which are always present in every ERP installation and as I have it used before on SAP HANA and Python? Yes Sir!, Bottle seemed to be a good option...because you don't want to see more command line screen, don't you?

I will show the code first and the I will tell you about some of the most significant changes that I can see from using PyRFC (And by the way...I fight myself to make my example better and have some error handling, which is always good, even for humble blogs like this one).

Bottle_PyRFC.py

from bottle import get, post, request, run, redirect

from sapnwrfc2 import Connection, ABAPApplicationError, LogonError

from ConfigParser import ConfigParser

conn = ""

@get('/login')

def login_form():

    return '''<DIV ALIGN='CENTER'><BR><BR><BR><BR>

                <H1>Python (Bottle) & SAP - using PyRFC</H1>

                <BR><TABLE BORDER='1' BORDERCOLOR='BLUE'

                     BGCOLOR='WHITE'>

                <FORM METHOD='POST'>

                <TR><TD>User</TD><TD>

                <INPUT TYPE='TEXT' NAME='User'></TD></TR>

                <TR><TD>Password</TD>

                <TD><INPUT TYPE='PASSWORD' NAME='Passwd'></TD></TR>

                <TR><TD COLSPAN='2' ALIGN='CENTER'>

                <INPUT TYPE='SUBMIT' value='Log In' NAME='LOG_IN'>

                <INPUT TYPE='RESET' value='Clear'></TD></TR>

                </FORM>

                <TABLE>

              </DIV>'''

@post('/login')

def login_submit():

    global conn

    try:

        user = request.forms.get('User')

        passwd = request.forms.get('Passwd')

        config = ConfigParser()

        config.read('sapnwrfc.cfg')

        params_connection = config._sections['connection']

        params_connection["user"] = user

        params_connection["passwd"] = passwd

        conn = Connection(**params_connection)

        redirect("/choose")

    except LogonError:

        redirect("/error")

@get('/choose')

def choose_table():

    return '''<CENTER>

                <FORM METHOD='POST'>

                <INPUT TYPE='TEXT' NAME='Table'><BR>

                <INPUT TYPE='SUBMIT' value='Show Table'

                 NAME='Show_Table'>

                </FORM>

              </CENTER>'''

@get('/error')

def error():

    output = "<div align='center'><h1>Invalid username or password</h1></div>"

    return output

@post('/choose')

def show_table():

    global conn

    fields = []

    fields_name = []

    counter = 0

    table = request.forms.get('Table')

    try:

        tables = conn.call("RFC_READ_TABLE", QUERY_TABLE=table, DELIMITER='|')

        data_fields = tables["DATA"]

        data_names = tables["FIELDS"]

        long_fields = len(data_fields)

        long_names = len(data_names)

        for line in range(0, long_fields):

            fields.append(data_fields[line]["WA"].strip())

        for line in range(0, long_names):

            fields_name.append(data_names[line]["FIELDNAME"].strip())

         output = "<div align='center'><h1>%s</h1></center>" % table

        output += "<table border='1'><tr>"

        for line in range(0, long_names):

            field_name = fields_name[line]

            output += "<th bgcolor='#B8D5F5'> %s </th>" % field_name

        output += "</tr>"

        for line in range(0, long_fields):

            counter += 1

            if(counter % 2 == 0):

                output += "<tr bgcolor='#DCE1E5'>"

            else:

                output += "<tr>"

            data_split = fields[line].split("|")

            for line in range(0, long_names):

                output += "<td> %s </td>" % data_split[line]

            output += "</tr>"

        output += "</table>"

     except ABAPApplicationError:

        output = "<div align='center'><h1>Table %s was not found</h1></div>" % table

        return output

     return output

    conn.close()

run(host='localhost', port=8080)

So, for me PyRFC has some mayor benefits, like the option to catch ABAPApplicationError and LoginError (I assume that Pier's version have it as well, but I never worried to look for it...shame on me), also the way to call the Function Module is very clean, a simple Python function that will receive as parameters the FM name and the parameters, taking from us the need to define each parameter as an attribute of the object. Also, it's really fast and it can be used on the Server side...but we will talk about that later...in other blog...when I got the chance to actually work with it...

Let's run this program and see how it looks...when running it from Python you might need to go to your browser a pass the following link (as we're executing a Bottle application):

http://localhost:8080/login

As always, was very enjoyable to work with Python, and of course, when mixing it my PyRFC the fun exceed my expectations as right now it's almost 8:00 pm on Saturday night...and I'm posting a blog of what I worked on almost all afternoon...programming is fun...don't forget it...

3 Comments