SAP позволяет создавать полноценные Web-приложения. Для этих целей используется oData. Для создания API существует стандарт — транзакция SEGW.
В данной статье не будет описываться процесс создания oData сервиса, эта тема хорошо описана в этом цикле статей
Чтение данных oData в python будет полезно как минимум в следующих случаях:
- Вариант получения данных не SAP системой;
- Возможность создавать RESTful приложения, где во фронтеде не будет использоваться технологии SAP. Мир фронтеда ушел далеко от SAP’а. По моему мнения, даже SAPUI5 и fiori не исправляет ситуации.
Данные oData возвращает в json, либо в xml формате. Для доступа к сервису необходима аутентификация. Обычно она реализована средствами протокола HTTP — Basic access authentication. Так же при входе обязательно используется access token. Это необходимо учитывать при написании скрипта. Тема очень обширная, если интересно как это работает под капотом, то в свободно доступе огромное количество информации.
Реализация
Итак, допустим у нас есть вводные. Готовый oData, например для отображения в браузере URL будет выглядеть следующим образом
http://{ВАШ IP}:{ВАШ ПОРТ}/sap/opu/odata/SAP/ZEXAMPLE/DataSet
Тогда для того что бы получить данные в помощью Python нужно использовать следующий код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import json import requests from requests.auth import HTTPBasicAuth sap_opt = { 'user': {ВАШ ЛОГИН}, 'passwd': {ВАШ ПАРОЛЬ}, 'baseurl': 'http://{ВАШ IP}:{ВАШ ПОРТ}/sap/opu/odata/SAP/ZEXAMPLE/', 'verify': True, } session = requests.Session() session.headers.update({'Connection': 'keep-alive', 'X-CSRF-TOKEN': 'Fetch'}) auth = HTTPBasicAuth(sap_opt['user'], sap_opt['passwd']) r = session.get(sap_opt['baseurl'], auth=(sap_opt['user'], sap_opt['passwd']), verify=sap_opt['verify']) token = r.headers['x-csrf-token'] format = '?$format=json' # по умолчанию выберем json set = 'DataSet' # Название вашего сета url = sap_opt['baseurl'] + set + format headers = {'Content-type': 'application/json;charset=utf-8', 'X-CSRF-TOKEN': token} get = session.get(url, headers=headers, auth=auth, verify=sap_opt['verify']) jdata = json.loads(get.text) result = jdata.get('d').get('results') print(result) |
В переменной result будет Ваш json
Как видно для доступа к данным, Вам необходим SAP пользователь, который имеет права на вызова oData, а точнее логин и пароль. В данном примере он прописан на прямую в коде, но Вы можете вынести его в любое удобное место и считывать при необходимости.
Так же для работы скрипта нужно будет установить недостающие пакеты в терминале командой pip install
Улучшение/декомпозиция
Представленный код отлично работает, однако его можно декомпозировать для более удобного использования.
Разобьем его на создание сессии и вызов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import json import requests from requests.auth import HTTPBasicAuth from .local_settings import sap_opt def sapCreateSession(): # Создание сессии для запросов oDATA # Коннектимся к SAP session = requests.Session() session.headers.update({'Connection': 'keep-alive', 'X-CSRF-TOKEN': 'Fetch'}) try: r = session.get(sap_opt['baseurl'], auth=(sap_opt['user'], sap_opt['passwd']), verify=sap_opt['verify']) except: message = "Нет соединения с системой %s %s" % (sap_opt['mandt'], sap_opt['name']) return ('NO TOKEN', 'NoSession', message) token = r.headers['x-csrf-token'] sess = (token, session, None) return sess def get_oData_set(set, filter, format='$format=json'): session = sapCreateSession() token = session[0] ss = session[1] url = sap_opt['baseurl'] + set + '?' + filter + '&' + format headers = {'Content-type': 'application/json;charset=utf-8', 'X-CSRF-TOKEN': token} auth = HTTPBasicAuth(sap_opt['user'], sap_opt['passwd']) # для auth get = ss.get(url, headers=headers, auth=auth, verify=sap_opt['verify']) jdata = json.loads(get.text) if jdata and 'error' not in jdata: jdata = jdata.get('d').get('results') else: jdata = '' return jdata |
Получаем 2 метода в отдельном файле, если обратите внимание на область подключения библиотек, то можно заметить подключение другого локального файла. Он у меня содержит настройки для подключения к SAP системе.
Выглядит так

т.е. ни чем не отличается от примера Выше.
Вызов
Итак, теперь для вызова oData из любого скрипта, необходимо подключить наш файл и вызвать метод get_oData_set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from . import Sap_connector parametr1_value = '' parametr2_value = '' # какая-то логика, инициализируем параметры для фильтра filter = '?param1=' + parametr1_value + '¶m2=' + parametr2_value set_res = Sap_connector.get_oData_set('DataSet', filter) # что бы вызвать любой другой сет, просто прописываем название нужного, при вызове метода set_res = Sap_connector.get_oData_set('DataSet2', filter) set_res = Sap_connector.get_oData_set('DataSet3', filter) set_res = Sap_connector.get_oData_set('DataSet4', filter) |
В коде прописана логика формирования get запроса. Соответственно в этой части можно прописать любые необходимые параметры
На этом все, описанный способ позволяет создать простой «мост» для объединения SAP и не SAP технологий. Что открывает огромный простор для разработок.