| 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())
|
|
|