From 0cfe9550683b72b31cd40c35f6e34654562ee861 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 22 Nov 2019 16:32:23 -0800 Subject: [PATCH] Add a simple unified importer --- .../python/grpcio_tools/grpc_tools/BUILD | 3 ++ .../grpcio_tools/grpc_tools/__init__.py | 31 +++++++++++++++++++ .../python/grpcio_tools/grpc_tools/protoc.py | 1 - .../grpcio_tools/grpc_tools/protoc_test.py | 15 +++++++-- .../grpcio_tools/grpc_tools/simple.proto | 21 +++++++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 tools/distrib/python/grpcio_tools/grpc_tools/simple.proto diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/BUILD b/tools/distrib/python/grpcio_tools/grpc_tools/BUILD index ecf45a42959..2aa111d2551 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/BUILD +++ b/tools/distrib/python/grpcio_tools/grpc_tools/BUILD @@ -3,6 +3,8 @@ package(default_visibility = ["//visibility:public"]) load("//bazel:cython_library.bzl", "pyx_library") +# TODO: Move this build file up a directory to ensure that this +# points to '.', not a directory above the package root. NON_BAZEL_ROOT = "../" cc_library( @@ -38,5 +40,6 @@ py_test( name = "protoc_test", srcs = ["protoc_test.py"], deps = ["//tools/distrib/python/grpcio_tools/grpc_tools:grpc_tools"], + data = ["simple.proto"], python_version = "PY3", ) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/__init__.py b/tools/distrib/python/grpcio_tools/grpc_tools/__init__.py index 5772620b602..d151994fc90 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/__init__.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/__init__.py @@ -11,3 +11,34 @@ # 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. + + +import importlib +import os +from .protoc import main + +# TODO: Get this thing to just give me the code via an FD. +# TODO: Figure out what to do about STDOUT pollution. +def import_protos(proto_path, project_root): + proto_basename = os.path.basename(proto_path) + proto_name, _ = os.path.splitext(proto_basename) + anchor_package = ".".join(os.path.normpath(os.path.dirname(proto_path)).split(os.sep)) + original_dir = os.getcwd() + try: + os.chdir(os.path.join(original_dir, project_root)) + return_value = protoc.main([ + "grpc_tools.protoc", + "--proto_path=.", + "--python_out=.", + "--grpc_python_out=.", + proto_path + ]) + finally: + os.chdir(original_dir) + if return_value != 0: + raise RuntimeError("Protoc failed.") + print("anchor_package: {}".format(anchor_package)) + protos = importlib.import_module("{}.{}_pb2".format(anchor_package, proto_name)) + services = importlib.import_module("{}.{}_pb2_grpc".format(anchor_package, proto_name)) + return protos, services + diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py index 582cba0e396..18a5ef22874 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py @@ -19,7 +19,6 @@ import sys from grpc_tools import _protoc_compiler - def main(command_arguments): """Run the protocol buffer compiler with the given command-line arguments. diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protoc_test.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc_test.py index 7de81ab62d0..01050d703ab 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/protoc_test.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc_test.py @@ -4,15 +4,24 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function +import importlib + import unittest import grpc_tools -from grpc_tools import protoc + +import os + class ProtocTest(unittest.TestCase): - def test_protoc(self): - pass + def test_protoc(self): + # TODO: Get this thing to just give me the code via an FD. + # TODO: Figure out what to do about STDOUT pollution. + # TODO: How do we convert protoc failure into a Python error? + protos, services = grpc_tools.import_protos("grpc_tools/simple.proto", "tools/distrib/python/grpcio_tools/") + print(dir(protos)) + print(dir(services)) if __name__ == '__main__': diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/simple.proto b/tools/distrib/python/grpcio_tools/grpc_tools/simple.proto new file mode 100644 index 00000000000..c4c21418e6f --- /dev/null +++ b/tools/distrib/python/grpcio_tools/grpc_tools/simple.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +message SimpleMessage { + string msg = 1; + oneof personal_or_business { + bool personal = 2; + bool business = 3; + }; +}; + +message SimpleMessageRequest { + SimpleMessage simple_msg = 1; +}; + +message SimpleMessageResponse { + bool understood = 1; +}; + +service SimpleMessageService { + rpc Tell(SimpleMessageRequest) returns (SimpleMessageResponse); +};