ibm_watson 0.5.1 → 0.6.0

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.
@@ -5,16 +5,16 @@ require("json")
5
5
  require("rbconfig")
6
6
  require_relative("./version.rb")
7
7
 
8
- DEFAULT_IAM_URL = "https://iam.bluemix.net/identity/token"
9
- CONTENT_TYPE = "application/x-www-form-urlencoded"
10
- ACCEPT = "application/json"
11
- DEFAULT_AUTHORIZATION = "Basic Yng6Yng="
12
- REQUEST_TOKEN_GRANT_TYPE = "urn:ibm:params:oauth:grant-type:apikey"
13
- REQUEST_TOKEN_RESPONSE_TYPE = "cloud_iam"
14
- REFRESH_TOKEN_GRANT_TYPE = "refresh_token"
15
-
16
8
  # Class to manage IAM Token Authentication
17
9
  class IAMTokenManager
10
+ DEFAULT_IAM_URL = "https://iam.bluemix.net/identity/token"
11
+ CONTENT_TYPE = "application/x-www-form-urlencoded"
12
+ ACCEPT = "application/json"
13
+ DEFAULT_AUTHORIZATION = "Basic Yng6Yng="
14
+ REQUEST_TOKEN_GRANT_TYPE = "urn:ibm:params:oauth:grant-type:apikey"
15
+ REQUEST_TOKEN_RESPONSE_TYPE = "cloud_iam"
16
+ REFRESH_TOKEN_GRANT_TYPE = "refresh_token"
17
+
18
18
  attr_accessor :token_info, :user_access_token
19
19
  def initialize(iam_apikey: nil, iam_access_token: nil, iam_url: nil)
20
20
  @iam_apikey = iam_apikey
@@ -45,6 +45,7 @@ class IAMTokenManager
45
45
  )
46
46
  end
47
47
  return JSON.parse(response.body.to_s) if (200..299).cover?(response.code)
48
+
48
49
  require_relative("./watson_api_exception.rb")
49
50
  raise WatsonApiException.new(response: response)
50
51
  end
@@ -54,17 +55,18 @@ class IAMTokenManager
54
55
  # 2. If this class is managing tokens and does not yet have one, make a request for one
55
56
  # 3. If this class is managing tokens and the token has expired refresh it. In case the refresh token is expired, get a new one
56
57
  # If this class is managing tokens and has a valid token stored, send it
57
- def _token
58
+ def token
58
59
  return @user_access_token unless @user_access_token.nil? || (@user_access_token.respond_to?(:empty?) && @user_access_token.empty?)
60
+
59
61
  if @token_info.all? { |_k, v| v.nil? }
60
- token_info = _request_token
61
- _save_token_info(
62
+ token_info = request_token
63
+ save_token_info(
62
64
  token_info: token_info
63
65
  )
64
66
  return @token_info["access_token"]
65
- elsif _is_token_expired?
66
- token_info = _is_refresh_token_expired? ? _request_token : _refresh_token
67
- _save_token_info(
67
+ elsif token_expired?
68
+ token_info = refresh_token_expired? ? request_token : refresh_token
69
+ save_token_info(
68
70
  token_info: token_info
69
71
  )
70
72
  return @token_info["access_token"]
@@ -73,8 +75,10 @@ class IAMTokenManager
73
75
  end
74
76
  end
75
77
 
78
+ private
79
+
76
80
  # Request an IAM token using an API key
77
- def _request_token
81
+ def request_token
78
82
  headers = {
79
83
  "Content-Type" => CONTENT_TYPE,
80
84
  "Authorization" => DEFAULT_AUTHORIZATION,
@@ -95,7 +99,7 @@ class IAMTokenManager
95
99
  end
96
100
 
97
101
  # Refresh an IAM token using a refresh token
98
- def _refresh_token
102
+ def refresh_token
99
103
  headers = {
100
104
  "Content-Type" => CONTENT_TYPE,
101
105
  "Authorization" => DEFAULT_AUTHORIZATION,
@@ -114,23 +118,13 @@ class IAMTokenManager
114
118
  response
115
119
  end
116
120
 
117
- # Set a self-managed IAM access token.
118
- # The access token should be valid and not yet expired.
119
- def _access_token(iam_access_token:)
120
- @user_access_token = iam_access_token
121
- end
122
-
123
- # Set the IAM api key
124
- def _iam_apikey(iam_apikey:)
125
- @iam_apikey = iam_apikey
126
- end
127
-
128
121
  # Check if currently stored token is expired.
129
122
  # Using a buffer to prevent the edge case of the
130
123
  # token expiring before the request could be made.
131
124
  # The buffer will be a fraction of the total TTL. Using 80%.
132
- def _is_token_expired?
125
+ def token_expired?
133
126
  return true if @token_info["expiration"].nil? || @token_info["expires_in"].nil?
127
+
134
128
  fraction_of_ttl = 0.8
135
129
  time_to_live = @token_info["expires_in"].nil? ? 0 : @token_info["expires_in"]
136
130
  expire_time = @token_info["expiration"].nil? ? 0 : @token_info["expiration"]
@@ -142,8 +136,9 @@ class IAMTokenManager
142
136
  # Used as a fail-safe to prevent the condition of a refresh token expiring,
143
137
  # which could happen after around 30 days. This function will return true
144
138
  # if it has been at least 7 days and 1 hour since the last token was set
145
- def _is_refresh_token_expired?
139
+ def refresh_token_expired?
146
140
  return true if @token_info["expiration"].nil?
141
+
147
142
  seven_days = 7 * 24 * 3600
148
143
  current_time = Time.now.to_i
149
144
  new_token_time = @token_info["expiration"] + seven_days
@@ -151,7 +146,7 @@ class IAMTokenManager
151
146
  end
152
147
 
153
148
  # Save the response from the IAM service request to the object's state
154
- def _save_token_info(token_info:)
149
+ def save_token_info(token_info:)
155
150
  @token_info = token_info
156
151
  end
157
152
  end
@@ -31,7 +31,7 @@ require_relative "./watson_service"
31
31
  module IBMWatson
32
32
  ##
33
33
  # The Language Translator V3 service.
34
- class LanguageTranslatorV3
34
+ class LanguageTranslatorV3 < WatsonService
35
35
  include Concurrent::Async
36
36
  ##
37
37
  # @!method initialize(args)
@@ -72,7 +72,6 @@ module IBMWatson
72
72
  # 'https://iam.ng.bluemix.net/identity/token'.
73
73
  def initialize(args = {})
74
74
  @__async_initialized__ = false
75
- super()
76
75
  defaults = {}
77
76
  defaults[:version] = nil
78
77
  defaults[:url] = "https://gateway.watsonplatform.net/language-translator/api"
@@ -82,84 +81,11 @@ module IBMWatson
82
81
  defaults[:iam_access_token] = nil
83
82
  defaults[:iam_url] = nil
84
83
  args = defaults.merge(args)
85
- @watson_service = WatsonService.new(
86
- vcap_services_name: "language_translator",
87
- url: args[:url],
88
- username: args[:username],
89
- password: args[:password],
90
- iam_apikey: args[:iam_apikey],
91
- iam_access_token: args[:iam_access_token],
92
- iam_url: args[:iam_url],
93
- use_vcap_services: true
94
- )
84
+ args[:vcap_services_name] = "language_translator"
85
+ super
95
86
  @version = args[:version]
96
87
  end
97
88
 
98
- # :nocov:
99
- def add_default_headers(headers: {})
100
- @watson_service.add_default_headers(headers: headers)
101
- end
102
-
103
- def _iam_access_token(iam_access_token:)
104
- @watson_service._iam_access_token(iam_access_token: iam_access_token)
105
- end
106
-
107
- def _iam_apikey(iam_apikey:)
108
- @watson_service._iam_apikey(iam_apikey: iam_apikey)
109
- end
110
-
111
- # @return [DetailedResponse]
112
- def request(args)
113
- @watson_service.request(args)
114
- end
115
-
116
- # @note Chainable
117
- # @param headers [Hash] Custom headers to be sent with the request
118
- # @return [self]
119
- def headers(headers)
120
- @watson_service.headers(headers)
121
- self
122
- end
123
-
124
- def password=(password)
125
- @watson_service.password = password
126
- end
127
-
128
- def password
129
- @watson_service.password
130
- end
131
-
132
- def username=(username)
133
- @watson_service.username = username
134
- end
135
-
136
- def username
137
- @watson_service.username
138
- end
139
-
140
- def url=(url)
141
- @watson_service.url = url
142
- end
143
-
144
- def url
145
- @watson_service.url
146
- end
147
-
148
- # @!method configure_http_client(proxy: {}, timeout: {})
149
- # Sets the http client config, currently works with timeout and proxies
150
- # @param proxy [Hash] The hash of proxy configurations
151
- # @option proxy address [String] The address of the proxy
152
- # @option proxy port [Integer] The port of the proxy
153
- # @option proxy username [String] The username of the proxy, if authentication is needed
154
- # @option proxy password [String] The password of the proxy, if authentication is needed
155
- # @option proxy headers [Hash] The headers to be used with the proxy
156
- # @param timeout [Hash] The hash for configuring timeouts. `per_operation` has priority over `global`
157
- # @option timeout per_operation [Hash] Timeouts per operation. Requires `read`, `write`, `connect`
158
- # @option timeout global [Integer] Upper bound on total request time
159
- def configure_http_client(proxy: {}, timeout: {})
160
- @watson_service.configure_http_client(proxy: proxy, timeout: timeout)
161
- end
162
- # :nocov:
163
89
  #########################
164
90
  # Translation
165
91
  #########################
@@ -182,6 +108,7 @@ module IBMWatson
182
108
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
183
109
  def translate(text:, model_id: nil, source: nil, target: nil)
184
110
  raise ArgumentError("text must be provided") if text.nil?
111
+
185
112
  headers = {
186
113
  }
187
114
  params = {
@@ -239,6 +166,7 @@ module IBMWatson
239
166
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
240
167
  def identify(text:)
241
168
  raise ArgumentError("text must be provided") if text.nil?
169
+
242
170
  headers = {
243
171
  }
244
172
  params = {
@@ -330,6 +258,7 @@ module IBMWatson
330
258
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
331
259
  def create_model(base_model_id:, name: nil, forced_glossary: nil, parallel_corpus: nil, forced_glossary_filename: nil, parallel_corpus_filename: nil)
332
260
  raise ArgumentError("base_model_id must be provided") if base_model_id.nil?
261
+
333
262
  headers = {
334
263
  }
335
264
  params = {
@@ -382,6 +311,7 @@ module IBMWatson
382
311
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
383
312
  def delete_model(model_id:)
384
313
  raise ArgumentError("model_id must be provided") if model_id.nil?
314
+
385
315
  headers = {
386
316
  }
387
317
  params = {
@@ -408,6 +338,7 @@ module IBMWatson
408
338
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
409
339
  def get_model(model_id:)
410
340
  raise ArgumentError("model_id must be provided") if model_id.nil?
341
+
411
342
  headers = {
412
343
  }
413
344
  params = {
@@ -30,7 +30,7 @@ require_relative "./watson_service"
30
30
  module IBMWatson
31
31
  ##
32
32
  # The Natural Language Classifier V1 service.
33
- class NaturalLanguageClassifierV1
33
+ class NaturalLanguageClassifierV1 < WatsonService
34
34
  include Concurrent::Async
35
35
  ##
36
36
  # @!method initialize(args)
@@ -61,7 +61,6 @@ module IBMWatson
61
61
  # 'https://iam.ng.bluemix.net/identity/token'.
62
62
  def initialize(args = {})
63
63
  @__async_initialized__ = false
64
- super()
65
64
  defaults = {}
66
65
  defaults[:url] = "https://gateway.watsonplatform.net/natural-language-classifier/api"
67
66
  defaults[:username] = nil
@@ -70,83 +69,10 @@ module IBMWatson
70
69
  defaults[:iam_access_token] = nil
71
70
  defaults[:iam_url] = nil
72
71
  args = defaults.merge(args)
73
- @watson_service = WatsonService.new(
74
- vcap_services_name: "natural_language_classifier",
75
- url: args[:url],
76
- username: args[:username],
77
- password: args[:password],
78
- iam_apikey: args[:iam_apikey],
79
- iam_access_token: args[:iam_access_token],
80
- iam_url: args[:iam_url],
81
- use_vcap_services: true
82
- )
83
- end
84
-
85
- # :nocov:
86
- def add_default_headers(headers: {})
87
- @watson_service.add_default_headers(headers: headers)
88
- end
89
-
90
- def _iam_access_token(iam_access_token:)
91
- @watson_service._iam_access_token(iam_access_token: iam_access_token)
92
- end
93
-
94
- def _iam_apikey(iam_apikey:)
95
- @watson_service._iam_apikey(iam_apikey: iam_apikey)
96
- end
97
-
98
- # @return [DetailedResponse]
99
- def request(args)
100
- @watson_service.request(args)
101
- end
102
-
103
- # @note Chainable
104
- # @param headers [Hash] Custom headers to be sent with the request
105
- # @return [self]
106
- def headers(headers)
107
- @watson_service.headers(headers)
108
- self
109
- end
110
-
111
- def password=(password)
112
- @watson_service.password = password
113
- end
114
-
115
- def password
116
- @watson_service.password
117
- end
118
-
119
- def username=(username)
120
- @watson_service.username = username
121
- end
122
-
123
- def username
124
- @watson_service.username
125
- end
126
-
127
- def url=(url)
128
- @watson_service.url = url
129
- end
130
-
131
- def url
132
- @watson_service.url
72
+ args[:vcap_services_name] = "natural_language_classifier"
73
+ super
133
74
  end
134
75
 
135
- # @!method configure_http_client(proxy: {}, timeout: {})
136
- # Sets the http client config, currently works with timeout and proxies
137
- # @param proxy [Hash] The hash of proxy configurations
138
- # @option proxy address [String] The address of the proxy
139
- # @option proxy port [Integer] The port of the proxy
140
- # @option proxy username [String] The username of the proxy, if authentication is needed
141
- # @option proxy password [String] The password of the proxy, if authentication is needed
142
- # @option proxy headers [Hash] The headers to be used with the proxy
143
- # @param timeout [Hash] The hash for configuring timeouts. `per_operation` has priority over `global`
144
- # @option timeout per_operation [Hash] Timeouts per operation. Requires `read`, `write`, `connect`
145
- # @option timeout global [Integer] Upper bound on total request time
146
- def configure_http_client(proxy: {}, timeout: {})
147
- @watson_service.configure_http_client(proxy: proxy, timeout: timeout)
148
- end
149
- # :nocov:
150
76
  #########################
151
77
  # Classify text
152
78
  #########################
@@ -161,7 +87,9 @@ module IBMWatson
161
87
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
162
88
  def classify(classifier_id:, text:)
163
89
  raise ArgumentError("classifier_id must be provided") if classifier_id.nil?
90
+
164
91
  raise ArgumentError("text must be provided") if text.nil?
92
+
165
93
  headers = {
166
94
  }
167
95
  data = {
@@ -190,7 +118,9 @@ module IBMWatson
190
118
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
191
119
  def classify_collection(classifier_id:, collection:)
192
120
  raise ArgumentError("classifier_id must be provided") if classifier_id.nil?
121
+
193
122
  raise ArgumentError("collection must be provided") if collection.nil?
123
+
194
124
  headers = {
195
125
  }
196
126
  data = {
@@ -230,7 +160,9 @@ module IBMWatson
230
160
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
231
161
  def create_classifier(metadata:, training_data:, metadata_filename: nil, training_data_filename: nil)
232
162
  raise ArgumentError("metadata must be provided") if metadata.nil?
163
+
233
164
  raise ArgumentError("training_data must be provided") if training_data.nil?
165
+
234
166
  headers = {
235
167
  }
236
168
  mime_type = "application/json"
@@ -291,6 +223,7 @@ module IBMWatson
291
223
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
292
224
  def get_classifier(classifier_id:)
293
225
  raise ArgumentError("classifier_id must be provided") if classifier_id.nil?
226
+
294
227
  headers = {
295
228
  }
296
229
  method_url = "/v1/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]
@@ -310,6 +243,7 @@ module IBMWatson
310
243
  # @return [nil]
311
244
  def delete_classifier(classifier_id:)
312
245
  raise ArgumentError("classifier_id must be provided") if classifier_id.nil?
246
+
313
247
  headers = {
314
248
  }
315
249
  method_url = "/v1/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]
@@ -35,7 +35,7 @@ require_relative "./watson_service"
35
35
  module IBMWatson
36
36
  ##
37
37
  # The Natural Language Understanding V1 service.
38
- class NaturalLanguageUnderstandingV1
38
+ class NaturalLanguageUnderstandingV1 < WatsonService
39
39
  include Concurrent::Async
40
40
  ##
41
41
  # @!method initialize(args)
@@ -76,7 +76,6 @@ module IBMWatson
76
76
  # 'https://iam.ng.bluemix.net/identity/token'.
77
77
  def initialize(args = {})
78
78
  @__async_initialized__ = false
79
- super()
80
79
  defaults = {}
81
80
  defaults[:version] = nil
82
81
  defaults[:url] = "https://gateway.watsonplatform.net/natural-language-understanding/api"
@@ -86,84 +85,11 @@ module IBMWatson
86
85
  defaults[:iam_access_token] = nil
87
86
  defaults[:iam_url] = nil
88
87
  args = defaults.merge(args)
89
- @watson_service = WatsonService.new(
90
- vcap_services_name: "natural-language-understanding",
91
- url: args[:url],
92
- username: args[:username],
93
- password: args[:password],
94
- iam_apikey: args[:iam_apikey],
95
- iam_access_token: args[:iam_access_token],
96
- iam_url: args[:iam_url],
97
- use_vcap_services: true
98
- )
88
+ args[:vcap_services_name] = "natural-language-understanding"
89
+ super
99
90
  @version = args[:version]
100
91
  end
101
92
 
102
- # :nocov:
103
- def add_default_headers(headers: {})
104
- @watson_service.add_default_headers(headers: headers)
105
- end
106
-
107
- def _iam_access_token(iam_access_token:)
108
- @watson_service._iam_access_token(iam_access_token: iam_access_token)
109
- end
110
-
111
- def _iam_apikey(iam_apikey:)
112
- @watson_service._iam_apikey(iam_apikey: iam_apikey)
113
- end
114
-
115
- # @return [DetailedResponse]
116
- def request(args)
117
- @watson_service.request(args)
118
- end
119
-
120
- # @note Chainable
121
- # @param headers [Hash] Custom headers to be sent with the request
122
- # @return [self]
123
- def headers(headers)
124
- @watson_service.headers(headers)
125
- self
126
- end
127
-
128
- def password=(password)
129
- @watson_service.password = password
130
- end
131
-
132
- def password
133
- @watson_service.password
134
- end
135
-
136
- def username=(username)
137
- @watson_service.username = username
138
- end
139
-
140
- def username
141
- @watson_service.username
142
- end
143
-
144
- def url=(url)
145
- @watson_service.url = url
146
- end
147
-
148
- def url
149
- @watson_service.url
150
- end
151
-
152
- # @!method configure_http_client(proxy: {}, timeout: {})
153
- # Sets the http client config, currently works with timeout and proxies
154
- # @param proxy [Hash] The hash of proxy configurations
155
- # @option proxy address [String] The address of the proxy
156
- # @option proxy port [Integer] The port of the proxy
157
- # @option proxy username [String] The username of the proxy, if authentication is needed
158
- # @option proxy password [String] The password of the proxy, if authentication is needed
159
- # @option proxy headers [Hash] The headers to be used with the proxy
160
- # @param timeout [Hash] The hash for configuring timeouts. `per_operation` has priority over `global`
161
- # @option timeout per_operation [Hash] Timeouts per operation. Requires `read`, `write`, `connect`
162
- # @option timeout global [Integer] Upper bound on total request time
163
- def configure_http_client(proxy: {}, timeout: {})
164
- @watson_service.configure_http_client(proxy: proxy, timeout: timeout)
165
- end
166
- # :nocov:
167
93
  #########################
168
94
  # Analyze
169
95
  #########################
@@ -218,18 +144,29 @@ module IBMWatson
218
144
  # \"Leonardo DiCaprio won an Oscar\" returns \"/art and entertainment/movies and
219
145
  # tv/movies\" as the most confident classification.
220
146
  # @param features [Features] Specific features to analyze the document for.
221
- # @param text [String] The plain text to analyze.
222
- # @param html [String] The HTML file to analyze.
223
- # @param url [String] The web page to analyze.
147
+ # @param text [String] The plain text to analyze. One of the `text`, `html`, or `url` parameters is
148
+ # required.
149
+ # @param html [String] The HTML file to analyze. One of the `text`, `html`, or `url` parameters is
150
+ # required.
151
+ # @param url [String] The web page to analyze. One of the `text`, `html`, or `url` parameters is
152
+ # required.
224
153
  # @param clean [Boolean] Remove website elements, such as links, ads, etc.
225
- # @param xpath [String] XPath query for targeting nodes in HTML.
154
+ # @param xpath [String] An [XPath query](https://www.w3.org/TR/xpath/) to perform on `html` or `url`
155
+ # input. Results of the query will be appended to the cleaned webpage text before it
156
+ # is analyzed. To analyze only the results of the XPath query, set the `clean`
157
+ # parameter to `false`.
226
158
  # @param fallback_to_raw [Boolean] Whether to use raw HTML content if text cleaning fails.
227
159
  # @param return_analyzed_text [Boolean] Whether or not to return the analyzed text.
228
- # @param language [String] ISO 639-1 code indicating the language to use in the analysis.
160
+ # @param language [String] ISO 639-1 code that specifies the language of your text. This overrides automatic
161
+ # language detection. Language support differs depending on the features you include
162
+ # in your analysis. See [Language
163
+ # support](https://www.bluemix.net/docs/services/natural-language-understanding/language-support.html)
164
+ # for more information.
229
165
  # @param limit_text_characters [Fixnum] Sets the maximum number of characters that are processed by the service.
230
166
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
231
167
  def analyze(features:, text: nil, html: nil, url: nil, clean: nil, xpath: nil, fallback_to_raw: nil, return_analyzed_text: nil, language: nil, limit_text_characters: nil)
232
168
  raise ArgumentError("features must be provided") if features.nil?
169
+
233
170
  headers = {
234
171
  }
235
172
  params = {
@@ -294,6 +231,7 @@ module IBMWatson
294
231
  # @return [DetailedResponse] A `DetailedResponse` object representing the response.
295
232
  def delete_model(model_id:)
296
233
  raise ArgumentError("model_id must be provided") if model_id.nil?
234
+
297
235
  headers = {
298
236
  }
299
237
  params = {