google-api-client 0.2.0 → 0.3.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 +10 -0
- data/README.md +69 -0
- data/Rakefile +3 -4
- data/bin/google-api +49 -27
- data/lib/google/api_client.rb +164 -134
- data/lib/google/api_client/discovery.rb +4 -562
- data/lib/google/api_client/discovery/api.rb +272 -0
- data/lib/google/api_client/discovery/method.rb +313 -0
- data/lib/google/api_client/discovery/resource.rb +149 -0
- data/lib/google/api_client/discovery/schema.rb +106 -0
- data/lib/google/api_client/environment.rb +5 -2
- data/lib/google/api_client/errors.rb +10 -0
- data/lib/google/api_client/parser.rb +59 -0
- data/lib/google/api_client/parsers/json/error_parser.rb +34 -0
- data/lib/google/api_client/parsers/json/pagination.rb +40 -0
- data/lib/google/api_client/parsers/json_parser.rb +90 -12
- data/lib/google/api_client/reference.rb +202 -0
- data/lib/google/api_client/result.rb +132 -0
- data/lib/google/api_client/version.rb +10 -7
- data/lib/google/inflection.rb +7 -2
- data/spec/google/api_client/discovery_spec.rb +162 -123
- data/spec/google/api_client/parsers/json_parser_spec.rb +27 -23
- data/spec/google/api_client_spec.rb +3 -29
- data/tasks/gem.rake +26 -9
- data/tasks/rdoc.rake +12 -5
- data/tasks/spec.rake +4 -1
- data/tasks/wiki.rake +41 -0
- data/tasks/yard.rake +1 -1
- metadata +48 -95
- data/README +0 -68
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.3.0
|
2
|
+
|
3
|
+
* updated to use v1 of the discovery API
|
4
|
+
* updated to use httpadapter 1.0.0
|
5
|
+
* added OAuth 2 support to the command line tool
|
6
|
+
* renamed some switches in the command line tool
|
7
|
+
* added additional configuration capabilities
|
8
|
+
* fixed a few deprecation warnings from dependencies
|
9
|
+
* added gemspec to source control
|
10
|
+
|
1
11
|
== 0.2.0
|
2
12
|
|
3
13
|
* updated to use v1 of the discovery API
|
data/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# APIClient
|
2
|
+
|
3
|
+
<dl>
|
4
|
+
<dt>Homepage</dt><dd><a href="http://code.google.com/p/google-api-ruby-client">http://code.google.com/p/google-api-ruby-client</a></dd>
|
5
|
+
<dt>Author</dt><dd><a href="mailto:bobaman@google.com">Bob Aman</a></dd>
|
6
|
+
<dt>Copyright</dt><dd>Copyright © 2011 Google, Inc.</dd>
|
7
|
+
<dt>License</dt><dd>Apache 2.0</dd>
|
8
|
+
</dl>
|
9
|
+
|
10
|
+
# Description
|
11
|
+
|
12
|
+
The Google API Ruby Client makes it trivial to discover and access supported
|
13
|
+
APIs.
|
14
|
+
|
15
|
+
# Example Usage
|
16
|
+
|
17
|
+
# Initialize the client
|
18
|
+
require 'google/api_client'
|
19
|
+
require 'signet/oauth_1/client'
|
20
|
+
client = Google::APIClient.new(
|
21
|
+
:service => 'buzz',
|
22
|
+
# Buzz has API-specific endpoints
|
23
|
+
:authorization => Signet::OAuth1::Client.new(
|
24
|
+
:temporary_credential_uri =>
|
25
|
+
'https://www.google.com/accounts/OAuthGetRequestToken',
|
26
|
+
:authorization_uri =>
|
27
|
+
'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken',
|
28
|
+
:token_credential_uri =>
|
29
|
+
'https://www.google.com/accounts/OAuthGetAccessToken',
|
30
|
+
:client_credential_key => 'anonymous',
|
31
|
+
:client_credential_secret => 'anonymous'
|
32
|
+
)
|
33
|
+
)
|
34
|
+
client.authorization.fetch_temporary_credential!(
|
35
|
+
:additional_parameters => {
|
36
|
+
'scope' => 'https://www.googleapis.com/auth/buzz'
|
37
|
+
}
|
38
|
+
)
|
39
|
+
redirect_uri = client.authorization.authorization_uri(
|
40
|
+
:additional_parameters => {
|
41
|
+
'domain' => client.authorization.client_credential_key,
|
42
|
+
'scope' => 'https://www.googleapis.com/auth/buzz'
|
43
|
+
}
|
44
|
+
)
|
45
|
+
# Redirect user here
|
46
|
+
client.authorization.fetch_token_credential!(:verifier => '12345')
|
47
|
+
|
48
|
+
# Discover available methods
|
49
|
+
method_names = client.discovered_api('buzz').to_h.keys
|
50
|
+
|
51
|
+
# Make an API call
|
52
|
+
response = client.execute(
|
53
|
+
'chili.activities.list',
|
54
|
+
{'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
|
55
|
+
)
|
56
|
+
status, headers, body = response
|
57
|
+
|
58
|
+
# Install
|
59
|
+
|
60
|
+
Be sure `http://rubygems.org/` is in your gem sources.
|
61
|
+
|
62
|
+
For normal client usage, this is sufficient:
|
63
|
+
|
64
|
+
$ sudo gem install google-api-client
|
65
|
+
|
66
|
+
The command line interface, the example applications, and the test suite
|
67
|
+
require additional dependencies. These may be obtained with:
|
68
|
+
|
69
|
+
$ sudo gem install google-api-client --development --force --no-rdoc --no-ri
|
data/Rakefile
CHANGED
@@ -4,11 +4,8 @@ $LOAD_PATH.uniq!
|
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
6
|
require 'rake'
|
7
|
-
require 'rake/testtask'
|
8
|
-
require 'rake/rdoctask'
|
9
|
-
require 'rake/packagetask'
|
10
|
-
require 'rake/gempackagetask'
|
11
7
|
|
8
|
+
gem 'rspec', '~> 1.2.9'
|
12
9
|
begin
|
13
10
|
require 'spec/rake/spectask'
|
14
11
|
rescue LoadError
|
@@ -27,6 +24,8 @@ PKG_HOMEPAGE = 'http://code.google.com/p/google-api-ruby-client/'
|
|
27
24
|
|
28
25
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
29
26
|
|
27
|
+
PKG_AUTHOR = "Bob Aman"
|
28
|
+
PKG_AUTHOR_EMAIL = "bobaman@google.com"
|
30
29
|
PKG_SUMMARY = 'Package Summary'
|
31
30
|
PKG_DESCRIPTION = <<-TEXT
|
32
31
|
The Google API Ruby Client makes it trivial to discover and access supported
|
data/bin/google-api
CHANGED
@@ -108,8 +108,8 @@ HTML
|
|
108
108
|
options[:api] = s
|
109
109
|
end
|
110
110
|
opts.on(
|
111
|
-
"--
|
112
|
-
"Select
|
111
|
+
"--api-version <id>", String,
|
112
|
+
"Select api version") do |id|
|
113
113
|
options[:version] = id
|
114
114
|
end
|
115
115
|
opts.on(
|
@@ -165,7 +165,7 @@ HTML
|
|
165
165
|
"\nAvailable commands:\n" +
|
166
166
|
" oauth-1-login Log a user into an API with OAuth 1.0a\n" +
|
167
167
|
" oauth-2-login Log a user into an API with OAuth 2.0 d10\n" +
|
168
|
-
" list List the methods available for
|
168
|
+
" list List the methods available for an API\n" +
|
169
169
|
" execute Execute a method on the API\n" +
|
170
170
|
" irb Start an interactive client session"
|
171
171
|
)
|
@@ -238,17 +238,27 @@ HTML
|
|
238
238
|
end
|
239
239
|
|
240
240
|
if options[:discovery_uri]
|
241
|
-
|
241
|
+
if options[:api] && options[:version]
|
242
|
+
client.register_discovery_uri(
|
243
|
+
options[:api], options[:version], options[:discovery_uri]
|
244
|
+
)
|
245
|
+
else
|
246
|
+
STDERR.puts(
|
247
|
+
'Cannot register a discovery URI without ' +
|
248
|
+
'specifying an API and version.'
|
249
|
+
)
|
250
|
+
exit(1)
|
251
|
+
end
|
242
252
|
end
|
243
253
|
|
244
254
|
return client
|
245
255
|
end
|
246
256
|
|
247
|
-
def api_version(
|
257
|
+
def api_version(api_name, version)
|
248
258
|
v = version
|
249
259
|
if !version
|
250
|
-
if client.preferred_version(
|
251
|
-
v = client.preferred_version(
|
260
|
+
if client.preferred_version(api_name)
|
261
|
+
v = client.preferred_version(api_name).version
|
252
262
|
else
|
253
263
|
v = 'v1'
|
254
264
|
end
|
@@ -284,13 +294,12 @@ HTML
|
|
284
294
|
exit(0)
|
285
295
|
else
|
286
296
|
$verifier = nil
|
287
|
-
# TODO(bobaman): Cross-platform?
|
288
|
-
logger = WEBrick::Log.new('/dev/null')
|
289
297
|
server = WEBrick::HTTPServer.new(
|
290
298
|
:Port => OAUTH_SERVER_PORT,
|
291
|
-
:Logger =>
|
292
|
-
:AccessLog =>
|
299
|
+
:Logger => WEBrick::Log.new,
|
300
|
+
:AccessLog => WEBrick::Log.new
|
293
301
|
)
|
302
|
+
server.logger.level = 0
|
294
303
|
trap("INT") { server.shutdown }
|
295
304
|
|
296
305
|
server.mount("/", OAuthVerifierServlet)
|
@@ -379,7 +388,7 @@ HTML
|
|
379
388
|
)
|
380
389
|
|
381
390
|
# Launch browser
|
382
|
-
Launchy
|
391
|
+
Launchy.open(oauth_client.authorization_uri.to_s)
|
383
392
|
|
384
393
|
server.start
|
385
394
|
oauth_client.code = $verifier
|
@@ -399,18 +408,28 @@ HTML
|
|
399
408
|
end
|
400
409
|
|
401
410
|
def list
|
402
|
-
|
403
|
-
unless
|
411
|
+
api_name = options[:api]
|
412
|
+
unless api_name
|
404
413
|
STDERR.puts('No API name supplied.')
|
405
414
|
exit(1)
|
406
415
|
end
|
407
416
|
client = Google::APIClient.new(:authorization => nil)
|
408
417
|
if options[:discovery_uri]
|
409
|
-
|
418
|
+
if options[:api] && options[:version]
|
419
|
+
client.register_discovery_uri(
|
420
|
+
options[:api], options[:version], options[:discovery_uri]
|
421
|
+
)
|
422
|
+
else
|
423
|
+
STDERR.puts(
|
424
|
+
'Cannot register a discovery URI without ' +
|
425
|
+
'specifying an API and version.'
|
426
|
+
)
|
427
|
+
exit(1)
|
428
|
+
end
|
410
429
|
end
|
411
|
-
version = api_version(
|
412
|
-
|
413
|
-
rpcnames =
|
430
|
+
version = api_version(api_name, options[:version])
|
431
|
+
api = client.discovered_api(api_name, version)
|
432
|
+
rpcnames = api.to_h.keys
|
414
433
|
puts rpcnames.sort.join("\n")
|
415
434
|
exit(0)
|
416
435
|
end
|
@@ -447,7 +466,7 @@ HTML
|
|
447
466
|
method.upcase!
|
448
467
|
request = [method, uri.to_str, headers, [request_body]]
|
449
468
|
request = client.generate_authenticated_request(:request => request)
|
450
|
-
response = client.
|
469
|
+
response = client.transmit(request)
|
451
470
|
status, headers, body = response
|
452
471
|
puts body
|
453
472
|
exit(0)
|
@@ -457,14 +476,14 @@ HTML
|
|
457
476
|
STDERR.puts('No rpcname supplied.')
|
458
477
|
exit(1)
|
459
478
|
end
|
460
|
-
|
461
|
-
version = api_version(
|
462
|
-
|
463
|
-
method =
|
479
|
+
api_name = options[:api] || self.rpcname[/^([^\.]+)\./, 1]
|
480
|
+
version = api_version(api_name, options[:version])
|
481
|
+
api = client.discovered_api(api_name, version)
|
482
|
+
method = api.to_h[self.rpcname]
|
464
483
|
if !method
|
465
484
|
STDERR.puts(
|
466
485
|
"Method #{self.rpcname} does not exist for " +
|
467
|
-
"#{
|
486
|
+
"#{api_name}-#{version}."
|
468
487
|
)
|
469
488
|
exit(1)
|
470
489
|
end
|
@@ -477,10 +496,13 @@ HTML
|
|
477
496
|
parameters['xoauth_requestor_id'] = options[:requestor_id]
|
478
497
|
end
|
479
498
|
begin
|
480
|
-
|
481
|
-
|
499
|
+
result = client.execute(
|
500
|
+
:api_method => method,
|
501
|
+
:parameters => parameters,
|
502
|
+
:merged_body => request_body,
|
503
|
+
:headers => headers
|
482
504
|
)
|
483
|
-
status, headers, body = response
|
505
|
+
status, headers, body = result.response
|
484
506
|
puts body
|
485
507
|
exit(0)
|
486
508
|
rescue ArgumentError => e
|
data/lib/google/api_client.rb
CHANGED
@@ -17,9 +17,12 @@ require 'httpadapter'
|
|
17
17
|
require 'json'
|
18
18
|
require 'stringio'
|
19
19
|
|
20
|
+
require 'google/api_client/version'
|
20
21
|
require 'google/api_client/errors'
|
21
22
|
require 'google/api_client/environment'
|
22
23
|
require 'google/api_client/discovery'
|
24
|
+
require 'google/api_client/reference'
|
25
|
+
require 'google/api_client/result'
|
23
26
|
|
24
27
|
module Google
|
25
28
|
# TODO(bobaman): Document all this stuff.
|
@@ -65,19 +68,11 @@ module Google
|
|
65
68
|
'google-api-ruby-client/' + VERSION::STRING +
|
66
69
|
' ' + ENV::OS_VERSION
|
67
70
|
).strip
|
68
|
-
# This is mostly a default for the sake of convenience.
|
69
|
-
# Unlike most other options, this one may be nil, so we check for
|
70
|
-
# the presence of the key rather than checking the value.
|
71
|
-
if options.has_key?("parser")
|
72
|
-
self.parser = options["parser"]
|
73
|
-
else
|
74
|
-
require 'google/api_client/parsers/json_parser'
|
75
|
-
# NOTE: Do not rely on this default value, as it may change
|
76
|
-
self.parser = Google::APIClient::JSONParser
|
77
|
-
end
|
78
71
|
# The writer method understands a few Symbols and will generate useful
|
79
72
|
# default authentication mechanisms.
|
80
73
|
self.authorization = options["authorization"] || :oauth_2
|
74
|
+
self.key = options["key"]
|
75
|
+
self.user_ip = options["user_ip"]
|
81
76
|
# The HTTP adapter controls all of the HTTP traffic the client generates.
|
82
77
|
# By default, Net::HTTP is used, but adding support for other clients
|
83
78
|
# is trivial.
|
@@ -94,33 +89,6 @@ module Google
|
|
94
89
|
return self
|
95
90
|
end
|
96
91
|
|
97
|
-
|
98
|
-
##
|
99
|
-
# Returns the parser used by the client.
|
100
|
-
#
|
101
|
-
# @return [#serialize, #parse]
|
102
|
-
# The parser used by the client. Any object that implements both a
|
103
|
-
# <code>#serialize</code> and a <code>#parse</code> method may be used.
|
104
|
-
# If <code>nil</code>, no parsing will be done.
|
105
|
-
attr_reader :parser
|
106
|
-
|
107
|
-
##
|
108
|
-
# Sets the parser used by the client.
|
109
|
-
#
|
110
|
-
# @param [#serialize, #parse] new_parser
|
111
|
-
# The parser used by the client. Any object that implements both a
|
112
|
-
# <code>#serialize</code> and a <code>#parse</code> method may be used.
|
113
|
-
# If <code>nil</code>, no parsing will be done.
|
114
|
-
def parser=(new_parser)
|
115
|
-
if new_parser &&
|
116
|
-
!new_parser.respond_to?(:serialize) &&
|
117
|
-
!new_parser.respond_to?(:parse)
|
118
|
-
raise TypeError,
|
119
|
-
'Expected parser object to respond to #serialize and #parse.'
|
120
|
-
end
|
121
|
-
@parser = new_parser
|
122
|
-
end
|
123
|
-
|
124
92
|
##
|
125
93
|
# Returns the authorization mechanism used by the client.
|
126
94
|
#
|
@@ -177,6 +145,18 @@ module Google
|
|
177
145
|
return @authorization
|
178
146
|
end
|
179
147
|
|
148
|
+
##
|
149
|
+
# The application's API key issued by the API console.
|
150
|
+
#
|
151
|
+
# @return [String] The API key..
|
152
|
+
attr_accessor :key
|
153
|
+
|
154
|
+
##
|
155
|
+
# The IP address of the user this request is being performed on behalf of.
|
156
|
+
#
|
157
|
+
# @return [String] The user's IP address.
|
158
|
+
attr_accessor :user_ip
|
159
|
+
|
180
160
|
##
|
181
161
|
# Returns the HTTP adapter used by the client.
|
182
162
|
#
|
@@ -280,7 +260,7 @@ module Google
|
|
280
260
|
"Expected String or StringIO, got #{discovery_document.class}."
|
281
261
|
end
|
282
262
|
@discovery_documents["#{api}:#{version}"] =
|
283
|
-
JSON.parse(discovery_document)
|
263
|
+
::JSON.parse(discovery_document)
|
284
264
|
end
|
285
265
|
|
286
266
|
##
|
@@ -289,18 +269,30 @@ module Google
|
|
289
269
|
# @return [Hash] The parsed JSON from the directory document.
|
290
270
|
def directory_document
|
291
271
|
return @directory_document ||= (begin
|
292
|
-
|
293
|
-
|
294
|
-
|
272
|
+
request = self.generate_request(
|
273
|
+
:http_method => 'GET',
|
274
|
+
:uri => self.directory_uri,
|
275
|
+
:authenticated => false
|
276
|
+
)
|
277
|
+
response = self.transmit(request)
|
295
278
|
status, headers, body = response
|
296
|
-
if status
|
297
|
-
|
298
|
-
body.
|
299
|
-
|
279
|
+
if status >= 200 && status < 300
|
280
|
+
# TODO(bobaman) Better status code handling?
|
281
|
+
merged_body = body.inject(StringIO.new) do |accu, chunk|
|
282
|
+
accu.write(chunk)
|
283
|
+
accu
|
300
284
|
end
|
301
|
-
merged_body.
|
302
|
-
|
303
|
-
|
285
|
+
::JSON.parse(merged_body.string)
|
286
|
+
elsif status >= 400 && status < 500
|
287
|
+
_, request_uri, _, _ = request
|
288
|
+
raise ClientError,
|
289
|
+
"Could not retrieve discovery document at: #{request_uri}"
|
290
|
+
elsif status >= 500 && status < 600
|
291
|
+
_, request_uri, _, _ = request
|
292
|
+
raise ServerError,
|
293
|
+
"Could not retrieve discovery document at: #{request_uri}"
|
294
|
+
elsif status > 600
|
295
|
+
_, request_uri, _, _ = request
|
304
296
|
raise TransmissionError,
|
305
297
|
"Could not retrieve discovery document at: #{request_uri}"
|
306
298
|
end
|
@@ -317,18 +309,30 @@ module Google
|
|
317
309
|
api = api.to_s
|
318
310
|
version = version || 'v1'
|
319
311
|
return @discovery_documents["#{api}:#{version}"] ||= (begin
|
320
|
-
|
321
|
-
|
322
|
-
|
312
|
+
request = self.generate_request(
|
313
|
+
:http_method => 'GET',
|
314
|
+
:uri => self.discovery_uri(api, version),
|
315
|
+
:authenticated => false
|
316
|
+
)
|
317
|
+
response = self.transmit(request)
|
323
318
|
status, headers, body = response
|
324
|
-
if status
|
325
|
-
|
326
|
-
body.
|
327
|
-
|
319
|
+
if status >= 200 && status < 300
|
320
|
+
# TODO(bobaman) Better status code handling?
|
321
|
+
merged_body = body.inject(StringIO.new) do |accu, chunk|
|
322
|
+
accu.write(chunk)
|
323
|
+
accu
|
328
324
|
end
|
329
|
-
merged_body.
|
330
|
-
|
331
|
-
|
325
|
+
::JSON.parse(merged_body.string)
|
326
|
+
elsif status >= 400 && status < 500
|
327
|
+
_, request_uri, _, _ = request
|
328
|
+
raise ClientError,
|
329
|
+
"Could not retrieve discovery document at: #{request_uri}"
|
330
|
+
elsif status >= 500 && status < 600
|
331
|
+
_, request_uri, _, _ = request
|
332
|
+
raise ServerError,
|
333
|
+
"Could not retrieve discovery document at: #{request_uri}"
|
334
|
+
elsif status > 600
|
335
|
+
_, request_uri, _, _ = request
|
332
336
|
raise TransmissionError,
|
333
337
|
"Could not retrieve discovery document at: #{request_uri}"
|
334
338
|
end
|
@@ -344,7 +348,7 @@ module Google
|
|
344
348
|
document_base = self.directory_uri
|
345
349
|
if self.directory_document && self.directory_document['items']
|
346
350
|
self.directory_document['items'].map do |discovery_document|
|
347
|
-
|
351
|
+
Google::APIClient::API.new(
|
348
352
|
document_base,
|
349
353
|
discovery_document
|
350
354
|
)
|
@@ -373,7 +377,7 @@ module Google
|
|
373
377
|
document_base = self.discovery_uri(api, version)
|
374
378
|
discovery_document = self.discovery_document(api, version)
|
375
379
|
if document_base && discovery_document
|
376
|
-
|
380
|
+
Google::APIClient::API.new(
|
377
381
|
document_base,
|
378
382
|
discovery_document
|
379
383
|
)
|
@@ -442,8 +446,6 @@ module Google
|
|
442
446
|
# - <code>:version</code> —
|
443
447
|
# The service version. Only used if <code>api_method</code> is a
|
444
448
|
# <code>String</code>. Defaults to <code>'v1'</code>.
|
445
|
-
# - <code>:parser</code> —
|
446
|
-
# The parser for the response.
|
447
449
|
# - <code>:authorization</code> —
|
448
450
|
# The authorization mechanism for the response. Used only if
|
449
451
|
# <code>:authenticated</code> is <code>true</code>.
|
@@ -457,17 +459,22 @@ module Google
|
|
457
459
|
#
|
458
460
|
# @example
|
459
461
|
# request = client.generate_request(
|
460
|
-
# 'chili.activities.list',
|
461
|
-
#
|
462
|
+
# :api_method => 'chili.activities.list',
|
463
|
+
# :parameters =>
|
464
|
+
# {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
|
462
465
|
# )
|
463
466
|
# method, uri, headers, body = request
|
464
|
-
def generate_request(
|
465
|
-
|
467
|
+
def generate_request(options={})
|
468
|
+
# Note: The merge method on a Hash object will coerce an API Reference
|
469
|
+
# object into a Hash and merge with the default options.
|
466
470
|
options={
|
467
|
-
:parser => self.parser,
|
468
471
|
:version => 'v1',
|
469
|
-
:authorization => self.authorization
|
472
|
+
:authorization => self.authorization,
|
473
|
+
:key => self.key,
|
474
|
+
:user_ip => self.user_ip
|
470
475
|
}.merge(options)
|
476
|
+
# The Reference object is going to need this to do method ID lookups.
|
477
|
+
options[:client] = self
|
471
478
|
# The default value for the :authenticated option depends on whether an
|
472
479
|
# authorization mechanism has been set.
|
473
480
|
if options[:authorization]
|
@@ -475,27 +482,8 @@ module Google
|
|
475
482
|
else
|
476
483
|
options = {:authenticated => false}.merge(options)
|
477
484
|
end
|
478
|
-
|
479
|
-
|
480
|
-
# This method of guessing the API is unreliable. This will fail for
|
481
|
-
# APIs where the first segment of the RPC name does not match the
|
482
|
-
# service name. However, this is a fallback mechanism anyway.
|
483
|
-
# Developers should be passing in a reference to the method, rather
|
484
|
-
# than passing in a string or symbol. This should raise an error
|
485
|
-
# in the case of a mismatch.
|
486
|
-
api = api_method[/^([^.]+)\./, 1]
|
487
|
-
api_method = self.discovered_method(
|
488
|
-
api_method, api, options[:version]
|
489
|
-
)
|
490
|
-
elsif !api_method.kind_of?(::Google::APIClient::Method)
|
491
|
-
raise TypeError,
|
492
|
-
"Expected String, Symbol, or Google::APIClient::Method, " +
|
493
|
-
"got #{api_method.class}."
|
494
|
-
end
|
495
|
-
unless api_method
|
496
|
-
raise ArgumentError, "API method could not be found."
|
497
|
-
end
|
498
|
-
request = api_method.generate_request(parameters, body, headers)
|
485
|
+
reference = Google::APIClient::Reference.new(options)
|
486
|
+
request = reference.to_request
|
499
487
|
if options[:authenticated]
|
500
488
|
request = self.generate_authenticated_request(:request => request)
|
501
489
|
end
|
@@ -503,47 +491,13 @@ module Google
|
|
503
491
|
end
|
504
492
|
|
505
493
|
##
|
506
|
-
#
|
507
|
-
#
|
508
|
-
# @param [Google::APIClient::Method, String] api_method
|
509
|
-
# The method object or the RPC name of the method being executed.
|
510
|
-
# @param [Hash, Array] parameters
|
511
|
-
# The parameters to send to the method.
|
512
|
-
# @param [String] body The body of the request.
|
513
|
-
# @param [Hash, Array] headers The HTTP headers for the request.
|
514
|
-
# @param [Hash] options
|
515
|
-
# The configuration parameters for the request.
|
516
|
-
# - <code>:version</code> —
|
517
|
-
# The service version. Only used if <code>api_method</code> is a
|
518
|
-
# <code>String</code>. Defaults to <code>'v1'</code>.
|
519
|
-
# - <code>:adapter</code> —
|
520
|
-
# The HTTP adapter.
|
521
|
-
# - <code>:parser</code> —
|
522
|
-
# The parser for the response.
|
523
|
-
# - <code>:authorization</code> —
|
524
|
-
# The authorization mechanism for the response. Used only if
|
525
|
-
# <code>:authenticated</code> is <code>true</code>.
|
526
|
-
# - <code>:authenticated</code> —
|
527
|
-
# <code>true</code> if the request must be signed or otherwise
|
528
|
-
# authenticated, <code>false</code>
|
529
|
-
# otherwise. Defaults to <code>true</code>.
|
494
|
+
# Signs a request using the current authorization mechanism.
|
530
495
|
#
|
531
|
-
# @
|
496
|
+
# @param [Hash] options The options to pass through.
|
532
497
|
#
|
533
|
-
# @
|
534
|
-
|
535
|
-
|
536
|
-
# {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
|
537
|
-
# )
|
538
|
-
# status, headers, body = response
|
539
|
-
def execute(api_method, parameters={}, body='', headers=[], options={})
|
540
|
-
request = self.generate_request(
|
541
|
-
api_method, parameters, body, headers, options
|
542
|
-
)
|
543
|
-
return self.transmit_request(
|
544
|
-
request,
|
545
|
-
options[:adapter] || self.http_adapter
|
546
|
-
)
|
498
|
+
# @return [Array] The signed or otherwise authenticated request.
|
499
|
+
def generate_authenticated_request(options={})
|
500
|
+
return authorization.generate_authenticated_request(options)
|
547
501
|
end
|
548
502
|
|
549
503
|
##
|
@@ -553,7 +507,7 @@ module Google
|
|
553
507
|
# @param [#transmit] adapter The HTTP adapter.
|
554
508
|
#
|
555
509
|
# @return [Array] The response from the server.
|
556
|
-
def
|
510
|
+
def transmit(request, adapter=self.http_adapter)
|
557
511
|
if self.user_agent != nil
|
558
512
|
# If there's no User-Agent header, set one.
|
559
513
|
method, uri, headers, body = request
|
@@ -577,13 +531,89 @@ module Google
|
|
577
531
|
end
|
578
532
|
|
579
533
|
##
|
580
|
-
#
|
534
|
+
# Executes a request, wrapping it in a Result object.
|
581
535
|
#
|
582
|
-
# @param [
|
536
|
+
# @param [Google::APIClient::Method, String] api_method
|
537
|
+
# The method object or the RPC name of the method being executed.
|
538
|
+
# @param [Hash, Array] parameters
|
539
|
+
# The parameters to send to the method.
|
540
|
+
# @param [String] body The body of the request.
|
541
|
+
# @param [Hash, Array] headers The HTTP headers for the request.
|
542
|
+
# @param [Hash] options
|
543
|
+
# The configuration parameters for the request.
|
544
|
+
# - <code>:version</code> —
|
545
|
+
# The service version. Only used if <code>api_method</code> is a
|
546
|
+
# <code>String</code>. Defaults to <code>'v1'</code>.
|
547
|
+
# - <code>:adapter</code> —
|
548
|
+
# The HTTP adapter.
|
549
|
+
# - <code>:authorization</code> —
|
550
|
+
# The authorization mechanism for the response. Used only if
|
551
|
+
# <code>:authenticated</code> is <code>true</code>.
|
552
|
+
# - <code>:authenticated</code> —
|
553
|
+
# <code>true</code> if the request must be signed or otherwise
|
554
|
+
# authenticated, <code>false</code>
|
555
|
+
# otherwise. Defaults to <code>true</code>.
|
583
556
|
#
|
584
|
-
# @return [Array] The
|
585
|
-
|
586
|
-
|
557
|
+
# @return [Array] The response from the API.
|
558
|
+
#
|
559
|
+
# @example
|
560
|
+
# request = client.generate_request(
|
561
|
+
# :api_method => 'chili.activities.list',
|
562
|
+
# :parameters =>
|
563
|
+
# {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
|
564
|
+
# )
|
565
|
+
def execute(*params)
|
566
|
+
# This block of code allows us to accept multiple parameter passing
|
567
|
+
# styles, and maintaining some backwards compatibility.
|
568
|
+
#
|
569
|
+
# Note: I'm extremely tempted to deprecate this style of execute call.
|
570
|
+
if params.last.respond_to?(:to_hash) && params.size == 1
|
571
|
+
options = params.pop
|
572
|
+
else
|
573
|
+
options = {}
|
574
|
+
end
|
575
|
+
options[:api_method] = params.shift if params.size > 0
|
576
|
+
options[:parameters] = params.shift if params.size > 0
|
577
|
+
options[:merged_body] = params.shift if params.size > 0
|
578
|
+
options[:headers] = params.shift if params.size > 0
|
579
|
+
options[:client] = self
|
580
|
+
|
581
|
+
reference = Google::APIClient::Reference.new(options)
|
582
|
+
request = self.generate_request(reference)
|
583
|
+
response = self.transmit(
|
584
|
+
request,
|
585
|
+
options[:adapter] || self.http_adapter
|
586
|
+
)
|
587
|
+
return Google::APIClient::Result.new(reference, request, response)
|
588
|
+
end
|
589
|
+
|
590
|
+
##
|
591
|
+
# Same as Google::APIClient#execute, but raises an exception if there was
|
592
|
+
# an error.
|
593
|
+
#
|
594
|
+
# @see Google::APIClient#execute
|
595
|
+
def execute!(*params)
|
596
|
+
result = self.execute(*params)
|
597
|
+
status, _, _ = result.response
|
598
|
+
if result.data.respond_to?(:error) &&
|
599
|
+
result.data.error.respond_to?(:message)
|
600
|
+
# You're going to get a terrible error message if the response isn't
|
601
|
+
# parsed successfully as an error.
|
602
|
+
error_message = result.data.error.message
|
603
|
+
elsif result.data['error'] && result.data['error']['message']
|
604
|
+
error_message = result.data['error']['message']
|
605
|
+
end
|
606
|
+
if status >= 400 && status < 500
|
607
|
+
raise ClientError,
|
608
|
+
error_message || "A client error has occurred."
|
609
|
+
elsif status >= 500 && status < 600
|
610
|
+
raise ServerError,
|
611
|
+
error_message || "A server error has occurred."
|
612
|
+
elsif status > 600
|
613
|
+
raise TransmissionError,
|
614
|
+
error_message || "A transmission error has occurred."
|
615
|
+
end
|
616
|
+
return result
|
587
617
|
end
|
588
618
|
end
|
589
619
|
end
|