google-api-client 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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