Skip to Content
SAP Leonardo is already very popular in China. Simply search in Wechat app with key word “sap leonardo”, lots of articles are found.
I have gone through them and it seems there are no articles talking about details from programming perspective, so I write this blog.

Requirement

Develop a simple Java application, user can specify a local picture file and use it as input to call a Machine Learning API hosted in SAP Leonardo and well trained. The API can smartly identify what this picture represents and return the result to user.
Here below is implementation detail.
1. Access https://api.sap.com, click “APIs”:
Then click “SAP Leonardo Machine Learning – Functional Services”:
Click “Product Image Classification API”:this is the very API we will use.
We now reach the API console page, which contains the detail explanation about the Model Schema used in this API. The schema is the definition of API response structure. You can also directly test the API in the console: simply specify a local picture file and click button “Try it out” to fire the API call.
For example I use the following picture to test:
The API is executed successfully: HTTP 200 is returned. The API tells us that it is 97% possible that this picture represents a notebook.
Now it’s time for us to consume this API via Java code.
2. Click “Download SDK” button in the top-right corner of API console page to download SDK locally.
The SDK is a Java project based on Gradle. Maven and Gradle is needed and also you have to setup environment of them accordingly. There are lots of detail steps explanation, just Google it.
After that import SDK into Eclipse:
Once import is finished, the project looks as below. The area marked with red are the code from SDK, the blue code is manually created by me, in order to call API and print result via System.out.println.
Add the following dependency into pom.xml:
Execute Maven command mvn install, ensure that the build is done successfully.
Now it’s ready to consume the API via SDK.
3. Use the following Java code to fire API call. The HTTP request send and response parse is encapsulated via SDK so the consumer code is now very neat and convenient to use:
For simplicity reason I hard code the absolute path of local picture file in line 13.
The API key hard coded in line 8 could be got from API console.
Executed the application, oops……

Issue analysis

Analyze the error message and the part highlighted with blue above actually tells the root cause already. An open-source Java library issued by Google, Gson, is used to deserialize the HTTP response stream into Java object. With the help of Gson, it is not necessary for application developers to reinvent the wheel – they need simply define some Java classes as Gson container to hold the deserialized result.
Go back to API console, the “request” field in API response structure is defined with type = “string”.
However via the actual test, we know the “request” field is actually a json object.
In the SDK code, the type of “request” field in Gson container class Response.java is defined as String( object is expected instead ). As a result Gson raised exception with message: Expected a string but was BEGIN_OBJECT at line 31 column 15 path $.request

Solution

Create a new Gson container class Request.java, and maintain the corresponding type of each member according to the actual field type observed in API response structure observed in API console.
For example the field “tenantName” in API response structure has type as “string”, so it should be defined as Java type String in Request.java; field “files” in API response structure is an array, and then defined in Request.java as List<String> accordingly.
Once adaptation is done, execute again and could see expected output this time. The deserialized text is printed out.
The complete source code used in this blog could be found from my github.
More API could be found from https://api.sap.com.
To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply