I am trying to setup a larger bazel infrastructure to Create .py files from a .proto file for gRPC using rules_proto_grpc_python Run the server code that implements the interfaces defined in 1 via a py_binary However, I am getting the error google.protobuf.runtime_version.VersionError: Detected incompatible Protobuf Gencode/Runtime versions when loading helloworld/hello.proto: gencode 5.29.1 runtime 5.27.2. Runtime version cannot be older than the linked gencode version. See Protobuf version guarantees at https://protobuf.dev/support/cross-version-runtime-guarantee. indicating that the protobuf version that rules_proto_grpc_python uses to generate the .py files is different from the version used at runtime. I tried to require protobuf>=5.29.1 for the `py_binary`` but that is not possible due to conficts with other packages in the project. In this minimal example, it is possible but issues several warnings about conflicting symlinks which seems concerning as well. Is there a way to either Specify the protobuf version to use for rules_proto_grpc_python Generate the .py files from the .proto in another way? Edit 2025-02-27 I managed to get this to work by playing around with the requirements in my larger repository. Specifying the minimum protobuf version causes it to work. Here are the relevant files to make a minimal example The top-level MODULE.bazel: # MODULE.bazel bazel_dep(name = "aspect_bazel_lib", version = "2.7.8") bazel_dep(name = "aspect_rules_py", version = "1.3.2") bazel_dep(name = "rules_python", version = "1.1.0") bazel_dep(name = "rules_proto", version = "7.1.0") bazel_dep(name = "rules_proto_grpc_python", version = "5.0.0") # deps for python projects. _PY_MINOR_VER = 10 _PY_VERSION = "3.%s" % _PY_MINOR_VER _PY_VER_ = "python_3_%s" % _PY_MINOR_VER python = use_extension("@rules_python//python/extensionsython.bzl", "python") python.toolchain( python_version = _PY_VERSION, is_default = True, ) # You can use this repo mapping to ensure that your BUILD.bazel files don't need # to be updated when the python version changes to a different `3.12` version. use_repo( python, "python_3_%s" % _PY_MINOR_VER, ) pip = use_extension("@rules_python//python/extensionsip.bzl", "pip") pip.parse( hub_name = "pypi", # We need to use the same version here as in the `python.toolchain` call. python_version = _PY_VERSION, requirements_lock = "//:requirements_lock.txt", ) use_repo(pip, "pypi") Inside a directory /proto_library/proto/hello.proto # proto_library/proto/hello.proto syntax = "proto3"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; } The BUILD.bazel alongside the proto file # proto_library/proto/BUILD.bazel load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_proto_grpc_python//:defs.bzl", "py_proto_library", "py_grpc_library") proto_library( name = "hello_proto", srcs = ["hello.proto"], # Add these to control Python package structure strip_import_prefix = "/proto_library/proto", import_prefix = "helloworld", visibility = ["//visibilityublic"], ) py_proto_library( name = "hello_py_proto", protos = [":hello_proto"], visibility = ["//visibilityublic"], ) py_grpc_library( name = "hello_py_grpc", protos = [":hello_proto"], visibility = ["//visibilityublic"], deps = [":hello_py_proto"], ) The python code to implement the server # proto_library/src/hello_server.py import logging import sys from concurrent import futures import grpc from helloworld import hello_pb2, hello_pb2_grpc class Greeter(hello_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return hello_pb2.HelloReply(message="Hello, %s!" % request.name) def serve(): port = "50051" server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) hello_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port("[::]:" + port) server.start() print("Server started, listening on " + port) server.wait_for_termination() if __name__ == "__main__": logging.basicConfig() serve() And finally, the BUILD file inside proto_library # proto_library/BUILD.bazel load("@aspect_rules_py//py:defs.bzl", "py_binary", "py_library") load("@pypi//:requirements.bzl", "requirement") py_binary( name = "hello_test", srcs = ["src/hello_server.py"], deps = [ "//proto_library/proto:hello_py_proto", "//proto_library/proto:hello_py_grpc", requirement("grpcio"), requirement("protobuf"), ], # Add these to handle Python packaging imports = [".."], # Make parent directories importable visibility = ["//visibilityublic"], package_collisions = "warning", # Create proper Python package structure main = "hello_server.py", ) Continue reading...