Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
omachace
Member

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!
1 Comment
Labels in this area