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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f3ea96d0530c44debcae0d8eb39eaf614c94643e767d226f474377da33d3f09
4
- data.tar.gz: f133f5b9a4536331c9a84abcf56c85d7837602af161a2c3816fa79c987728ba4
3
+ metadata.gz: 39e925f6844d37eeebbebfb1e39ff405a88e73d98c9ac17132b4884c8d36c6ab
4
+ data.tar.gz: cd57ff7e6d36132f415aad355ebae50f09b79c64f649e08b6d3bd3e5559fa926
5
5
  SHA512:
6
- metadata.gz: d561ca5bf849d5c9a626b5983d7ca79301e1d6b1db3118122ed847f7199ac7bed73f87f05bcb0fb07d7ddf6aa2f247056b00a7792996674188c369d9ce9f2d3f
7
- data.tar.gz: 6d1b1025b78e068a4824bba18134422800879ba2a935900d140dcfcfbabb8524aeb0d1c1a69934f6c716c437f05541b5ab3fdedabf6ef55ff9075a2a7c37b505
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
@@ -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 Assistant V1 service.
@@ -27,6 +27,7 @@ require_relative "./detailed_response"
27
27
 
28
28
  require_relative "./watson_service"
29
29
 
30
+ # Module for the Watson APIs
30
31
  module IBMWatson
31
32
  ##
32
33
  # The Discovery V1 service.
@@ -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")
@@ -27,6 +27,7 @@ require_relative "./detailed_response"
27
27
 
28
28
  require_relative "./watson_service"
29
29
 
30
+ # Module for the Watson APIs
30
31
  module IBMWatson
31
32
  ##
32
33
  # The Language Translator V3 service.
@@ -26,6 +26,7 @@ require_relative "./detailed_response"
26
26
 
27
27
  require_relative "./watson_service"
28
28
 
29
+ # Module for the Watson APIs
29
30
  module IBMWatson
30
31
  ##
31
32
  # The Natural Language Classifier V1 service.
@@ -31,6 +31,7 @@ require_relative "./detailed_response"
31
31
 
32
32
  require_relative "./watson_service"
33
33
 
34
+ # Module for the Watson APIs
34
35
  module IBMWatson
35
36
  ##
36
37
  # The Natural Language Understanding V1 service.
@@ -42,6 +42,7 @@ require_relative "./detailed_response"
42
42
 
43
43
  require_relative "./watson_service"
44
44
 
45
+ # Module for the Watson APIs
45
46
  module IBMWatson
46
47
  ##
47
48
  # The Personality Insights V3 service.
@@ -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
- headers["Authorization"] = "Basic " + Base64.strict_encode64("#{@watson_service.username}:#{@watson_service.password}")
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:, word: nil, sounds_like: nil, display_as: nil)
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:, word: nil, sounds_like: nil, display_as: nil)
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" => word,
1535
+ "word" => word_name,
1538
1536
  "sounds_like" => sounds_like,
1539
1537
  "display_as" => display_as
1540
1538
  }
@@ -75,6 +75,7 @@ require_relative "./detailed_response"
75
75
 
76
76
  require_relative "./watson_service"
77
77
 
78
+ # Module for the Watson APIs
78
79
  module IBMWatson
79
80
  ##
80
81
  # The Text to Speech V1 service.
@@ -33,6 +33,7 @@ require_relative "./detailed_response"
33
33
 
34
34
  require_relative "./watson_service"
35
35
 
36
+ # Module for the Watson APIs
36
37
  module IBMWatson
37
38
  ##
38
39
  # The Tone Analyzer V3 service.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IBMWatson
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -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:, classname_positive_examples:, negative_examples: nil, classname_positive_examples_filename: nil, negative_examples_filename: nil)
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 classname_positive_examples [File] A .zip file of images that depict the visual subject of a class in the new
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
- # @param classname_positive_examples_filename [String] The filename for classname_positive_examples.
319
- # @param negative_examples_filename [String] The filename for negative_examples.
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:, classname_positive_examples:, negative_examples: nil, classname_positive_examples_filename: nil, negative_examples_filename: nil)
323
+ def create_classifier(name:, **args)
322
324
  raise ArgumentError("name must be provided") if name.nil?
323
- raise ArgumentError("classname_positive_examples must be provided") if classname_positive_examples.nil?
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
- unless classname_positive_examples.instance_of?(StringIO) || classname_positive_examples.instance_of?(File)
331
- classname_positive_examples = classname_positive_examples.respond_to?(:to_json) ? StringIO.new(classname_positive_examples.to_json) : StringIO.new(classname_positive_examples)
332
- end
333
- if classname_positive_examples_filename
334
- classname_positive_examples = classname_positive_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(classname_positive_examples, content_type: mime_type, filename: classname_positive_examples_filename) : HTTP::FormData::File.new(classname_positive_examples.path, content_type: mime_type, filename: classname_positive_examples_filename)
335
- else
336
- classname_positive_examples = classname_positive_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(classname_positive_examples, content_type: mime_type) : HTTP::FormData::File.new(classname_positive_examples.path, content_type: mime_type)
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:, classname_positive_examples: nil, negative_examples: nil, classname_positive_examples_filename: nil, negative_examples_filename: nil)
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
- # @param classname_positive_examples [File] A .zip file of images that depict the visual subject of a class in the classifier.
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
- # @param negative_examples [File] A .zip file of images that do not depict the visual subject of any of the classes
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
- # @param classname_positive_examples_filename [String] The filename for classname_positive_examples.
448
- # @param negative_examples_filename [String] The filename for negative_examples.
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:, classname_positive_examples: nil, negative_examples: nil, classname_positive_examples_filename: nil, negative_examples_filename: nil)
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
- unless classname_positive_examples.nil?
458
- mime_type = "application/octet-stream"
459
- unless classname_positive_examples.instance_of?(StringIO) || classname_positive_examples.instance_of?(File)
460
- classname_positive_examples = classname_positive_examples.respond_to?(:to_json) ? StringIO.new(classname_positive_examples.to_json) : StringIO.new(classname_positive_examples)
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 classname_positive_examples_filename
463
- classname_positive_examples = classname_positive_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(classname_positive_examples, content_type: mime_type, filename: classname_positive_examples_filename) : HTTP::FormData::File.new(classname_positive_examples.path, content_type: mime_type, filename: classname_positive_examples_filename)
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
- classname_positive_examples = classname_positive_examples.instance_of?(StringIO) ? HTTP::FormData::File.new(classname_positive_examples, content_type: mime_type) : HTTP::FormData::File.new(classname_positive_examples.path, content_type: mime_type)
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
- p event.message
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
- if @data_size > @bytes_sent
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(error:)
17
- puts "Error received: #{error}"
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
- classname_positive_examples: cars,
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" => "applicaiton/json"
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" => "application/json",
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" => "application/json",
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
- classname_positive_examples: "cars",
128
- classname_positive_examples_filename: "cars",
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
- classname_positive_examples: "positive examples classname",
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
- classname_positive_examples: "positive examples file",
170
- classname_positive_examples_filename: "positive_filename",
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.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-09 00:00:00.000000000 Z
11
+ date: 2018-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby