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.
- data/CHANGELOG.md +43 -0
- data/README.md +4 -5
- data/bin/google-api +12 -7
- data/lib/google/api_client.rb +179 -161
- data/lib/google/api_client/discovery/api.rb +1 -0
- data/lib/google/api_client/discovery/method.rb +11 -8
- data/lib/google/api_client/discovery/resource.rb +1 -0
- data/lib/google/api_client/discovery/schema.rb +2 -1
- data/lib/google/api_client/environment.rb +15 -0
- data/lib/google/api_client/reference.rb +41 -31
- data/lib/google/api_client/result.rb +5 -10
- data/lib/google/api_client/version.rb +3 -1
- data/spec/google/api_client/discovery_spec.rb +44 -51
- data/spec/google/api_client_spec.rb +19 -10
- data/tasks/gem.rake +7 -6
- data/tasks/git.rake +1 -1
- data/tasks/rdoc.rake +5 -8
- data/tasks/spec.rake +3 -2
- data/tasks/wiki.rake +48 -7
- data/tasks/yard.rake +7 -4
- metadata +11 -17
- data/CHANGELOG +0 -36
- data/lib/google/api_client/parser.rb +0 -59
- data/lib/google/api_client/parsers/json/error_parser.rb +0 -34
- data/lib/google/api_client/parsers/json/pagination.rb +0 -40
- data/lib/google/api_client/parsers/json_parser.rb +0 -119
- data/spec/google/api_client/parsers/json_parser_spec.rb +0 -55
- data/tasks/clobber.rake +0 -2
@@ -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
|
-
#
|
143
|
-
|
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]
|
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 ||
|
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
|
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.
|
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(', ')}."
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
|
16
16
|
require 'time'
|
17
|
-
require '
|
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
|
-
|
16
|
-
|
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 =
|
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.
|
55
|
+
self.body = serialized_body
|
52
56
|
else
|
53
|
-
self.
|
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?(:
|
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
|
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.
|
183
|
+
self.parameters, self.body, self.headers
|
181
184
|
)
|
182
185
|
else
|
183
|
-
return
|
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
|
34
|
+
return @response.status
|
34
35
|
end
|
35
36
|
|
36
37
|
def headers
|
37
|
-
return @response
|
38
|
+
return @response.headers
|
38
39
|
end
|
39
40
|
|
40
41
|
def body
|
41
|
-
return @body
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
117
|
-
|
118
|
-
'
|
119
|
-
|
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
|
171
|
-
|
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
|
-
|
175
|
-
body.should
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
222
|
-
headers
|
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
|
-
|
235
|
-
headers
|
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
|
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
|
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
|
-
|
293
|
+
MultiJson.encode({"id" => "bucket/object"}),
|
293
294
|
{'Content-Type' => 'application/json'}
|
294
295
|
)
|
295
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
478
|
-
status.should == 401
|
471
|
+
result.response.status.should == 401
|
479
472
|
end
|
480
473
|
end
|
481
474
|
end
|