ibm_watson 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/ibm_watson/assistant_v1.rb +1 -0
- data/lib/ibm_watson/discovery_v1.rb +1 -0
- data/lib/ibm_watson/iam_token_manager.rb +0 -9
- data/lib/ibm_watson/language_translator_v3.rb +1 -0
- data/lib/ibm_watson/natural_language_classifier_v1.rb +1 -0
- data/lib/ibm_watson/natural_language_understanding_v1.rb +1 -0
- data/lib/ibm_watson/personality_insights_v3.rb +1 -0
- data/lib/ibm_watson/speech_to_text_v1.rb +12 -14
- data/lib/ibm_watson/text_to_speech_v1.rb +1 -0
- data/lib/ibm_watson/tone_analyzer_v3.rb +1 -0
- data/lib/ibm_watson/version.rb +1 -1
- data/lib/ibm_watson/visual_recognition_v3.rb +54 -47
- data/lib/ibm_watson/watson_api_exception.rb +3 -3
- data/lib/ibm_watson/watson_service.rb +2 -2
- data/lib/ibm_watson/websocket/speech_to_text_websocket_listener.rb +3 -6
- data/rakefile +1 -1
- data/test/integration/test_assistant_v1.rb +8 -0
- data/test/integration/test_discovery_v1.rb +8 -0
- data/test/integration/test_iam_assistant_v1.rb +10 -1
- data/test/integration/test_speech_to_text_v1.rb +67 -2
- data/test/integration/test_text_to_speech_v1.rb +1 -0
- data/test/integration/test_visual_recognition_v3.rb +1 -1
- data/test/unit/test_personality_insights_v3.rb +3 -3
- data/test/unit/test_speech_to_text_v1.rb +18 -1
- data/test/unit/test_vcap_using_personality_insights.rb +1 -1
- data/test/unit/test_visual_recognition_v3.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39e925f6844d37eeebbebfb1e39ff405a88e73d98c9ac17132b4884c8d36c6ab
|
4
|
+
data.tar.gz: cd57ff7e6d36132f415aad355ebae50f09b79c64f649e08b6d3bd3e5559fa926
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a86e448912a28076ff77fc3a81de35b0c022da99bf25595c171f80767315c5941867937cc44c1275b2790c8f0316cc557ea65457e7dc1a8c3141658cc795420e
|
7
|
+
data.tar.gz: c1903e079f5f41a3218ea182ffd99f00b043521ff57798ad25282e033407e73a8685d44a434063190db7b81743b21d080bd7e4196b6f488f6a8a850e4d7d6675
|
data/README.md
CHANGED
@@ -207,8 +207,8 @@ p "Result: #{response.result}"
|
|
207
207
|
This would give an output of `DetailedResponse` having the structure:
|
208
208
|
```ruby
|
209
209
|
Status: 200
|
210
|
-
Headers: <http response headers>
|
211
|
-
Result: <response returned by service>
|
210
|
+
Headers: "<http response headers>"
|
211
|
+
Result: "<response returned by service>"
|
212
212
|
```
|
213
213
|
|
214
214
|
## Using Websockets
|
@@ -43,15 +43,6 @@ class IAMTokenManager
|
|
43
43
|
headers: headers,
|
44
44
|
params: params
|
45
45
|
)
|
46
|
-
else
|
47
|
-
data = data.to_json if data.respond_to?(:to_json)
|
48
|
-
response = HTTP.request(
|
49
|
-
method,
|
50
|
-
url,
|
51
|
-
headers: headers,
|
52
|
-
body: data,
|
53
|
-
params: params
|
54
|
-
)
|
55
46
|
end
|
56
47
|
return JSON.parse(response.body.to_s) if (200..299).cover?(response.code)
|
57
48
|
require_relative("./watson_api_exception.rb")
|
@@ -74,6 +74,7 @@ require_relative "./detailed_response"
|
|
74
74
|
|
75
75
|
require_relative "./watson_service"
|
76
76
|
|
77
|
+
# Module for the Watson APIs
|
77
78
|
module IBMWatson
|
78
79
|
##
|
79
80
|
# The Speech to Text V1 service.
|
@@ -408,6 +409,7 @@ module IBMWatson
|
|
408
409
|
response
|
409
410
|
end
|
410
411
|
|
412
|
+
##
|
411
413
|
# @!method recognize_with_websocket(audio: nil,chunk_data: false,content_type: "audio/l16; rate=44100",model: "en-US_BroadbandModel",recognize_callback: nil,customization_id: nil,acoustic_customization_id: nil,customization_weight: nil,version: nil,inactivity_timeout: 30,interim_results: false,keywords: nil,keywords_threshold: nil,max_alternatives: 1,word_alternatives_threshold: nil,word_confidence: false,timestamps: false,profanity_filter: nil,smart_formatting: false,speaker_labels: nil)
|
412
414
|
# Sends audio for speech recognition using web sockets.
|
413
415
|
# @param audio [IO] Audio to transcribe in the format specified by the `Content-Type` header.
|
@@ -455,13 +457,16 @@ module IBMWatson
|
|
455
457
|
)
|
456
458
|
raise ArgumentError("Audio must be provided") if audio.nil? && !chunk_data
|
457
459
|
raise ArgumentError("Recognize callback must be provided") if recognize_callback.nil?
|
458
|
-
raise TypeError("Callback is not a derived class of RecognizeCallback") unless recognize_callback.is_a?(RecognizeCallback)
|
459
|
-
|
460
|
+
raise TypeError("Callback is not a derived class of RecognizeCallback") unless recognize_callback.is_a?(IBMWatson::RecognizeCallback)
|
460
461
|
require_relative("./websocket/speech_to_text_websocket_listener.rb")
|
461
|
-
|
462
462
|
headers = {}
|
463
463
|
headers = @watson_service.conn.default_options.headers.to_hash unless @watson_service.conn.default_options.headers.to_hash.empty?
|
464
|
-
|
464
|
+
if !@watson_service.token_manager.nil?
|
465
|
+
access_token = @watson_service.token_manager._token
|
466
|
+
headers["Authorization"] = "Bearer #{access_token}"
|
467
|
+
elsif !@watson_service.username.nil? && !@watson_service.password.nil?
|
468
|
+
headers["Authorization"] = "Basic " + Base64.strict_encode64("#{@watson_service.username}:#{@watson_service.password}")
|
469
|
+
end
|
465
470
|
url = @watson_service.url.gsub("https:", "wss:")
|
466
471
|
params = {
|
467
472
|
"model" => model,
|
@@ -472,7 +477,6 @@ module IBMWatson
|
|
472
477
|
}
|
473
478
|
params.delete_if { |_, v| v.nil? }
|
474
479
|
url += "/v1/recognize?" + HTTP::URI.form_encode(params)
|
475
|
-
|
476
480
|
options = {
|
477
481
|
"content_type" => content_type,
|
478
482
|
"inactivity_timeout" => inactivity_timeout,
|
@@ -490,7 +494,6 @@ module IBMWatson
|
|
490
494
|
options.delete_if { |_, v| v.nil? }
|
491
495
|
WebSocketClient.new(audio: audio, chunk_data: chunk_data, options: options, recognize_callback: recognize_callback, url: url, headers: headers)
|
492
496
|
end
|
493
|
-
|
494
497
|
#########################
|
495
498
|
# Asynchronous
|
496
499
|
#########################
|
@@ -1467,7 +1470,7 @@ module IBMWatson
|
|
1467
1470
|
end
|
1468
1471
|
|
1469
1472
|
##
|
1470
|
-
# @!method add_word(customization_id:, word_name:,
|
1473
|
+
# @!method add_word(customization_id:, word_name:, sounds_like: nil, display_as: nil)
|
1471
1474
|
# Add a custom word.
|
1472
1475
|
# Adds a custom word to a custom language model. The service populates the words
|
1473
1476
|
# resource for a custom model with out-of-vocabulary (OOV) words found in each
|
@@ -1509,11 +1512,6 @@ module IBMWatson
|
|
1509
1512
|
# @param word_name [String] The custom word for the custom language model. When you add or update a custom
|
1510
1513
|
# word with the **Add a custom word** method, do not include spaces in the word. Use
|
1511
1514
|
# a `-` (dash) or `_` (underscore) to connect the tokens of compound words.
|
1512
|
-
# @param word [String] For the **Add custom words** method, you must specify the custom word that is to
|
1513
|
-
# be added to or updated in the custom model. Do not include spaces in the word. Use
|
1514
|
-
# a `-` (dash) or `_` (underscore) to connect the tokens of compound words.
|
1515
|
-
#
|
1516
|
-
# Omit this field for the **Add a custom word** method.
|
1517
1515
|
# @param sounds_like [Array[String]] An array of sounds-like pronunciations for the custom word. Specify how words that
|
1518
1516
|
# are difficult to pronounce, foreign words, acronyms, and so on can be pronounced
|
1519
1517
|
# by users. For a word that is not in the service's base vocabulary, omit the
|
@@ -1528,13 +1526,13 @@ module IBMWatson
|
|
1528
1526
|
# the parameter when you want the word to have a spelling that is different from its
|
1529
1527
|
# usual representation or from its spelling in corpora training data.
|
1530
1528
|
# @return [nil]
|
1531
|
-
def add_word(customization_id:, word_name:,
|
1529
|
+
def add_word(customization_id:, word_name:, sounds_like: nil, display_as: nil)
|
1532
1530
|
raise ArgumentError("customization_id must be provided") if customization_id.nil?
|
1533
1531
|
raise ArgumentError("word_name must be provided") if word_name.nil?
|
1534
1532
|
headers = {
|
1535
1533
|
}
|
1536
1534
|
data = {
|
1537
|
-
"word" =>
|
1535
|
+
"word" => word_name,
|
1538
1536
|
"sounds_like" => sounds_like,
|
1539
1537
|
"display_as" => display_as
|
1540
1538
|
}
|
data/lib/ibm_watson/version.rb
CHANGED
@@ -25,6 +25,7 @@ require_relative "./detailed_response"
|
|
25
25
|
|
26
26
|
require_relative "./watson_service"
|
27
27
|
|
28
|
+
# Module for the Watson APIs
|
28
29
|
module IBMWatson
|
29
30
|
##
|
30
31
|
# The Visual Recognition V3 service.
|
@@ -288,7 +289,7 @@ module IBMWatson
|
|
288
289
|
#########################
|
289
290
|
|
290
291
|
##
|
291
|
-
# @!method create_classifier(name:,
|
292
|
+
# @!method create_classifier(name:, **args)
|
292
293
|
# Create a classifier.
|
293
294
|
# Train a new multi-faceted classifier on the uploaded image data. Create your
|
294
295
|
# custom classifier with positive or negative examples. Include at least two sets of
|
@@ -299,7 +300,8 @@ module IBMWatson
|
|
299
300
|
# file names, and classifier and class names). The service assumes UTF-8 encoding if
|
300
301
|
# it encounters non-ASCII characters.
|
301
302
|
# @param name [String] The name of the new classifier. Encode special characters in UTF-8.
|
302
|
-
# @param
|
303
|
+
# @param args [Hash] Hash for optional parameters
|
304
|
+
# @option args classname_positive_examples [File] A .zip file of images that depict the visual subject of a class in the new
|
303
305
|
# classifier. You can include more than one positive example file in a call.
|
304
306
|
#
|
305
307
|
# Specify the parameter name by appending `_positive_examples` to the class name.
|
@@ -315,48 +317,51 @@ module IBMWatson
|
|
315
317
|
# of the new classifier. Must contain a minimum of 10 images.
|
316
318
|
#
|
317
319
|
# Encode special characters in the file name in UTF-8.
|
318
|
-
# @
|
319
|
-
# @
|
320
|
+
# @option args classname_positive_examples_filename [String] The filename for classname_positive_examples.
|
321
|
+
# @option args negative_examples_filename [String] The filename for negative_examples.
|
320
322
|
# @return [DetailedResponse] A `DetailedResponse` object representing the response.
|
321
|
-
def create_classifier(name:,
|
323
|
+
def create_classifier(name:, **args)
|
322
324
|
raise ArgumentError("name must be provided") if name.nil?
|
323
|
-
raise ArgumentError("
|
325
|
+
raise ArgumentError("<classname>_positive_examples must be provided") unless args.keys.any? { |key| key.to_s.end_with?("_positive_examples") }
|
326
|
+
positive_keys = args.keys
|
327
|
+
positive_keys.keep_if { |key| key.to_s.end_with?("_positive_examples") }
|
324
328
|
headers = {
|
325
329
|
}
|
326
330
|
params = {
|
327
331
|
"version" => @version
|
328
332
|
}
|
329
333
|
mime_type = "application/octet-stream"
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
334
|
+
positive_keys.each do |k|
|
335
|
+
unless args[k].instance_of?(StringIO) || args[k].instance_of?(File)
|
336
|
+
args[k] = args[k].respond_to?(:to_json) ? StringIO.new(args[k].to_json) : StringIO.new(args[k])
|
337
|
+
end
|
338
|
+
if !args[(k.to_s + "_filename").to_sym].nil?
|
339
|
+
args[k] = args[k].instance_of?(StringIO) ? HTTP::FormData::File.new(args[k], content_type: mime_type, filename: args[(k.to_s + "_filename").to_sym]) : HTTP::FormData::File.new(args[k].path, content_type: mime_type, filename: args[(k.to_s + "_filename").to_sym])
|
340
|
+
else
|
341
|
+
args[k] = args[k].instance_of?(StringIO) ? HTTP::FormData::File.new(args[k], content_type: mime_type) : HTTP::FormData::File.new(args[k].path, content_type: mime_type)
|
342
|
+
end
|
337
343
|
end
|
338
|
-
unless negative_examples.nil?
|
344
|
+
unless args[:negative_examples].nil?
|
339
345
|
mime_type = "application/octet-stream"
|
340
|
-
unless negative_examples.instance_of?(StringIO) || negative_examples.instance_of?(File)
|
341
|
-
negative_examples = negative_examples.respond_to?(:to_json) ? StringIO.new(negative_examples.to_json) : StringIO.new(negative_examples)
|
346
|
+
unless args[:negative_examples].instance_of?(StringIO) || args[:negative_examples].instance_of?(File)
|
347
|
+
args[:negative_examples] = args[:negative_examples].respond_to?(:to_json) ? StringIO.new(args[:negative_examples].to_json) : StringIO.new(args[:negative_examples])
|
342
348
|
end
|
343
|
-
if negative_examples_filename
|
344
|
-
negative_examples = negative_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(negative_examples, content_type: mime_type, filename: negative_examples_filename) : HTTP::FormData::File.new(negative_examples.path, content_type: mime_type, filename: negative_examples_filename)
|
349
|
+
if args[:negative_examples_filename]
|
350
|
+
args[:negative_examples] = args[:negative_examples].instance_of?(StringIO) ? HTTP::FormData::File.new(args[:negative_examples], content_type: mime_type, filename: args[:negative_examples_filename]) : HTTP::FormData::File.new(args[:negative_examples].path, content_type: mime_type, filename: args[:negative_examples_filename])
|
345
351
|
else
|
346
|
-
negative_examples = negative_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(negative_examples, content_type: mime_type) : HTTP::FormData::File.new(negative_examples.path, content_type: mime_type)
|
352
|
+
args[:negative_examples] = args[:negative_examples].instance_of?(StringIO) ? HTTP::FormData::File.new(args[:negative_examples], content_type: mime_type) : HTTP::FormData::File.new(args[:negative_examples].path, content_type: mime_type)
|
347
353
|
end
|
348
354
|
end
|
355
|
+
form_hash = { name: name }
|
356
|
+
positive_keys.each { |k| form_hash[k] = args[k] }
|
357
|
+
form_hash[:negative_examples] = args[:negative_examples] unless args[:negative_examples].nil?
|
349
358
|
method_url = "/v3/classifiers"
|
350
359
|
response = request(
|
351
360
|
method: "POST",
|
352
361
|
url: method_url,
|
353
362
|
headers: headers,
|
354
363
|
params: params,
|
355
|
-
form:
|
356
|
-
name: name,
|
357
|
-
classname_positive_examples: classname_positive_examples,
|
358
|
-
negative_examples: negative_examples
|
359
|
-
},
|
364
|
+
form: form_hash,
|
360
365
|
accept_json: true
|
361
366
|
)
|
362
367
|
response
|
@@ -411,7 +416,7 @@ module IBMWatson
|
|
411
416
|
end
|
412
417
|
|
413
418
|
##
|
414
|
-
# @!method update_classifier(classifier_id:,
|
419
|
+
# @!method update_classifier(classifier_id:, **args)
|
415
420
|
# Update a classifier.
|
416
421
|
# Update a custom classifier by adding new positive or negative classes (examples)
|
417
422
|
# or by adding new images to existing classes. You must supply at least one set of
|
@@ -427,7 +432,7 @@ module IBMWatson
|
|
427
432
|
# previous requests. The retrained property shows the last time the classifier
|
428
433
|
# retraining finished.
|
429
434
|
# @param classifier_id [String] The ID of the classifier.
|
430
|
-
# @
|
435
|
+
# @option args classname_positive_examples [File] A .zip file of images that depict the visual subject of a class in the classifier.
|
431
436
|
# The positive examples create or update classes in the classifier. You can include
|
432
437
|
# more than one positive example file in a call.
|
433
438
|
#
|
@@ -440,52 +445,54 @@ module IBMWatson
|
|
440
445
|
# MB per .zip file.
|
441
446
|
#
|
442
447
|
# Encode special characters in the file name in UTF-8.
|
443
|
-
# @
|
448
|
+
# @option args negative_examples [File] A .zip file of images that do not depict the visual subject of any of the classes
|
444
449
|
# of the new classifier. Must contain a minimum of 10 images.
|
445
450
|
#
|
446
451
|
# Encode special characters in the file name in UTF-8.
|
447
|
-
# @
|
448
|
-
# @
|
452
|
+
# @option args classname_positive_examples_filename [String] The filename for classname_positive_examples.
|
453
|
+
# @option args negative_examples_filename [String] The filename for negative_examples.
|
449
454
|
# @return [DetailedResponse] A `DetailedResponse` object representing the response.
|
450
|
-
def update_classifier(classifier_id:,
|
455
|
+
def update_classifier(classifier_id:, **args)
|
451
456
|
raise ArgumentError("classifier_id must be provided") if classifier_id.nil?
|
452
457
|
headers = {
|
453
458
|
}
|
454
459
|
params = {
|
455
460
|
"version" => @version
|
456
461
|
}
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
462
|
+
positive_keys = args.keys
|
463
|
+
positive_keys.keep_if { |key| key.to_s.end_with?("_positive_examples") }
|
464
|
+
mime_type = "application/octet-stream"
|
465
|
+
positive_keys.each do |k|
|
466
|
+
unless args[k].instance_of?(StringIO) || args[k].instance_of?(File)
|
467
|
+
args[k] = args[k].respond_to?(:to_json) ? StringIO.new(args[k].to_json) : StringIO.new(args[k])
|
461
468
|
end
|
462
|
-
if
|
463
|
-
|
469
|
+
if !args[(k.to_s + "_filename").to_sym].nil?
|
470
|
+
args[k] = args[k].instance_of?(StringIO) ? HTTP::FormData::File.new(args[k], content_type: mime_type, filename: args[(k.to_s + "_filename").to_sym]) : HTTP::FormData::File.new(args[k].path, content_type: mime_type, filename: args[(k.to_s + "_filename").to_sym])
|
464
471
|
else
|
465
|
-
|
472
|
+
args[k] = args[k].instance_of?(StringIO) ? HTTP::FormData::File.new(args[k], content_type: mime_type) : HTTP::FormData::File.new(args[k].path, content_type: mime_type)
|
466
473
|
end
|
467
474
|
end
|
468
|
-
unless negative_examples.nil?
|
475
|
+
unless args[:negative_examples].nil?
|
469
476
|
mime_type = "application/octet-stream"
|
470
|
-
unless negative_examples.instance_of?(StringIO) || negative_examples.instance_of?(File)
|
471
|
-
negative_examples = negative_examples.respond_to?(:to_json) ? StringIO.new(negative_examples.to_json) : StringIO.new(negative_examples)
|
477
|
+
unless args[:negative_examples].instance_of?(StringIO) || args[:negative_examples].instance_of?(File)
|
478
|
+
args[:negative_examples] = args[:negative_examples].respond_to?(:to_json) ? StringIO.new(args[:negative_examples].to_json) : StringIO.new(args[:negative_examples])
|
472
479
|
end
|
473
|
-
if negative_examples_filename
|
474
|
-
negative_examples = negative_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(negative_examples, content_type: mime_type, filename: negative_examples_filename) : HTTP::FormData::File.new(negative_examples.path, content_type: mime_type, filename: negative_examples_filename)
|
480
|
+
if args[:negative_examples_filename]
|
481
|
+
args[:negative_examples] = args[:negative_examples].instance_of?(StringIO) ? HTTP::FormData::File.new(args[:negative_examples], content_type: mime_type, filename: args[:negative_examples_filename]) : HTTP::FormData::File.new(args[:negative_examples].path, content_type: mime_type, filename: args[:negative_examples_filename])
|
475
482
|
else
|
476
|
-
negative_examples = negative_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(negative_examples, content_type: mime_type) : HTTP::FormData::File.new(negative_examples.path, content_type: mime_type)
|
483
|
+
args[:negative_examples] = args[:negative_examples].instance_of?(StringIO) ? HTTP::FormData::File.new(args[:negative_examples], content_type: mime_type) : HTTP::FormData::File.new(args[:negative_examples].path, content_type: mime_type)
|
477
484
|
end
|
478
485
|
end
|
486
|
+
form_hash = {}
|
487
|
+
positive_keys.each { |k| form_hash[k] = args[k] }
|
488
|
+
form_hash[:negative_examples] = args[:negative_examples] unless args[:negative_examples].nil?
|
479
489
|
method_url = "/v3/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]
|
480
490
|
response = request(
|
481
491
|
method: "POST",
|
482
492
|
url: method_url,
|
483
493
|
headers: headers,
|
484
494
|
params: params,
|
485
|
-
form:
|
486
|
-
classname_positive_examples: classname_positive_examples,
|
487
|
-
negative_examples: negative_examples
|
488
|
-
},
|
495
|
+
form: form_hash,
|
489
496
|
accept_json: true
|
490
497
|
)
|
491
498
|
response
|
@@ -11,9 +11,9 @@ class WatsonApiException < StandardError
|
|
11
11
|
@error = response.reason
|
12
12
|
unless response.body.empty?
|
13
13
|
body_hash = JSON.parse(response.body.to_s)
|
14
|
-
@code = body_hash["code"] || body_hash["error_code"]
|
15
|
-
@error = body_hash["error"] || body_hash["error_message"]
|
16
|
-
%w[code error_code error error_message].each { |k| body_hash.delete(k) }
|
14
|
+
@code = body_hash["code"] || body_hash["error_code"] || body_hash["status"]
|
15
|
+
@error = body_hash["error"] || body_hash["error_message"] || body_hash["statusInfo"] || body_hash["description"]
|
16
|
+
%w[code error_code status error error_message statusInfo description].each { |k| body_hash.delete(k) }
|
17
17
|
@info = body_hash
|
18
18
|
end
|
19
19
|
@transaction_id = transaction_id
|
@@ -21,7 +21,7 @@ require_relative("./version.rb")
|
|
21
21
|
# Class for interacting with the Watson API
|
22
22
|
class WatsonService
|
23
23
|
attr_accessor :password, :url, :username
|
24
|
-
attr_reader :conn
|
24
|
+
attr_reader :conn, :token_manager
|
25
25
|
def initialize(vars)
|
26
26
|
defaults = {
|
27
27
|
vcap_services_name: nil,
|
@@ -123,7 +123,7 @@ class WatsonService
|
|
123
123
|
args[:json] = args[:data].merge(args[:json]) if args[:data].respond_to?(:merge)
|
124
124
|
args[:json] = args[:data] if args[:json].empty? || (args[:data].instance_of?(String) && !args[:data].empty?)
|
125
125
|
args[:json].delete_if { |_k, v| v.nil? } if args[:json].instance_of?(Hash)
|
126
|
-
args[:headers]["Accept"] = "application/json" if args[:accept_json]
|
126
|
+
args[:headers]["Accept"] = "application/json" if args[:accept_json] && args[:headers]["Accept"].nil?
|
127
127
|
args[:headers]["Content-Type"] = "application/json" unless args[:headers].key?("Content-Type")
|
128
128
|
args[:json] = args[:json].to_json if args[:json].instance_of?(Hash)
|
129
129
|
args[:headers].delete_if { |_k, v| v.nil? } if args[:headers].instance_of?(Hash)
|
@@ -72,7 +72,7 @@ class WebSocketClient
|
|
72
72
|
end
|
73
73
|
|
74
74
|
on_error = lambda do |event|
|
75
|
-
|
75
|
+
@callback.on_error(error: event)
|
76
76
|
end
|
77
77
|
|
78
78
|
EM&.reactor_thread&.join
|
@@ -127,12 +127,9 @@ class WebSocketClient
|
|
127
127
|
end
|
128
128
|
else
|
129
129
|
if @bytes_sent + ONE_KB >= @data_size
|
130
|
-
|
131
|
-
send_chunk(chunk: data.read(ONE_KB), final: true)
|
132
|
-
@timer.cancel if @timer.respond_to?(:cancel)
|
133
|
-
return
|
134
|
-
end
|
130
|
+
send_chunk(chunk: data.read(ONE_KB), final: true)
|
135
131
|
@timer.cancel if @timer.respond_to?(:cancel)
|
132
|
+
return
|
136
133
|
end
|
137
134
|
send_chunk(chunk: data.read(ONE_KB), final: false)
|
138
135
|
end
|
data/rakefile
CHANGED
@@ -37,7 +37,7 @@ end
|
|
37
37
|
|
38
38
|
desc "Run tests and generate a code coverage report"
|
39
39
|
task :coverage do
|
40
|
-
ENV["COVERAGE"] = "true" if ENV["TRAVIS_RUBY_VERSION"] == "2.5.1"
|
40
|
+
ENV["COVERAGE"] = "true" if ENV["TRAVIS_RUBY_VERSION"] == "2.5.1" || ENV["CI"].nil?
|
41
41
|
Rake::Task["test"].execute
|
42
42
|
end
|
43
43
|
|
@@ -7,6 +7,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
7
7
|
# Integration tests for the Watson Assistant V1 Service
|
8
8
|
class AssistantV1Test < Minitest::Test
|
9
9
|
def test_create_update_delete_workspace
|
10
|
+
skip "Skip to allow for concurrent travis jobs"
|
10
11
|
service = IBMWatson::AssistantV1.new(
|
11
12
|
username: ENV["ASSISTANT_USERNAME"],
|
12
13
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -78,6 +79,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def test_create_update_delete_counterexample
|
82
|
+
skip "Skip to allow for concurrent travis jobs"
|
81
83
|
service = IBMWatson::AssistantV1.new(
|
82
84
|
version: "2018-02-16",
|
83
85
|
username: ENV["ASSISTANT_USERNAME"],
|
@@ -147,6 +149,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
147
149
|
end
|
148
150
|
|
149
151
|
def test_create_update_delete_entity
|
152
|
+
skip "Skip to allow for concurrent travis jobs"
|
150
153
|
service = IBMWatson::AssistantV1.new(
|
151
154
|
username: ENV["ASSISTANT_USERNAME"],
|
152
155
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -222,6 +225,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
222
225
|
end
|
223
226
|
|
224
227
|
def test_create_update_delete_example
|
228
|
+
skip "Skip to allow for concurrent travis jobs"
|
225
229
|
service = IBMWatson::AssistantV1.new(
|
226
230
|
username: ENV["ASSISTANT_USERNAME"],
|
227
231
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -296,6 +300,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
296
300
|
end
|
297
301
|
|
298
302
|
def test_create_update_delete_intent
|
303
|
+
skip "Skip to allow for concurrent travis jobs"
|
299
304
|
service = IBMWatson::AssistantV1.new(
|
300
305
|
username: ENV["ASSISTANT_USERNAME"],
|
301
306
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -433,6 +438,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
433
438
|
end
|
434
439
|
|
435
440
|
def test_create_update_delete_synonym
|
441
|
+
skip "Skip to allow for concurrent travis jobs"
|
436
442
|
service = IBMWatson::AssistantV1.new(
|
437
443
|
username: ENV["ASSISTANT_USERNAME"],
|
438
444
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -512,6 +518,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
512
518
|
end
|
513
519
|
|
514
520
|
def test_create_update_delete_value
|
521
|
+
skip "Skip to allow for concurrent travis jobs"
|
515
522
|
service = IBMWatson::AssistantV1.new(
|
516
523
|
username: ENV["ASSISTANT_USERNAME"],
|
517
524
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -590,6 +597,7 @@ unless ENV["ASSISTANT_USERNAME"].nil? || ENV["ASSISTANT_PASSWORD"].nil?
|
|
590
597
|
end
|
591
598
|
|
592
599
|
def test_dialog_nodes
|
600
|
+
skip "Skip to allow for concurrent travis jobs"
|
593
601
|
service = IBMWatson::AssistantV1.new(
|
594
602
|
username: ENV["ASSISTANT_USERNAME"],
|
595
603
|
password: ENV["ASSISTANT_PASSWORD"],
|
@@ -45,6 +45,7 @@ unless ENV["DISCOVERY_USERNAME"].nil? || ENV["DISCOVERY_PASSWORD"].nil?
|
|
45
45
|
).result
|
46
46
|
refute(configs.nil?)
|
47
47
|
|
48
|
+
skip "Skip to allow for concurrent travis jobs"
|
48
49
|
name = "test" + ("A".."Z").to_a.sample
|
49
50
|
new_configuration_id = @service.create_configuration(
|
50
51
|
environment_id: @environment_id,
|
@@ -199,5 +200,12 @@ unless ENV["DISCOVERY_USERNAME"].nil? || ENV["DISCOVERY_PASSWORD"].nil?
|
|
199
200
|
).result
|
200
201
|
refute(query_results.nil?)
|
201
202
|
end
|
203
|
+
|
204
|
+
def test_list_credentials
|
205
|
+
credentials = @service.list_credentials(
|
206
|
+
environment_id: @environment_id
|
207
|
+
).result
|
208
|
+
refute(credentials.nil?)
|
209
|
+
end
|
202
210
|
end
|
203
211
|
end
|
@@ -6,6 +6,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
6
6
|
# Integration tests for the Watson Assistant V1 Service
|
7
7
|
class IAMAssistantV1Test < Minitest::Test
|
8
8
|
def test_create_update_delete_workspace
|
9
|
+
skip "Skip to allow for concurrent travis jobs"
|
9
10
|
service = IBMWatson::AssistantV1.new(
|
10
11
|
url: ENV["ASSISTANT_IAM_URL"],
|
11
12
|
version: "2018-02-16"
|
@@ -44,10 +45,11 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
44
45
|
|
45
46
|
def test_get_workspace
|
46
47
|
service = IBMWatson::AssistantV1.new(
|
47
|
-
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
48
48
|
url: ENV["ASSISTANT_IAM_URL"],
|
49
49
|
version: "2018-02-16"
|
50
50
|
)
|
51
|
+
service._iam_api_key(iam_api_key: ENV["ASSISTANT_IAM_APIKEY"])
|
52
|
+
service._iam_api_key(iam_api_key: ENV["ASSISTANT_IAM_APIKEY"])
|
51
53
|
service.add_default_headers(
|
52
54
|
headers: {
|
53
55
|
"X-Watson-Learning-Opt-Out" => "1",
|
@@ -78,6 +80,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
78
80
|
end
|
79
81
|
|
80
82
|
def test_create_update_delete_counterexample
|
83
|
+
skip "Skip to allow for concurrent travis jobs"
|
81
84
|
service = IBMWatson::AssistantV1.new(
|
82
85
|
version: "2018-02-16",
|
83
86
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
@@ -147,6 +150,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
147
150
|
end
|
148
151
|
|
149
152
|
def test_create_update_delete_entity
|
153
|
+
skip "Skip to allow for concurrent travis jobs"
|
150
154
|
service = IBMWatson::AssistantV1.new(
|
151
155
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
152
156
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -222,6 +226,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
222
226
|
end
|
223
227
|
|
224
228
|
def test_create_update_delete_example
|
229
|
+
skip "Skip to allow for concurrent travis jobs"
|
225
230
|
service = IBMWatson::AssistantV1.new(
|
226
231
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
227
232
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -296,6 +301,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
296
301
|
end
|
297
302
|
|
298
303
|
def test_create_update_delete_intent
|
304
|
+
skip "Skip to allow for concurrent travis jobs"
|
299
305
|
service = IBMWatson::AssistantV1.new(
|
300
306
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
301
307
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -433,6 +439,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
433
439
|
end
|
434
440
|
|
435
441
|
def test_create_update_delete_synonym
|
442
|
+
skip "Skip to allow for concurrent travis jobs"
|
436
443
|
service = IBMWatson::AssistantV1.new(
|
437
444
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
438
445
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -512,6 +519,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
512
519
|
end
|
513
520
|
|
514
521
|
def test_create_update_delete_value
|
522
|
+
skip "Skip to allow for concurrent travis jobs"
|
515
523
|
service = IBMWatson::AssistantV1.new(
|
516
524
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
517
525
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -590,6 +598,7 @@ unless ENV["ASSISTANT_IAM_URL"].nil? || ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
590
598
|
end
|
591
599
|
|
592
600
|
def test_dialog_nodes
|
601
|
+
skip "Skip to allow for concurrent travis jobs"
|
593
602
|
service = IBMWatson::AssistantV1.new(
|
594
603
|
iam_api_key: ENV["ASSISTANT_IAM_APIKEY"],
|
595
604
|
url: ENV["ASSISTANT_IAM_URL"],
|
@@ -13,8 +13,8 @@ class MyRecognizeCallback < IBMWatson::RecognizeCallback
|
|
13
13
|
@atomic_boolean = atomic_boolean
|
14
14
|
end
|
15
15
|
|
16
|
-
def on_error(
|
17
|
-
|
16
|
+
def on_error(*)
|
17
|
+
@atomic_boolean.make_true
|
18
18
|
end
|
19
19
|
|
20
20
|
def on_inactivity_timeout(*)
|
@@ -86,6 +86,7 @@ unless ENV["SPEECH_TO_TEXT_USERNAME"].nil? || ENV["SPEECH_TO_TEXT_PASSWORD"].nil
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def test_custom_corpora
|
89
|
+
skip "Skip to allow for concurrent travis jobs"
|
89
90
|
model = @service.create_language_model(
|
90
91
|
name: "integration_test_model",
|
91
92
|
base_model_name: "en-US_BroadbandModel"
|
@@ -106,6 +107,7 @@ unless ENV["SPEECH_TO_TEXT_USERNAME"].nil? || ENV["SPEECH_TO_TEXT_PASSWORD"].nil
|
|
106
107
|
list_models = @service.list_acoustic_models.result
|
107
108
|
refute_nil(list_models)
|
108
109
|
|
110
|
+
skip "Skip to allow for concurrent travis jobs"
|
109
111
|
create_acoustic_model = @service.create_acoustic_model(
|
110
112
|
name: "integration_test_model_ruby",
|
111
113
|
base_model_name: "en-US_BroadbandModel"
|
@@ -184,5 +186,68 @@ unless ENV["SPEECH_TO_TEXT_USERNAME"].nil? || ENV["SPEECH_TO_TEXT_PASSWORD"].nil
|
|
184
186
|
thr.join
|
185
187
|
assert(atomic_boolean.true?)
|
186
188
|
end
|
189
|
+
|
190
|
+
def test_broken_audio_with_websocket
|
191
|
+
audio_file = File.open(Dir.getwd + "/resources/car.jpg")
|
192
|
+
atomic_boolean = Concurrent::AtomicBoolean.new
|
193
|
+
mycallback = MyRecognizeCallback.new(atomic_boolean: atomic_boolean)
|
194
|
+
speech = @service.recognize_with_websocket(
|
195
|
+
audio: audio_file,
|
196
|
+
recognize_callback: mycallback,
|
197
|
+
interim_results: true,
|
198
|
+
timestamps: true,
|
199
|
+
max_alternatives: 2,
|
200
|
+
word_alternatives_threshold: 0.5,
|
201
|
+
model: "en-US_BroadbandModel"
|
202
|
+
)
|
203
|
+
thr = Thread.new { speech.start }
|
204
|
+
thr.join
|
205
|
+
assert(atomic_boolean.true?)
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_invalid_auth_with_websocket
|
209
|
+
audio_file = File.open(Dir.getwd + "/resources/speech.wav")
|
210
|
+
atomic_boolean = Concurrent::AtomicBoolean.new
|
211
|
+
mycallback = MyRecognizeCallback.new(atomic_boolean: atomic_boolean)
|
212
|
+
temp_service = IBMWatson::SpeechToTextV1.new(
|
213
|
+
iam_access_token: "bogus_iam_access_token"
|
214
|
+
)
|
215
|
+
temp_service.add_default_headers(
|
216
|
+
headers: {
|
217
|
+
"X-Watson-Learning-Opt-Out" => "1",
|
218
|
+
"X-Watson-Test" => "1"
|
219
|
+
}
|
220
|
+
)
|
221
|
+
speech = temp_service.recognize_with_websocket(
|
222
|
+
audio: audio_file,
|
223
|
+
recognize_callback: mycallback,
|
224
|
+
interim_results: true,
|
225
|
+
timestamps: true,
|
226
|
+
max_alternatives: 2,
|
227
|
+
word_alternatives_threshold: 0.5,
|
228
|
+
model: "en-US_BroadbandModel"
|
229
|
+
)
|
230
|
+
thr = Thread.new { speech.start }
|
231
|
+
thr.join
|
232
|
+
assert(atomic_boolean.true?)
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_add_word
|
236
|
+
model = @service.create_language_model(
|
237
|
+
name: "integration_test_model",
|
238
|
+
base_model_name: "en-US_BroadbandModel"
|
239
|
+
).result
|
240
|
+
customization_id = model["customization_id"]
|
241
|
+
service_response = @service.add_word(
|
242
|
+
customization_id: customization_id,
|
243
|
+
word_name: "IEEE",
|
244
|
+
sounds_like: ["i triple e"],
|
245
|
+
display_as: "IEEE"
|
246
|
+
)
|
247
|
+
assert_nil(service_response)
|
248
|
+
@service.delete_language_model(
|
249
|
+
customization_id: customization_id
|
250
|
+
)
|
251
|
+
end
|
187
252
|
end
|
188
253
|
end
|
@@ -50,6 +50,7 @@ unless ENV["TEXT_TO_SPEECH_USERNAME"].nil? || ENV["TEXT_TO_SPEECH_PASSWORD"].nil
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_custom_words
|
53
|
+
skip "Skip to allow for concurrent travis jobs"
|
53
54
|
customization_id = @service.create_voice_model(
|
54
55
|
name: "test_integration_customization",
|
55
56
|
description: "customization for tests"
|
@@ -47,7 +47,7 @@ unless ENV["VISUAL_RECOGNITION_IAM_APIKEY"].nil? || ENV["VISUAL_RECOGNITION_IAM_
|
|
47
47
|
trucks = File.open(Dir.getwd + "/resources/trucks.zip")
|
48
48
|
classifier = @service.create_classifier(
|
49
49
|
name: "CarsVsTrucks",
|
50
|
-
|
50
|
+
cars_positive_examples: cars,
|
51
51
|
negative_examples: trucks
|
52
52
|
).result
|
53
53
|
refute(classifier.nil?)
|
@@ -62,9 +62,9 @@ class PersonalityInsightsV3Test < Minitest::Test
|
|
62
62
|
profile_response = File.read(Dir.getwd + "/resources/personality-v3-expect2.txt")
|
63
63
|
personality_text = File.read(Dir.getwd + "/resources/personality-v3.json")
|
64
64
|
headers = {
|
65
|
-
"Content-Type" => "
|
65
|
+
"Content-Type" => "application/json"
|
66
66
|
}
|
67
|
-
expected_response = DetailedResponse.new(status: 200, body: profile_response, headers: headers)
|
67
|
+
expected_response = DetailedResponse.new(status: 200, body: JSON.parse(profile_response), headers: headers)
|
68
68
|
stub_request(:post, "https://gateway.watsonplatform.net/personality-insights/api/v3/profile?consumption_preferences=true&raw_scores=true&version=2017-10-13")
|
69
69
|
.with(
|
70
70
|
body: personality_text,
|
@@ -105,7 +105,7 @@ class PersonalityInsightsV3Test < Minitest::Test
|
|
105
105
|
.with(
|
106
106
|
body: personality_text,
|
107
107
|
headers: {
|
108
|
-
"Accept" => "
|
108
|
+
"Accept" => "text/csv",
|
109
109
|
"Authorization" => "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
|
110
110
|
"Content-Type" => "application/json",
|
111
111
|
"Host" => "gateway.watsonplatform.net"
|
@@ -408,7 +408,7 @@ class SpeechToTextV1Test < Minitest::Test
|
|
408
408
|
)
|
409
409
|
stub_request(:put, "https://stream.watsonplatform.net/speech-to-text/api/v1/customizations/custid/words/IEEE")
|
410
410
|
.with(
|
411
|
-
body: "{\"sounds_like\":[\"i triple e\"],\"display_as\":\"IEEE\"}",
|
411
|
+
body: "{\"word\":\"IEEE\",\"sounds_like\":[\"i triple e\"],\"display_as\":\"IEEE\"}",
|
412
412
|
headers: {
|
413
413
|
"Accept" => "application/json",
|
414
414
|
"Authorization" => "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
|
@@ -752,4 +752,21 @@ class SpeechToTextV1Test < Minitest::Test
|
|
752
752
|
service_response = service.upgrade_acoustic_model(customization_id: "customization_id")
|
753
753
|
assert_nil(service_response)
|
754
754
|
end
|
755
|
+
|
756
|
+
def test_reset_acoustic_model
|
757
|
+
service = IBMWatson::SpeechToTextV1.new(
|
758
|
+
username: "username",
|
759
|
+
password: "password"
|
760
|
+
)
|
761
|
+
stub_request(:post, "https://stream.watsonplatform.net/speech-to-text/api/v1/acoustic_customizations/customization_id/reset")
|
762
|
+
.with(
|
763
|
+
headers: {
|
764
|
+
"Accept" => "application/json",
|
765
|
+
"Authorization" => "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
|
766
|
+
"Host" => "stream.watsonplatform.net"
|
767
|
+
}
|
768
|
+
).to_return(status: 200, body: "", headers: {})
|
769
|
+
service_response = service.reset_acoustic_model(customization_id: "customization_id")
|
770
|
+
assert_nil(service_response)
|
771
|
+
end
|
755
772
|
end
|
@@ -87,7 +87,7 @@ class VcapPersonalityInsightsV3Test < Minitest::Test
|
|
87
87
|
.with(
|
88
88
|
body: personality_text,
|
89
89
|
headers: {
|
90
|
-
"Accept" => "
|
90
|
+
"Accept" => "text/csv",
|
91
91
|
"Authorization" => "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
|
92
92
|
"Content-Type" => "application/json",
|
93
93
|
"Host" => "gateway.watsonplatform.net"
|
@@ -124,8 +124,8 @@ class VisualRecognitionV3Test < Minitest::Test
|
|
124
124
|
|
125
125
|
service_response = service.create_classifier(
|
126
126
|
name: "Cars vs Trucks",
|
127
|
-
|
128
|
-
|
127
|
+
cars_positive_examples: "cars",
|
128
|
+
cars_positive_examples_filename: "cars",
|
129
129
|
negative_examples: "trucks",
|
130
130
|
negative_examples_filename: "trucks"
|
131
131
|
)
|
@@ -159,15 +159,15 @@ class VisualRecognitionV3Test < Minitest::Test
|
|
159
159
|
).to_return(status: 200, body: response.to_json, headers: { "Content-Type" => "application/json" })
|
160
160
|
service_response = service.update_classifier(
|
161
161
|
classifier_id: "bogusid",
|
162
|
-
|
162
|
+
positive_positive_examples: "positive examples classname",
|
163
163
|
negative_examples: "negative examples"
|
164
164
|
)
|
165
165
|
assert_equal(response, service_response.result)
|
166
166
|
|
167
167
|
service_response = service.update_classifier(
|
168
168
|
classifier_id: "bogusid",
|
169
|
-
|
170
|
-
|
169
|
+
positive_positive_examples: "positive examples file",
|
170
|
+
positive_positive_examples_filename: "positive_filename",
|
171
171
|
negative_examples: "negative examples",
|
172
172
|
negative_examples_filename: "negative_filename"
|
173
173
|
)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ibm_watson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Nussbaum
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|