Skip to content

Commit 9ed39fd

Browse files
add entity recognition for alchemy language #72
1 parent 69ddccf commit 9ed39fd

File tree

5 files changed

+128
-8
lines changed

5 files changed

+128
-8
lines changed

lib/helper.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ module.exports = {
3838
missing.push(require);
3939
});
4040
return missing.length > 0 ? missing : null;
41+
},
42+
43+
/**
44+
* Return true if 'text' is html
45+
* @param {String} text The 'text' to analyze
46+
* @return {Boolean} true if 'text' has html tags
47+
*/
48+
isHTML: function (text){
49+
return /<[a-z][\s\S]*>/i.test(text);
4150
}
4251

4352
};

lib/index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ var omit = require('object.omit');
2727
function createServiceAPI(serviceName) {
2828
return function(user_options) {
2929
var options = extend({}, user_options);
30+
var alchemy = (serviceName.indexOf('alchemy_') === 0);
31+
32+
// For Alchemy we use 'v1' by default,
33+
// and check if `apikey` was specified.
34+
// We don't use VCAP_SERVICES
35+
if (alchemy) {
36+
options.alchemy = true;
37+
options.version = 'v1';
38+
options.api_key = options.apikey || options.api_key;
39+
}
3040

3141
// Check if 'version' was provided
3242
var version = options.version;
@@ -49,7 +59,10 @@ function createServiceAPI(serviceName) {
4959
// Check if 'api_key' or 'username' and 'password' were provided
5060
if (typeof api_key === 'undefined') {
5161
if (typeof user === 'undefined' || typeof pass === 'undefined') {
52-
throw new Error('Argument error: api_key or username and password were not specified');
62+
if (alchemy)
63+
throw new Error('Argument error: api_key was not specified');
64+
else
65+
throw new Error('Argument error: api_key or username and password were not specified');
5366
}
5467

5568
// Calculate and add api_key
@@ -58,7 +71,7 @@ function createServiceAPI(serviceName) {
5871
}
5972

6073
options = omit(options, ['version', 'username', 'password',
61-
'use_vcap_services', 'use_unauthenticated']);
74+
'use_vcap_services', 'use_unauthenticated', 'apikey']);
6275

6376
if (options.url)
6477
options.url = helper.stripTrailingSlash(options.url);
@@ -97,7 +110,10 @@ var watson = {};
97110
// deprecated
98111
'language_identification',
99112
'machine_translation',
100-
'user_modeling'
113+
'user_modeling',
114+
115+
// alchemy
116+
'alchemy_language'
101117

102118
].forEach(function(api) {
103119
watson[api] = createServiceAPI(api);

lib/requestwrapper.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,25 @@ function createRequest(parameters, callback) {
100100
options.url = parsePath(options.url, path);
101101
delete options.path;
102102

103-
// Query params
104-
if (options.qs && Object.keys(options.qs).length > 0)
105-
options.useQuerystring = true;
106-
107103
// Headers
108104
options.headers = extend({}, options.headers);
109105
options.headers['User-Agent'] = pkg.name + '-nodejs-'+ pkg.version;
110106

111107
if (typeof(options.api_key) !== 'undefined') {
112-
options.headers['Authorization'] = 'Basic ' + options.api_key;
108+
// Alchemy uses the apikey(a.k.a api_key) as query parameter
109+
if (options.alchemy)
110+
options.qs.apikey = options.api_key;
111+
else
112+
// IBM Watson uses Basic auth
113+
options.headers['Authorization'] = 'Basic ' + options.api_key;
113114
delete options.api_key;
114115
}
115116

117+
// Query params
118+
if (options.qs && Object.keys(options.qs).length > 0)
119+
options.useQuerystring = true;
120+
121+
116122
// Add service default endpoint if options.url start with /
117123
if(options.url.charAt(0) === '/'){
118124
options.url = parameters.defaultOptions.url + options.url;

services/alchemy_language/v1.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright 2015 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
var extend = require('extend');
20+
var requestFactory = require('../../lib/requestwrapper');
21+
var pick = require('object.pick');
22+
var omit = require('object.omit');
23+
var isStream = require('isstream');
24+
25+
function AlchemyLanguage(options) {
26+
// Default URL
27+
var serviceDefaults = {
28+
url: 'https://access.alchemyapi.com/calls',
29+
alchmemy: true
30+
};
31+
32+
this.paths = {
33+
text: 'text/TextGetRankedNamedEntities',
34+
url: 'url/URLGetRankedNamedEntities',
35+
html: 'html/HTMLGetRankedNamedEntities'
36+
};
37+
38+
// Replace default options with user provided
39+
this._options = extend(serviceDefaults, options);
40+
}
41+
42+
/**
43+
* Extracts a grouped, ranked list of named entities (people, companies,
44+
* organizations, etc.) from within a text, url or html.
45+
*/
46+
AlchemyLanguage.prototype.entities = function(_params, callback) {
47+
var params = _params || {};
48+
var path = null;
49+
50+
if (typeof(params.text) === 'undefined' &&
51+
typeof(params.url) === 'undefined' &&
52+
typeof(params.html) === 'undefined') {
53+
callback(new Error('Missing required parameters: either text, ' +
54+
'url or html needs to be specified'));
55+
return;
56+
}
57+
58+
if (typeof(params.text) !== 'undefined')
59+
path = '/text/TextGetRankedNamedEntities';
60+
else if (typeof(params.url) !== 'undefined')
61+
path = '/url/URLGetRankedNamedEntities';
62+
else
63+
path = '/url/HTMLGetRankedNamedEntities';
64+
65+
var parameters = {
66+
options: {
67+
url: path,
68+
method: 'GET',
69+
json: true,
70+
path: params,
71+
qs: extend({outputMode: 'json'}, params) // change default output to json
72+
},
73+
requiredParams: ['text'],
74+
defaultOptions: this._options
75+
};
76+
return requestFactory(parameters, callback);
77+
};
78+
79+
module.exports = AlchemyLanguage;

test/test.wrapper.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ describe('wrapper', function() {
9999
assert.equal(service._options.api_key, 'dXNlcjpwYXNz');
100100
});
101101

102+
it('should use apikey (not documented) for alchemy service', function() {
103+
var service = watson.alchemy_language({ apikey: 'not-gonna-work'});
104+
assert.equal(service._options.api_key, 'not-gonna-work');
105+
});
106+
107+
it('should use api_key for alchemy service', function() {
108+
var service = watson.alchemy_language({ api_key: 'not-gonna-work'});
109+
assert.equal(service._options.api_key, 'not-gonna-work');
110+
});
111+
102112
it('should not use VCAP_SERVICES if use_vcap_services is false', function() {
103113
process.env.VCAP_SERVICES = JSON.stringify(vcap_services);
104114
var service = create_service({

0 commit comments

Comments
 (0)