ibm_watson 0.5.1 → 0.6.0

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