Reputation: 13
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
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:
Upvotes: 0