Index: third_party/google-endpoints/apitools/gen/gen_client.py |
diff --git a/third_party/google-endpoints/apitools/gen/gen_client.py b/third_party/google-endpoints/apitools/gen/gen_client.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8f19dfcbdaedbcc6d540186304abcbb3c3a92ba6 |
--- /dev/null |
+++ b/third_party/google-endpoints/apitools/gen/gen_client.py |
@@ -0,0 +1,347 @@ |
+#!/usr/bin/env python |
+# |
+# Copyright 2015 Google Inc. |
+# |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
+# you may not use this file except in compliance with the License. |
+# You may obtain a copy of the License at |
+# |
+# http://www.apache.org/licenses/LICENSE-2.0 |
+# |
+# Unless required by applicable law or agreed to in writing, software |
+# distributed under the License is distributed on an "AS IS" BASIS, |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+# See the License for the specific language governing permissions and |
+# limitations under the License. |
+ |
+"""Command-line interface to gen_client.""" |
+ |
+import argparse |
+import contextlib |
+import json |
+import logging |
+import os |
+import pkgutil |
+import sys |
+ |
+from apitools.base.py import exceptions |
+from apitools.gen import gen_client_lib |
+from apitools.gen import util |
+ |
+ |
+def _CopyLocalFile(filename): |
+ with contextlib.closing(open(filename, 'w')) as out: |
+ src_data = pkgutil.get_data( |
+ 'apitools.base.py', filename) |
+ if src_data is None: |
+ raise exceptions.GeneratedClientError( |
+ 'Could not find file %s' % filename) |
+ out.write(src_data) |
+ |
+ |
+_DISCOVERY_DOC = None |
+ |
+ |
+def _GetDiscoveryDocFromFlags(args): |
+ """Get the discovery doc from flags.""" |
+ global _DISCOVERY_DOC # pylint: disable=global-statement |
+ if _DISCOVERY_DOC is None: |
+ if args.discovery_url: |
+ try: |
+ discovery_doc = util.FetchDiscoveryDoc(args.discovery_url) |
+ except exceptions.CommunicationError: |
+ raise exceptions.GeneratedClientError( |
+ 'Could not fetch discovery doc') |
+ else: |
+ infile = os.path.expanduser(args.infile) or '/dev/stdin' |
+ discovery_doc = json.load(open(infile)) |
+ _DISCOVERY_DOC = discovery_doc |
+ return _DISCOVERY_DOC |
+ |
+ |
+def _GetCodegenFromFlags(args): |
+ """Create a codegen object from flags.""" |
+ discovery_doc = _GetDiscoveryDocFromFlags(args) |
+ names = util.Names( |
+ args.strip_prefix, |
+ args.experimental_name_convention, |
+ args.experimental_capitalize_enums) |
+ |
+ if args.client_json: |
+ try: |
+ with open(args.client_json) as client_json: |
+ f = json.loads(client_json.read()) |
+ web = f.get('installed', f.get('web', {})) |
+ client_id = web.get('client_id') |
+ client_secret = web.get('client_secret') |
+ except IOError: |
+ raise exceptions.NotFoundError( |
+ 'Failed to open client json file: %s' % args.client_json) |
+ else: |
+ client_id = args.client_id |
+ client_secret = args.client_secret |
+ |
+ if not client_id: |
+ logging.warning('No client ID supplied') |
+ client_id = '' |
+ |
+ if not client_secret: |
+ logging.warning('No client secret supplied') |
+ client_secret = '' |
+ |
+ client_info = util.ClientInfo.Create( |
+ discovery_doc, args.scope, client_id, client_secret, |
+ args.user_agent, names, args.api_key) |
+ outdir = os.path.expanduser(args.outdir) or client_info.default_directory |
+ if os.path.exists(outdir) and not args.overwrite: |
+ raise exceptions.ConfigurationValueError( |
+ 'Output directory exists, pass --overwrite to replace ' |
+ 'the existing files.') |
+ if not os.path.exists(outdir): |
+ os.makedirs(outdir) |
+ |
+ return gen_client_lib.DescriptorGenerator( |
+ discovery_doc, client_info, names, args.root_package, outdir, |
+ base_package=args.base_package, |
+ protorpc_package=args.protorpc_package, |
+ generate_cli=args.generate_cli, |
+ use_proto2=args.experimental_proto2_output, |
+ unelidable_request_methods=args.unelidable_request_methods, |
+ apitools_version=args.apitools_version) |
+ |
+ |
+# TODO(craigcitro): Delete this if we don't need this functionality. |
+def _WriteBaseFiles(codegen): |
+ with util.Chdir(codegen.outdir): |
+ _CopyLocalFile('app2.py') |
+ _CopyLocalFile('base_api.py') |
+ _CopyLocalFile('base_cli.py') |
+ _CopyLocalFile('credentials_lib.py') |
+ _CopyLocalFile('exceptions.py') |
+ |
+ |
+def _WriteIntermediateInit(codegen): |
+ with open('__init__.py', 'w') as out: |
+ codegen.WriteIntermediateInit(out) |
+ |
+ |
+def _WriteProtoFiles(codegen): |
+ with util.Chdir(codegen.outdir): |
+ with open(codegen.client_info.messages_proto_file_name, 'w') as out: |
+ codegen.WriteMessagesProtoFile(out) |
+ with open(codegen.client_info.services_proto_file_name, 'w') as out: |
+ codegen.WriteServicesProtoFile(out) |
+ |
+ |
+def _WriteGeneratedFiles(args, codegen): |
+ if codegen.use_proto2: |
+ _WriteProtoFiles(codegen) |
+ with util.Chdir(codegen.outdir): |
+ with open(codegen.client_info.messages_file_name, 'w') as out: |
+ codegen.WriteMessagesFile(out) |
+ with open(codegen.client_info.client_file_name, 'w') as out: |
+ codegen.WriteClientLibrary(out) |
+ if args.generate_cli: |
+ with open(codegen.client_info.cli_file_name, 'w') as out: |
+ codegen.WriteCli(out) |
+ os.chmod(codegen.client_info.cli_file_name, 0o755) |
+ |
+ |
+def _WriteInit(codegen): |
+ with util.Chdir(codegen.outdir): |
+ with open('__init__.py', 'w') as out: |
+ codegen.WriteInit(out) |
+ |
+ |
+def _WriteSetupPy(codegen): |
+ with open('setup.py', 'w') as out: |
+ codegen.WriteSetupPy(out) |
+ |
+ |
+def GenerateClient(args): |
+ |
+ """Driver for client code generation.""" |
+ |
+ codegen = _GetCodegenFromFlags(args) |
+ if codegen is None: |
+ logging.error('Failed to create codegen, exiting.') |
+ return 128 |
+ _WriteGeneratedFiles(args, codegen) |
+ _WriteInit(codegen) |
+ |
+ |
+def GeneratePipPackage(args): |
+ |
+ """Generate a client as a pip-installable tarball.""" |
+ |
+ discovery_doc = _GetDiscoveryDocFromFlags(args) |
+ package = discovery_doc['name'] |
+ original_outdir = os.path.expanduser(args.outdir) |
+ args.outdir = os.path.join( |
+ args.outdir, 'apitools/clients/%s' % package) |
+ args.root_package = 'apitools.clients.%s' % package |
+ args.generate_cli = False |
+ codegen = _GetCodegenFromFlags(args) |
+ if codegen is None: |
+ logging.error('Failed to create codegen, exiting.') |
+ return 1 |
+ _WriteGeneratedFiles(args, codegen) |
+ _WriteInit(codegen) |
+ with util.Chdir(original_outdir): |
+ _WriteSetupPy(codegen) |
+ with util.Chdir('apitools'): |
+ _WriteIntermediateInit(codegen) |
+ with util.Chdir('clients'): |
+ _WriteIntermediateInit(codegen) |
+ |
+ |
+def GenerateProto(args): |
+ """Generate just the two proto files for a given API.""" |
+ |
+ codegen = _GetCodegenFromFlags(args) |
+ _WriteProtoFiles(codegen) |
+ |
+ |
+class _SplitCommaSeparatedList(argparse.Action): |
+ |
+ def __call__(self, parser, namespace, values, option_string=None): |
+ setattr(namespace, self.dest, values.split(',')) |
+ |
+ |
+def main(argv=None): |
+ if argv is None: |
+ argv = sys.argv |
+ parser = argparse.ArgumentParser( |
+ description='Apitools Client Code Generator') |
+ |
+ discovery_group = parser.add_mutually_exclusive_group() |
+ discovery_group.add_argument( |
+ '--infile', |
+ help=('Filename for the discovery document. Mutually exclusive with ' |
+ '--discovery_url')) |
+ |
+ discovery_group.add_argument( |
+ '--discovery_url', |
+ help=('URL (or "name.version") of the discovery document to use. ' |
+ 'Mutually exclusive with --infile.')) |
+ |
+ parser.add_argument( |
+ '--base_package', |
+ default='apitools.base.py', |
+ help='Base package path of apitools (defaults to apitools.base.py') |
+ |
+ parser.add_argument( |
+ '--protorpc_package', |
+ default='apitools.base.protorpclite', |
+ help=('Base package path of protorpc ' |
+ '(defaults to apitools.base.protorpclite')) |
+ |
+ parser.add_argument( |
+ '--outdir', |
+ default='', |
+ help='Directory name for output files. (Defaults to the API name.)') |
+ |
+ parser.add_argument( |
+ '--overwrite', |
+ default=False, action='store_true', |
+ help='Only overwrite the output directory if this flag is specified.') |
+ |
+ parser.add_argument( |
+ '--root_package', |
+ default='', |
+ help=('Python import path for where these modules ' |
+ 'should be imported from.')) |
+ |
+ parser.add_argument( |
+ '--strip_prefix', nargs='*', |
+ default=[], |
+ help=('Prefix to strip from type names in the discovery document. ' |
+ '(May be specified multiple times.)')) |
+ |
+ parser.add_argument( |
+ '--api_key', |
+ help=('API key to use for API access.')) |
+ |
+ parser.add_argument( |
+ '--client_json', |
+ help=('Use the given file downloaded from the dev. console for ' |
+ 'client_id and client_secret.')) |
+ |
+ parser.add_argument( |
+ '--client_id', |
+ default='1042881264118.apps.googleusercontent.com', |
+ help='Client ID to use for the generated client.') |
+ |
+ parser.add_argument( |
+ '--client_secret', |
+ default='x_Tw5K8nnjoRAqULM9PFAC2b', |
+ help='Client secret for the generated client.') |
+ |
+ parser.add_argument( |
+ '--scope', nargs='*', |
+ default=[], |
+ help=('Scopes to request in the generated client. ' |
+ 'May be specified more than once.')) |
+ |
+ parser.add_argument( |
+ '--user_agent', |
+ default='x_Tw5K8nnjoRAqULM9PFAC2b', |
+ help=('User agent for the generated client. ' |
+ 'Defaults to <api>-generated/0.1.')) |
+ |
+ parser.add_argument( |
+ '--generate_cli', dest='generate_cli', action='store_true', |
+ help='If specified (default), a CLI is also generated.') |
+ parser.add_argument( |
+ '--nogenerate_cli', dest='generate_cli', action='store_false', |
+ help='CLI will not be generated.') |
+ parser.set_defaults(generate_cli=True) |
+ |
+ parser.add_argument( |
+ '--unelidable_request_methods', |
+ action=_SplitCommaSeparatedList, |
+ default=[], |
+ help=('Full method IDs of methods for which we should NOT try to ' |
+ 'elide the request type. (Should be a comma-separated list.')) |
+ |
+ parser.add_argument( |
+ '--apitools_version', |
+ default='', dest='apitools_version', |
+ help=('Apitools version used as a requirement in generated clients. ' |
+ 'Defaults to version of apitools used to generate the clients.')) |
+ |
+ parser.add_argument( |
+ '--experimental_capitalize_enums', |
+ default=False, action='store_true', |
+ help='Dangerous: attempt to rewrite enum values to be uppercase.') |
+ |
+ parser.add_argument( |
+ '--experimental_name_convention', |
+ choices=util.Names.NAME_CONVENTIONS, |
+ default=util.Names.DEFAULT_NAME_CONVENTION, |
+ help='Dangerous: use a particular style for generated names.') |
+ |
+ parser.add_argument( |
+ '--experimental_proto2_output', |
+ default=False, action='store_true', |
+ help='Dangerous: also output a proto2 message file.') |
+ |
+ subparsers = parser.add_subparsers(help='Type of generated code') |
+ |
+ client_parser = subparsers.add_parser( |
+ 'client', help='Generate apitools client in destination folder') |
+ client_parser.set_defaults(func=GenerateClient) |
+ |
+ pip_package_parser = subparsers.add_parser( |
+ 'pip_package', help='Generate apitools client pip package') |
+ pip_package_parser.set_defaults(func=GeneratePipPackage) |
+ |
+ proto_parser = subparsers.add_parser( |
+ 'proto', help='Generate apitools client protos') |
+ proto_parser.set_defaults(func=GenerateProto) |
+ |
+ args = parser.parse_args(argv[1:]) |
+ return args.func(args) or 0 |
+ |
+if __name__ == '__main__': |
+ sys.exit(main()) |