Skip to content

Commit e0722af

Browse files
Merge pull request #314 from watson-developer-cloud/vr-similarity-search
VR similarity search
2 parents 08b9554 + dd3e6e0 commit e0722af

14 files changed

Lines changed: 630 additions & 61 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# v2.4.0
2+
* Added support for Visual Recognition similarity search beta
3+
* Refactored handling of credentials to support constraints in similarity search
4+
15
# v2.3.0
26
* Add support for RetrieveAndRankV1.rank() answers param
37

lib/base_service.js

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,14 @@ BaseService.prototype.initCredentials = function(options) {
7575
options
7676
);
7777

78-
// Use api_key or username and password as Authorization
79-
var user = options.username,
80-
pass = options.password,
81-
api_key = options.api_key;
82-
8378
if (!options.use_unauthenticated) {
84-
// Check if 'api_key' or 'username' and 'password' were provided
85-
if (typeof api_key === 'undefined') {
86-
if (typeof user === 'undefined' || typeof pass === 'undefined') {
87-
throw new Error('Argument error: api_key or username and password were not specified');
88-
}
89-
90-
// Calculate and add api_key
91-
options.api_key = new Buffer(user + ':' + pass).toString('base64');
79+
if (!options.username || !options.password) {
80+
throw new Error('Argument error: username and password are required unless use_unauthenticated is set');
9281
}
82+
83+
// Calculate and add Authorization header to base options
84+
var authHeader = {Authorization: 'Basic ' + new Buffer(options.username + ':' + options.password).toString('base64')};
85+
options.headers = extend(authHeader, options.headers);
9386
}
9487

9588
return options;

lib/base_service_alchemy.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ BaseServiceAlchemy.prototype.initCredentials = function(options) {
3030
this.getCredentialsFromEnvironment(this.name),
3131
options
3232
);
33-
if (!options.use_unauthenticated && !options.api_key) {
34-
throw new Error('Argument error: api_key was not specified');
33+
if (!options.use_unauthenticated) {
34+
if (!options.api_key) {
35+
throw new Error('Argument error: api_key was not specified');
36+
}
37+
options.qs = extend({ api_key : options.api_key }, options.qs);
3538
}
3639
return options
3740
};

lib/requestwrapper.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,6 @@ function createRequest(parameters, callback) {
117117
options.headers['User-Agent'] = pkg.name + '-nodejs-'+ pkg.version;
118118
}
119119

120-
if (typeof(options.api_key) !== 'undefined') {
121-
// Alchemy uses the apikey(a.k.a api_key) as query parameter
122-
// (Visual Recognition v3 accepts either one (api_key or apikey) but does not accept the key in an Authorization header!
123-
if (options.alchemy) {
124-
options.qs = extend({ apikey : options.api_key }, options.qs);
125-
delete options.alchemy;
126-
} else {
127-
// IBM Watson uses Basic auth
128-
options.headers['Authorization'] = 'Basic ' + options.api_key;
129-
}
130-
delete options.api_key;
131-
}
132-
133120
// Query params
134121
if (options.qs && Object.keys(options.qs).length > 0)
135122
options.useQuerystring = true;

speech-to-text/v1.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ SpeechToTextV1.prototype.createRecognizeStream = function(params) {
354354

355355
params.headers = extend({
356356
'user-agent': pkg.name + '-nodejs-'+ pkg.version,
357-
authorization: 'Basic ' + this._options.api_key
357+
authorization: this._options.headers.Authorization
358358
}, params.headers);
359359

360360
return new RecognizeStream(params);

test/resources/obama2.jpg

7.89 KB
Loading

test/test.alchemy_data_news.v1.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var watson = require('../');
55
var nock = require('nock');
66
var qs = require('querystring');
77

8-
describe('alchemy_language', function() {
8+
describe('alchemy_data_news', function() {
99

1010
var noop = function() {};
1111

@@ -51,7 +51,7 @@ describe('alchemy_language', function() {
5151
var req = alchemy.getNews(payload, noop);
5252
assert.equal(req.method, 'GET');
5353
var query = qs.stringify({
54-
apikey: 'foobar',
54+
api_key: 'foobar',
5555
start: 'bar',
5656
end: 'foo',
5757
q: 'q1.q2',

test/test.alchemy_language.v1.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('alchemy_language', function() {
4848

4949
it('should generate a valid payload', function() {
5050
var req = alchemy.entities(payload, noop);
51-
assert.equal(req.uri.href, service.url + apiPath + '?apikey=' + service.api_key);
51+
assert.equal(req.uri.href, service.url + apiPath + '?api_key=' + service.api_key);
5252
assert.equal(req.method, 'POST');
5353
assert(req.form);
5454
var body = new Buffer(req.body).toString('ascii');
@@ -57,7 +57,7 @@ describe('alchemy_language', function() {
5757

5858
it('should use sentiment_target if target is specified', function() {
5959
var req = alchemy.sentiment({text: payload.text, target:'bat'}, noop);
60-
var sentimenTargetPath = service.url + '/text/TextGetTargetedSentiment?apikey=' + service.api_key;
60+
var sentimenTargetPath = service.url + '/text/TextGetTargetedSentiment?api_key=' + service.api_key;
6161
assert.equal(req.uri.href, sentimenTargetPath);
6262
assert.equal(req.method, 'POST');
6363
assert(req.form);
@@ -68,7 +68,7 @@ describe('alchemy_language', function() {
6868

6969
it('should use sentiment if target is not specified', function() {
7070
var req = alchemy.sentiment(payload, noop);
71-
var sentimenPath = service.url + '/text/TextGetTextSentiment?apikey=' + service.api_key;
71+
var sentimenPath = service.url + '/text/TextGetTextSentiment?api_key=' + service.api_key;
7272
assert.equal(req.uri.href, sentimenPath);
7373
assert.equal(req.method, 'POST');
7474
assert(req.form);
@@ -79,7 +79,7 @@ describe('alchemy_language', function() {
7979

8080
it('should use /text/ endpoint if the text parameter is passed', function() {
8181
var req = alchemy.sentiment({text: payload.text, url:'www.ibm.com'}, noop);
82-
var sentimenPath = service.url + '/text/TextGetTextSentiment?apikey=' + service.api_key;
82+
var sentimenPath = service.url + '/text/TextGetTextSentiment?api_key=' + service.api_key;
8383
assert.equal(req.uri.href, sentimenPath);
8484
assert.equal(req.method, 'POST');
8585
assert(req.form);
@@ -90,7 +90,7 @@ describe('alchemy_language', function() {
9090

9191
it('should use /html/ endpoint if the html parameter is passed', function() {
9292
var req = alchemy.sentiment({html: '<html><body>test</body></html>', url:'www.ibm.com'}, noop);
93-
var sentimenPath = service.url + '/html/HTMLGetTextSentiment?apikey=' + service.api_key;
93+
var sentimenPath = service.url + '/html/HTMLGetTextSentiment?api_key=' + service.api_key;
9494
assert.equal(req.uri.href, sentimenPath);
9595
assert.equal(req.method, 'POST');
9696
assert(req.form);
@@ -119,7 +119,7 @@ describe('alchemy_language', function() {
119119

120120
it('should generate a valid payload', function() {
121121
var req = alchemy.title(payload, noop);
122-
assert.equal(req.uri.href, service.url + apiPath + '?apikey=' + service.api_key);
122+
assert.equal(req.uri.href, service.url + apiPath + '?api_key=' + service.api_key);
123123
assert.equal(req.method, 'POST');
124124
assert(req.form);
125125
var body = new Buffer(req.body).toString('ascii');
@@ -136,7 +136,7 @@ describe('alchemy_language', function() {
136136

137137
it('should generate a valid payload', function() {
138138
var req = alchemy.title(payload, noop);
139-
assert.equal(req.uri.href, service.url + apiPath + '?apikey=' + service.api_key);
139+
assert.equal(req.uri.href, service.url + apiPath + '?api_key=' + service.api_key);
140140
assert.equal(req.method, 'POST');
141141
assert(req.form);
142142
var body = new Buffer(req.body).toString('ascii');
@@ -155,7 +155,7 @@ describe('alchemy_language', function() {
155155

156156
it('should generate a valid payload', function() {
157157
var req = alchemy.dates(payload, noop);
158-
assert.equal(req.uri.href, service.url + apiPath + '?apikey=' + service.api_key);
158+
assert.equal(req.uri.href, service.url + apiPath + '?api_key=' + service.api_key);
159159
assert.equal(req.method, 'POST');
160160
assert(req.form);
161161
var body = new Buffer(req.body).toString('ascii');
@@ -178,7 +178,7 @@ describe('alchemy_language', function() {
178178

179179
it('should get document-level emotion if no target is passed', function() {
180180
var req = alchemy.emotion(payload, noop);
181-
var emotionPath = service.url + '/text/TextGetEmotion?apikey=' + service.api_key;
181+
var emotionPath = service.url + '/text/TextGetEmotion?api_key=' + service.api_key;
182182
assert.equal(req.uri.href, emotionPath);
183183
assert.equal(req.method, 'POST');
184184
assert(req.form);
@@ -190,7 +190,7 @@ describe('alchemy_language', function() {
190190

191191
it('should get targeted emotion if targets are passed', function() {
192192
var req = alchemy.emotion(target_payload, noop);
193-
var targetedEmotionPath = service.url + '/text/TextGetTargetedEmotion?apikey=' + service.api_key;
193+
var targetedEmotionPath = service.url + '/text/TextGetTargetedEmotion?api_key=' + service.api_key;
194194
assert.equal(req.uri.href, targetedEmotionPath);
195195
assert.equal(req.method, 'POST');
196196
assert(req.form);

test/test.alchemy_vision.v1.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('alchemy_vision', function() {
5050
assert.equal(req.method, 'POST');
5151
assert(req.form);
5252
var query = qs.stringify({
53-
apikey: 'foobar',
53+
api_key: 'foobar',
5454
outputMode: 'json',
5555
imagePostMode: 'raw'
5656
});
@@ -64,7 +64,7 @@ describe('alchemy_vision', function() {
6464
var req = alchemy.recognizeFaces({image: 'base64img'}, noop);
6565
assert.equal(req.method, 'POST');
6666
assert(req.form);
67-
assert.equal(req.uri.href, service.url + apiPath + '?apikey=foobar');
67+
assert.equal(req.uri.href, service.url + apiPath + '?api_key=foobar');
6868
var body = new Buffer(req.body).toString('ascii');
6969
var expectedBody = qs.stringify({
7070
image: 'base64img',
@@ -76,7 +76,7 @@ describe('alchemy_vision', function() {
7676

7777
it('should generate a valid payload with a url', function() {
7878
var req = alchemy.recognizeFaces({url : 'http://bat.com/foo.png'}, noop);
79-
var imagePath = service.url + '/url/URLGetRankedImageFaceTags?apikey=foobar';
79+
var imagePath = service.url + '/url/URLGetRankedImageFaceTags?api_key=foobar';
8080
assert.equal(req.uri.href, imagePath);
8181
assert.equal(req.method, 'POST');
8282
assert(req.form);

test/test.language_translator.v2.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ describe('language_translator', function() {
6666
"language_translation": details
6767
});
6868
var instance = watson.language_translator({version: 'v2', version_date: '2016-07-01'});
69-
assert(instance._options.api_key);
69+
assert(instance._options.headers.Authorization);
7070
});
7171

7272
it('should initialize with new-style VCAP_SERVICES credentials', function() {
7373
process.env.VCAP_SERVICES = JSON.stringify({
7474
"language_translator": details
7575
});
7676
var instance = watson.language_translator({version: 'v2', version_date: '2016-07-01'});
77-
assert(instance._options.api_key);
77+
assert(instance._options.headers.Authorization);
7878
});
7979
});
8080

0 commit comments

Comments
 (0)