google-api-client 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|