Search our Blogs
Showing results for 
Search instead for 
Do you mean 
 

Call the HPE Haven OnDemand APIs using the HODClient library for Windows Universal 8.1

HPE Haven OnDemand is a complete solution for bringing extensive data analytics (text analysis, speech recognition, image analysis, indexing and advanced search etc.) to your application and for augmenting your Big Data solution using advanced data processing engines via RESTful APIs. With more than 60 APIs, you can create consumer and enterprise applications that harness the wealth of information in social media, videos, images, free text etc. to enrich your application’s content.

 

Accessing RESTful APIs using a platform’s native HTTP request is not that hard, but we all want to make our lives easier right? So when there is a choice to implement less code and avoid rewriting and handling routine operations, why not go for that choice and focus more on building features for your app?



In this post, I am going to show you how to use the HODClient library for Windows Universal 8.1 to call HPE Haven OnDemand APIs and then how to use the HODResponseParser library to parse responses. If you are a Windows application developer using the C# programming language, go on to read this article. Ruby, Node.js and Python developers read this one.



 

Requirements

 

  • Make sure that you have the Visual Studio 2015 IDE installed in your environment. If not, you can download it from here.
  • You are familiar with using Visual Studio and know how to create a CSharp Windows application project.



 

Get the library and get ready

 

The first thing you need to do is to download the library zip package to your local environment. Then unzip it to a folder, where you can easily access it later.

 

Note: Unfortunately, at this point in time, we don’t have a Nuget package for easy integration but we may consider providing one in the future!

 

Now let’s run Visual Studio 2015 and create a new project and follow the instructions below to integrate the libraries to our project.

 

From the project Solution Explorer window, right click on the project's References folder and select "Add reference...".

 

PaymentProgramPrint_EverSource_5H.pdf

 

Browse to the folder where you saved the library and select the HODClient.dll, HODResponseParser.dll and Newtonsoft.json.dll.

 

phong2.jpg

 

That’s all it takes for integrating the libraries to a project. And now we should be ready for the implementation.

 

Note: Implementation code in this article is only for demo purposes. Even you can make some copy/paste from the code section, we recommend you to look at the complete example project included in the library package.



 

Use the HODClient and HODResponseParser libraries

 

First, we declare using library package and create library instance.

 

using HOD.Client;
using HOD.Response.Parser;

public class HODPage : Page
{
HODClient hodClient = new HODClient("your-api-key");
HODResponseParser parser = new HODResponseParser();
}

Note: to use any API from Haven OnDemand, you will need to sign up and get a developer API key. If you have not done so, click here to sign up and get one.

 

Then we will need to implement a few callback functions to receive responses from the hodClient library.

 

public HODPage()
{
this.InitializeComponent();
hodClient.onErrorOccurred += onErrorOccurred;
hodClient.requestCompletedWithJobID += requestCompletedWithJobID;
hodClient.requestCompletedWithContent += requestCompletedWithContent;
}

private void requestCompletedWithContent(string response)
{
}
private void requestCompletedWithJobID(string response)
{
}
private void onErrorOccurred(string errorMessage)
{
}

We are now ready to call any API from Haven OnDemand. All supported APIs at the present time are defined in the HODApps class. We can simply type “HODApps.” and select one from the dropdown list.

 

The HODClient provides 2 separate functions for sending an HTTP GET and HTTP POST request using GetRequest() and PostRequest() function, respectively. We just need to consider which function should be used and in what scenario. There are fundamental differences and use cases between HTTP GET and POST requests, but for now there are 2 points to remember:

 

  1. We cannot use the GetRequest() function for uploading a file to Haven OnDemand.
  2. We do not use the GetRequest() function for sending a large amount of content to Haven OnDemand.

Both GetRequest() and PostRequest() functions take similar function’s parameters and we will discuss the function parameters shortly.

 

When calling an API from Haven OnDemand, we need to know the required and optional parameters of that API. We detect the valid parameters by browsing to the API’s request page from Haven OnDemand website. Let’s have a look at the Speech Recognition API at https://dev.havenondemand.com/apis/recognizespeech#request.

 

We can see the first parameter is the api-key for authentication. By using the HODClient library, we don’t need to specify the API key in each function call because we already initialized the library with an api-key, and it will be added automatically to every request.

 

The rest of the parameters are for specifying the source of input data and API’s configurations. Some are required parameters and some are optional ones. For the Speech Recognition API, we can see the following required and optional parameters:

 

phong3.jpg

 

We are planning to call the Speech Recognition API to process an audio file and extract text from the audio. Thus, we will need to use the PostRequest() function from the library. Let’s write some code and discuss the details later.

 

async private void LoadFilePicker(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
filePicker.FileTypeFilter.Add(".mp3");
filePicker.ViewMode = PickerViewMode.List;
StorageFile file = await filePicker.PickSingleFileAsync ();
if (file != null)
      {
          CallSpeechRecognition(file);
      }
      else
      {
          // pick file cancelled
      }
}
private void CallSpeechRecognition(StorageFile aFile)
{
var Params = new Dictionary<string, object>()
      	{
         {"file", aFile },
         {"interval", "20000" }
      	};
hodClient.PostRequest(ref Params,
  HODApps.RECOGNIZE_SPEECH, 
  HODClient.REQ_MODE.ASYNC);
}

In the code above, we add a function called LoadFilePicker(…) where we implement code to pick an audio file in Windows application. Once the file is chosen, we then call the CallSpeechRecognition() function with the specified file as the function parameter.

 

In the CallSpeechRecognition() function, we define a variable “Params” as a dictionary and create it with the “file” as the source of input data and the “interval” value to segment the speech output on every 20 seconds as specified in the Speech Recognition API reference.

 

When calling the PostRequest() function, we pass the “Params” as reference, and we specify the Haven OnDemand API using the predefined name HODApps.RECOGNIZE_SPEECH. And the last parameter is the operation mode as HODClient.REQ_MODE.ASYNC.

 

Why ASYNC mode? Haven OnDemand supports synchronous and asynchronous APIs. In response to the synchronous call, the server processes the call immediately and after the job is done, it returns a single response containing the actual result. In addition to the file upload time, it takes about 1 second per second of audio for processing, so bigger files may take a while before it returns a response, thus, if we use the SYNC mode, we may end up getting an HTTP request timeout response from the server.

 

In response to the asynchronous call, the server receives the call and returns a job ID, which we will use to fetch the actual result later in a separate call.

 

Now we have called the PostRequest() function, how can we receive the response?

 

  1. In response to a GetRequest() or a PostRequest() function call with a SYNC mode, or to the call on GetJobResult() or GetJobStatus() function, the response will be returned via the requestCompletedWithContent() callback function.
  2. In response to a GetRequest() or PostRequest() function call with an ASYNC mode, the response will be returned via the requestCompletedWithJobID() callback function.

As we called the PostRequest() function with the ASYNC mode, now we can expect to receive a job ID via the requestCompletedWithJobID() callback function. We will also start using the HODResponseParser to parse response from the server.

 

private void requestCompletedWithJobID(string response)
{
var jobID = hodParser.ParseJobID(response);
if (jobID != "")
hodClient.GetJobStatus(jobID);
}

From the code above, we call the ParseJobID() function from the HODResponseParser library to get the jobID value from the JSON response from the server. Then we call the GetJobStatus() function from the HODClient library to check for the job status identified by the jobID.

 

The HODClient library also offers a GetJobResult() function. What is the difference between GetJobStatus() and GetJobResult() functions?

 

  1. The GetJobStatus() function is for querying the status of a job identified by a job ID. If the job is completed, the response will be the result of that job. Otherwise, the response will contain the current status of the job.
  2. The GetJobResult() function is for fetching the result identified by the job ID. This function call is acting similar to a SYNC request as it will wait until the job is done before the server returns the response. Using this function for long-time operation such as processing a long audio file may result in a HTTP request timeout response.

For a lengthy audio clip, it may take a while to process. Therefore, it is recommended that we call the GetJobStatus() instead of the GetJobResult() function.

 

Parse content response from Haven OnDemand API

 

Currently, the HODResponseParser includes 47 standard response parser functions which can parse standard responses and return predefined content object classes. Predefined content object classes are listed in the README.md file included in the library package. It is also easy to find a standard response parser by typing “hodParser.” in Visual Studio IDE and scroll through the dropdown list to select one. A predefined content object is an object class which was predefined to hold the actual content from an API’s response. Below is the example of the Speech Recognition content object.

 

public class SpeechRecognitionResponse
{
public List<Document> document { get; set; } 
public class Document
       {
public Int64 offset { get; set; }
public string content { get; set; }
}
}

We can also define a custom response object if we want to parse just part of the content values from a response (e.g. we can define a class SpeechRecognitionText without the offset value), or if we cannot find a predefined object class for a certain Haven OnDemand API from the supported list.

 

A custom response object needs to be parsed using the ParseCustomResponse<T>() function, where T is the name of the custom object class. When defining a custom response object, we need to know the keywords, data type and structure (aka the model) of the data in the JSON response. One way to find out about that is to look at the API documentation at the “response” tab. For instance, the response of the GetContent API can be found here: https://dev.havenondemand.com/apis/getcontent#response.

 

phong4.jpg

 

From the data model above, we can define a custom response object class like this.

 

public class GetContentResponse 
{
	public List<Document> documents { get; set; }
	public class Document
{
	public string index {get; set; }
public string reference {get; set; }
public int section {get; set; }
public string title {get; set; }
public string summary {get; set; }
}
}

However, some APIs return responses with different data fields depending on values specified in the API’s call configurations or depending on the content itself. For instance, the GetContent API may return more or less metadata depending on the “print_fields” parameter specified in the API call. In that case, we need to detect and verify the actual response model before defining a suitable response object class for it.

 

Let’s continue with our app to catch and parse the speech recognition response from the server

 

private void requestCompletedWithContent(string response)
{
    String text = "";
var resp = parser.ParseSpeechRecognitionResponse(ref response);
    if (resp != null)
    {
foreach (SpeechRecognitionResponse.Document doc in resp.document)
      	{
          text += String.Format("Text: {0}\nOffset: {1}\n" + doc.content, doc.offset);
       }
    }
    else
    {
    	var errors = parser.GetLastError();
    	foreach (HODErrorObject err in errors)
      	{
      	if (err.error == HODErrorCode.QUEUED)
      	{
          jobID = err.jobID;
          // Job is in queue. Cause some delay and try again
          hodClient.GetJobStatus(jobID);      	
          break;
      	}
       else if (err.error == HODErrorCode.IN_PROGRESS)
      	{
          jobID = err.jobID;
   // Job is in progress. Cause some delay and try again 
	   hodClient.GetJobStatus(jobID);      
   break;
     	}
else
      	{
   text += "Error code: " + err.error.ToString() + "\n";
   text += "Error reason: " + err.reason + "\n";
   text += "Error detail: " + err.detail + "\n";
     	}
   }
}

When the requestCompletedWithContent() callback function is called, we receive a JSON formatted string from Haven OnDemand server in the response parameter. We will use the HODResponseParser library to parse the content in the response.

 

As we called the Speech Recognition API, we expect to parse the JSON response into a SpeechRecognitionResponse object. That is why we call the ParseSpeechRecognitionResponse() function. If the response is parsed successfully, the function will return a SpeechRecognitionResponse object and we can easily access the data as shown in the demo code above.

 

If the server’s response contains error messages, or the status of an incomplete task, the returned object will be set to null and we will need to call the hodParser.GetLastError function to get the error and handle it accordingly. On the code above, we check if the task is in “queued” or is being “in progress” status, then we will wait for some time and call the GetJobStatus() function again with the jobID returned in the error object.

 

We have extracted the text from an audio file, we may want to determine the topics or sentiment expression of the speaker by using the Sentiment Analysis API. Or we may want to make the text searchable by using the Add To Text Index API. I will leave this open to your practical and innovative choices to further exploit the full capabilities of Haven OnDemand platform.

 

Please leave us feedback and comments below.

 

Phong 
Developer Evangelist

A mobile technologies engineer and Web services architecture veteran. Moving toward big data with my biggest passion. Gyms, fishing and traveling are things I'd love to do whenever I have time for them.

Follow me on Twitter @pacovu.

 

 

Useful Haven OnDemand Links:

 

Developer Documentation

Developer resources for your hackathon

 

Client Libraries

 

Social Media
About the Author
Topics
† The opinions expressed above are the personal opinions of the authors, not of HPE. By using this site, you accept the Terms of Use and Rules of Participation