ibm_watson 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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