watson-api-client 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -14
- data/lib/watson-api-client.rb +161 -121
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fec45c50b850da9cd802179d152e89d98891076
|
4
|
+
data.tar.gz: 773b646ed640000c56789f6d07083274b1e40ded
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28a9d5c4e20a7eb5bf088a1a075883165958dd4df037e5d3d1268fcc0eafbef9efa10b23e916ce50164262b0efe47272368b66112818a3936da788e1ba6b056d
|
7
|
+
data.tar.gz: 8a17361402286dffe07a2c34724ba537c68fe37b1aeb528b0111b2164293d7a4c109b478039af3f072aebfe425a1546b2eb7bcc40890035eeb49550c55e57695
|
data/README.md
CHANGED
@@ -102,29 +102,31 @@ Next, let's use 'Personality Insights'.
|
|
102
102
|
The class name, the method name, and the argument setting rules are the same as that of the case of 'Relationship Extraction' almost.
|
103
103
|
The rest-client and the watson-api-client judge which of path, query, header, body each argument is used for automatically.
|
104
104
|
|
105
|
-
|
105
|
+
More
|
106
|
+
-------
|
107
|
+
The documents which 'watson-api-client' referred to have changed in [February 2016](https://github.com/suchowan/watson-api-client/issues/1).
|
106
108
|
|
107
|
-
Last, let's use 'Visual Recognition'.
|
108
109
|
|
109
|
-
|
110
|
-
:password=>"yyyyy",
|
111
|
-
:verify_ssl=>OpenSSL::SSL::VERIFY_NONE)
|
112
|
-
result = service.recognizeLabelsService(
|
113
|
-
'img_File' => open('image.jpg','rb')
|
114
|
-
)
|
115
|
-
p JSON.parse(result.body)
|
110
|
+
(1) The JSON file which held the list of APIs emptied.
|
116
111
|
|
117
|
-
|
112
|
+
(2) The version of Swagger which describes API specifications went up from 1.2 to 2.0.
|
118
113
|
|
119
|
-
|
120
|
-
|
121
|
-
|
114
|
+
|
115
|
+
They may be linked to the release of the IBM Watson for Japanese language.
|
116
|
+
|
117
|
+
The new version 0.0.3 corresponding to them was released provisionally.
|
118
|
+
Concerning about (1) in the version 0.0.3, the locations of JSON files which describe API specification are acquired from contents of web pages for human using regular expressions.
|
119
|
+
|
120
|
+
Essentially, as well as former versions, the location of the API documents should be readable with JSON file.
|
121
|
+
I will request to the IBM to revive the JSON file which held the list of APIs.
|
122
|
+
|
123
|
+
At present this gem is an alpha version and only the normal behavior of RelationshipExtraction and PersonalityInsights are confirmed.
|
122
124
|
It is welcome when you can cooperate with the confirmation of other various functions.
|
123
125
|
|
124
126
|
|
125
127
|
Credits
|
126
128
|
-------
|
127
|
-
Copyright (c) 2015 [Takashi SUGA](http://hosi.org/TakashiSuga.ttl)
|
129
|
+
Copyright (c) 2015-2016 [Takashi SUGA](http://hosi.org/TakashiSuga.ttl)
|
128
130
|
|
129
131
|
|
130
132
|
Legal
|
data/lib/watson-api-client.rb
CHANGED
@@ -1,121 +1,161 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'openssl'
|
3
|
-
require 'open-uri'
|
4
|
-
require 'rest-client'
|
5
|
-
require 'pp' if __FILE__ == $PROGRAM_NAME
|
6
|
-
|
7
|
-
class WatsonAPIClient
|
8
|
-
|
9
|
-
VERSION = '0.0.
|
10
|
-
|
11
|
-
class << self
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
1
|
+
require 'json'
|
2
|
+
require 'openssl'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'rest-client'
|
5
|
+
require 'pp' if __FILE__ == $PROGRAM_NAME
|
6
|
+
|
7
|
+
class WatsonAPIClient
|
8
|
+
|
9
|
+
VERSION = '0.0.3'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def retrieve_doc(doc_urls)
|
16
|
+
apis = {}
|
17
|
+
|
18
|
+
# Watson API Explorer
|
19
|
+
host1 = doc_urls[:doc_base1][/^https?:\/\/[^\/]+/]
|
20
|
+
open(doc_urls[:doc_base1], Options, &:read).scan(/<p>\s*<a href="\/(.+?)".*?>\s*(.+?)\s*<\/a><\/p>/i) do
|
21
|
+
api = {'path'=>doc_urls[:doc_base1] + $1, 'title'=>$2.sub(/\s*\(.+?\)$/,'')}
|
22
|
+
open(api['path'], Options, &:read).scan(/url:\s*'(.+?)'/) do
|
23
|
+
api['path'] = host1 + $1
|
24
|
+
end
|
25
|
+
apis[api['title']] = api
|
26
|
+
end
|
27
|
+
|
28
|
+
# Watson Developercloud
|
29
|
+
host2 = doc_urls[:doc_base2][/^https?:\/\/[^\/]+/]
|
30
|
+
open(doc_urls[:doc_base2], Options, &:read).scan(/<li>\s*<img src=.+?>\s*<h2><a href="(.+?)".*?>\s*(.+?)\s*<\/a><\/h2>\s*<p>(.+?)<\/p>\s*<\/li>/im) do
|
31
|
+
api = {'path'=>$1, 'title'=>$2, 'description'=>$3}
|
32
|
+
next if api['path'] =~ /\.\./
|
33
|
+
if apis.key?(api['title'])
|
34
|
+
apis[api['title']]['description'] = api['description']
|
35
|
+
else
|
36
|
+
# Only for Relationship Extraction
|
37
|
+
open(doc_urls[:doc_base2] + api['path'], Options, &:read).scan(/<li><a href="(.+?)".*?>API\s+explorer<\/a><\/li>/i) do
|
38
|
+
ref = host2 + $1
|
39
|
+
open(ref, Options, &:read).scan(/getAbsoluteUrl\("(.+?)"\)/) do
|
40
|
+
api['path'] = ref.split('/')[0..-2].join('/') + '/' + $1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
apis[api['title']] = api
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
apis
|
48
|
+
end
|
49
|
+
|
50
|
+
# for Swagger 2.0
|
51
|
+
def listings(apis)
|
52
|
+
methods = {}
|
53
|
+
digest = {}
|
54
|
+
apis['paths'].each_pair do |path, operations|
|
55
|
+
operations.each_pair do |method, operation|
|
56
|
+
body = nil
|
57
|
+
(operation['parameters']||[]).each do |parameter|
|
58
|
+
next unless parameter['in'] == 'body'
|
59
|
+
body = parameter['name']
|
60
|
+
break
|
61
|
+
end
|
62
|
+
nickname = operation['operationId'].sub(/(.)/) {$1.downcase}
|
63
|
+
methods[nickname] = {'method'=>method, 'path'=>path, 'operation'=>operation, 'body'=>body}
|
64
|
+
digest[nickname] = {'method'=>method, 'path'=>path, 'summary'=>operation['summary']}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
{'apis'=>apis, 'methods'=>methods, 'digest'=>digest}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
api_docs = {
|
72
|
+
:gateway => 'https://gateway.watsonplatform.net',
|
73
|
+
:doc_base1 => 'https://watson-api-explorer.mybluemix.net/',
|
74
|
+
:doc_base2 => 'https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/',
|
75
|
+
:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE
|
76
|
+
}
|
77
|
+
JSON.parse(ENV['WATSON_API_DOCS'] || '{}').each_pair do |key, value|
|
78
|
+
api_docs[key.to_sym] = value
|
79
|
+
end
|
80
|
+
doc_urls = {
|
81
|
+
:doc_base1 => api_docs.delete(:doc_base1),
|
82
|
+
:doc_base2 => api_docs.delete(:doc_base2)
|
83
|
+
}
|
84
|
+
|
85
|
+
Gateway = api_docs.delete(:gateway)
|
86
|
+
Options = api_docs
|
87
|
+
Services = JSON.parse(ENV['VCAP_SERVICES'] || '{}')
|
88
|
+
|
89
|
+
retrieve_doc(doc_urls).each_value do |list|
|
90
|
+
module_eval %Q{
|
91
|
+
class #{list['title'].gsub(/\s+(.)/) {$1.upcase}} < self
|
92
|
+
Service = superclass::Services['#{list['title'].sub(/\s+/,'_').downcase}']
|
93
|
+
RawDoc = "#{list['path']}"
|
94
|
+
|
95
|
+
class << self
|
96
|
+
alias :_const_missing :const_missing
|
97
|
+
|
98
|
+
def const_missing(constant)
|
99
|
+
if constant == :API
|
100
|
+
const_set(:API, listings(JSON.parse(open(RawDoc, superclass::Options, &:read))))
|
101
|
+
else
|
102
|
+
_const_missing(constant)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
pp [self, 'See ' + RawDoc, API['digest']] if '#{__FILE__}' == '#{$PROGRAM_NAME}'
|
107
|
+
end
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
# All subclass constructors use following hash parameter -
|
112
|
+
#
|
113
|
+
# @param [Hash] options See following..
|
114
|
+
# @option options [String] :url API URL (default: the url described in listings or VCAP_SERVICES)
|
115
|
+
# @option options [String] :user USER ID (default: the username described in VCAP_SERVICES)
|
116
|
+
# @option options [String] :password USER Password (default: the password described in VCAP_SERVICES)
|
117
|
+
# @option options [Object] other_options Other options are passed to RestClient::Resource.new[http://www.rubydoc.info/gems/rest-client/RestClient/Resource] as it is.
|
118
|
+
#
|
119
|
+
# @note VCAP_SERVICES[http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/getting_started/gs-bluemix.shtml#vcapViewing] is IBM Bluemix™ environment variable.
|
120
|
+
#
|
121
|
+
def initialize(options={})
|
122
|
+
self.class::API['methods'].each_pair do |method, definition|
|
123
|
+
self.class.module_eval %Q{define_method("#{method}",
|
124
|
+
Proc.new {|options={}| rest_access_#{definition['body'] ? 'with' : 'without'}_body("#{method}", options)}
|
125
|
+
)} unless respond_to?(method)
|
126
|
+
end
|
127
|
+
credential = self.class::Service ? self.class::Service.first['credentials'] : {}
|
128
|
+
if options[:url]
|
129
|
+
@url = options.delete(:url)
|
130
|
+
elsif credential['url']
|
131
|
+
@url = credential['url']
|
132
|
+
else
|
133
|
+
@url = Gateway + self.class::API['apis']['basePath']
|
134
|
+
end
|
135
|
+
@options = {:user=>credential['username'], :password=>credential['password']}.merge(options)
|
136
|
+
@service = RestClient::Resource.new(@url, @options)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def rest_access_without_body(method, options={})
|
142
|
+
path, access = swagger_info(method, options)
|
143
|
+
@service[path].send(access, options)
|
144
|
+
end
|
145
|
+
|
146
|
+
def rest_access_with_body(method, options={})
|
147
|
+
path, access = swagger_info(method, options)
|
148
|
+
body = options.delete(self.class::API['methods'][method.to_s]['body'])
|
149
|
+
@service[path].send(access, body, options)
|
150
|
+
end
|
151
|
+
|
152
|
+
def swagger_info(method, options)
|
153
|
+
spec = self.class::API['methods'][method.to_s]
|
154
|
+
lacked = []
|
155
|
+
spec['operation']['parameters'].each do |parameter|
|
156
|
+
lacked << parameter['name'] if parameter['required'] && !options[parameter['name']]
|
157
|
+
end
|
158
|
+
raise ArgumentError, "Parameter(s) '#{lacked.join(', ')}' required, see #{self.class::RawDoc}." unless lacked.empty?
|
159
|
+
[spec['path'].gsub(/\{(.+?)\}/) {options.delete($1)}, spec['method']]
|
160
|
+
end
|
161
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watson-api-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi SUGA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|