google-api-client 0.3.0 → 0.4.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.
@@ -19,6 +19,7 @@ require 'google/inflection'
19
19
  require 'google/api_client/discovery/resource'
20
20
  require 'google/api_client/discovery/method'
21
21
 
22
+
22
23
  module Google
23
24
  class APIClient
24
25
  ##
@@ -18,6 +18,7 @@ require 'addressable/template'
18
18
 
19
19
  require 'google/api_client/errors'
20
20
 
21
+
21
22
  module Google
22
23
  class APIClient
23
24
  ##
@@ -139,16 +140,14 @@ module Google
139
140
  def normalize_parameters(parameters={})
140
141
  # Convert keys to Strings when appropriate
141
142
  if parameters.kind_of?(Hash) || parameters.kind_of?(Array)
142
- # Is a Hash or an Array a better return type? Do we ever need to
143
- # worry about the same parameter being sent twice with different
144
- # values?
145
- parameters = parameters.inject({}) do |accu, (k, v)|
143
+ # Returning an array since parameters can be repeated (ie, Adsense Management API)
144
+ parameters = parameters.inject([]) do |accu, (k, v)|
146
145
  k = k.to_s if k.kind_of?(Symbol)
147
146
  k = k.to_str if k.respond_to?(:to_str)
148
147
  unless k.kind_of?(String)
149
148
  raise TypeError, "Expected String, got #{k.class}."
150
149
  end
151
- accu[k] = v
150
+ accu << [k,v]
152
151
  accu
153
152
  end
154
153
  else
@@ -174,7 +173,7 @@ module Google
174
173
  template_variables.include?(k)
175
174
  end
176
175
  if query_parameters.size > 0
177
- uri.query_values = (uri.query_values || {}).merge(query_parameters)
176
+ uri.query_values = (uri.query_values || []) + query_parameters
178
177
  end
179
178
  # Normalization is necessary because of undesirable percent-escaping
180
179
  # during URI template expansion
@@ -204,7 +203,11 @@ module Google
204
203
  method = self.http_method
205
204
  uri = self.generate_uri(parameters)
206
205
  headers = headers.to_a if headers.kind_of?(Hash)
207
- return [method, uri.to_str, headers, [body]]
206
+ return Faraday::Request.create(method.to_s.downcase.to_sym) do |req|
207
+ req.url(Addressable::URI.parse(uri))
208
+ req.headers = Faraday::Utils::Headers.new(headers)
209
+ req.body = body
210
+ end
208
211
  end
209
212
 
210
213
  ##
@@ -271,7 +274,7 @@ module Google
271
274
  required_variables = ((self.parameter_descriptions.select do |k, v|
272
275
  v['required']
273
276
  end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
274
- missing_variables = required_variables - parameters.keys
277
+ missing_variables = required_variables - parameters.map(&:first)
275
278
  if missing_variables.size > 0
276
279
  raise ArgumentError,
277
280
  "Missing required parameters: #{missing_variables.join(', ')}."
@@ -18,6 +18,7 @@ require 'addressable/uri'
18
18
  require 'google/inflection'
19
19
  require 'google/api_client/discovery/method'
20
20
 
21
+
21
22
  module Google
22
23
  class APIClient
23
24
  ##
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
  require 'time'
17
- require 'json'
17
+ require 'multi_json'
18
18
  require 'base64'
19
19
  require 'autoparse'
20
20
  require 'addressable/uri'
@@ -23,6 +23,7 @@ require 'addressable/template'
23
23
  require 'google/inflection'
24
24
  require 'google/api_client/errors'
25
25
 
26
+
26
27
  module Google
27
28
  class APIClient
28
29
  module Schema
@@ -1,3 +1,18 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
1
16
  module Google
2
17
  class APIClient
3
18
  module ENV
@@ -12,11 +12,16 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'stringio'
16
- require 'json'
15
+
16
+ gem 'faraday', '~> 0.7.0'
17
+ require 'faraday'
18
+ require 'faraday/utils'
19
+ require 'multi_json'
17
20
  require 'addressable/uri'
21
+ require 'stringio'
18
22
  require 'google/api_client/discovery'
19
23
 
24
+
20
25
  module Google
21
26
  class APIClient
22
27
  class Reference
@@ -27,6 +32,7 @@ module Google
27
32
  @client = options[:client]
28
33
  @version = options[:version] || 'v1'
29
34
 
35
+ self.connection = options[:connection] || Faraday.default_connection
30
36
  self.api_method = options[:api_method]
31
37
  self.parameters = options[:parameters] || {}
32
38
  # These parameters are handled differently because they're not
@@ -36,21 +42,19 @@ module Google
36
42
  self.headers = options[:headers] || []
37
43
  if options[:body]
38
44
  self.body = options[:body]
39
- elsif options[:merged_body]
40
- self.merged_body = options[:merged_body]
41
45
  elsif options[:body_object]
42
46
  if options[:body_object].respond_to?(:to_json)
43
47
  serialized_body = options[:body_object].to_json
44
48
  elsif options[:body_object].respond_to?(:to_hash)
45
- serialized_body = JSON.generate(options[:body_object].to_hash)
49
+ serialized_body = MultiJson.encode(options[:body_object].to_hash)
46
50
  else
47
51
  raise TypeError,
48
52
  'Could not convert body object to JSON.' +
49
53
  'Must respond to :to_json or :to_hash.'
50
54
  end
51
- self.merged_body = serialized_body
55
+ self.body = serialized_body
52
56
  else
53
- self.merged_body = ''
57
+ self.body = ''
54
58
  end
55
59
  unless self.api_method
56
60
  self.http_method = options[:http_method] || 'GET'
@@ -62,6 +66,19 @@ module Google
62
66
  end
63
67
  end
64
68
 
69
+ def connection
70
+ return @connection
71
+ end
72
+
73
+ def connection=(new_connection)
74
+ if new_connection.kind_of?(Faraday::Connection)
75
+ @connection = new_connection
76
+ else
77
+ raise TypeError,
78
+ "Expected Faraday::Connection, got #{new_connection.class}."
79
+ end
80
+ end
81
+
65
82
  def api_method
66
83
  return @api_method
67
84
  end
@@ -113,32 +130,18 @@ module Google
113
130
  end
114
131
 
115
132
  def body=(new_body)
116
- if new_body.respond_to?(:each)
117
- @body = new_body
133
+ if new_body.respond_to?(:to_str)
134
+ @body = new_body.to_str
135
+ elsif new_body.respond_to?(:inject)
136
+ @body = (new_body.inject(StringIO.new) do |accu, chunk|
137
+ accu.write(chunk)
138
+ accu
139
+ end).string
118
140
  else
119
- raise TypeError, "Expected body to respond to :each."
141
+ raise TypeError, "Expected body to be String or Enumerable chunks."
120
142
  end
121
143
  end
122
144
 
123
- def merged_body
124
- return (self.body.inject(StringIO.new) do |accu, chunk|
125
- accu.write(chunk)
126
- accu
127
- end).string
128
- end
129
-
130
- def merged_body=(new_merged_body)
131
- if new_merged_body.respond_to?(:string)
132
- new_merged_body = new_merged_body.string
133
- elsif new_merged_body.respond_to?(:to_str)
134
- new_merged_body = new_merged_body.to_str
135
- else
136
- raise TypeError,
137
- "Expected String or StringIO, got #{new_merged_body.class}."
138
- end
139
- self.body = [new_merged_body]
140
- end
141
-
142
145
  def headers
143
146
  return @headers ||= []
144
147
  end
@@ -177,10 +180,16 @@ module Google
177
180
  def to_request
178
181
  if self.api_method
179
182
  return self.api_method.generate_request(
180
- self.parameters, self.merged_body, self.headers
183
+ self.parameters, self.body, self.headers
181
184
  )
182
185
  else
183
- return [self.http_method, self.uri, self.headers, self.body]
186
+ return Faraday::Request.create(
187
+ self.http_method.to_s.downcase.to_sym
188
+ ) do |req|
189
+ req.url(Addressable::URI.parse(self.uri))
190
+ req.headers = Faraday::Utils::Headers.new(self.headers)
191
+ req.body = self.body
192
+ end
184
193
  end
185
194
  end
186
195
 
@@ -195,6 +204,7 @@ module Google
195
204
  end
196
205
  options[:headers] = self.headers
197
206
  options[:body] = self.body
207
+ options[:connection] = self.connection
198
208
  return options
199
209
  end
200
210
  end
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+
15
16
  module Google
16
17
  class APIClient
17
18
  ##
@@ -30,21 +31,15 @@ module Google
30
31
  attr_reader :response
31
32
 
32
33
  def status
33
- return @response[0]
34
+ return @response.status
34
35
  end
35
36
 
36
37
  def headers
37
- return @response[1]
38
+ return @response.headers
38
39
  end
39
40
 
40
41
  def body
41
- return @body ||= (begin
42
- response_body = @response[2]
43
- merged_body = (response_body.inject(StringIO.new) do |accu, chunk|
44
- accu.write(chunk)
45
- accu
46
- end).string
47
- end)
42
+ return @response.body
48
43
  end
49
44
 
50
45
  def data
@@ -56,7 +51,7 @@ module Google
56
51
  data = self.body
57
52
  case media_type
58
53
  when 'application/json'
59
- data = ::JSON.parse(data)
54
+ data = MultiJson.decode(data)
60
55
  # Strip data wrapper, if present
61
56
  data = data['data'] if data.has_key?('data')
62
57
  else
@@ -15,11 +15,13 @@
15
15
 
16
16
  # Used to prevent the class/module from being loaded more than once
17
17
  if !defined?(::Google::APIClient::VERSION)
18
+
19
+
18
20
  module Google
19
21
  class APIClient
20
22
  module VERSION
21
23
  MAJOR = 0
22
- MINOR = 3
24
+ MINOR = 4
23
25
  TINY = 0
24
26
 
25
27
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -14,9 +14,13 @@
14
14
 
15
15
  require 'spec_helper'
16
16
 
17
- require 'json'
17
+ gem 'faraday', '~> 0.7.0'
18
+ require 'faraday'
19
+ require 'faraday/utils'
20
+ require 'multi_json'
21
+
22
+ gem 'signet', '~> 0.3.0'
18
23
  require 'signet/oauth_1/client'
19
- require 'httpadapter/adapters/net_http'
20
24
 
21
25
  require 'google/api_client'
22
26
  require 'google/api_client/version'
@@ -84,8 +88,7 @@ describe Google::APIClient do
84
88
  :uri => @client.discovery_uri('prediction', 'v1.2'),
85
89
  :authenticated => false
86
90
  )
87
- http_method, uri, headers, body = request
88
- uri.should === (
91
+ request.to_env(Faraday.default_connection)[:url].should === (
89
92
  'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
90
93
  '?userIp=127.0.0.1'
91
94
  )
@@ -98,8 +101,7 @@ describe Google::APIClient do
98
101
  :uri => @client.discovery_uri('prediction', 'v1.2'),
99
102
  :authenticated => false
100
103
  )
101
- http_method, uri, headers, body = request
102
- uri.should === (
104
+ request.to_env(Faraday.default_connection)[:url].should === (
103
105
  'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
104
106
  '?key=qwerty'
105
107
  )
@@ -113,11 +115,10 @@ describe Google::APIClient do
113
115
  :uri => @client.discovery_uri('prediction', 'v1.2'),
114
116
  :authenticated => false
115
117
  )
116
- http_method, uri, headers, body = request
117
- uri.should === (
118
- 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
119
- '?key=qwerty&userIp=127.0.0.1'
120
- )
118
+ request.to_env(Faraday.default_connection)[:url].query_values.should == {
119
+ 'key' => 'qwerty',
120
+ 'userIp' => '127.0.0.1'
121
+ }
121
122
  end
122
123
 
123
124
  it 'should correctly generate API objects' do
@@ -167,12 +168,21 @@ describe Google::APIClient do
167
168
  :api_method => @prediction.training.insert,
168
169
  :parameters => {'data' => '12345', }
169
170
  )
170
- method, uri, headers, body = request
171
- method.should == 'POST'
172
- uri.should ==
171
+ request.method.should == :post
172
+ request.to_env(Faraday.default_connection)[:url].should ===
173
173
  'https://www.googleapis.com/prediction/v1.2/training?data=12345'
174
- (headers.inject({}) { |h,(k,v)| h[k]=v; h }).should == {}
175
- body.should respond_to(:each)
174
+ request.headers.should be_empty
175
+ request.body.should == ''
176
+ end
177
+
178
+ it 'should generate valid requests when repeated parameters are passed' do
179
+ request = @client.generate_request(
180
+ :api_method => @prediction.training.insert,
181
+ :parameters => [['data', '1'],['data','2']]
182
+ )
183
+ request.method.should == :post
184
+ request.to_env(Faraday.default_connection)[:url].should ===
185
+ 'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
176
186
  end
177
187
 
178
188
  it 'should generate requests against the correct URIs' do
@@ -180,8 +190,7 @@ describe Google::APIClient do
180
190
  :api_method => @prediction.training.insert,
181
191
  :parameters => {'data' => '12345'}
182
192
  )
183
- method, uri, headers, body = request
184
- uri.should ==
193
+ request.to_env(Faraday.default_connection)[:url].should ===
185
194
  'https://www.googleapis.com/prediction/v1.2/training?data=12345'
186
195
  end
187
196
 
@@ -190,8 +199,7 @@ describe Google::APIClient do
190
199
  :api_method => @prediction.training.insert,
191
200
  :parameters => {'data' => '12345'}
192
201
  )
193
- method, uri, headers, body = request
194
- uri.should ==
202
+ request.to_env(Faraday.default_connection)[:url].should ===
195
203
  'https://www.googleapis.com/prediction/v1.2/training?data=12345'
196
204
  end
197
205
 
@@ -203,8 +211,7 @@ describe Google::APIClient do
203
211
  :api_method => prediction.training.insert,
204
212
  :parameters => {'data' => '123'}
205
213
  )
206
- method, uri, headers, body = request
207
- uri.should == (
214
+ request.to_env(Faraday.default_connection)[:url].should === (
208
215
  'https://testing-domain.googleapis.com/' +
209
216
  'prediction/v1.2/training?data=123'
210
217
  )
@@ -218,10 +225,8 @@ describe Google::APIClient do
218
225
  :api_method => @prediction.training.insert,
219
226
  :parameters => {'data' => '12345'}
220
227
  )
221
- method, uri, headers, body = request
222
- headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
223
- headers.keys.should include('Authorization')
224
- headers['Authorization'].should =~ /^OAuth/
228
+ request.headers.should have_key('Authorization')
229
+ request.headers['Authorization'].should =~ /^OAuth/
225
230
  end
226
231
 
227
232
  it 'should generate OAuth 2 requests' do
@@ -231,10 +236,8 @@ describe Google::APIClient do
231
236
  :api_method => @prediction.training.insert,
232
237
  :parameters => {'data' => '12345'}
233
238
  )
234
- method, uri, headers, body = request
235
- headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
236
- headers.keys.should include('Authorization')
237
- headers['Authorization'].should =~ /^OAuth/
239
+ request.headers.should have_key('Authorization')
240
+ request.headers['Authorization'].should =~ /^Bearer/
238
241
  end
239
242
 
240
243
  it 'should not be able to execute improperly authorized requests' do
@@ -245,8 +248,7 @@ describe Google::APIClient do
245
248
  @prediction.training.insert,
246
249
  {'data' => '12345'}
247
250
  )
248
- status, headers, body = result.response
249
- status.should == 401
251
+ result.response.status.should == 401
250
252
  end
251
253
 
252
254
  it 'should not be able to execute improperly authorized requests' do
@@ -256,8 +258,7 @@ describe Google::APIClient do
256
258
  @prediction.training.insert,
257
259
  {'data' => '12345'}
258
260
  )
259
- status, headers, body = result.response
260
- status.should == 401
261
+ result.response.status.should == 401
261
262
  end
262
263
 
263
264
  it 'should not be able to execute improperly authorized requests' do
@@ -289,11 +290,10 @@ describe Google::APIClient do
289
290
  result = @client.execute(
290
291
  @prediction.training.insert,
291
292
  {},
292
- JSON.generate({"id" => "bucket/object"}),
293
+ MultiJson.encode({"id" => "bucket/object"}),
293
294
  {'Content-Type' => 'application/json'}
294
295
  )
295
- method, uri, headers, body = result.request
296
- Hash[headers]['Content-Type'].should == 'application/json'
296
+ result.request.headers['Content-Type'].should == 'application/json'
297
297
  end
298
298
  end
299
299
 
@@ -334,8 +334,7 @@ describe Google::APIClient do
334
334
  },
335
335
  :authenticated => false
336
336
  )
337
- method, uri, headers, body = request
338
- uri.should == (
337
+ request.to_env(Faraday.default_connection)[:url].should === (
339
338
  'https://www.googleapis.com/plus/v1/' +
340
339
  'people/107807692475771887386/activities/public'
341
340
  )
@@ -395,8 +394,7 @@ describe Google::APIClient do
395
394
  :api_method => 'latitude.currentLocation.get',
396
395
  :authenticated => false
397
396
  )
398
- method, uri, headers, body = request
399
- uri.should ==
397
+ request.to_env(Faraday.default_connection)[:url].should ===
400
398
  'https://www.googleapis.com/latitude/v1/currentLocation'
401
399
  end
402
400
 
@@ -405,8 +403,7 @@ describe Google::APIClient do
405
403
  :api_method => @latitude.current_location.get,
406
404
  :authenticated => false
407
405
  )
408
- method, uri, headers, body = request
409
- uri.should ==
406
+ request.to_env(Faraday.default_connection)[:url].should ===
410
407
  'https://www.googleapis.com/latitude/v1/currentLocation'
411
408
  end
412
409
 
@@ -415,8 +412,7 @@ describe Google::APIClient do
415
412
  :api_method => 'latitude.currentLocation.get',
416
413
  :authenticated => false
417
414
  )
418
- status, headers, body = result.response
419
- status.should == 401
415
+ result.response.status.should == 401
420
416
  end
421
417
  end
422
418
 
@@ -451,8 +447,7 @@ describe Google::APIClient do
451
447
  :api_method => 'moderator.profiles.get',
452
448
  :authenticated => false
453
449
  )
454
- method, uri, headers, body = request
455
- uri.should ==
450
+ request.to_env(Faraday.default_connection)[:url].should ===
456
451
  'https://www.googleapis.com/moderator/v1/profiles/@me'
457
452
  end
458
453
 
@@ -461,8 +456,7 @@ describe Google::APIClient do
461
456
  :api_method => @moderator.profiles.get,
462
457
  :authenticated => false
463
458
  )
464
- method, uri, headers, body = request
465
- uri.should ==
459
+ request.to_env(Faraday.default_connection)[:url].should ===
466
460
  'https://www.googleapis.com/moderator/v1/profiles/@me'
467
461
  end
468
462
 
@@ -474,8 +468,7 @@ describe Google::APIClient do
474
468
  [],
475
469
  {:authenticated => false}
476
470
  )
477
- status, headers, body = result.response
478
- status.should == 401
471
+ result.response.status.should == 401
479
472
  end
480
473
  end
481
474
  end