Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: third_party/google-endpoints/apitools/gen/gen_client.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright 2015 Google Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """Command-line interface to gen_client."""
18
19 import argparse
20 import contextlib
21 import json
22 import logging
23 import os
24 import pkgutil
25 import sys
26
27 from apitools.base.py import exceptions
28 from apitools.gen import gen_client_lib
29 from apitools.gen import util
30
31
32 def _CopyLocalFile(filename):
33 with contextlib.closing(open(filename, 'w')) as out:
34 src_data = pkgutil.get_data(
35 'apitools.base.py', filename)
36 if src_data is None:
37 raise exceptions.GeneratedClientError(
38 'Could not find file %s' % filename)
39 out.write(src_data)
40
41
42 _DISCOVERY_DOC = None
43
44
45 def _GetDiscoveryDocFromFlags(args):
46 """Get the discovery doc from flags."""
47 global _DISCOVERY_DOC # pylint: disable=global-statement
48 if _DISCOVERY_DOC is None:
49 if args.discovery_url:
50 try:
51 discovery_doc = util.FetchDiscoveryDoc(args.discovery_url)
52 except exceptions.CommunicationError:
53 raise exceptions.GeneratedClientError(
54 'Could not fetch discovery doc')
55 else:
56 infile = os.path.expanduser(args.infile) or '/dev/stdin'
57 discovery_doc = json.load(open(infile))
58 _DISCOVERY_DOC = discovery_doc
59 return _DISCOVERY_DOC
60
61
62 def _GetCodegenFromFlags(args):
63 """Create a codegen object from flags."""
64 discovery_doc = _GetDiscoveryDocFromFlags(args)
65 names = util.Names(
66 args.strip_prefix,
67 args.experimental_name_convention,
68 args.experimental_capitalize_enums)
69
70 if args.client_json:
71 try:
72 with open(args.client_json) as client_json:
73 f = json.loads(client_json.read())
74 web = f.get('installed', f.get('web', {}))
75 client_id = web.get('client_id')
76 client_secret = web.get('client_secret')
77 except IOError:
78 raise exceptions.NotFoundError(
79 'Failed to open client json file: %s' % args.client_json)
80 else:
81 client_id = args.client_id
82 client_secret = args.client_secret
83
84 if not client_id:
85 logging.warning('No client ID supplied')
86 client_id = ''
87
88 if not client_secret:
89 logging.warning('No client secret supplied')
90 client_secret = ''
91
92 client_info = util.ClientInfo.Create(
93 discovery_doc, args.scope, client_id, client_secret,
94 args.user_agent, names, args.api_key)
95 outdir = os.path.expanduser(args.outdir) or client_info.default_directory
96 if os.path.exists(outdir) and not args.overwrite:
97 raise exceptions.ConfigurationValueError(
98 'Output directory exists, pass --overwrite to replace '
99 'the existing files.')
100 if not os.path.exists(outdir):
101 os.makedirs(outdir)
102
103 return gen_client_lib.DescriptorGenerator(
104 discovery_doc, client_info, names, args.root_package, outdir,
105 base_package=args.base_package,
106 protorpc_package=args.protorpc_package,
107 generate_cli=args.generate_cli,
108 use_proto2=args.experimental_proto2_output,
109 unelidable_request_methods=args.unelidable_request_methods,
110 apitools_version=args.apitools_version)
111
112
113 # TODO(craigcitro): Delete this if we don't need this functionality.
114 def _WriteBaseFiles(codegen):
115 with util.Chdir(codegen.outdir):
116 _CopyLocalFile('app2.py')
117 _CopyLocalFile('base_api.py')
118 _CopyLocalFile('base_cli.py')
119 _CopyLocalFile('credentials_lib.py')
120 _CopyLocalFile('exceptions.py')
121
122
123 def _WriteIntermediateInit(codegen):
124 with open('__init__.py', 'w') as out:
125 codegen.WriteIntermediateInit(out)
126
127
128 def _WriteProtoFiles(codegen):
129 with util.Chdir(codegen.outdir):
130 with open(codegen.client_info.messages_proto_file_name, 'w') as out:
131 codegen.WriteMessagesProtoFile(out)
132 with open(codegen.client_info.services_proto_file_name, 'w') as out:
133 codegen.WriteServicesProtoFile(out)
134
135
136 def _WriteGeneratedFiles(args, codegen):
137 if codegen.use_proto2:
138 _WriteProtoFiles(codegen)
139 with util.Chdir(codegen.outdir):
140 with open(codegen.client_info.messages_file_name, 'w') as out:
141 codegen.WriteMessagesFile(out)
142 with open(codegen.client_info.client_file_name, 'w') as out:
143 codegen.WriteClientLibrary(out)
144 if args.generate_cli:
145 with open(codegen.client_info.cli_file_name, 'w') as out:
146 codegen.WriteCli(out)
147 os.chmod(codegen.client_info.cli_file_name, 0o755)
148
149
150 def _WriteInit(codegen):
151 with util.Chdir(codegen.outdir):
152 with open('__init__.py', 'w') as out:
153 codegen.WriteInit(out)
154
155
156 def _WriteSetupPy(codegen):
157 with open('setup.py', 'w') as out:
158 codegen.WriteSetupPy(out)
159
160
161 def GenerateClient(args):
162
163 """Driver for client code generation."""
164
165 codegen = _GetCodegenFromFlags(args)
166 if codegen is None:
167 logging.error('Failed to create codegen, exiting.')
168 return 128
169 _WriteGeneratedFiles(args, codegen)
170 _WriteInit(codegen)
171
172
173 def GeneratePipPackage(args):
174
175 """Generate a client as a pip-installable tarball."""
176
177 discovery_doc = _GetDiscoveryDocFromFlags(args)
178 package = discovery_doc['name']
179 original_outdir = os.path.expanduser(args.outdir)
180 args.outdir = os.path.join(
181 args.outdir, 'apitools/clients/%s' % package)
182 args.root_package = 'apitools.clients.%s' % package
183 args.generate_cli = False
184 codegen = _GetCodegenFromFlags(args)
185 if codegen is None:
186 logging.error('Failed to create codegen, exiting.')
187 return 1
188 _WriteGeneratedFiles(args, codegen)
189 _WriteInit(codegen)
190 with util.Chdir(original_outdir):
191 _WriteSetupPy(codegen)
192 with util.Chdir('apitools'):
193 _WriteIntermediateInit(codegen)
194 with util.Chdir('clients'):
195 _WriteIntermediateInit(codegen)
196
197
198 def GenerateProto(args):
199 """Generate just the two proto files for a given API."""
200
201 codegen = _GetCodegenFromFlags(args)
202 _WriteProtoFiles(codegen)
203
204
205 class _SplitCommaSeparatedList(argparse.Action):
206
207 def __call__(self, parser, namespace, values, option_string=None):
208 setattr(namespace, self.dest, values.split(','))
209
210
211 def main(argv=None):
212 if argv is None:
213 argv = sys.argv
214 parser = argparse.ArgumentParser(
215 description='Apitools Client Code Generator')
216
217 discovery_group = parser.add_mutually_exclusive_group()
218 discovery_group.add_argument(
219 '--infile',
220 help=('Filename for the discovery document. Mutually exclusive with '
221 '--discovery_url'))
222
223 discovery_group.add_argument(
224 '--discovery_url',
225 help=('URL (or "name.version") of the discovery document to use. '
226 'Mutually exclusive with --infile.'))
227
228 parser.add_argument(
229 '--base_package',
230 default='apitools.base.py',
231 help='Base package path of apitools (defaults to apitools.base.py')
232
233 parser.add_argument(
234 '--protorpc_package',
235 default='apitools.base.protorpclite',
236 help=('Base package path of protorpc '
237 '(defaults to apitools.base.protorpclite'))
238
239 parser.add_argument(
240 '--outdir',
241 default='',
242 help='Directory name for output files. (Defaults to the API name.)')
243
244 parser.add_argument(
245 '--overwrite',
246 default=False, action='store_true',
247 help='Only overwrite the output directory if this flag is specified.')
248
249 parser.add_argument(
250 '--root_package',
251 default='',
252 help=('Python import path for where these modules '
253 'should be imported from.'))
254
255 parser.add_argument(
256 '--strip_prefix', nargs='*',
257 default=[],
258 help=('Prefix to strip from type names in the discovery document. '
259 '(May be specified multiple times.)'))
260
261 parser.add_argument(
262 '--api_key',
263 help=('API key to use for API access.'))
264
265 parser.add_argument(
266 '--client_json',
267 help=('Use the given file downloaded from the dev. console for '
268 'client_id and client_secret.'))
269
270 parser.add_argument(
271 '--client_id',
272 default='1042881264118.apps.googleusercontent.com',
273 help='Client ID to use for the generated client.')
274
275 parser.add_argument(
276 '--client_secret',
277 default='x_Tw5K8nnjoRAqULM9PFAC2b',
278 help='Client secret for the generated client.')
279
280 parser.add_argument(
281 '--scope', nargs='*',
282 default=[],
283 help=('Scopes to request in the generated client. '
284 'May be specified more than once.'))
285
286 parser.add_argument(
287 '--user_agent',
288 default='x_Tw5K8nnjoRAqULM9PFAC2b',
289 help=('User agent for the generated client. '
290 'Defaults to <api>-generated/0.1.'))
291
292 parser.add_argument(
293 '--generate_cli', dest='generate_cli', action='store_true',
294 help='If specified (default), a CLI is also generated.')
295 parser.add_argument(
296 '--nogenerate_cli', dest='generate_cli', action='store_false',
297 help='CLI will not be generated.')
298 parser.set_defaults(generate_cli=True)
299
300 parser.add_argument(
301 '--unelidable_request_methods',
302 action=_SplitCommaSeparatedList,
303 default=[],
304 help=('Full method IDs of methods for which we should NOT try to '
305 'elide the request type. (Should be a comma-separated list.'))
306
307 parser.add_argument(
308 '--apitools_version',
309 default='', dest='apitools_version',
310 help=('Apitools version used as a requirement in generated clients. '
311 'Defaults to version of apitools used to generate the clients.'))
312
313 parser.add_argument(
314 '--experimental_capitalize_enums',
315 default=False, action='store_true',
316 help='Dangerous: attempt to rewrite enum values to be uppercase.')
317
318 parser.add_argument(
319 '--experimental_name_convention',
320 choices=util.Names.NAME_CONVENTIONS,
321 default=util.Names.DEFAULT_NAME_CONVENTION,
322 help='Dangerous: use a particular style for generated names.')
323
324 parser.add_argument(
325 '--experimental_proto2_output',
326 default=False, action='store_true',
327 help='Dangerous: also output a proto2 message file.')
328
329 subparsers = parser.add_subparsers(help='Type of generated code')
330
331 client_parser = subparsers.add_parser(
332 'client', help='Generate apitools client in destination folder')
333 client_parser.set_defaults(func=GenerateClient)
334
335 pip_package_parser = subparsers.add_parser(
336 'pip_package', help='Generate apitools client pip package')
337 pip_package_parser.set_defaults(func=GeneratePipPackage)
338
339 proto_parser = subparsers.add_parser(
340 'proto', help='Generate apitools client protos')
341 proto_parser.set_defaults(func=GenerateProto)
342
343 args = parser.parse_args(argv[1:])
344 return args.func(args) or 0
345
346 if __name__ == '__main__':
347 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698