Watson api using node.js
Asked Answered
S

2

6

I am trying to use this node.js code to use watson api which is in ibm cloud bluemix in our ios app. Can anybody tell me what this code is doing and provide us an answer how to use the watson service from our app.

var express = require('express');
var https = require('https');
var url = require('url');

// setup middleware

var app = express();
app.use(express.errorHandler());
app.use(express.urlencoded()); // to support URL-encoded bodies
app.use(app.router);

app.use(express.static(__dirname + '/public')); //setup static public directory
app.set('view engine', 'jade');
app.set('views', __dirname + '/views'); //optional since express defaults to CWD/views

// There are many useful environment variables available in process.env.
// VCAP_APPLICATION contains useful information about a deployed application.

var appInfo = JSON.parse(process.env.VCAP_APPLICATION || "{}");
// TODO: Get application information and use it in your app.

// defaults for dev outside bluemix

var service_url = '<service_url>';
var service_username = '<service_username>';
var service_password = '<service_password>';

// VCAP_SERVICES contains all the credentials of services bound to
// this application. For details of its content, please refer to
// the document or sample of each service.

if (process.env.VCAP_SERVICES) {
  console.log('Parsing VCAP_SERVICES');
  var services = JSON.parse(process.env.VCAP_SERVICES);

//service name, check the VCAP_SERVICES in bluemix to get the name of the services you have

var service_name = 'question_and_answer';

  if (services[service_name]) {
    var svc = services[service_name][0].credentials;
    service_url = svc.url;
    service_username = svc.username;
    service_password = svc.password;
  } else {
    console.log('The service '+service_name+' is not in the VCAP_SERVICES, did you forget to bind it?');
  }

} else {
  console.log('No VCAP_SERVICES found in ENV, using defaults for local development');
}

console.log('service_url = ' + service_url);
console.log('service_username = ' + service_username);
console.log('service_password = ' + new Array(service_password.length).join("X"));

var auth = "Basic " + new Buffer(service_username + ":" +    service_password).toString("base64");

// render index page

app.get('/', function(req, res){
    res.render('index');
});

// Handle the form POST containing the question to ask Watson and reply with the answer

app.post('/', function(req, res){

// Select healthcare as endpoint 

var parts = url.parse(service_url +'/v1/question/healthcare');
// create the request options to POST our question to Watson

var options = { host: parts.hostname,
    port: parts.port,
    path: parts.pathname,
    method: 'POST',
    headers: {
      'Content-Type'  :'application/json',
      'Accept':'application/json',
      'X-synctimeout' : '30',
      'Authorization' :  auth }
  };

// Create a request to POST to Watson

var watson_req = https.request(options, function(result) {
    result.setEncoding('utf-8');
    var response_string = '';

    result.on('data', function(chunk) {
      response_string += chunk;
    });

    result.on('end', function() {
      var answers_pipeline = JSON.parse(response_string),
          answers = answers_pipeline[0];
      return res.render('index',{'questionText': req.body.questionText, 'answers': answers})
   })

  });

  watson_req.on('error', function(e) {
    return res.render('index', {'error': e.message})
  });

// create the question to Watson

var questionData = {
    'question': {
      'evidenceRequest': { 
        'items': 5 // the number of anwers
      },
      'questionText': req.body.questionText // the question
    }
  };

// Set the POST body and send to Watson

 watson_req.write(JSON.stringify(questionData));
 watson_req.end();

});

// The IP address of the Cloud Foundry DEA (Droplet Execution Agent) that hosts this application:

var host = (process.env.VCAP_APP_HOST || 'localhost');
// The port on the DEA for communication with the application:

var port = (process.env.VCAP_APP_PORT || 3000);
// Start server

app.listen(port, host);
Scandent answered 31/10, 2014 at 9:53 Comment(0)
G
6

Majority of this code is required for Node and for executing in the BlueMix environment. VCAP_SERVICES is the Bluemix environment variable that you use to obtain credentials for a given service that you are interested in using. In this case the service_name is set to "question_and_answer" to access the Question and Answer platform service.

In your Bluemix environment, you should have a Question and Answer service instance and an application. When the application is bound to the Question and Answer service it creates a service binding. The service binding has the application credentials to access the service instance. In this case, VCAP_SERVICES contains the URL, username and password of the binding used to communicated and authenticate with the service instance.

From your iOS app you will need a couple of things. First, you need a service binding and you have to, for now, create that in Bluemix. Once you have the credentials in Bluemix then you may use those in your iOS app. Or you could host an application on Bluemix and let that handle communication with Watson.

Next, you need the capability to invoke the Question and Answer service which is a RESTful service. In the code above, the variable options contains the necessary information to POST a question to the Watson service. Note that the service_url obtained from the credentials is appended with an additional path information to use the Watson For Healthcare domain.

From there you can create your question. Variable questionData contains the question in the code above. The question.questionText property is set to the question that you want to ask Watson, like, "Should I take aspirin on a daily basis?".

Then you can POST the question to Watson, as the following snippet does:

watson_req.write(JSON.stringify(questionData));

Node is asynchronous, so the response is handled in the http.request(...). The answer is sent back to the requesting application in

result.on('end', function() {
  var answers_pipeline = JSON.parse(response_string),
      answers = answers_pipeline[0];
  return res.render('index',{'questionText': req.body.questionText, 'answers': answers})
   })

Rest of the code is node specific. But I've outlined the basics that you need in your iOS application.

Greiner answered 5/11, 2014 at 20:17 Comment(0)
A
3

All the code is to handle a HTTPS request to the Watson Question and Answer service.

If you want to use the service in your IOs app you will have to:

  1. Modify the nodejs code and add REST API capabilities.

    For example, you should have an endpoint to receive a questions and return answers:

    app.get('/api/question', function(req, res){
        // Call the service with a question and get an array with the answers
        var answers = watson.question(req.query);
        // Send the answers and the question to the client in json
        res.json({answers: answers, question: req.query.question});
    });
    
  2. Start your app in bluemix and save the URL, it will be something like:

       http://my-cool-app.mybluemix.net
    
  3. Call your API at http://my-cool-app.mybluemix.net/api/question?question=Watson

Notes:

For the IOs app you can use AFNetworking.

You should also read move about the question and answer service documentation here, and read the about the service API here

Ascender answered 6/11, 2014 at 15:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.