Skip to content

Commit 6fb4a64

Browse files
authored
Merge pull request #674 from watson-developer-cloud/new-features
feat(visual recognition & nlc): vr: new coreML endpoint nlc: new classifyCollection endpoint
2 parents b87c063 + e444b40 commit 6fb4a64

File tree

7 files changed

+271
-57
lines changed

7 files changed

+271
-57
lines changed

natural-language-classifier/v1-generated.ts

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,49 @@ class NaturalLanguageClassifierV1 extends BaseService {
9797
return createRequest(parameters, _callback);
9898
};
9999

100+
/**
101+
* Classify multiple phrases.
102+
*
103+
* Returns label information for multiple phrases. The status must be `Available` before you can use the classifier to classify text. Note that classifying Japanese texts is a beta feature.
104+
*
105+
* @param {Object} params - The parameters to send to the service.
106+
* @param {string} params.classifier_id - Classifier ID to use.
107+
* @param {ClassifyInput[]} params.collection - The submitted phrases.
108+
* @param {Function} [callback] - The callback that handles the response.
109+
* @returns {NodeJS.ReadableStream|void}
110+
*/
111+
public classifyCollection(params: NaturalLanguageClassifierV1.ClassifyCollectionParams, callback?: NaturalLanguageClassifierV1.Callback<NaturalLanguageClassifierV1.ClassificationCollection>): NodeJS.ReadableStream | void {
112+
const _params = extend({}, params);
113+
const _callback = (callback) ? callback : () => { /* noop */ };
114+
const requiredParams = ['classifier_id', 'collection'];
115+
const missingParams = getMissingParams(_params, requiredParams);
116+
if (missingParams) {
117+
return _callback(missingParams);
118+
}
119+
const body = {
120+
'collection': _params.collection
121+
};
122+
const path = {
123+
'classifier_id': _params.classifier_id
124+
};
125+
const parameters = {
126+
options: {
127+
url: '/v1/classifiers/{classifier_id}/classify_collection',
128+
method: 'POST',
129+
json: true,
130+
body,
131+
path,
132+
},
133+
defaultOptions: extend(true, {}, this._options, {
134+
headers: {
135+
'Accept': 'application/json',
136+
'Content-Type': 'application/json',
137+
}
138+
})
139+
};
140+
return createRequest(parameters, _callback);
141+
};
142+
100143
/*************************
101144
* manageClassifiers
102145
************************/
@@ -107,8 +150,8 @@ class NaturalLanguageClassifierV1 extends BaseService {
107150
* Sends data to create and train a classifier and returns information about the new classifier.
108151
*
109152
* @param {Object} params - The parameters to send to the service.
110-
* @param {NodeJS.ReadableStream|FileObject|Buffer} params.metadata - Metadata in JSON format. The metadata identifies the language of the data, and an optional name to identify the classifier.
111-
* @param {NodeJS.ReadableStream|FileObject|Buffer} params.training_data - Training data in CSV format. Each text value must have at least one class. The data can include up to 15,000 records. For details, see [Using your own data](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html).
153+
* @param {NodeJS.ReadableStream|FileObject|Buffer} params.metadata - Metadata in JSON format. The metadata identifies the language of the data, and an optional name to identify the classifier. Specify the language with the 2-letter primary language code as assigned in ISO standard 639. Supported languages are English (`en`), Arabic (`ar`), French (`fr`), German, (`de`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Brazilian Portuguese (`pt`), and Spanish (`es`).
154+
* @param {NodeJS.ReadableStream|FileObject|Buffer} params.training_data - Training data in CSV format. Each text value must have at least one class. The data can include up to 20,000 records. For details, see [Data preparation](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html).
112155
* @param {Function} [callback] - The callback that handles the response.
113156
* @returns {NodeJS.ReadableStream|void}
114157
*/
@@ -283,11 +326,19 @@ namespace NaturalLanguageClassifierV1 {
283326
text: string;
284327
}
285328

329+
/** Parameters for the `classifyCollection` operation. */
330+
export interface ClassifyCollectionParams {
331+
/** Classifier ID to use. */
332+
classifier_id: string;
333+
/** The submitted phrases. */
334+
collection: ClassifyInput[];
335+
}
336+
286337
/** Parameters for the `createClassifier` operation. */
287338
export interface CreateClassifierParams {
288-
/** Metadata in JSON format. The metadata identifies the language of the data, and an optional name to identify the classifier. */
339+
/** Metadata in JSON format. The metadata identifies the language of the data, and an optional name to identify the classifier. Specify the language with the 2-letter primary language code as assigned in ISO standard 639. Supported languages are English (`en`), Arabic (`ar`), French (`fr`), German, (`de`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Brazilian Portuguese (`pt`), and Spanish (`es`). */
289340
metadata: NodeJS.ReadableStream|FileObject|Buffer;
290-
/** Training data in CSV format. Each text value must have at least one class. The data can include up to 15,000 records. For details, see [Using your own data](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html). */
341+
/** Training data in CSV format. Each text value must have at least one class. The data can include up to 20,000 records. For details, see [Data preparation](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html). */
291342
training_data: NodeJS.ReadableStream|FileObject|Buffer;
292343
}
293344

@@ -325,6 +376,16 @@ namespace NaturalLanguageClassifierV1 {
325376
classes?: ClassifiedClass[];
326377
}
327378

379+
/** Response from the classifier for multiple phrases. */
380+
export interface ClassificationCollection {
381+
/** Unique identifier for this classifier. */
382+
classifier_id?: string;
383+
/** Link to the classifier. */
384+
url?: string;
385+
/** An array of classifier responses for each submitted phrase. */
386+
collection?: CollectionItem[];
387+
}
388+
328389
/** Class and confidence. */
329390
export interface ClassifiedClass {
330391
/** A decimal percentage that represents the confidence that Watson has in this class. Higher values represent higher confidences. */
@@ -357,6 +418,22 @@ namespace NaturalLanguageClassifierV1 {
357418
classifiers: Classifier[];
358419
}
359420

421+
/** Request payload to classify. */
422+
export interface ClassifyInput {
423+
/** The submitted phrase. */
424+
text: string;
425+
}
426+
427+
/** Response from the classifier for a phrase in a collection. */
428+
export interface CollectionItem {
429+
/** The submitted phrase. */
430+
text?: string;
431+
/** The class with the highest confidence. */
432+
top_class?: string;
433+
/** An array of up to ten class-confidence pairs sorted in descending order of confidence. */
434+
classes?: ClassifiedClass[];
435+
}
436+
360437
}
361438

362439
export = NaturalLanguageClassifierV1;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
const nock = require('nock');
4+
const watson = require('../../index');
5+
const assert = require('assert');
6+
const authHelper = require('./auth_helper.js');
7+
const auth = authHelper.auth;
8+
const describe = authHelper.describe; // this runs describe.skip if there is no auth.js file :)
9+
const TWENTY_SECONDS = 20000;
10+
const TWO_SECONDS = 2000;
11+
12+
describe('natural_language_classifier_integration', function() {
13+
this.retries(1);
14+
15+
this.slow(TWO_SECONDS); // this controls when the tests get a colored warning for taking too long
16+
this.timeout(TWENTY_SECONDS);
17+
let natural_language_classifier;
18+
19+
before(function() {
20+
natural_language_classifier = new watson.NaturalLanguageClassifierV1(
21+
auth.natural_language_classifier
22+
);
23+
nock.enableNetConnect();
24+
});
25+
26+
after(function() {
27+
nock.disableNetConnect();
28+
});
29+
30+
it('getClassifier', function(done) {
31+
const params = {
32+
classifier_id: '842a87x335-nlc-94',
33+
};
34+
natural_language_classifier.getClassifier(params, function(err, result) {
35+
if (err) {
36+
return done(err);
37+
}
38+
assert.equal(result.classifier_id, params.classifier_id);
39+
done();
40+
});
41+
});
42+
43+
it('classifyCollection', function(done) {
44+
const params = {
45+
classifier_id: '842a87x335-nlc-94',
46+
collection: [{ text: 'string' }],
47+
};
48+
natural_language_classifier.classifyCollection(params, function(err, result) {
49+
if (err) {
50+
return done(err);
51+
}
52+
assert.equal(result.classifier_id, params.classifier_id);
53+
done();
54+
});
55+
});
56+
});

test/integration/test.visual_recognition.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ describe('visual_recognition_integration', function() {
121121
assert.equal(result.images[0].faces.length, 1, 'There should be exactly one face detected'); // note: the api was sometimes failing to detect any faces right after the release
122122
const face = result.images[0].faces[0];
123123
assert.equal(face.gender.gender, 'MALE');
124-
assert.equal(face.identity.name, 'Barack Obama');
125124
done();
126125
});
127126
});
@@ -147,7 +146,6 @@ describe('visual_recognition_integration', function() {
147146
assert.equal(result.images[0].faces.length, 1, 'There should be exactly one face detected'); // note: the api was sometimes failing to detect any faces right after the release
148147
const face = result.images[0].faces[0];
149148
assert.equal(face.gender.gender, 'MALE');
150-
assert.equal(face.identity.name, 'Barack Obama');
151149
done();
152150
});
153151
});

test/unit/test.adapter.natural_language_classifier.v1.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const watson = require('../../index');
55
const nock = require('nock');
66
const fs = require('fs');
77
const extend = require('extend');
8+
const pick = require('object.pick');
89

910
const service = {
1011
username: 'foo',
@@ -72,7 +73,7 @@ const createWithJson = extend(
7273
);
7374

7475
describe('natural_language_classifer', function() {
75-
it('should fail if no parameters are provided for create, classify, status and delete requests', function() {
76+
it('should fail if no parameters are provided for create, classify, classifyCollection, status and delete requests', function() {
7677
natural_language_classifier.classify({}, missingParameter);
7778
natural_language_classifier.classify(null, missingParameter);
7879
natural_language_classifier.classify(undefined, missingParameter);
@@ -88,9 +89,13 @@ describe('natural_language_classifer', function() {
8889
natural_language_classifier.remove({}, missingParameter);
8990
natural_language_classifier.remove(null, missingParameter);
9091
natural_language_classifier.remove(undefined, missingParameter);
92+
93+
natural_language_classifier.classifyCollection({}, missingParameter);
94+
natural_language_classifier.classifyCollection(null, missingParameter);
95+
natural_language_classifier.classifyCollection(undefined, missingParameter);
9196
});
9297

93-
it('should fail if no classifier is provided for classify, status and delete requests', function() {
98+
it('should fail if no classifier is provided for classify, status, classifyCollection, and delete requests', function() {
9499
natural_language_classifier.classify(emptyData, missingParameter);
95100
natural_language_classifier.classify(emptyClassifier, missingParameter);
96101
natural_language_classifier.classify(nullClassifier, missingParameter);
@@ -110,6 +115,13 @@ describe('natural_language_classifer', function() {
110115
natural_language_classifier.remove(undefinedClassifier, missingParameter);
111116
natural_language_classifier.remove(emptyDataClassifier, missingParameter);
112117
natural_language_classifier.remove(nullDataClassifier, missingParameter);
118+
119+
natural_language_classifier.classifyCollection(emptyData, missingParameter);
120+
natural_language_classifier.classifyCollection(emptyClassifier, missingParameter);
121+
natural_language_classifier.classifyCollection(nullClassifier, missingParameter);
122+
natural_language_classifier.classifyCollection(undefinedClassifier, missingParameter);
123+
natural_language_classifier.classifyCollection(emptyDataClassifier, missingParameter);
124+
natural_language_classifier.classifyCollection(nullDataClassifier, missingParameter);
113125
});
114126

115127
it('should fail if no data provided create and classify requests', function() {
@@ -159,4 +171,16 @@ describe('natural_language_classifer', function() {
159171
params.training_data = [{ json: 'bad' }];
160172
natural_language_classifier.create(params, invalidFormatParameter);
161173
});
174+
175+
it('should classify collection', function() {
176+
const params = {
177+
classifier_id: 'good',
178+
collection: { text: 'text' },
179+
};
180+
const req = natural_language_classifier.classifyCollection(params, goodRequest);
181+
const body = Buffer.from(req.body).toString('ascii');
182+
assert.deepEqual(JSON.parse(body), pick(params, ['collection']));
183+
assert.equal(req.method, 'POST');
184+
assert.equal(req.uri.href, 'http://ibm.com:80/v1/classifiers/good/classify_collection');
185+
});
162186
});

test/unit/test.assistant.v1.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const assert = require('assert');
44
const watson = require('../../index');
5-
const sinon = require('sinon');
65
const nock = require('nock');
76
const extend = require('extend');
87
const pick = require('object.pick');

test/unit/test.visual_recognition.v3.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,25 @@ describe('visual_recognition', function() {
523523
});
524524
});
525525

526+
describe('getCoreMlModel()', function() {
527+
it('should check no parameters provided', function() {
528+
visual_recognition.getCoreMlModel({}, missingParameter);
529+
visual_recognition.getCoreMlModel(null, missingParameter);
530+
visual_recognition.getCoreMlModel(undefined, missingParameter);
531+
});
532+
533+
it('should generate a valid payload ', function() {
534+
const params = { classifier_id: 'foo' };
535+
536+
const req = visual_recognition.getCoreMlModel(params, noop);
537+
assert.equal(
538+
req.uri.href,
539+
service.url + '/v3/classifiers/foo/core_ml_model?' + api_key_qs + '&' + version_qs
540+
);
541+
assert.equal(req.method, 'GET');
542+
});
543+
});
544+
526545
describe('Print a warning for deprecated methods()', function() {
527546
let spy;
528547
beforeEach(function() {

0 commit comments

Comments
 (0)