Programming

How to Integrate a Python App with SAP Business Application Studio for an SAP S/4HANA Cloud System

SAP Business Application Studio has recently broadened its support to encompass Python, as indicated by SAP.

 

This additional capability facilitates the development of Python-based applications. In this blog post, I'll walk you through how to establish a Python-driven development environment in SAP Business Application Studio. We'll also initiate a project and develop a compact web application, which includes a REST API endpoint that interfaces with the SAP S/4HANA Cloud system to retrieve supplier details via the destination service, thereby pulling the list of suppliers. For a more in-depth understanding of SAP Business Technology Platform (SAP BTP) setup and SAP Business Application Studio setup, consider referencing the E-Bite I co-authored for SAP PRESS. If you're interested in gaining more insights about Python, please consult the provided link.

 

Introduction

This post serves as a continuation of our previous discussion on the Python RESTful API, where we've delved into the development of RESTful APIs in Python. Here, we'll focus on how to use the OData service of the SAP S/4HANA Cloud system, how to incorporate it into a Python application, and how to expose it through a RESTful API by crafting a wrapper for the OData API of SAP S/4HANA Cloud.

 

My secondary objective is to guide you in creating a prototype application. This will involve setting up a Python project and configuring a destination to link it to in the SAP S/4HANA Cloud system. The application is aimed to interpret the OData API to acquire a list of suppliers and create a wrapper RESTful API in Python, which will be obtained by consuming supplier data from SAP S/4HANA Cloud.

 

RESTful APIs are potent resources that facilitate communication between various software applications. In the scope of our tutorial, it will be employed to extract a list of suppliers by creating a wrapper for the pre-existing OData service from the SAP S/4HANA Cloud ES5 demo system. This is to exemplify how we can consume any services from the cloud system and manage the data or services in Python for customization, or to perform any form of data manipulation using the Python programming language.

 

Join us in exploring the intriguing domain of Python development, where we will set up a development environment and build an application that interacts with RESTful APIs. I am certain that this post will offer essential knowledge and practical experience that will be beneficial for your upcoming Python projects.

 

Pre-requisite Steps:

  • Set up the ES5 demo system as per the mentioned at this link.
  • Navigate to the SAP BTP account and create a trial account.
  • Set up the SAP Business Application Studio to launch the URL as mentioned in this link.
  • Launch the URL in the browser as shown below and click on “dev space creation.” 

Overview of SAP Business Application Studio screen

 

Now click on the dev space and provide a unique name such as “py_dev”. Select the “Python Tools” from the Additional SAP Extensions; you may select other extensions also based on your requirement and development activity. I selected a couple of other extensions in my tutorial but that is optional. After selection, click on “Create Dev Space” and wait for a few minutes. Refer to the figure below for a preview.

 

Overview of dev space creation with Python extension

 

Once the dev space creation state is being shown as “RUNNING,” as shown below, click on it to open the dev space. It may take some time to load.

 

Overview of created “Py_dev” dev space with the Python extension

 

Once the dev space is launched, navigate to the workspace and create a new “Basic Multitarget Application” by selecting the option “New project from Template” as shown below.

 

Overview of creation of project from template

 

Select “Basic Multitarget Application” and click the start option. On the next screen, provide the project name as “mywebApp” and click on FINISH as shown below.

 

Overview of creation of space

 

The reason you create the “Basic Multitarget template” is because you need to create a project with mta.yml, since it will be used to create the MTA-based application. Once the full stack app is developed, you can deploy it to SAP BTP.

 

SAP S/4HANA Destination Configuration

After you set up the ES5 demo system, configure the destination in the SAP BTP account as mentioned below.

  • Navigate to the SAP BTP account.
  • Click on sub-account and navigate to the “Connectivity” section in the right panel.
  • Expand it and click on the Destinations tab. Configure the destination system as mentioned in this link (step 2).

Overview of ES5 demo destination setup

 

Development Setup

Now open a terminal/create a folder for “mywebApp” and navigate to this folder using command. Then install the package related to Python as shown below.

 

Overview of terminal selection and installation of packages for development

 

> mkdir mywebApp

> cd mywebApp

> npm install python

> python –version // 3.0+ version should be 3+

> npm install pip // python package installer

> pip install flask // python web development package should be 3.0.0

> pip install jsonify

> npm i cfenv

> npm i requests

> pip3 install werkzeug

> touch app.py

> touch BTPServices.py

> touch ProcFile

> touch requirements.txt

> touch runtime.txt

> touch manifest.yml

 

The given command must be run in the SAP Business Application Studio terminal. Once the installation package is in place, you can then open app.py and introduce a get method to procure a list of suppliers from the SAP S/4HANA Cloud system. However, before we proceed, it's important to touch upon the Python packages used to realize this Python web-based application. There are numerous Python web frameworks at our disposal, many of which are open-source. The more popular ones include Django, CherryPy, Falcon, Flask, and Tornado. From this list, I have chosen to construct the REST API using Flask due to its lightweight, RESTful web framework that carries a minimal technical debt.

 

In this example, I created a REST API to retrieve the list of suppliers from the SAP S/4HANA Cloud system using the OData service, and put together a wrapper to return the response as a RESTful API response in JSON format. These APIs are asynchronous and are built using WSGI (Web Server Gateway Interface). Below is a code snippet screenshot of app.py for your perusal.

 

Overview of code snippet to implement the RESTful API

 

# importing modules

# ---------------------------------------------------------------------

# import all the necessary modules here that will be used in the program

from flask import Flask, jsonify

import os

import requests

from requests.auth import HTTPBasicAuth

 

# importing local module: BTPservices: containing generic codes for destination

# ---------------------------------------------------------------------

import BTPServices

 

# application initialization

# ---------------------------------------------------------------------

app = Flask(__name__)

# data fetch using the destination

# ---------------------------------------------------------------------

@app.route('/getSuppliers', methods=['GET'])

def getSuppliersES5():

   lv_request = getSuppliersList('ES5', '/sap/opu/odata/sap/EPM_REF_APPS_SHOP_SRV/Suppliers?$format=json')

   return jsonify(lv_request)

 

# fetching of records having BasicAuthentication authorization

# ---------------------------------------------------------------------

def getSuppliersList(lv_dest, lv_string):

   lv_usr = ""

   lv_pass=""

   lv_destination = BTPServices.getDestination(sDestinationService='python_dest_service', sDestinationName=lv_dest)

   if lv_destination is None:

       return "Error: Destination not found"

   lv_url = lv_destination['destinationConfiguration']['URL'] + lv_string

   lv_usr = lv_destination['destinationConfiguration']['User']

   lv_pass = lv_destination['destinationConfiguration']['Password']

   try:

       lv_request = requests.get(lv_url, headers={'Accept': 'application/json'}, auth=HTTPBasicAuth(lv_usr, lv_pass))

       lv_request.raise_for_status()

   except requests.exceptions.HTTPError as err:

       return jsonify(replies=str(err))  

   response_json = lv_request.json()

# clearing variables

   del lv_destination, lv_url, lv_usr, lv_pass  

   return response_json

 

Here you will notice that I utilized the Flask framework in Python and imported the necessary modules for the code. I then invoked the getSuppliersES5 method to retrieve a list of suppliers. This method, in turn, calls the getSuppliersList method, which calls a generic method to obtain information from an instance that has been created. It retrieves the details of the destination named "ES5.” Subsequently, it establishes a connection and acquires the suppliers' data from the ES5 demo system of the SAP S/4HANA Cloud system. After receiving the response, I could convert it into a JSON response.

 

Here's a code snippet of BTPServices.py for the SAP BTP destination connection setup.

 

Overview of SAP BTP destination service method

 

from cfenv import AppEnv

import requests

 

def getDestination(sDestinationService, sDestinationName):

# Read the environment variables

# -------------------------------------------------------------------------------

env = AppEnv()

dest_service = env.get_service(name=sDestinationService)

if dest_service is None:

     print(f"Service {sDestinationService} not found")

     return None

sUaaCredentials = dest_service.credentials['clientid'] + ':' + dest_service.credentials['clientsecret']

 

# Request a JWT token to access the destination service

# -------------------------------------------------------------------------------

headers = {'Authorization': 'Basic '+sUaaCredentials, 'content-type': 'application/x-www-form-urlencoded'}

form = [('client_id', dest_service.credentials['clientid'] ),('client_secret', dest_service.credentials['clientsecret'] ), ('grant_type', 'client_credentials')]

url = dest_service.credentials['url'] +"/oauth/token"

headers = {

   'Content-Type': 'application/x-www-form-urlencoded'

}

response = requests.request("POST", url, headers=headers, data=form)

 

# Search your destination in the destination service

# -------------------------------------------------------------------------------

token = response.json()["access_token"]

headers= { 'Authorization': 'Bearer ' + token }

r = requests.get(dest_service.credentials['uri'] + '/destination-configuration/v1/destinations/'+sDestinationName, headers=headers)

print("DEST URI:",dest_service.credentials['uri'])

 

# Access the destination securely

# -------------------------------------------------------------------------------

destination = r.json()

return destination

 

The above code is to show how to establish the connection with the destination service and get the URL and other details of the ES5 system, using the JWT token mechanism.

 

Now create the remaining three files mentioned in the figure below, since they are required to run the application configurations.

 

Overview of ProcFile, requirements.txt, runtime.txt files details

 

The package version may change in the future based on the releases of these libraries.

 

Deployment Steps

Once the application changes are done, now we need to deploy the application in SAP BTP. The first step would be to create the manifest.yml to define the deployment configurations.

 

---

applications:

- name: myPythonApp

routes:

   - route: app-python.cfapps.ap21.hana.ondemand.com

path: ./

memory: 128M

stack: cflinuxfs4

disk_quota: 512M

buildpack: python_buildpack

command: python3 app.py

services:

   - python_dest_service

 

Follow these steps:

  • Log in to SAP BTP applications: cf login -a “api end points”
  • Enter the email ID and password.
  • Execute the command to create the destination service instance “python_dest_service”
    • cf create-service destination lite python_dest_service
  • Execute the command cf push (make sure the manifest.yml file is in the current folder path) as shown below.

Overview of deployment of sample Python app

 

After the successful deployment of the application, navigate to the SAP BTP subaccounts, click on the dev space, and then click on the deployed app as mentioned in the manifest.yml file.

 

Now click on the URL as shown below (“Application url”). It will open the API endpoints in a new browser tab and append the text /getSuppliers.

 

Overview of deployed app navigation and deployed app URL

 

Below is the response snapshot.

 

Overview of RESTful API response

 

This is the process used to retrieve supplier data from an SAP S/4HANA Cloud system via a web application framework that utilizes the Python programming language.

 

Conclusion

This integration with SAP S/4HANA Cloud opens up new opportunities for other programming languages, such as Python, to fully exploit their capabilities in the implementation of such services, thereby enhancing the overall ecosystem. This post not only demonstrated the versatility of Python as a programming language, but also underscored its potential in enhancing the functionality and efficiency of SAP Business Application Studio.

Recommendation

Hands On with SAP Business Application Studio
Hands On with SAP Business Application Studio

Jump into development with SAP’s latest IDE: SAP Business Application Studio! First walk through setup, from authorizations to extensions. Then use SAP Business Application Studio to build mobile, SAP Fiori, native SAP HANA, and full stack cloud applications. Round out your training by seeing how to migrate SAP Fiori and SAP Cloud Application Programming Model applications from SAP Web IDE to SAP Business Application Studio. Master your new development environment!

Learn More
Rajnish Tiwari
by Rajnish Tiwari

Rajnish Tiwari has over nine years in software development and has extensively worked on database-related technologies like SAP HANA, Kafka, SAP Vora, noSQL, and postgreSQL. An SAP employee, Rajnish currently works on the SAP Predictive Engineering Insights product team.

Comments