Skip to Content
Author's profile photo Former Member

Getting started with SAP Leonardo Machine Learning Foundation

You want to know how to actually start using SAP Leonardo Machine Learning? The Machine Learning foundation offers a wide range of functional services, from image to text classification that are easy to consume. You can find a first overview of all these services available on the SAP API Business Hub and try them out through APIs calls. The only prerequisites you will need are the SAP Cloud Platform Tools for Java in your Eclipse IDE, SAP Cloud Platform Software  Development Kit, Eclipse (they can be set up and configured with this tutorial).

 

Steps

1. Open Eclipse and create new project

  • Select „File“ menu > „New“ in drop-down > „Dynamic Web Project“ in drop-down.

 

2. Start the project

  • Set project name to “MLConsumption” and choose “Finish”.
    Check that Target Runtime is set to “Java Web Tomcat 8” (or “Java Web Tomcat 7”).

3. Create new Servlet

  • Right click on project and select “New” in drop-down > “Servlet”.

4. Set class name

  • Set Java packages to “mlconsumption” and the Class name to “MLConsumptionServlet”.
    Click on “Next”.

5. Set URL Mapping

  • Click on “MLConsumptionServlet” > “Edit”. Set Pattern to “/”. Choose “OK” and on “Finish”.

6. Paste code into Eclipse

  • Replace code in method doGet (line 29 and 30) with
        	// create a new URLConnection object to configure our HTTP request
        	URLConnection connection = new URL("https://sandbox.api.sap.com/ml/prodimgclassifier/inference_sync").openConnection();
        	connection.setDoOutput(true); // send data through this connection --> HTTP POST request
        	
        	// user authentication and authorization
       	    connection.setRequestProperty("APIKey", "<API_KEY>");
        	 
    	    // random boundary between different files of multipart/form-data request
        	String boundary = Long.toHexString(System.currentTimeMillis());
        	// line separator required by multipart/form-data format
        	String CRLF = "\r\n";
        	// for sending files we need multipart/form-data
        	connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    
        	// character encoding used in our http requests
        	String charset = java.nio.charset.StandardCharsets.UTF_8.name();
        	// the image file we want to classify
    		String path = "";
    
    		    OutputStream output = connection.getOutputStream();
    		    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
    		) {
    			 // send image file
    		    writer.append("--" + boundary).append(CRLF);
    		    writer.append("Content-Disposition: form-data; name=\"files\"; filename=\"" + imgFile.getName() + "\"").append(CRLF);
    		    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(imgFile.getName())).append(CRLF);
    		    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    		    writer.append(CRLF).flush();
    
    		    Files.copy(imgFile.toPath(), output);
    		    output.flush(); // need to flush before continuing with writer
    		    writer.append(CRLF);
    
    		    // mark end of multipart/form-data
    		    writer.append("--" + boundary + "--").append(CRLF).flush();
    		}
    
        	// performing the http request against the Leonardo ML service endpoint
        	InputStream mlServiceResponse = connection.getInputStream();
       
    		try (Scanner scanner = new Scanner(mlServiceResponse)) {
    			// reading the response from the Leonardo ML service endpoint
    		    String responseBody = scanner.useDelimiter("\\A").next();
    		    // sending a response to the client
    		    userResp.getWriter().println(responseBody);
    		}
    ​

 

7.  Add missing imports

  • Insert the following code below line 8:
    import java.net.URISyntaxException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.io.File;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.io.OutputStreamWriter;
    import java.util.Scanner;
    import java.nio.file.Files;
    ​

     

8. Login to API Business Hub

  • Open API Business Hub in your browser and choose “APIs”. Click on “Login” (alternatively click “Register” and follow registration wizard). 

9. Select Product Image Classification

  • Search for “SAP Leonardo Machine Learning”. Select “SAP Leonardo Machine Learning -Functional Services” and click on “Artifacts” >  “Product Image Classification API”.

10. Generate API Key

  • Switch back to Browser, click on key icon and “Copy API Key”.

11. Insert API Key

  • Return to Eclipse and select <API_KEY> in line 40, then Press [CTRL]+[c].

12. Add product image to the project

  • Download “smartphone.jpg” and drop image into the “mlconsumption” package.

(Source)

 

13. Deploy and Execute Project

Assigned tags

      19 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Sebastian Wieczorek
      Sebastian Wieczorek

      Hey Hannah, very cool!

      Author's profile photo Minh Tri Nguyen
      Minh Tri Nguyen

      Did you try it at all?

       

      Author's profile photo Former Member
      Former Member

      Hi Hannah,

      very helpful hands on!

       

      Author's profile photo Minh Tri Nguyen
      Minh Tri Nguyen

      11. Insert API Key

      • Return to Eclipse and select <API_KEY> in line

      // user authentication and authorization
      connection.setRequestProperty("APIKey", "<API>");

      then Press [CTRL]+[v].

      Author's profile photo Minh Tri Nguyen
      Minh Tri Nguyen

      How did you drop image into the “mlconsumption” package?

       

      Author's profile photo Praveen Singh
      Praveen Singh

      Hi Minh,

      You need to drag file from  file location and drop it at eclipse folder.

      Thanks,

      Praveen

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Minh, hi Praveen, you are right, thanks for sharing this information!

      Author's profile photo Praveen Singh
      Praveen Singh

      Hi,

      Can you show how output of this application will look like?

      is it something like this?

      If not can you explain a bit more?

      Thanks,

      Praveen

      Author's profile photo Harikrishnan Panakkal
      Harikrishnan Panakkal

      see my below comment ....

      Author's profile photo Harikrishnan Panakkal
      Harikrishnan Panakkal

      Provided code need some corrections it seems

      use this instead

      // create a new URLConnection object to configure our HTTP request
          	URLConnection connection = new URL("https://sandbox.api.sap.com/ml/prodimgclassifier/inference_sync").openConnection();
          	connection.setDoOutput(true); // send data through this connection --> HTTP POST request
          	
          	// user authentication and authorization
         	    connection.setRequestProperty("APIKey", "<API_KEY");
          	 
      	    // random boundary between different files of multipart/form-data request
          	String boundary = Long.toHexString(System.currentTimeMillis());
          	// line separator required by multipart/form-data format
          	String CRLF = "\r\n";
          	// for sending files we need multipart/form-data
          	connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
      
          	// character encoding used in our http requests
          	String charset = java.nio.charset.StandardCharsets.UTF_8.name();
          	// the image file we want to classify
      		String path = "";
      		File imgFile = new File( "C:/Users/XXXX/Desktop/download.jpg");
      	
      		    OutputStream output = connection.getOutputStream();
      		    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
      		 {
      			 // send image file
      		    writer.append("--" + boundary).append(CRLF);
      		    writer.append("Content-Disposition: form-data; name=\"files\"; filename=\"" + imgFile.getName() + "\"").append(CRLF);
      		    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(imgFile.getName())).append(CRLF);
      		    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
      		    writer.append(CRLF).flush();
      
      		    Files.copy(imgFile.toPath(), output);
      		    output.flush(); // need to flush before continuing with writer
      		    writer.append(CRLF);
      
      		    // mark end of multipart/form-data
      		    writer.append("--" + boundary + "--").append(CRLF).flush();
      		}
      
          	// performing the http request against the Leonardo ML service endpoint
          	InputStream mlServiceResponse = connection.getInputStream();
         
      		try (Scanner scanner = new Scanner(mlServiceResponse)) {
      			// reading the response from the Leonardo ML service endpoint
      		    String responseBody = scanner.useDelimiter("\\A").next();
      		    // sending a response to the client
      		    response.getWriter().println(responseBody);
      		}

      You dont need to copy the image to project file, instead use absolute path like this "C:/Users/XXXX/Desktop/download.jpg". you may have to change to forward("/") slash instead of backward("\") if you copy file location in windows.

      Output would look like this if you send say a mobile phone image, the score tells most promising match:

      { "_id": "a0eb4a3d-bd55-4112-be16-046d56e9dcc7", "predictions": [ { "name": "download.jpg", "results": [ { "label": "smartphones", "score": 0.919782 }, { "label": "tablets", "score": 0.079877 }, { "label": "other", "score": 0.000213 }, { "label": "mobile device chargers", "score": 4.9e-05 }, { "label": "storage servers", "score": 3e-05 } ] } ], "processed_time": "Tue, 08 Aug 2017 01:34:22 GMT", "request": { "files": [ "download.jpg" ], "options": {}, "tenantName": "imgclassif-tech-user", "texts": [] }, "status": "DONE", "tenantName": "imgclassif-tech-user" }

       

      Author's profile photo Ajay Rawat
      Ajay Rawat

      Thanks a Lot

      It really helped me get the demo working

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thanks for mentioning this, I will have a look into it!

      Author's profile photo Chan Jin Park
      Chan Jin Park

      Also,

      line 88 you will see invalid character constant as error. simply move your backspace key left and right, then you can remove it the error

       

      }

      /**

      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

      */

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      // TODO Auto-generated method stub

      doGet(request, response);}

      }

      { “_id”: “a0370ed2-aa67-4872-9f1b-d9fcc8dd656b”, “predictions”: [ { “name”: “smartphone.jpg”, “results”: [ { “label”: “storage servers”, “score”: 0.468144 }, { “label”: “smartphones”, “score”: 0.275224 }, { “label”: “other”, “score”: 0.101539 }, { “label”: “printers & accessories”, “score”: 0.085432 }, { “label”: “USB flash drives & accessories”, “score”: 0.043441 } ] } ], “processed_time”: “Sat, 12 Aug 2017 08:20:25 GMT”, “request”: { “files”: [ “smartphone.jpg” ], “options”: {}, “tenantName”: “imgclassif-tech-user”, “texts”: [] }, “status”: “DONE”, “tenantName”: “imgclassif-tech-user” }

      Author's profile photo Douglas Cezar
      Douglas Cezar

      Hi Hannah,

      Please, do you know if at this point is it possible to achieve the ML library consumption using SAP Web IDE instead of Eclipse?

       

      Thank you

      Douglas

      Author's profile photo Matthias Sessler
      Matthias Sessler

      Hi Douglas,

      yes, this is possible as well.

       

      Kind regards,

      Matthias

      Author's profile photo harish vyas
      harish vyas

      Hi Hannah,

      Thanks for posting this blog. Really helpful to start learning Leonardo.

      I have a small question, in the above example you have used standard model "Product Image Classification API".

      Do you have any documentation to know how to Customize the Model. Like where to navigate and process of doing it. I am referring to section "Custom Machine Learning Models" in URL https://cloudplatform.sap.com/capabilities/machine-learning.html

       

      Thanks,

      Harish

      Author's profile photo Hot Yao
      Hot Yao

      Hi Hannah,

       

      Thanks for posting this blog.

      according to the reply, the first prediction is the storage server while the input image is a smart phone. Does this mean customer or partner need retrain the models using their own data before they can use them in a production environment?

      Thanks,

      Hot

      Author's profile photo Samuel Armbrust
      Samuel Armbrust

      Very nice blog post! Simple and very useful! Thank you for sharing!

       

      Author's profile photo Prosenjit Majumder
      Prosenjit Majumder

      @Harikrishnan Panakkal Matthias Sessler

      Hi, While deployed in hana cloud the local image location is not being identified whereas in local tomcat deployment it went well… please find the below error found in cloud:

      2019 02 19 13:38:57#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/MLConsumption].[com.sap.mlconsumption.MLConsumptionServlet]##anonymous#https-jsse-nio-8041-exec-13#na#i505458trial#mlconsumption#web#i505458trial#na#na#na#na#Servlet.service() for servlet [com.sap.mlconsumption.MLConsumptionServlet] in context with path [/MLConsumption] threw exception java.nio.file.NoSuchFileException: C:/images/V30-medium01.jpg 

      Any suggestion?