google-api-client 0.1.3 → 0.2.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.
- data/CHANGELOG +8 -0
- data/README +1 -1
- data/bin/google-api +174 -120
- data/lib/google/api_client.rb +333 -135
- data/lib/google/api_client/discovery.rb +106 -108
- data/lib/google/api_client/environment.rb +13 -0
- data/lib/google/api_client/errors.rb +30 -0
- data/lib/google/api_client/parsers/json_parser.rb +1 -0
- data/lib/google/api_client/version.rb +3 -2
- data/lib/google/inflection.rb +23 -0
- data/spec/google/api_client/discovery_spec.rb +381 -381
- data/spec/google/api_client_spec.rb +78 -28
- data/tasks/gem.rake +4 -6
- metadata +32 -60
@@ -12,81 +12,113 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
|
15
16
|
require 'json'
|
16
17
|
require 'addressable/uri'
|
17
18
|
require 'addressable/template'
|
18
|
-
|
19
|
+
|
20
|
+
require 'google/inflection'
|
21
|
+
require 'google/api_client/errors'
|
19
22
|
|
20
23
|
module Google
|
21
24
|
class APIClient
|
22
|
-
##
|
23
|
-
# An exception that is raised if a method is called with missing or
|
24
|
-
# invalid parameter values.
|
25
|
-
class ValidationError < StandardError
|
26
|
-
end
|
27
|
-
|
28
25
|
##
|
29
26
|
# A service that has been described by a discovery document.
|
30
|
-
class
|
27
|
+
class API
|
31
28
|
|
32
29
|
##
|
33
30
|
# Creates a description of a particular version of a service.
|
34
31
|
#
|
35
|
-
# @param [String]
|
32
|
+
# @param [String] api
|
36
33
|
# The identifier for the service. Note that while this frequently
|
37
34
|
# matches the first segment of all of the service's RPC names, this
|
38
35
|
# should not be assumed. There is no requirement that these match.
|
39
|
-
# @param [String]
|
36
|
+
# @param [String] version
|
40
37
|
# The identifier for the service version.
|
41
|
-
# @param [Hash]
|
38
|
+
# @param [Hash] api_description
|
42
39
|
# The section of the discovery document that applies to this service
|
43
40
|
# version.
|
44
41
|
#
|
45
|
-
# @return [Google::APIClient::
|
46
|
-
def initialize(
|
47
|
-
@
|
48
|
-
@
|
49
|
-
@description = service_description
|
42
|
+
# @return [Google::APIClient::API] The constructed service object.
|
43
|
+
def initialize(document_base, discovery_document)
|
44
|
+
@document_base = Addressable::URI.parse(document_base)
|
45
|
+
@discovery_document = discovery_document
|
50
46
|
metaclass = (class <<self; self; end)
|
51
47
|
self.resources.each do |resource|
|
52
|
-
method_name =
|
48
|
+
method_name = Google::INFLECTOR.underscore(resource.name).to_sym
|
53
49
|
if !self.respond_to?(method_name)
|
54
50
|
metaclass.send(:define_method, method_name) { resource }
|
55
51
|
end
|
56
52
|
end
|
57
53
|
self.methods.each do |method|
|
58
|
-
method_name =
|
54
|
+
method_name = Google::INFLECTOR.underscore(method.name).to_sym
|
59
55
|
if !self.respond_to?(method_name)
|
60
56
|
metaclass.send(:define_method, method_name) { method }
|
61
57
|
end
|
62
58
|
end
|
63
59
|
end
|
64
60
|
|
61
|
+
##
|
62
|
+
# Returns the id of the service.
|
63
|
+
#
|
64
|
+
# @return [String] The service id.
|
65
|
+
def id
|
66
|
+
return @discovery_document['id']
|
67
|
+
end
|
68
|
+
|
65
69
|
##
|
66
70
|
# Returns the identifier for the service.
|
67
71
|
#
|
68
72
|
# @return [String] The service identifier.
|
69
|
-
|
73
|
+
def name
|
74
|
+
return @discovery_document['name']
|
75
|
+
end
|
70
76
|
|
71
77
|
##
|
72
78
|
# Returns the version of the service.
|
73
79
|
#
|
74
80
|
# @return [String] The service version.
|
75
|
-
|
81
|
+
def version
|
82
|
+
return @discovery_document['version']
|
83
|
+
end
|
76
84
|
|
77
85
|
##
|
78
86
|
# Returns the parsed section of the discovery document that applies to
|
79
87
|
# this version of the service.
|
80
88
|
#
|
81
89
|
# @return [Hash] The service description.
|
82
|
-
|
90
|
+
def description
|
91
|
+
return @discovery_document['description']
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Returns true if this is the preferred version of this API.
|
96
|
+
#
|
97
|
+
# @return [TrueClass, FalseClass]
|
98
|
+
# Whether or not this is the preferred version of this API.
|
99
|
+
def preferred
|
100
|
+
return @discovery_document['preferred']
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Returns the base URI for the discovery document.
|
105
|
+
#
|
106
|
+
# @return [Addressable::URI] The base URI.
|
107
|
+
attr_reader :document_base
|
83
108
|
|
84
109
|
##
|
85
110
|
# Returns the base URI for this version of the service.
|
86
111
|
#
|
87
112
|
# @return [Addressable::URI] The base URI that methods are joined to.
|
88
|
-
def
|
89
|
-
|
113
|
+
def method_base
|
114
|
+
if @discovery_document['basePath']
|
115
|
+
return @method_base ||= (
|
116
|
+
self.document_base +
|
117
|
+
Addressable::URI.parse(@discovery_document['basePath'])
|
118
|
+
).normalize
|
119
|
+
else
|
120
|
+
return nil
|
121
|
+
end
|
90
122
|
end
|
91
123
|
|
92
124
|
##
|
@@ -94,13 +126,13 @@ module Google
|
|
94
126
|
#
|
95
127
|
# @param [Addressable::URI, #to_str, String] new_base
|
96
128
|
# The new base URI to use for the service.
|
97
|
-
def
|
98
|
-
@
|
129
|
+
def method_base=(new_method_base)
|
130
|
+
@method_base = Addressable::URI.parse(new_method_base)
|
99
131
|
self.resources.each do |resource|
|
100
|
-
resource.
|
132
|
+
resource.method_base = @method_base
|
101
133
|
end
|
102
134
|
self.methods.each do |method|
|
103
|
-
method.
|
135
|
+
method.method_base = @method_base
|
104
136
|
end
|
105
137
|
end
|
106
138
|
|
@@ -111,8 +143,8 @@ module Google
|
|
111
143
|
# @return [Array] A list of {Google::APIClient::Resource} objects.
|
112
144
|
def resources
|
113
145
|
return @resources ||= (
|
114
|
-
(
|
115
|
-
accu << ::Google::APIClient::Resource.new(self.
|
146
|
+
(@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
|
147
|
+
accu << ::Google::APIClient::Resource.new(self.method_base, k, v)
|
116
148
|
accu
|
117
149
|
end
|
118
150
|
)
|
@@ -125,8 +157,8 @@ module Google
|
|
125
157
|
# @return [Array] A list of {Google::APIClient::Method} objects.
|
126
158
|
def methods
|
127
159
|
return @methods ||= (
|
128
|
-
(
|
129
|
-
accu << ::Google::APIClient::Method.new(self.
|
160
|
+
(@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
|
161
|
+
accu << ::Google::APIClient::Method.new(self.method_base, k, v)
|
130
162
|
accu
|
131
163
|
end
|
132
164
|
)
|
@@ -139,12 +171,12 @@ module Google
|
|
139
171
|
#
|
140
172
|
# @example
|
141
173
|
# # Discover available methods
|
142
|
-
# method_names = client.
|
174
|
+
# method_names = client.discovered_api('buzz').to_h.keys
|
143
175
|
def to_h
|
144
176
|
return @hash ||= (begin
|
145
177
|
methods_hash = {}
|
146
178
|
self.methods.each do |method|
|
147
|
-
methods_hash[method.
|
179
|
+
methods_hash[method.id] = method
|
148
180
|
end
|
149
181
|
self.resources.each do |resource|
|
150
182
|
methods_hash.merge!(resource.to_h)
|
@@ -153,55 +185,13 @@ module Google
|
|
153
185
|
end)
|
154
186
|
end
|
155
187
|
|
156
|
-
##
|
157
|
-
# Compares two versions of a service.
|
158
|
-
#
|
159
|
-
# @param [Object] other The service to compare.
|
160
|
-
#
|
161
|
-
# @return [Integer]
|
162
|
-
# <code>-1</code> if the service is older than <code>other</code>.
|
163
|
-
# <code>0</code> if the service is the same as <code>other</code>.
|
164
|
-
# <code>1</code> if the service is newer than <code>other</code>.
|
165
|
-
# <code>nil</code> if the service cannot be compared to
|
166
|
-
# <code>other</code>.
|
167
|
-
def <=>(other)
|
168
|
-
# We can only compare versions of the same service
|
169
|
-
if other.kind_of?(self.class) && self.name == other.name
|
170
|
-
split_version = lambda do |version|
|
171
|
-
dotted_version = version[/^v?(\d+(.\d+)*)-?(.*?)?$/, 1]
|
172
|
-
suffix = version[/^v?(\d+(.\d+)*)-?(.*?)?$/, 3]
|
173
|
-
if dotted_version && suffix
|
174
|
-
[dotted_version.split('.').map { |v| v.to_i }, suffix]
|
175
|
-
else
|
176
|
-
[[-1], version]
|
177
|
-
end
|
178
|
-
end
|
179
|
-
self_sortable, self_suffix = split_version.call(self.version)
|
180
|
-
other_sortable, other_suffix = split_version.call(other.version)
|
181
|
-
result = self_sortable <=> other_sortable
|
182
|
-
if result != 0
|
183
|
-
return result
|
184
|
-
# If the dotted versions are equal, check the suffix.
|
185
|
-
# An omitted suffix should be sorted after an included suffix.
|
186
|
-
elsif self_suffix == ''
|
187
|
-
return 1
|
188
|
-
elsif other_suffix == ''
|
189
|
-
return -1
|
190
|
-
else
|
191
|
-
return self_suffix <=> other_suffix
|
192
|
-
end
|
193
|
-
else
|
194
|
-
return nil
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
188
|
##
|
199
189
|
# Returns a <code>String</code> representation of the service's state.
|
200
190
|
#
|
201
191
|
# @return [String] The service's state, as a <code>String</code>.
|
202
192
|
def inspect
|
203
193
|
sprintf(
|
204
|
-
"#<%s:%#0x
|
194
|
+
"#<%s:%#0x ID:%s>", self.class.to_s, self.object_id, self.id
|
205
195
|
)
|
206
196
|
end
|
207
197
|
end
|
@@ -221,19 +211,19 @@ module Google
|
|
221
211
|
# The section of the discovery document that applies to this resource.
|
222
212
|
#
|
223
213
|
# @return [Google::APIClient::Resource] The constructed resource object.
|
224
|
-
def initialize(
|
225
|
-
@
|
214
|
+
def initialize(method_base, resource_name, discovery_document)
|
215
|
+
@method_base = method_base
|
226
216
|
@name = resource_name
|
227
|
-
@
|
217
|
+
@discovery_document = discovery_document
|
228
218
|
metaclass = (class <<self; self; end)
|
229
219
|
self.resources.each do |resource|
|
230
|
-
method_name =
|
220
|
+
method_name = Google::INFLECTOR.underscore(resource.name).to_sym
|
231
221
|
if !self.respond_to?(method_name)
|
232
222
|
metaclass.send(:define_method, method_name) { resource }
|
233
223
|
end
|
234
224
|
end
|
235
225
|
self.methods.each do |method|
|
236
|
-
method_name =
|
226
|
+
method_name = Google::INFLECTOR.underscore(method.name).to_sym
|
237
227
|
if !self.respond_to?(method_name)
|
238
228
|
metaclass.send(:define_method, method_name) { method }
|
239
229
|
end
|
@@ -257,20 +247,20 @@ module Google
|
|
257
247
|
# Returns the base URI for this resource.
|
258
248
|
#
|
259
249
|
# @return [Addressable::URI] The base URI that methods are joined to.
|
260
|
-
attr_reader :
|
250
|
+
attr_reader :method_base
|
261
251
|
|
262
252
|
##
|
263
253
|
# Updates the hierarchy of resources and methods with the new base.
|
264
254
|
#
|
265
255
|
# @param [Addressable::URI, #to_str, String] new_base
|
266
256
|
# The new base URI to use for the resource.
|
267
|
-
def
|
268
|
-
@
|
257
|
+
def method_base=(new_method_base)
|
258
|
+
@method_base = Addressable::URI.parse(new_method_base)
|
269
259
|
self.resources.each do |resource|
|
270
|
-
resource.
|
260
|
+
resource.method_base = @method_base
|
271
261
|
end
|
272
262
|
self.methods.each do |method|
|
273
|
-
method.
|
263
|
+
method.method_base = @method_base
|
274
264
|
end
|
275
265
|
end
|
276
266
|
|
@@ -280,8 +270,8 @@ module Google
|
|
280
270
|
# @return [Array] A list of {Google::APIClient::Resource} objects.
|
281
271
|
def resources
|
282
272
|
return @resources ||= (
|
283
|
-
(
|
284
|
-
accu << ::Google::APIClient::Resource.new(self.
|
273
|
+
(@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
|
274
|
+
accu << ::Google::APIClient::Resource.new(self.method_base, k, v)
|
285
275
|
accu
|
286
276
|
end
|
287
277
|
)
|
@@ -293,8 +283,8 @@ module Google
|
|
293
283
|
# @return [Array] A list of {Google::APIClient::Method} objects.
|
294
284
|
def methods
|
295
285
|
return @methods ||= (
|
296
|
-
(
|
297
|
-
accu << ::Google::APIClient::Method.new(self.
|
286
|
+
(@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
|
287
|
+
accu << ::Google::APIClient::Method.new(self.method_base, k, v)
|
298
288
|
accu
|
299
289
|
end
|
300
290
|
)
|
@@ -309,7 +299,7 @@ module Google
|
|
309
299
|
return @hash ||= (begin
|
310
300
|
methods_hash = {}
|
311
301
|
self.methods.each do |method|
|
312
|
-
methods_hash[method.
|
302
|
+
methods_hash[method.id] = method
|
313
303
|
end
|
314
304
|
self.resources.each do |resource|
|
315
305
|
methods_hash.merge!(resource.to_h)
|
@@ -336,7 +326,7 @@ module Google
|
|
336
326
|
##
|
337
327
|
# Creates a description of a particular method.
|
338
328
|
#
|
339
|
-
# @param [Addressable::URI]
|
329
|
+
# @param [Addressable::URI] method_base
|
340
330
|
# The base URI for the service.
|
341
331
|
# @param [String] method_name
|
342
332
|
# The identifier for the method.
|
@@ -344,10 +334,10 @@ module Google
|
|
344
334
|
# The section of the discovery document that applies to this method.
|
345
335
|
#
|
346
336
|
# @return [Google::APIClient::Method] The constructed method object.
|
347
|
-
def initialize(
|
348
|
-
@
|
337
|
+
def initialize(method_base, method_name, discovery_document)
|
338
|
+
@method_base = method_base
|
349
339
|
@name = method_name
|
350
|
-
@
|
340
|
+
@discovery_document = discovery_document
|
351
341
|
end
|
352
342
|
|
353
343
|
##
|
@@ -368,24 +358,24 @@ module Google
|
|
368
358
|
#
|
369
359
|
# @return [Addressable::URI]
|
370
360
|
# The base URI that this method will be joined to.
|
371
|
-
attr_reader :
|
361
|
+
attr_reader :method_base
|
372
362
|
|
373
363
|
##
|
374
364
|
# Updates the method with the new base.
|
375
365
|
#
|
376
366
|
# @param [Addressable::URI, #to_str, String] new_base
|
377
367
|
# The new base URI to use for the method.
|
378
|
-
def
|
379
|
-
@
|
368
|
+
def method_base=(new_method_base)
|
369
|
+
@method_base = Addressable::URI.parse(new_method_base)
|
380
370
|
@uri_template = nil
|
381
371
|
end
|
382
372
|
|
383
373
|
##
|
384
|
-
# Returns the
|
374
|
+
# Returns the method ID.
|
385
375
|
#
|
386
|
-
# @return [String] The
|
387
|
-
def
|
388
|
-
return
|
376
|
+
# @return [String] The method identifier.
|
377
|
+
def id
|
378
|
+
return @discovery_document['id']
|
389
379
|
end
|
390
380
|
|
391
381
|
##
|
@@ -398,8 +388,9 @@ module Google
|
|
398
388
|
# a join operation on a URI, but we have to treat these as Strings
|
399
389
|
# because of the way the discovery document provides the URIs.
|
400
390
|
# This should be fixed soon.
|
401
|
-
return @uri_template ||=
|
402
|
-
|
391
|
+
return @uri_template ||= Addressable::Template.new(
|
392
|
+
self.method_base + @discovery_document['path']
|
393
|
+
)
|
403
394
|
end
|
404
395
|
|
405
396
|
##
|
@@ -474,7 +465,7 @@ module Google
|
|
474
465
|
if !headers.kind_of?(Array) && !headers.kind_of?(Hash)
|
475
466
|
raise TypeError, "Expected Hash or Array, got #{headers.class}."
|
476
467
|
end
|
477
|
-
method =
|
468
|
+
method = @discovery_document['httpMethod'] || 'GET'
|
478
469
|
uri = self.generate_uri(parameters)
|
479
470
|
headers = headers.to_a if headers.kind_of?(Hash)
|
480
471
|
return [method, uri.to_str, headers, [body]]
|
@@ -487,7 +478,7 @@ module Google
|
|
487
478
|
# @return [Hash] The parameter descriptions.
|
488
479
|
def parameter_descriptions
|
489
480
|
@parameter_descriptions ||= (
|
490
|
-
|
481
|
+
@discovery_document['parameters'] || {}
|
491
482
|
).inject({}) { |h,(k,v)| h[k]=v; h }
|
492
483
|
end
|
493
484
|
|
@@ -497,7 +488,7 @@ module Google
|
|
497
488
|
# @return [Array] The parameters.
|
498
489
|
def parameters
|
499
490
|
@parameters ||= ((
|
500
|
-
|
491
|
+
@discovery_document['parameters'] || {}
|
501
492
|
).inject({}) { |h,(k,v)| h[k]=v; h }).keys
|
502
493
|
end
|
503
494
|
|
@@ -551,6 +542,12 @@ module Google
|
|
551
542
|
end
|
552
543
|
parameters.each do |k, v|
|
553
544
|
if self.parameter_descriptions[k]
|
545
|
+
enum = self.parameter_descriptions[k]['enum']
|
546
|
+
if enum && !enum.include?(v)
|
547
|
+
raise ArgumentError,
|
548
|
+
"Parameter '#{k}' has an invalid value: #{v}. " +
|
549
|
+
"Must be one of #{enum.inspect}."
|
550
|
+
end
|
554
551
|
pattern = self.parameter_descriptions[k]['pattern']
|
555
552
|
if pattern
|
556
553
|
regexp = Regexp.new("^#{pattern}$")
|
@@ -571,7 +568,8 @@ module Google
|
|
571
568
|
# @return [String] The method's state, as a <code>String</code>.
|
572
569
|
def inspect
|
573
570
|
sprintf(
|
574
|
-
"#<%s:%#0x
|
571
|
+
"#<%s:%#0x ID:%s>",
|
572
|
+
self.class.to_s, self.object_id, self.id
|
575
573
|
)
|
576
574
|
end
|
577
575
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Google
|
2
|
+
class APIClient
|
3
|
+
module ENV
|
4
|
+
OS_VERSION = if RUBY_PLATFORM =~ /win32/
|
5
|
+
`ver`.sub(/\s*\[Version\s*/, '/').sub(']', '')
|
6
|
+
elsif RUBY_PLATFORM =~ /darwin/i
|
7
|
+
"Mac OS X/#{`sw_vers -productVersion`}"
|
8
|
+
else
|
9
|
+
`uname -sr`.sub(' ', '/')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|