Technical Articles
Python library to ease the automation of SAP download center links
A plugin to support SAP authentication in Python Requests
Requests is a simple HTTP library for Python. It supports many authentication mechanisms, but also creating a custom one.
In this blog post I will explain how to use custom authentication plugin for SAP portal authentication.
Why would we need it? In cases we want to automate the file management on SAP portal, we may have an automation to check if files are valid or similar.
The SAP portal authentication
The SAP portal authenation consist of few steps. In each step the client must send the hidden data to the post from, which is returned in the HTTP response.
At the end we receive SAMLResponse data, which we can use to create a HTTP session and access our HTTP link.
The code
class SAPAuth(AuthBase):
"""
SAPAuth is class which implements the SAP launchpad authentication.
"""
sso_url = 'https://accounts.sap.com/saml2/idp/sso'
def get_next_url(self, text):
return ET.fromstring(text, parser=etree.HTMLParser()).find(".//body//form[@method='post']").attrib['action']
def get_all_inputs(self, text):
ret = {}
for i in ET.fromstring(text, parser=etree.HTMLParser()).findall(".//body//form[@method='post']//input"):
if i.attrib.get('name') and i.attrib.get('value'):
ret[i.attrib['name']] = i.attrib['value']
return ret
def __init__(self, username=None, password=None):
self._username = username
self._password = password
def _next_step(self, response, history, next_url=None, headers=None, **kwargs):
if next_url is None:
next_url = self.get_next_url(response.text)
post_data = self.get_all_inputs(response.text)
for k, v in kwargs.items():
post_data[k] = v
cookies = dict()
for r in history:
cookies.update(dict(r.cookies.items()))
next_response = requests.post(
next_url,
data=post_data,
cookies=cookies,
headers=headers,
)
history.append(next_response)
return next_response
def handle_response(self, response, **kwargs):
history = [response]
response = self._next_step(response, history)
response = self._next_step(response, history, j_username=self._username)
# We need to pass the next_url explicitly, because the response only contains relative URL for some reason:
response = self._next_step(response, history, next_url=self.sso_url, j_password=self._password)
response = self._next_step(response, history)
return self._next_step(response, history, headers=self._headers)
def __call__(self, request):
request.register_hook('response', self.handle_response)
self._headers = request.headers
return request
Usage
The usage of the library is very simple, you just need to pass the SAPAuth instance to the requests HTTP call.
And the authentication is happening behind the scene for you, no need to know any details, just username and password.
Install
The library is hosted on pypi, so you can simply install it via pip.
pip install requests-sap
Sample code
This sample code will login to SAP portal, and fetch information and print the information to stdout.
import json
import os
import requests
from requests_sap import SAPAuth
r = requests.get(
"https://launchpad.support.sap.com/services/odata/svt/swdcuisrv/ObjectSet('0030000000103162022')",
auth=SAPAuth(username=os.environ['LP_USERNAME'], password=os.environ['LP_PASSWORD']),
headers={'Accept': 'application/json'}
)
data = json.loads(r.text)
print(data['d']['Title'] + ' is ' + data['d']['Status'])
The output is:
SAP HANA Platform Edt. 2.0 SPS05 rev57 Linux x86_64 is AVAILABLE
Summary
Today we have shown how to abstract the authentication to the SAP service and ease the automation of the SAP files management. You no longer need to worry about authentication, but focus on the data and automation itself. Please share your thoughts about the library in the comments. Hope the library will be useful for the community!
Works fine so far!
May it possible, that you can add support for SAP IAS (Identity Authentication) in BTP too? The login site looks quite similar.