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.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/lib/ibm_watson/assistant_v1.rb +109 -101
- data/lib/ibm_watson/discovery_v1.rb +102 -77
- data/lib/ibm_watson/iam_token_manager.rb +25 -30
- data/lib/ibm_watson/language_translator_v3.rb +8 -77
- data/lib/ibm_watson/natural_language_classifier_v1.rb +11 -77
- data/lib/ibm_watson/natural_language_understanding_v1.rb +20 -82
- data/lib/ibm_watson/personality_insights_v3.rb +5 -77
- data/lib/ibm_watson/speech_to_text_v1.rb +139 -175
- data/lib/ibm_watson/text_to_speech_v1.rb +21 -77
- data/lib/ibm_watson/tone_analyzer_v3.rb +6 -77
- data/lib/ibm_watson/version.rb +1 -1
- data/lib/ibm_watson/visual_recognition_v3.rb +10 -76
- data/lib/ibm_watson/watson_service.rb +23 -17
- data/lib/ibm_watson/websocket/speech_to_text_websocket_listener.rb +1 -0
- data/test/integration/test_iam_assistant_v1.rb +3 -5
- data/test/unit/test_assistant_v1.rb +31 -0
- data/test/unit/test_configure_http_client.rb +0 -18
- data/test/unit/test_iam_token_manager.rb +21 -11
- data/test/unit/test_visual_recognition_v3.rb +1 -2
- metadata +2 -2
@@ -39,6 +39,7 @@ class WatsonService
|
|
39
39
|
@password = nil
|
40
40
|
@token_manager = nil
|
41
41
|
@temp_headers = nil
|
42
|
+
@icp_prefix = vars[:password]&.start_with?("icp-") ? true : false
|
42
43
|
|
43
44
|
user_agent_string = "watson-apis-ruby-sdk-" + IBMWatson::VERSION
|
44
45
|
user_agent_string += " #{RbConfig::CONFIG["host"]}"
|
@@ -60,10 +61,10 @@ class WatsonService
|
|
60
61
|
end
|
61
62
|
|
62
63
|
if !vars[:iam_access_token].nil? || !vars[:iam_apikey].nil?
|
63
|
-
|
64
|
+
set_token_manager(iam_apikey: vars[:iam_apikey], iam_access_token: vars[:iam_access_token], iam_url: vars[:iam_url])
|
64
65
|
elsif !vars[:username].nil? && !vars[:password].nil?
|
65
|
-
if vars[:username] == "apikey"
|
66
|
-
|
66
|
+
if vars[:username] == "apikey" && !@icp_prefix
|
67
|
+
iam_apikey(iam_apikey: vars[:password])
|
67
68
|
else
|
68
69
|
@username = vars[:username]
|
69
70
|
@password = vars[:password]
|
@@ -86,24 +87,16 @@ class WatsonService
|
|
86
87
|
|
87
88
|
def add_default_headers(headers: {})
|
88
89
|
raise TypeError unless headers.instance_of?(Hash)
|
89
|
-
headers.each_pair { |k, v| @conn.default_options.headers.add(k, v) }
|
90
|
-
end
|
91
90
|
|
92
|
-
|
93
|
-
@iam_apikey = iam_apikey
|
94
|
-
@iam_access_token = iam_access_token
|
95
|
-
@iam_url = iam_url
|
96
|
-
@token_manager = IAMTokenManager.new(iam_apikey: iam_apikey, iam_access_token: iam_access_token, iam_url: iam_url)
|
91
|
+
headers.each_pair { |k, v| @conn.default_options.headers.add(k, v) }
|
97
92
|
end
|
98
93
|
|
99
|
-
def
|
100
|
-
@token_manager&._access_token(iam_access_token: iam_access_token)
|
94
|
+
def iam_access_token(iam_access_token:)
|
101
95
|
@token_manager = IAMTokenManager.new(iam_access_token: iam_access_token) if @token_manager.nil?
|
102
96
|
@iam_access_token = iam_access_token
|
103
97
|
end
|
104
98
|
|
105
|
-
def
|
106
|
-
@token_manager&._iam_apikey(iam_apikey: iam_apikey)
|
99
|
+
def iam_apikey(iam_apikey:)
|
107
100
|
@token_manager = IAMTokenManager.new(iam_apikey: iam_apikey) if @token_manager.nil?
|
108
101
|
@iam_apikey = iam_apikey
|
109
102
|
end
|
@@ -125,14 +118,14 @@ class WatsonService
|
|
125
118
|
args.delete_if { |_, v| v.nil? }
|
126
119
|
args[:headers].delete("Content-Type") if args.key?(:form) || args[:json].nil?
|
127
120
|
|
128
|
-
if @username == "apikey"
|
129
|
-
|
121
|
+
if @username == "apikey" && !@icp_prefix
|
122
|
+
iam_apikey(iam_apikey: @password)
|
130
123
|
@username = nil
|
131
124
|
end
|
132
125
|
|
133
126
|
conn = @conn
|
134
127
|
if !@token_manager.nil?
|
135
|
-
access_token = @token_manager.
|
128
|
+
access_token = @token_manager.token
|
136
129
|
args[:headers]["Authorization"] = "Bearer #{access_token}"
|
137
130
|
elsif !@username.nil? && !@password.nil?
|
138
131
|
conn = @conn.basic_auth(user: @username, pass: @password)
|
@@ -159,6 +152,7 @@ class WatsonService
|
|
159
152
|
)
|
160
153
|
end
|
161
154
|
return DetailedResponse.new(response: response) if (200..299).cover?(response.code)
|
155
|
+
|
162
156
|
raise WatsonApiException.new(response: response)
|
163
157
|
end
|
164
158
|
|
@@ -167,6 +161,7 @@ class WatsonService
|
|
167
161
|
# @return [self]
|
168
162
|
def headers(headers)
|
169
163
|
raise TypeError("Expected Hash type, received #{headers.class}") unless headers.instance_of?(Hash)
|
164
|
+
|
170
165
|
@temp_headers = headers
|
171
166
|
self
|
172
167
|
end
|
@@ -184,16 +179,26 @@ class WatsonService
|
|
184
179
|
# @option timeout global [Integer] Upper bound on total request time
|
185
180
|
def configure_http_client(proxy: {}, timeout: {})
|
186
181
|
raise TypeError("proxy parameter must be a Hash") unless proxy.empty? || proxy.instance_of?(Hash)
|
182
|
+
|
187
183
|
raise TypeError("timeout parameter must be a Hash") unless timeout.empty? || timeout.instance_of?(Hash)
|
184
|
+
|
188
185
|
add_proxy(proxy) unless proxy.empty? || !proxy.dig(:address).is_a?(String) || !proxy.dig(:port).is_a?(Integer)
|
189
186
|
add_timeout(timeout) unless timeout.empty? || (!timeout.key?(:per_operation) && !timeout.key?(:global))
|
190
187
|
end
|
191
188
|
|
192
189
|
private
|
193
190
|
|
191
|
+
def set_token_manager(iam_apikey: nil, iam_access_token: nil, iam_url: nil)
|
192
|
+
@iam_apikey = iam_apikey
|
193
|
+
@iam_access_token = iam_access_token
|
194
|
+
@iam_url = iam_url
|
195
|
+
@token_manager = IAMTokenManager.new(iam_apikey: iam_apikey, iam_access_token: iam_access_token, iam_url: iam_url)
|
196
|
+
end
|
197
|
+
|
194
198
|
def add_timeout(timeout)
|
195
199
|
if timeout.key?(:per_operation)
|
196
200
|
raise TypeError("per_operation in timeout must be a Hash") unless timeout[:per_operation].instance_of?(Hash)
|
201
|
+
|
197
202
|
defaults = {
|
198
203
|
write: 0,
|
199
204
|
connect: 0,
|
@@ -203,6 +208,7 @@ class WatsonService
|
|
203
208
|
@conn = @conn.timeout(:per_operation, write: time[:write], connect: time[:connect], read: time[:read])
|
204
209
|
else
|
205
210
|
raise TypeError("global in timeout must be an Integer") unless timeout[:global].is_a?(Integer)
|
211
|
+
|
206
212
|
@conn = @conn.timeout(:global, write: timeout[:global], connect: 0, read: 0)
|
207
213
|
end
|
208
214
|
end
|
@@ -11,8 +11,7 @@ if !ENV["ASSISTANT_IAM_URL"].nil? && !ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
11
11
|
url: ENV["ASSISTANT_IAM_URL"],
|
12
12
|
version: "2018-02-16"
|
13
13
|
)
|
14
|
-
service.
|
15
|
-
service._iam_apikey(iam_apikey: ENV["ASSISTANT_IAM_APIKEY"])
|
14
|
+
service.iam_apikey(iam_apikey: ENV["ASSISTANT_IAM_APIKEY"])
|
16
15
|
service.add_default_headers(
|
17
16
|
headers: {
|
18
17
|
"X-Watson-Learning-Opt-Out" => "1",
|
@@ -48,8 +47,7 @@ if !ENV["ASSISTANT_IAM_URL"].nil? && !ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
48
47
|
url: ENV["ASSISTANT_IAM_URL"],
|
49
48
|
version: "2018-02-16"
|
50
49
|
)
|
51
|
-
service.
|
52
|
-
service._iam_apikey(iam_apikey: ENV["ASSISTANT_IAM_APIKEY"])
|
50
|
+
service.iam_apikey(iam_apikey: ENV["ASSISTANT_IAM_APIKEY"])
|
53
51
|
service.add_default_headers(
|
54
52
|
headers: {
|
55
53
|
"X-Watson-Learning-Opt-Out" => "1",
|
@@ -706,7 +704,7 @@ if !ENV["ASSISTANT_IAM_URL"].nil? && !ENV["ASSISTANT_IAM_APIKEY"].nil?
|
|
706
704
|
)
|
707
705
|
error_received = false
|
708
706
|
begin
|
709
|
-
service.
|
707
|
+
service.iam_apikey(iam_apikey: "bogus_api_key")
|
710
708
|
service.list_workspaces
|
711
709
|
rescue WatsonApiException => e
|
712
710
|
assert_equal("Provided API key could not be found", e.info["errorMessage"])
|
@@ -40,6 +40,37 @@ class AssistantV1Test < Minitest::Test
|
|
40
40
|
assert_equal(response, service_response.result)
|
41
41
|
end
|
42
42
|
|
43
|
+
def test_plain_to_json_icp
|
44
|
+
response = {
|
45
|
+
"text" => "I want financial advice today.",
|
46
|
+
"created" => "2016-07-11T16:39:01.774Z",
|
47
|
+
"updated" => "2015-12-07T18:53:59.153Z"
|
48
|
+
}
|
49
|
+
headers = {
|
50
|
+
"Content-Type" => "application/json"
|
51
|
+
}
|
52
|
+
stub_request(:post, "https://gateway.watsonplatform.net/assistant/api/v1/workspaces/boguswid/counterexamples?version=2018-02-16")
|
53
|
+
.with(
|
54
|
+
body: "{\"text\":\"I want financial advice today.\"}",
|
55
|
+
headers: {
|
56
|
+
"Accept" => "application/json",
|
57
|
+
"Authorization" => "Basic YXBpa2V5OmljcC14eXo=",
|
58
|
+
"Content-Type" => "application/json",
|
59
|
+
"Host" => "gateway.watsonplatform.net"
|
60
|
+
}
|
61
|
+
).to_return(status: 201, body: response.to_json, headers: headers)
|
62
|
+
service = IBMWatson::AssistantV1.new(
|
63
|
+
version: "2018-02-16",
|
64
|
+
username: "apikey",
|
65
|
+
password: "icp-xyz"
|
66
|
+
)
|
67
|
+
service_response = service.create_counterexample(
|
68
|
+
workspace_id: "boguswid",
|
69
|
+
text: "I want financial advice today."
|
70
|
+
)
|
71
|
+
assert_equal(response, service_response.result)
|
72
|
+
end
|
73
|
+
|
43
74
|
def test_rate_limit_exceeded
|
44
75
|
error_code = 429
|
45
76
|
error_msg = "Rate limit exceeded"
|
@@ -14,9 +14,6 @@ class HTTPConfigTest < Minitest::Test
|
|
14
14
|
username: "username",
|
15
15
|
password: "password"
|
16
16
|
)
|
17
|
-
def service.conn
|
18
|
-
@watson_service.conn
|
19
|
-
end
|
20
17
|
service.configure_http_client(
|
21
18
|
proxy: {
|
22
19
|
address: "bogus_address.com",
|
@@ -34,9 +31,6 @@ class HTTPConfigTest < Minitest::Test
|
|
34
31
|
username: "username",
|
35
32
|
password: "password"
|
36
33
|
)
|
37
|
-
def service.conn
|
38
|
-
@watson_service.conn
|
39
|
-
end
|
40
34
|
service.configure_http_client(
|
41
35
|
proxy: {
|
42
36
|
address: "bogus_address.com",
|
@@ -58,9 +52,6 @@ class HTTPConfigTest < Minitest::Test
|
|
58
52
|
username: "username",
|
59
53
|
password: "password"
|
60
54
|
)
|
61
|
-
def service.conn
|
62
|
-
@watson_service.conn
|
63
|
-
end
|
64
55
|
service.configure_http_client(
|
65
56
|
proxy: {
|
66
57
|
address: "bogus_address.com",
|
@@ -82,9 +73,6 @@ class HTTPConfigTest < Minitest::Test
|
|
82
73
|
username: "username",
|
83
74
|
password: "password"
|
84
75
|
)
|
85
|
-
def service.conn
|
86
|
-
@watson_service.conn
|
87
|
-
end
|
88
76
|
service.configure_http_client(
|
89
77
|
proxy: {
|
90
78
|
address: "bogus_address.com",
|
@@ -110,9 +98,6 @@ class HTTPConfigTest < Minitest::Test
|
|
110
98
|
username: "username",
|
111
99
|
password: "password"
|
112
100
|
)
|
113
|
-
def service.conn
|
114
|
-
@watson_service.conn
|
115
|
-
end
|
116
101
|
service.configure_http_client(
|
117
102
|
timeout: {
|
118
103
|
per_operation: {
|
@@ -140,9 +125,6 @@ class HTTPConfigTest < Minitest::Test
|
|
140
125
|
username: "username",
|
141
126
|
password: "password"
|
142
127
|
)
|
143
|
-
def service.conn
|
144
|
-
@watson_service.conn
|
145
|
-
end
|
146
128
|
service.configure_http_client(
|
147
129
|
timeout: {
|
148
130
|
global: 20
|
@@ -33,7 +33,7 @@ class IAMTokenManagerTest < Minitest::Test
|
|
33
33
|
"Host" => "iam.bluemix.net"
|
34
34
|
}
|
35
35
|
).to_return(status: 200, body: response.to_json, headers: {})
|
36
|
-
token_response = token_manager.
|
36
|
+
token_response = token_manager.send(:request_token)
|
37
37
|
assert_equal(response, token_response)
|
38
38
|
end
|
39
39
|
|
@@ -61,7 +61,7 @@ class IAMTokenManagerTest < Minitest::Test
|
|
61
61
|
"Host" => "iam.bluemix.net"
|
62
62
|
}
|
63
63
|
).to_return(status: 200, body: response.to_json, headers: {})
|
64
|
-
token_response = token_manager.
|
64
|
+
token_response = token_manager.send(:refresh_token)
|
65
65
|
assert_equal(response, token_response)
|
66
66
|
end
|
67
67
|
|
@@ -79,9 +79,9 @@ class IAMTokenManagerTest < Minitest::Test
|
|
79
79
|
"refresh_token" => "jy4gl91BQ"
|
80
80
|
}
|
81
81
|
|
82
|
-
refute(token_manager.
|
82
|
+
refute(token_manager.send(:token_expired?))
|
83
83
|
token_manager.token_info["expiration"] = Time.now.to_i - 3600
|
84
|
-
assert(token_manager.
|
84
|
+
assert(token_manager.send(:token_expired?))
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_is_refresh_token_expired
|
@@ -98,9 +98,9 @@ class IAMTokenManagerTest < Minitest::Test
|
|
98
98
|
"refresh_token" => "jy4gl91BQ"
|
99
99
|
}
|
100
100
|
|
101
|
-
refute(token_manager.
|
101
|
+
refute(token_manager.send(:refresh_token_expired?))
|
102
102
|
token_manager.token_info["expiration"] = Time.now.to_i - (8 * 24 * 3600)
|
103
|
-
assert(token_manager.
|
103
|
+
assert(token_manager.send(:token_expired?))
|
104
104
|
end
|
105
105
|
|
106
106
|
def test_get_token
|
@@ -111,7 +111,7 @@ class IAMTokenManagerTest < Minitest::Test
|
|
111
111
|
)
|
112
112
|
token_manager.user_access_token = "user_access_token"
|
113
113
|
|
114
|
-
token = token_manager.
|
114
|
+
token = token_manager.token
|
115
115
|
assert_equal(token_manager.user_access_token, token)
|
116
116
|
|
117
117
|
response = {
|
@@ -132,11 +132,11 @@ class IAMTokenManagerTest < Minitest::Test
|
|
132
132
|
}
|
133
133
|
).to_return(status: 200, body: response.to_json, headers: {})
|
134
134
|
token_manager.user_access_token = ""
|
135
|
-
token = token_manager.
|
135
|
+
token = token_manager.token
|
136
136
|
assert_equal("hellohello", token)
|
137
137
|
|
138
138
|
token_manager.token_info["expiration"] = Time.now.to_i - (20 * 24 * 3600)
|
139
|
-
token = token_manager.
|
139
|
+
token = token_manager.token
|
140
140
|
assert_equal("hellohello", token)
|
141
141
|
|
142
142
|
stub_request(:post, "https://iam.bluemix.net/identity/token")
|
@@ -149,7 +149,7 @@ class IAMTokenManagerTest < Minitest::Test
|
|
149
149
|
}
|
150
150
|
).to_return(status: 200, body: response.to_json, headers: {})
|
151
151
|
token_manager.token_info["expiration"] = Time.now.to_i - 4000
|
152
|
-
token = token_manager.
|
152
|
+
token = token_manager.token
|
153
153
|
assert_equal("hellohello", token)
|
154
154
|
|
155
155
|
token_manager.token_info = {
|
@@ -159,7 +159,17 @@ class IAMTokenManagerTest < Minitest::Test
|
|
159
159
|
"expiration" => Time.now.to_i + 3600,
|
160
160
|
"refresh_token" => "jy4gl91BQ"
|
161
161
|
}
|
162
|
-
token = token_manager.
|
162
|
+
token = token_manager.token
|
163
163
|
assert_equal("dummy", token)
|
164
164
|
end
|
165
|
+
|
166
|
+
def test_dont_leak_constants
|
167
|
+
assert_nil(defined? DEFAULT_IAM_URL)
|
168
|
+
assert_nil(defined? CONTENT_TYPE)
|
169
|
+
assert_nil(defined? ACCEPT)
|
170
|
+
assert_nil(defined? DEFAULT_AUTHORIZATION)
|
171
|
+
assert_nil(defined? REQUEST_TOKEN_GRANT_TYPE)
|
172
|
+
assert_nil(defined? REQUEST_TOKEN_RESPONSE_TYPE)
|
173
|
+
assert_nil(defined? REFRESH_TOKEN_GRANT_TYPE)
|
174
|
+
end
|
165
175
|
end
|
@@ -12,8 +12,7 @@ class VisualRecognitionV3Test < Minitest::Test
|
|
12
12
|
service = IBMWatson::VisualRecognitionV3.new(
|
13
13
|
version: "2018-03-19"
|
14
14
|
)
|
15
|
-
service.
|
16
|
-
service._iam_access_token(iam_access_token: "bogus_access_token")
|
15
|
+
service.iam_access_token(iam_access_token: "bogus_access_token")
|
17
16
|
response = {
|
18
17
|
"classifier_id" => "bogusnumber",
|
19
18
|
"name" => "Dog Breeds",
|
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.
|
4
|
+
version: 0.6.0
|
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-09-
|
11
|
+
date: 2018-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|