1import sys 2import subprocess 3import os.path 4 5import traceback 6 7def has_grpcio_protoc(verbose = False): 8 # type: () -> bool 9 """ checks if grpcio-tools protoc is installed""" 10 11 try: 12 import grpc_tools.protoc 13 except ImportError: 14 if verbose: 15 sys.stderr.write("Failed to import grpc_tools: %s\n" % traceback.format_exc()) 16 return False 17 18 return True 19 20def get_grpc_tools_proto_path(): 21 if sys.hexversion > 0x03090000: 22 import importlib.resources as ir 23 with ir.as_file(ir.files('grpc_tools') / '_proto') as path: 24 return str(path) 25 else: 26 import pkg_resources 27 return pkg_resources.resource_filename('grpc_tools', '_proto') 28 29def get_proto_builtin_include_path(): 30 """Find include path for standard google/protobuf includes and for 31 nanopb.proto. 32 """ 33 34 if getattr(sys, 'frozen', False): 35 # Pyinstaller package 36 paths = [ 37 os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'proto'), 38 os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'grpc_tools', '_proto') 39 ] 40 41 else: 42 # Stand-alone script 43 paths = [ 44 os.path.dirname(os.path.abspath(__file__)) 45 ] 46 47 if has_grpcio_protoc(): 48 paths.append(get_grpc_tools_proto_path()) 49 50 return paths 51 52def invoke_protoc(argv): 53 # type: (list) -> typing.Any 54 """ 55 Invoke protoc. 56 57 This routine will use grpcio-provided protoc if it exists, 58 using system-installed protoc as a fallback. 59 60 Args: 61 argv: protoc CLI invocation, first item must be 'protoc' 62 """ 63 64 # Add current directory to include path if nothing else is specified 65 if not [x for x in argv if x.startswith('-I')]: 66 argv.append("-I.") 67 68 # Add default protoc include paths 69 for incpath in get_proto_builtin_include_path(): 70 argv.append('-I' + incpath) 71 72 if has_grpcio_protoc(): 73 import grpc_tools.protoc as protoc 74 return protoc.main(argv) 75 else: 76 return subprocess.call(argv) 77 78def print_versions(): 79 try: 80 if has_grpcio_protoc(verbose = True): 81 import grpc_tools.protoc 82 sys.stderr.write("Using grpcio-tools protoc from " + grpc_tools.protoc.__file__ + "\n") 83 else: 84 sys.stderr.write("Using protoc from system path\n") 85 86 invoke_protoc(['protoc', '--version']) 87 except Exception as e: 88 sys.stderr.write("Failed to determine protoc version: " + str(e) + "\n") 89 90 try: 91 sys.stderr.write("protoc builtin include path: " + str(get_proto_builtin_include_path()) + "\n") 92 except Exception as e: 93 sys.stderr.write("Failed to construct protoc include path: " + str(e) + "\n") 94 95 try: 96 import google.protobuf 97 sys.stderr.write("Python version " + sys.version + "\n") 98 sys.stderr.write("Using python-protobuf from " + google.protobuf.__file__ + "\n") 99 sys.stderr.write("Python-protobuf version: " + google.protobuf.__version__ + "\n") 100 except Exception as e: 101 sys.stderr.write("Failed to determine python-protobuf version: " + str(e) + "\n") 102 103if __name__ == '__main__': 104 print_versions() 105