Skip to Content

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

To report this post you need to login first.

12 Comments

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

  1. 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].

    (0) 
  2. 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

    (0) 
  3. 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” }

     

    (0) 
  4. 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” }

    (0) 

Leave a Reply