CDP
CDP

Reputation: 13

How do I send an image to an Azure AutoML endpoint in java?

I have an object detection model deployed to an endpoint in azure. In python, the code works perfect and looks like this:

    headers = {'Content-Type': 'application/json',
               'Authorization': ('Bearer ' + api_key)}
    sample_image = os.path.join(directory, filename)
    # Load image data
    body = open(sample_image, "rb").read()

    req = urllib.request.Request(url, body, headers)

    response = urllib.request.urlopen(req)

I'm trying to do the same thing in a UDJC in PDI Kettle. This is what that code looks like:

    String urlString = get(Fields.In, "ENDPOINT_URL").getString(r);
    HttpPost post = new HttpPost(urlString);
    post.addHeader("Content-Type",get(Fields.In, "CONTENTTYPE").getString(r));
    post.addHeader("Authorization",get(Fields.In, "API_KEY").getString(r));
    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    entity.setMode(HttpMultipartMode.STRICT);
    entity.addBinaryBody("file", get(Fields.In, "IMAGEDATA").getBinary(r));
    post.setEntity(entity.build());

    HttpClient httpClient = HttpClients.createDefault();
    HttpResponse response = httpClient.execute(post);

I'm getting this error: http_status result -1 java.net.SocketException: Broken pipe (Write failed)

I think there's an issue in how the image is being written. How do I get java to write it the same way python is writing it? Any suggestions? Thanks

Upvotes: 0

Views: 176

Answers (1)

JayashankarGS
JayashankarGS

Reputation: 8020

You can use following packages in java to score an endpoint.

import  java.net.HttpURLConnection;
import  java.net.URL;

Below is the code.

import  java.io.IOException;
import  java.io.InputStream;
import  java.net.HttpURLConnection;
import  java.net.URL;
import  java.nio.file.Files;
import  java.nio.file.Paths;
import  java.util.Base64;
import  org.json.JSONArray;
import  org.json.JSONObject;
import  java.io.InputStreamReader;
import  java.io.BufferedReader;

class  HelloWorld {
    public  static  void  main(String  args[])
    {
        String  url  =  "https://jml-hgrrb.westeurope.inference.ml.azure.com/score";
        String  api_key  =  "Your_api_key";
        String  directory  =  "C:\\Users\\v-jgs\\Downloads";
        String  filename  =  "download.jpg";
        
      try {
          String  authorizationHeader  =  "Bearer "  +  api_key;
          byte[] imageBytes  =  Files.readAllBytes(Paths.get(directory,filename));
          String  base64ImageData  =  Base64.getEncoder().encodeToString(imageBytes);
          JSONObject  inputData  =  new  JSONObject();
          inputData.put("columns", new  JSONArray().put("image"));
          inputData.put("index", new  JSONArray().put(0));
          inputData.put("data", new  JSONArray().put(base64ImageData));
          JSONObject  requestBody  =  new  JSONObject();
          requestBody.put("input_data", inputData);
          
          URL  apiUrl  =  new  URL(url);
          HttpURLConnection  connection  = (HttpURLConnection) apiUrl.openConnection();
          connection.setRequestMethod("POST");
          connection.setRequestProperty("Content-Type", "application/json");
          connection.setRequestProperty("Authorization", authorizationHeader);
          connection.setDoOutput(true);
          connection.getOutputStream().write(requestBody.toString().getBytes());
          
          int  responseCode  =  connection.getResponseCode();
          System.out.println("Response Code: "  +  responseCode);
          
          if (responseCode  ==  HttpURLConnection.HTTP_OK) 
          {
            InputStream  responseStream  =  connection.getInputStream();
            String  responseData  =  readInputStream(responseStream);
            System.out.println("Response Data: "  +  responseData);
            } else {
            InputStream  errorStream  =  connection.getErrorStream();
            String  errorData  =  readInputStream(errorStream);
            System.out.println("Error Data: "  +  errorData);
            }
            
            connection.disconnect();
            
        } catch (IOException  e) 
        {
        e.printStackTrace();
        }
    }
    private  static  String  readInputStream(InputStream  inputStream) throws  IOException {
        BufferedReader  reader  =  new  BufferedReader(new  InputStreamReader(inputStream));
        StringBuilder  response  =  new  StringBuilder();
        String  line;
        while ((line  =  reader.readLine()) !=  null) {
        response.append(line);
        }
        reader.close();
        return  response.toString();
    }
}

This is the endpoint responses the object detection boundaries.

https://jml-hgrrb.westeurope.inference.ml.azure.com/score

And this accepts the json body like below.

{
    "input_data": {
            "columns": ["image"],
            "index": [0],
            "data":["base64_string"]
            }
}

Here, you need to provide base64 string in data option. If you have multiple images, you can also add them in index and data correspondingly like below.

"index":[0,1],
"data":["image1","image2"]

So, in code you need to create a json object whichever your endpoint accepts. Check the auto-ml deployment details to know the input structure. In this code below part creates json object.

          JSONObject  inputData  =  new  JSONObject();
          inputData.put("columns", new  JSONArray().put("image"));
          inputData.put("index", new  JSONArray().put(0));
          inputData.put("data", new  JSONArray().put(base64ImageData));
          JSONObject  requestBody  =  new  JSONObject();
          requestBody.put("input_data", inputData);

Output:

enter image description here

Upvotes: 0

Related Questions