Skip to Content
Technical Articles

OData for Pythonistas

I am a member of a team building SAP S/4HANA Cloud applications. I am mainly working on the back-end part (ABAP) but these days I am more involved in automation of our development processes where I often create tools in Python and Bash.

I would like to briefly introduce the Python library providing OData client our team has built while we were working on test automation of OData services providing data for our Fiori applications.

The library has name pyodata and its has three homes:

Why Python?

In the beginning of our Fiori journey, we made the decision to go for BTD and ATTD and since we were experienced Python programmers we took Robot Framework as the test tool.

Our goals

Due to our lack of deep knowledge of OData protocol, our test base started growing by ad-hoc OData URLs builders and results processors. We were aware of the existing Python libraries but no one was willing to tailor them to our needs and some of them looked un-maintained.

In the next step, we created Robot keywords executing basic OData request and were happy until we ran into the need to prepare test data. It was a natural decision to start building the test-data preparation tools in Python too. At the moment we already had a metadata analyzer verifying validity of $metadata document (e.g. checking ValueList annotations points to the existing EntityTypes and EntityProperties).

So, we took the metadata analyzer and used its output to create a OData request builder seamlessly integrated into Python. We want to save us a lot of typing by avoiding the need to use brackets for function calls and providing string literals – instead we rather leverage Python dynamic features to enable writing code as if you had native Python types and functions.

Features

Currently the library supports only

  • OData V2

However, we plan to add support for V4 soon and potentially V3 in future.

Even though we started with Python 2.7 we no longer support this version of Python and focus on

  • Python >= 3.6

We did not want to make the library dependent on any HTTP framework, thus you must provide an object implementing Python Requests Session object’s interface. That allows to focus on OData protocol and ignore service vendor implementation details.

However, we have been building the library against SAP Gateway, so the implementation favors this vendor (for example, the library gracefully handle errors reported by SAP Gateway).

Examples

For demonstration purposes, I took the backend OData service at https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/services/SingleApp.xsodata/ which provides data for SAP Fiori Apps Reference Library

List of all OnPremis Releases

import requests
import pyodata


SERVICE_URL = 'https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/services/SingleApp.xsodata/'

client = pyodata.Client(SERVICE_URL, requests)

query = client.entity_sets.Releases.get_entities()
query = query.filter(query.releaseType == 'SOP')

for rel in query.execute():
    print(f'{rel.releaseName} ({rel.releaseId})')

List of all apps in the release SAP S/4HANA 1809 and its FPSes

import requests
import pyodata
from pyodata.v2.service import GetEntitySetFilter as esf


SERVICE_URL = 'https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/services/SingleApp.xsodata/'

client = pyodata.Client(SERVICE_URL, requests)

rel_query = client.entity_sets.Releases.get_entities().filter("startswith(releaseName, 'S/4HANA 1809')")
sop_releases = rel_query.execute()

apps_query = client.entity_sets.AppsOnSearch.get_entities()
apps_cond = esf.or_(*[apps_query.releaseId == sop.releaseId for sop in sop_releases])

for app in apps_query.filter(apps_cond).execute():
    print(f'{app.AppNameAll} ({app.appId})')

Bottom line

PyOData is being developed with Developer Experience in our minds and we have some ideas how to make the library even more comfortable (our Wish List). However, only the developers using the library know which parts are not optimal, so I encourage you to report us your ideas.

I hope I will enjoy the python way of consuming OData services as our team do!

3 Comments
You must be Logged on to comment or reply to a post.
  • hi jakub,

    thank you for sharing valuable information

    please correct me if i am wrong

    so pyodata is a library in python programming language which was created by you and your team members.

    pyodata is capable of consuming OData service so  hear pyoddata acts as a Odata service consumer write.

    can we use pyodata as  Odata service producer?

    there are many OData service producers are there. among all of them if the OData service is genarated from SAP vendor it is added advantage of catching exceptions in a efficient manner.

     

    • Hi bala,

      unfortunately, pyodata is only service consumer and does not work as service provider at all.

      If you need a service provided by an SAP tool, you can use #ABAP_trial

       

      Regards,

      Jakub