Currently, there’s no canonical implementation of py_proto_library in bazel. This post shows how to build protobufs for python using the version from the protobuf team.

Import Protobuf Dependency

If you haven’t done so already, add the following to your WORKSPACE to import the protobuf repo as an external dependency.

# WORKSPACE

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
    name = "com_google_protobuf",
    remote = "https://github.com/protocolbuffers/protobuf",
    tag = "v3.10.0",
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

Compile Protobufs to Python Library

To invoke the protobuf compiler on x.proto, we use the py_proto_library rule from protobuf repo.

# lib/BUILD.bazel

load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")

py_proto_library(
    name = "my_py_proto",
    srcs = ["x.proto"],
    visibility = ["//visibility:public"],
)

Using the Compiled Protobuf

The output of py_proto_library is a set of .py files whose names are the same as the .proto files but with a _pb2 extension. For example, x.proto becomes x_pb2.py. For more info, see protobuf documentation.

These generated python files are at the same relative path to the root of the workspace as the .proto file that generated them. So in your python code, you can import them using the relative path. For example:

from lib.x_pb2 import MyMessage

Well-Known Types

To include well-known types in your protobuf messages, add @com_google_protobuf//:protobuf_python as a dependency to your py_proto_library targets.

For example:

py_proto_library(
    name = "my_py_proto",
    srcs = ["x.proto"],
    deps = ["@com_google_protobuf//:protobuf_python"],
    visibility = ["//visibility:public"],
)
  • Alternative implementation by gRPC team: link
  • Alternative implementation by stackb: link
  • Discussion on py_proto_library for bazel: link