google-api-client 0.6.4 → 0.7.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +13 -3
- data/README.md +133 -97
- data/Rakefile +1 -1
- data/lib/cacerts.pem +2183 -0
- data/lib/google/api_client/auth/compute_service_account.rb +28 -0
- data/lib/google/api_client/auth/file_storage.rb +87 -0
- data/lib/google/api_client/auth/installed_app.rb +8 -1
- data/lib/google/api_client/auth/jwt_asserter.rb +0 -11
- data/lib/google/api_client/client_secrets.rb +1 -1
- data/lib/google/api_client/discovery/method.rb +1 -0
- data/lib/google/api_client/errors.rb +11 -0
- data/lib/google/api_client/gzip.rb +28 -0
- data/lib/google/api_client/media.rb +80 -5
- data/lib/google/api_client/request.rb +15 -9
- data/lib/google/api_client/service/batch.rb +103 -0
- data/lib/google/api_client/service/request.rb +144 -0
- data/lib/google/api_client/service/resource.rb +40 -0
- data/lib/google/api_client/service/result.rb +162 -0
- data/lib/google/api_client/service/simple_file_store.rb +151 -0
- data/lib/google/api_client/service/stub_generator.rb +59 -0
- data/lib/google/api_client/service.rb +233 -0
- data/lib/google/api_client/service_account.rb +1 -0
- data/lib/google/api_client/version.rb +4 -3
- data/lib/google/api_client.rb +81 -42
- data/spec/google/api_client/batch_spec.rb +4 -4
- data/spec/google/api_client/discovery_spec.rb +60 -102
- data/spec/google/api_client/gzip_spec.rb +86 -0
- data/spec/google/api_client/media_spec.rb +49 -1
- data/spec/google/api_client/request_spec.rb +30 -0
- data/spec/google/api_client/result_spec.rb +3 -4
- data/spec/google/api_client/service_account_spec.rb +21 -0
- data/spec/google/api_client/service_spec.rb +586 -0
- data/spec/google/api_client/simple_file_store_spec.rb +137 -0
- data/spec/google/api_client_spec.rb +101 -3
- data/spec/spec_helper.rb +3 -0
- data/tasks/gem.rake +3 -4
- metadata +95 -50
- data/bin/google-api +0 -391
- /data/{CONTRIB.md → CONTRIBUTING.md} +0 -0
data/bin/google-api
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
bin_dir = File.expand_path("..", __FILE__)
|
|
4
|
-
lib_dir = File.expand_path("../lib", bin_dir)
|
|
5
|
-
|
|
6
|
-
$LOAD_PATH.unshift(lib_dir)
|
|
7
|
-
$LOAD_PATH.uniq!
|
|
8
|
-
|
|
9
|
-
OAUTH_SERVER_PORT = 12736
|
|
10
|
-
|
|
11
|
-
require 'rubygems'
|
|
12
|
-
require 'optparse'
|
|
13
|
-
require 'faraday'
|
|
14
|
-
require 'faraday/utils'
|
|
15
|
-
require 'webrick'
|
|
16
|
-
require 'google/api_client/version'
|
|
17
|
-
require 'google/api_client'
|
|
18
|
-
require 'google/api_client/auth/installed_app'
|
|
19
|
-
require 'irb'
|
|
20
|
-
|
|
21
|
-
ARGV.unshift('--help') if ARGV.empty?
|
|
22
|
-
|
|
23
|
-
module Google
|
|
24
|
-
class APIClient
|
|
25
|
-
class CLI
|
|
26
|
-
|
|
27
|
-
# Initialize with default parameter values
|
|
28
|
-
def initialize(argv)
|
|
29
|
-
@options = {
|
|
30
|
-
:command => 'execute',
|
|
31
|
-
:rpcname => nil,
|
|
32
|
-
:verbose => false
|
|
33
|
-
}
|
|
34
|
-
@argv = argv.clone
|
|
35
|
-
if @argv.first =~ /^[a-z0-9][a-z0-9_-]*$/i
|
|
36
|
-
self.options[:command] = @argv.shift
|
|
37
|
-
end
|
|
38
|
-
if @argv.first =~ /^[a-z0-9_-]+\.[a-z0-9_\.-]+$/i
|
|
39
|
-
self.options[:rpcname] = @argv.shift
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
attr_reader :options
|
|
44
|
-
attr_reader :argv
|
|
45
|
-
|
|
46
|
-
def command
|
|
47
|
-
return self.options[:command]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def rpcname
|
|
51
|
-
return self.options[:rpcname]
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def parser
|
|
55
|
-
@parser ||= OptionParser.new do |opts|
|
|
56
|
-
opts.banner = "Usage: google-api " +
|
|
57
|
-
"(execute <rpcname> | [command]) [options] [-- <parameters>]"
|
|
58
|
-
|
|
59
|
-
opts.separator "\nAvailable options:"
|
|
60
|
-
|
|
61
|
-
opts.on(
|
|
62
|
-
"--scope <scope>", String, "Set the OAuth scope") do |s|
|
|
63
|
-
options[:scope] = s
|
|
64
|
-
end
|
|
65
|
-
opts.on(
|
|
66
|
-
"--client-id <key>", String,
|
|
67
|
-
"Set the OAuth client id or key") do |k|
|
|
68
|
-
options[:client_credential_key] = k
|
|
69
|
-
end
|
|
70
|
-
opts.on(
|
|
71
|
-
"--client-secret <secret>", String,
|
|
72
|
-
"Set the OAuth client secret") do |s|
|
|
73
|
-
options[:client_credential_secret] = s
|
|
74
|
-
end
|
|
75
|
-
opts.on(
|
|
76
|
-
"--api <name>", String,
|
|
77
|
-
"Perform discovery on API") do |s|
|
|
78
|
-
options[:api] = s
|
|
79
|
-
end
|
|
80
|
-
opts.on(
|
|
81
|
-
"--api-version <id>", String,
|
|
82
|
-
"Select api version") do |id|
|
|
83
|
-
options[:version] = id
|
|
84
|
-
end
|
|
85
|
-
opts.on(
|
|
86
|
-
"--content-type <format>", String,
|
|
87
|
-
"Content-Type for request") do |f|
|
|
88
|
-
# Resolve content type shortcuts
|
|
89
|
-
case f
|
|
90
|
-
when 'json'
|
|
91
|
-
f = 'application/json'
|
|
92
|
-
when 'xml'
|
|
93
|
-
f = 'application/xml'
|
|
94
|
-
when 'atom'
|
|
95
|
-
f = 'application/atom+xml'
|
|
96
|
-
when 'rss'
|
|
97
|
-
f = 'application/rss+xml'
|
|
98
|
-
end
|
|
99
|
-
options[:content_type] = f
|
|
100
|
-
end
|
|
101
|
-
opts.on(
|
|
102
|
-
"-u", "--uri <uri>", String,
|
|
103
|
-
"Sets the URI to perform a request against") do |u|
|
|
104
|
-
options[:uri] = u
|
|
105
|
-
end
|
|
106
|
-
opts.on(
|
|
107
|
-
"--discovery-uri <uri>", String,
|
|
108
|
-
"Sets the URI to perform discovery") do |u|
|
|
109
|
-
options[:discovery_uri] = u
|
|
110
|
-
end
|
|
111
|
-
opts.on(
|
|
112
|
-
"-m", "--method <method>", String,
|
|
113
|
-
"Sets the HTTP method to use for the request") do |m|
|
|
114
|
-
options[:http_method] = m
|
|
115
|
-
end
|
|
116
|
-
opts.on(
|
|
117
|
-
"--requestor-id <email>", String,
|
|
118
|
-
"Sets the email address of the requestor") do |e|
|
|
119
|
-
options[:requestor_id] = e
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
opts.on("-v", "--verbose", "Run verbosely") do |v|
|
|
123
|
-
options[:verbose] = v
|
|
124
|
-
end
|
|
125
|
-
opts.on("-h", "--help", "Show this message") do
|
|
126
|
-
puts opts
|
|
127
|
-
exit
|
|
128
|
-
end
|
|
129
|
-
opts.on("--version", "Show version") do
|
|
130
|
-
puts "google-api-client (#{Google::APIClient::VERSION::STRING})"
|
|
131
|
-
exit
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
opts.separator(
|
|
135
|
-
"\nAvailable commands:\n" +
|
|
136
|
-
" oauth-2-login Log a user into an API with OAuth 2.0\n" +
|
|
137
|
-
" list List the methods available for an API\n" +
|
|
138
|
-
" execute Execute a method on the API\n" +
|
|
139
|
-
" irb Start an interactive client session"
|
|
140
|
-
)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def parse!
|
|
145
|
-
self.parser.parse!(self.argv)
|
|
146
|
-
symbol = self.command.gsub(/-/, "_").to_sym
|
|
147
|
-
if !COMMANDS.include?(symbol)
|
|
148
|
-
STDERR.puts("Invalid command: #{self.command}")
|
|
149
|
-
exit(1)
|
|
150
|
-
end
|
|
151
|
-
self.send(symbol)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def client
|
|
155
|
-
require 'yaml'
|
|
156
|
-
config_file = File.expand_path('~/.google-api.yaml')
|
|
157
|
-
authorization = nil
|
|
158
|
-
if File.exist?(config_file)
|
|
159
|
-
config = open(config_file, 'r') { |file| YAML.load(file.read) }
|
|
160
|
-
else
|
|
161
|
-
config = {}
|
|
162
|
-
end
|
|
163
|
-
if config["mechanism"]
|
|
164
|
-
authorization = config["mechanism"].to_sym
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
client = Google::APIClient.new(
|
|
168
|
-
:application_name => 'Ruby CLI',
|
|
169
|
-
:application_version => Google::APIClient::VERSION::STRING,
|
|
170
|
-
:authorization => authorization)
|
|
171
|
-
|
|
172
|
-
case authorization
|
|
173
|
-
when :oauth_1
|
|
174
|
-
STDERR.puts('OAuth 1 is deprecated. Please reauthorize with OAuth 2.')
|
|
175
|
-
client.authorization.client_credential_key =
|
|
176
|
-
config["client_credential_key"]
|
|
177
|
-
client.authorization.client_credential_secret =
|
|
178
|
-
config["client_credential_secret"]
|
|
179
|
-
client.authorization.token_credential_key =
|
|
180
|
-
config["token_credential_key"]
|
|
181
|
-
client.authorization.token_credential_secret =
|
|
182
|
-
config["token_credential_secret"]
|
|
183
|
-
when :oauth_2
|
|
184
|
-
client.authorization.scope = options[:scope]
|
|
185
|
-
client.authorization.client_id = config["client_id"]
|
|
186
|
-
client.authorization.client_secret = config["client_secret"]
|
|
187
|
-
client.authorization.access_token = config["access_token"]
|
|
188
|
-
client.authorization.refresh_token = config["refresh_token"]
|
|
189
|
-
else
|
|
190
|
-
# Dunno?
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
if options[:discovery_uri]
|
|
194
|
-
if options[:api] && options[:version]
|
|
195
|
-
client.register_discovery_uri(
|
|
196
|
-
options[:api], options[:version], options[:discovery_uri]
|
|
197
|
-
)
|
|
198
|
-
else
|
|
199
|
-
STDERR.puts(
|
|
200
|
-
'Cannot register a discovery URI without ' +
|
|
201
|
-
'specifying an API and version.'
|
|
202
|
-
)
|
|
203
|
-
exit(1)
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
return client
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def api_version(api_name, version)
|
|
211
|
-
v = version
|
|
212
|
-
if !version
|
|
213
|
-
if client.preferred_version(api_name)
|
|
214
|
-
v = client.preferred_version(api_name).version
|
|
215
|
-
else
|
|
216
|
-
v = 'v1'
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
return v
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
COMMANDS = [
|
|
223
|
-
:oauth_2_login,
|
|
224
|
-
:list,
|
|
225
|
-
:execute,
|
|
226
|
-
:irb,
|
|
227
|
-
]
|
|
228
|
-
|
|
229
|
-
def oauth_2_login
|
|
230
|
-
require 'signet/oauth_2/client'
|
|
231
|
-
require 'yaml'
|
|
232
|
-
if !options[:client_credential_key] ||
|
|
233
|
-
!options[:client_credential_secret]
|
|
234
|
-
STDERR.puts('No client ID and secret supplied.')
|
|
235
|
-
exit(1)
|
|
236
|
-
end
|
|
237
|
-
if options[:access_token]
|
|
238
|
-
config = {
|
|
239
|
-
"mechanism" => "oauth_2",
|
|
240
|
-
"scope" => options[:scope],
|
|
241
|
-
"client_id" => options[:client_credential_key],
|
|
242
|
-
"client_secret" => options[:client_credential_secret],
|
|
243
|
-
"access_token" => options[:access_token],
|
|
244
|
-
"refresh_token" => options[:refresh_token]
|
|
245
|
-
}
|
|
246
|
-
config_file = File.expand_path('~/.google-api.yaml')
|
|
247
|
-
open(config_file, 'w') { |file| file.write(YAML.dump(config)) }
|
|
248
|
-
exit(0)
|
|
249
|
-
else
|
|
250
|
-
flow = Google::APIClient::InstalledAppFlow.new(
|
|
251
|
-
:port => OAUTH_SERVER_PORT,
|
|
252
|
-
:client_id => options[:client_credential_key],
|
|
253
|
-
:client_secret => options[:client_credential_secret],
|
|
254
|
-
:scope => options[:scope]
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
oauth_client = flow.authorize
|
|
258
|
-
if oauth_client
|
|
259
|
-
config = {
|
|
260
|
-
"mechanism" => "oauth_2",
|
|
261
|
-
"scope" => options[:scope],
|
|
262
|
-
"client_id" => oauth_client.client_id,
|
|
263
|
-
"client_secret" => oauth_client.client_secret,
|
|
264
|
-
"access_token" => oauth_client.access_token,
|
|
265
|
-
"refresh_token" => oauth_client.refresh_token
|
|
266
|
-
}
|
|
267
|
-
config_file = File.expand_path('~/.google-api.yaml')
|
|
268
|
-
open(config_file, 'w') { |file| file.write(YAML.dump(config)) }
|
|
269
|
-
end
|
|
270
|
-
exit(0)
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def list
|
|
275
|
-
api_name = options[:api]
|
|
276
|
-
unless api_name
|
|
277
|
-
STDERR.puts('No API name supplied.')
|
|
278
|
-
exit(1)
|
|
279
|
-
end
|
|
280
|
-
#client = Google::APIClient.new(:authorization => nil)
|
|
281
|
-
if options[:discovery_uri]
|
|
282
|
-
if options[:api] && options[:version]
|
|
283
|
-
client.register_discovery_uri(
|
|
284
|
-
options[:api], options[:version], options[:discovery_uri]
|
|
285
|
-
)
|
|
286
|
-
else
|
|
287
|
-
STDERR.puts(
|
|
288
|
-
'Cannot register a discovery URI without ' +
|
|
289
|
-
'specifying an API and version.'
|
|
290
|
-
)
|
|
291
|
-
exit(1)
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
version = api_version(api_name, options[:version])
|
|
295
|
-
api = client.discovered_api(api_name, version)
|
|
296
|
-
rpcnames = api.to_h.keys
|
|
297
|
-
puts rpcnames.sort.join("\n")
|
|
298
|
-
exit(0)
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
def execute
|
|
302
|
-
client = self.client
|
|
303
|
-
|
|
304
|
-
# Setup HTTP request data
|
|
305
|
-
request_body = ''
|
|
306
|
-
input_streams, _, _ = IO.select([STDIN], [], [], 0)
|
|
307
|
-
request_body = STDIN.read || '' if input_streams
|
|
308
|
-
headers = []
|
|
309
|
-
if options[:content_type]
|
|
310
|
-
headers << ['Content-Type', options[:content_type]]
|
|
311
|
-
elsif request_body
|
|
312
|
-
# Default to JSON
|
|
313
|
-
headers << ['Content-Type', 'application/json']
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
if options[:uri]
|
|
317
|
-
# Make request with URI manually specified
|
|
318
|
-
uri = Addressable::URI.parse(options[:uri])
|
|
319
|
-
if uri.relative?
|
|
320
|
-
STDERR.puts('URI may not be relative.')
|
|
321
|
-
exit(1)
|
|
322
|
-
end
|
|
323
|
-
if options[:requestor_id]
|
|
324
|
-
uri.query_values = uri.query_values.merge(
|
|
325
|
-
'xoauth_requestor_id' => options[:requestor_id]
|
|
326
|
-
)
|
|
327
|
-
end
|
|
328
|
-
method = options[:http_method]
|
|
329
|
-
method ||= request_body == '' ? 'GET' : 'POST'
|
|
330
|
-
method.upcase!
|
|
331
|
-
response = client.execute(:http_method => method, :uri => uri.to_str,
|
|
332
|
-
:headers => headers, :body => request_body)
|
|
333
|
-
puts response.body
|
|
334
|
-
exit(0)
|
|
335
|
-
else
|
|
336
|
-
# Make request with URI generated from template and parameters
|
|
337
|
-
if !self.rpcname
|
|
338
|
-
STDERR.puts('No rpcname supplied.')
|
|
339
|
-
exit(1)
|
|
340
|
-
end
|
|
341
|
-
api_name = options[:api] || self.rpcname[/^([^\.]+)\./, 1]
|
|
342
|
-
version = api_version(api_name, options[:version])
|
|
343
|
-
api = client.discovered_api(api_name, version)
|
|
344
|
-
method = api.to_h[self.rpcname]
|
|
345
|
-
if !method
|
|
346
|
-
STDERR.puts(
|
|
347
|
-
"Method #{self.rpcname} does not exist for " +
|
|
348
|
-
"#{api_name}-#{version}."
|
|
349
|
-
)
|
|
350
|
-
exit(1)
|
|
351
|
-
end
|
|
352
|
-
parameters = self.argv.inject({}) do |accu, pair|
|
|
353
|
-
name, value = pair.split('=', 2)
|
|
354
|
-
accu[name] = value
|
|
355
|
-
accu
|
|
356
|
-
end
|
|
357
|
-
if options[:requestor_id]
|
|
358
|
-
parameters['xoauth_requestor_id'] = options[:requestor_id]
|
|
359
|
-
end
|
|
360
|
-
begin
|
|
361
|
-
result = client.execute(
|
|
362
|
-
:api_method => method,
|
|
363
|
-
:parameters => parameters,
|
|
364
|
-
:merged_body => request_body,
|
|
365
|
-
:headers => headers
|
|
366
|
-
)
|
|
367
|
-
puts result.response.body
|
|
368
|
-
exit(0)
|
|
369
|
-
rescue ArgumentError => e
|
|
370
|
-
puts e.message
|
|
371
|
-
exit(1)
|
|
372
|
-
end
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
def irb
|
|
377
|
-
$client = self.client
|
|
378
|
-
# Otherwise IRB will misinterpret command-line options
|
|
379
|
-
ARGV.clear
|
|
380
|
-
IRB.start(__FILE__)
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
def help
|
|
384
|
-
puts self.parser
|
|
385
|
-
exit(0)
|
|
386
|
-
end
|
|
387
|
-
end
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
Google::APIClient::CLI.new(ARGV).parse!
|
|
File without changes
|