pw_rpc: Remove dependency on runtime generation

- Commit protoc-generated packet_pb2.py file as a temporary workaround
  to remove the dependency on runtime protobuf generation. This makes
  packaging and distribution simpler.
- Commit mypy stub for packet_pb2.py (packet_pb2.pyi). This was
  generated with mypy-protobuf, and will be removed eventually.
- Fix some mypy and pylint issues.

Change-Id: I4159f188faf7cd618861a5941bcf0e59c4257674
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/15905
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Joe Ethier <jethier@google.com>
diff --git a/.pylintrc b/.pylintrc
index 2feb460..d4ce122 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -384,7 +384,8 @@
 ignored-classes=optparse.Values,
                 thread._local,
                 _thread._local,
-                pw_cli.envparse.EnvNamespace
+                pw_cli.envparse.EnvNamespace,
+                pw_rpc.packet_pb2.RpcPacket
 
 # List of module names for which member attributes should not be checked
 # (useful for modules/projects where namespaces are manipulated during runtime
diff --git a/pw_rpc/py/callback_client_test.py b/pw_rpc/py/callback_client_test.py
index 22ab810..0ae02c4 100755
--- a/pw_rpc/py/callback_client_test.py
+++ b/pw_rpc/py/callback_client_test.py
@@ -19,7 +19,7 @@
 from typing import List, Tuple
 
 from pw_protobuf_compiler import python_protos
-from pw_rpc import callback_client, client, packets
+from pw_rpc import callback_client, client, packet_pb2, packets
 from pw_status import Status
 
 TEST_PROTO_1 = """\
@@ -65,7 +65,7 @@
             callback_client.Impl(), [client.Channel(1, self._handle_request)],
             self._protos.modules())
 
-        self._last_request: packets.RpcPacket = None
+        self._last_request: packet_pb2.RpcPacket = None
         self._next_packets: List[Tuple[bytes, Status]] = []
         self._send_responses_on_request = True
 
@@ -90,12 +90,12 @@
             payload = response.SerializeToString()
 
         self._next_packets.append(
-            (packets.RpcPacket(type=packets.PacketType.RESPONSE,
-                               channel_id=channel_id,
-                               service_id=service_id,
-                               method_id=method_id,
-                               status=status.value,
-                               payload=payload).SerializeToString(),
+            (packet_pb2.RpcPacket(type=packets.PacketType.RESPONSE,
+                                  channel_id=channel_id,
+                                  service_id=service_id,
+                                  method_id=method_id,
+                                  status=status.value,
+                                  payload=payload).SerializeToString(),
              process_status))
 
     def _enqueue_stream_end(self,
@@ -104,11 +104,11 @@
                             status: Status = Status.OK,
                             process_status=Status.OK):
         self._next_packets.append(
-            (packets.RpcPacket(type=packets.PacketType.SERVER_STREAM_END,
-                               channel_id=channel_id,
-                               service_id=method.service.id,
-                               method_id=method.id,
-                               status=status.value).SerializeToString(),
+            (packet_pb2.RpcPacket(type=packets.PacketType.SERVER_STREAM_END,
+                                  channel_id=channel_id,
+                                  service_id=method.service.id,
+                                  method_id=method.id,
+                                  status=status.value).SerializeToString(),
              process_status))
 
     def _handle_request(self, data: bytes):
diff --git a/pw_rpc/py/client_test.py b/pw_rpc/py/client_test.py
index 93daebd..90dc402 100755
--- a/pw_rpc/py/client_test.py
+++ b/pw_rpc/py/client_test.py
@@ -18,6 +18,7 @@
 
 from pw_protobuf_compiler import python_protos
 from pw_rpc import callback_client, client, packets
+from pw_rpc.packet_pb2 import RpcPacket
 import pw_rpc.ids
 from pw_status import Status
 
@@ -165,7 +166,7 @@
         self._last_packet_sent_bytes = packet
 
     def _last_packet_sent(self):
-        packet = packets.RpcPacket()
+        packet = RpcPacket()
         self.assertIsNotNone(self._last_packet_sent_bytes)
         packet.MergeFromString(self._last_packet_sent_bytes)
         return packet
@@ -226,7 +227,7 @@
     def test_process_packet_not_for_client(self):
         self.assertIs(
             self._client.process_packet(
-                packets.RpcPacket(
+                RpcPacket(
                     type=packets.PacketType.REQUEST).SerializeToString()),
             Status.INVALID_ARGUMENT)
 
@@ -247,11 +248,11 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            packets.RpcPacket(type=packets.PacketType.CLIENT_ERROR,
-                              channel_id=1,
-                              service_id=456,
-                              method_id=789,
-                              status=Status.NOT_FOUND.value))
+            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+                      channel_id=1,
+                      service_id=456,
+                      method_id=789,
+                      status=Status.NOT_FOUND.value))
 
     def test_process_packet_unrecognized_method(self):
         service = next(iter(self._client.services))
@@ -264,11 +265,11 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            packets.RpcPacket(type=packets.PacketType.CLIENT_ERROR,
-                              channel_id=1,
-                              service_id=service.id,
-                              method_id=789,
-                              status=Status.NOT_FOUND.value))
+            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+                      channel_id=1,
+                      service_id=service.id,
+                      method_id=789,
+                      status=Status.NOT_FOUND.value))
 
     def test_process_packet_non_pending_method(self):
         service = next(iter(self._client.services))
@@ -282,11 +283,11 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            packets.RpcPacket(type=packets.PacketType.CLIENT_ERROR,
-                              channel_id=1,
-                              service_id=service.id,
-                              method_id=method.id,
-                              status=Status.FAILED_PRECONDITION.value))
+            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+                      channel_id=1,
+                      service_id=service.id,
+                      method_id=method.id,
+                      status=Status.FAILED_PRECONDITION.value))
 
 
 if __name__ == '__main__':
diff --git a/pw_rpc/py/packets_test.py b/pw_rpc/py/packets_test.py
index f2b8b82..c8ed99e 100755
--- a/pw_rpc/py/packets_test.py
+++ b/pw_rpc/py/packets_test.py
@@ -17,36 +17,34 @@
 import unittest
 
 from pw_rpc import packets
+from pw_rpc.packet_pb2 import RpcPacket
 from pw_status import Status
 
-_TEST_REQUEST = packets.RpcPacket(
-    type=packets.PacketType.REQUEST,
-    channel_id=1,
-    service_id=2,
-    method_id=3,
-    payload=packets.RpcPacket(status=321).SerializeToString())
+_TEST_REQUEST = RpcPacket(type=packets.PacketType.REQUEST,
+                          channel_id=1,
+                          service_id=2,
+                          method_id=3,
+                          payload=RpcPacket(status=321).SerializeToString())
 
 
 class PacketsTest(unittest.TestCase):
     """Tests for packet encoding and decoding."""
     def test_encode_request(self):
-        data = packets.encode_request((1, 2, 3), packets.RpcPacket(status=321))
-        packet = packets.RpcPacket()
+        data = packets.encode_request((1, 2, 3), RpcPacket(status=321))
+        packet = RpcPacket()
         packet.ParseFromString(data)
 
         self.assertEqual(_TEST_REQUEST, packet)
 
     def test_encode_response(self):
-        response = packets.RpcPacket(
-            type=packets.PacketType.RESPONSE,
-            channel_id=1,
-            service_id=2,
-            method_id=3,
-            payload=packets.RpcPacket(status=321).SerializeToString())
+        response = RpcPacket(type=packets.PacketType.RESPONSE,
+                             channel_id=1,
+                             service_id=2,
+                             method_id=3,
+                             payload=RpcPacket(status=321).SerializeToString())
 
-        data = packets.encode_response((1, 2, 3),
-                                       packets.RpcPacket(status=321))
-        packet = packets.RpcPacket()
+        data = packets.encode_response((1, 2, 3), RpcPacket(status=321))
+        packet = RpcPacket()
         packet.ParseFromString(data)
 
         self.assertEqual(response, packet)
@@ -54,29 +52,29 @@
     def test_encode_cancel(self):
         data = packets.encode_cancel((9, 8, 7))
 
-        packet = packets.RpcPacket()
+        packet = RpcPacket()
         packet.ParseFromString(data)
 
         self.assertEqual(
             packet,
-            packets.RpcPacket(type=packets.PacketType.CANCEL_SERVER_STREAM,
-                              channel_id=9,
-                              service_id=8,
-                              method_id=7))
+            RpcPacket(type=packets.PacketType.CANCEL_SERVER_STREAM,
+                      channel_id=9,
+                      service_id=8,
+                      method_id=7))
 
     def test_encode_client_error(self):
         data = packets.encode_client_error(_TEST_REQUEST, Status.NOT_FOUND)
 
-        packet = packets.RpcPacket()
+        packet = RpcPacket()
         packet.ParseFromString(data)
 
         self.assertEqual(
             packet,
-            packets.RpcPacket(type=packets.PacketType.CLIENT_ERROR,
-                              channel_id=1,
-                              service_id=2,
-                              method_id=3,
-                              status=Status.NOT_FOUND.value))
+            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+                      channel_id=1,
+                      service_id=2,
+                      method_id=3,
+                      status=Status.NOT_FOUND.value))
 
     def test_decode(self):
         self.assertEqual(_TEST_REQUEST,
@@ -87,12 +85,11 @@
 
         self.assertFalse(
             packets.for_server(
-                packets.RpcPacket(type=packets.PacketType.RESPONSE,
-                                  channel_id=1,
-                                  service_id=2,
-                                  method_id=3,
-                                  payload=packets.RpcPacket(
-                                      status=321).SerializeToString())))
+                RpcPacket(type=packets.PacketType.RESPONSE,
+                          channel_id=1,
+                          service_id=2,
+                          method_id=3,
+                          payload=RpcPacket(status=321).SerializeToString())))
 
 
 if __name__ == '__main__':
diff --git a/pw_rpc/py/pw_rpc/client.py b/pw_rpc/py/pw_rpc/client.py
index a1a10ca..e009398 100644
--- a/pw_rpc/py/pw_rpc/client.py
+++ b/pw_rpc/py/pw_rpc/client.py
@@ -20,6 +20,7 @@
 from typing import Optional
 
 from pw_rpc import descriptors, packets
+from pw_rpc.packet_pb2 import RpcPacket
 from pw_rpc.packets import PacketType
 from pw_rpc.descriptors import Channel, Service, Method
 from pw_status import Status
@@ -63,7 +64,10 @@
                         'Cancel the RPC before invoking it again')
 
         _LOG.debug('Starting %s', rpc)
-        rpc.channel.output(packets.encode_request(rpc, request))
+        # TODO(hepler): Remove `type: ignore` on this and other lines when
+        #     https://github.com/python/mypy/issues/5485 is fixed
+        rpc.channel.output(  # type: ignore
+            packets.encode_request(rpc, request))
 
     def cancel(self, rpc: PendingRpc) -> bool:
         """Cancels the RPC, including sending a CANCEL packet.
@@ -78,7 +82,7 @@
             return False
 
         if rpc.method.type is not Method.Type.UNARY:
-            rpc.channel.output(packets.encode_cancel(rpc))
+            rpc.channel.output(packets.encode_cancel(rpc))  # type: ignore
 
         return True
 
@@ -313,7 +317,7 @@
         try:
             rpc = self._look_up_service_and_method(packet, channel_client)
         except ValueError as err:
-            channel_client.channel.output(
+            channel_client.channel.output(  # type: ignore
                 packets.encode_client_error(packet, Status.NOT_FOUND))
             _LOG.warning('%s', err)
             return Status.OK
@@ -336,7 +340,7 @@
         try:
             context = self._rpcs.get_pending(rpc, status)
         except KeyError:
-            channel_client.channel.output(
+            channel_client.channel.output(  # type: ignore
                 packets.encode_client_error(packet,
                                             Status.FAILED_PRECONDITION))
             _LOG.debug('Discarding response for %s, which is not pending', rpc)
@@ -352,7 +356,7 @@
         return Status.OK
 
     def _look_up_service_and_method(
-            self, packet: packets.RpcPacket,
+            self, packet: RpcPacket,
             channel_client: ChannelClient) -> PendingRpc:
         try:
             service = self.services[packet.service_id]
diff --git a/pw_rpc/py/pw_rpc/packet_pb2.py b/pw_rpc/py/pw_rpc/packet_pb2.py
new file mode 100644
index 0000000..a86d53c
--- /dev/null
+++ b/pw_rpc/py/pw_rpc/packet_pb2.py
@@ -0,0 +1,168 @@
+# [Pigweed] This file is a checked-in version of a generated protobuf module.
+# TODO(pwbug/239) Implement the pw_protobuf_package GN template and Python
+#     proto generation, then delete this file.
+
+# pylint: skip-file
+
+# type: ignore
+
+# yapf: disable
+
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: pw_rpc/pw_rpc_protos/packet.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='pw_rpc/pw_rpc_protos/packet.proto',
+  package='pw.rpc.internal',
+  syntax='proto3',
+  serialized_options=None,
+  serialized_pb=_b('\n!pw_rpc/pw_rpc_protos/packet.proto\x12\x0fpw.rpc.internal\"\x92\x01\n\tRpcPacket\x12)\n\x04type\x18\x01 \x01(\x0e\x32\x1b.pw.rpc.internal.PacketType\x12\x12\n\nchannel_id\x18\x02 \x01(\r\x12\x12\n\nservice_id\x18\x03 \x01(\x07\x12\x11\n\tmethod_id\x18\x04 \x01(\x07\x12\x0f\n\x07payload\x18\x05 \x01(\x0c\x12\x0e\n\x06status\x18\x06 \x01(\r*\x93\x01\n\nPacketType\x12\x0b\n\x07REQUEST\x10\x00\x12\x15\n\x11\x43LIENT_STREAM_END\x10\x02\x12\x10\n\x0c\x43LIENT_ERROR\x10\x04\x12\x18\n\x14\x43\x41NCEL_SERVER_STREAM\x10\x06\x12\x0c\n\x08RESPONSE\x10\x01\x12\x15\n\x11SERVER_STREAM_END\x10\x03\x12\x10\n\x0cSERVER_ERROR\x10\x05\x62\x06proto3')
+)
+
+_PACKETTYPE = _descriptor.EnumDescriptor(
+  name='PacketType',
+  full_name='pw.rpc.internal.PacketType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='REQUEST', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CLIENT_STREAM_END', index=1, number=2,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CLIENT_ERROR', index=2, number=4,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CANCEL_SERVER_STREAM', index=3, number=6,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='RESPONSE', index=4, number=1,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SERVER_STREAM_END', index=5, number=3,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SERVER_ERROR', index=6, number=5,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=204,
+  serialized_end=351,
+)
+_sym_db.RegisterEnumDescriptor(_PACKETTYPE)
+
+PacketType = enum_type_wrapper.EnumTypeWrapper(_PACKETTYPE)
+REQUEST = 0
+CLIENT_STREAM_END = 2
+CLIENT_ERROR = 4
+CANCEL_SERVER_STREAM = 6
+RESPONSE = 1
+SERVER_STREAM_END = 3
+SERVER_ERROR = 5
+
+
+
+_RPCPACKET = _descriptor.Descriptor(
+  name='RpcPacket',
+  full_name='pw.rpc.internal.RpcPacket',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='pw.rpc.internal.RpcPacket.type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='channel_id', full_name='pw.rpc.internal.RpcPacket.channel_id', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='pw.rpc.internal.RpcPacket.service_id', index=2,
+      number=3, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='method_id', full_name='pw.rpc.internal.RpcPacket.method_id', index=3,
+      number=4, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='pw.rpc.internal.RpcPacket.payload', index=4,
+      number=5, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='pw.rpc.internal.RpcPacket.status', index=5,
+      number=6, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=55,
+  serialized_end=201,
+)
+
+_RPCPACKET.fields_by_name['type'].enum_type = _PACKETTYPE
+DESCRIPTOR.message_types_by_name['RpcPacket'] = _RPCPACKET
+DESCRIPTOR.enum_types_by_name['PacketType'] = _PACKETTYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+RpcPacket = _reflection.GeneratedProtocolMessageType('RpcPacket', (_message.Message,), {
+  'DESCRIPTOR' : _RPCPACKET,
+  '__module__' : 'pw_rpc.pw_rpc_protos.packet_pb2'
+  # @@protoc_insertion_point(class_scope:pw.rpc.internal.RpcPacket)
+  })
+_sym_db.RegisterMessage(RpcPacket)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/pw_rpc/py/pw_rpc/packet_pb2.pyi b/pw_rpc/py/pw_rpc/packet_pb2.pyi
new file mode 100644
index 0000000..e13b07d
--- /dev/null
+++ b/pw_rpc/py/pw_rpc/packet_pb2.pyi
@@ -0,0 +1,76 @@
+# @generated by generate_proto_mypy_stubs.py.  Do not edit!
+import sys
+from google.protobuf.descriptor import (
+    Descriptor as google___protobuf___descriptor___Descriptor,
+    EnumDescriptor as google___protobuf___descriptor___EnumDescriptor,
+    FileDescriptor as google___protobuf___descriptor___FileDescriptor,
+)
+
+from google.protobuf.internal.enum_type_wrapper import (  # type: ignore
+    _EnumTypeWrapper as google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper,
+)
+
+from google.protobuf.message import (
+    Message as google___protobuf___message___Message,
+)
+
+from typing import (
+    NewType as typing___NewType,
+    Optional as typing___Optional,
+    cast as typing___cast,
+)
+
+from typing_extensions import (
+    Literal as typing_extensions___Literal,
+)
+
+
+builtin___bool = bool
+builtin___bytes = bytes
+builtin___float = float
+builtin___int = int
+
+
+DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ...
+
+PacketTypeValue = typing___NewType('PacketTypeValue', builtin___int)
+type___PacketTypeValue = PacketTypeValue
+PacketType: _PacketType
+class _PacketType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[PacketTypeValue]):
+    DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ...
+    REQUEST = typing___cast(PacketTypeValue, 0)
+    CLIENT_STREAM_END = typing___cast(PacketTypeValue, 2)
+    CLIENT_ERROR = typing___cast(PacketTypeValue, 4)
+    CANCEL_SERVER_STREAM = typing___cast(PacketTypeValue, 6)
+    RESPONSE = typing___cast(PacketTypeValue, 1)
+    SERVER_STREAM_END = typing___cast(PacketTypeValue, 3)
+    SERVER_ERROR = typing___cast(PacketTypeValue, 5)
+REQUEST = typing___cast(PacketTypeValue, 0)
+CLIENT_STREAM_END = typing___cast(PacketTypeValue, 2)
+CLIENT_ERROR = typing___cast(PacketTypeValue, 4)
+CANCEL_SERVER_STREAM = typing___cast(PacketTypeValue, 6)
+RESPONSE = typing___cast(PacketTypeValue, 1)
+SERVER_STREAM_END = typing___cast(PacketTypeValue, 3)
+SERVER_ERROR = typing___cast(PacketTypeValue, 5)
+type___PacketType = PacketType
+
+class RpcPacket(google___protobuf___message___Message):
+    DESCRIPTOR: google___protobuf___descriptor___Descriptor = ...
+    type: type___PacketTypeValue = ...
+    channel_id: builtin___int = ...
+    service_id: builtin___int = ...
+    method_id: builtin___int = ...
+    payload: builtin___bytes = ...
+    status: builtin___int = ...
+
+    def __init__(self,
+        *,
+        type : typing___Optional[type___PacketTypeValue] = None,
+        channel_id : typing___Optional[builtin___int] = None,
+        service_id : typing___Optional[builtin___int] = None,
+        method_id : typing___Optional[builtin___int] = None,
+        payload : typing___Optional[builtin___bytes] = None,
+        status : typing___Optional[builtin___int] = None,
+        ) -> None: ...
+    def ClearField(self, field_name: typing_extensions___Literal[u"channel_id",b"channel_id",u"method_id",b"method_id",u"payload",b"payload",u"service_id",b"service_id",u"status",b"status",u"type",b"type"]) -> None: ...
+type___RpcPacket = RpcPacket
diff --git a/pw_rpc/py/pw_rpc/packets.py b/pw_rpc/py/pw_rpc/packets.py
index 1296cb9..dca5a10 100644
--- a/pw_rpc/py/pw_rpc/packets.py
+++ b/pw_rpc/py/pw_rpc/packets.py
@@ -13,24 +13,18 @@
 # the License.
 """Functions for working with pw_rpc packets."""
 
-import os
-
 from google.protobuf import message
-from pw_protobuf_compiler import python_protos
 from pw_status import Status
-
-packet_pb2 = python_protos.compile_and_import_file(
-    os.path.join(__file__, '..', '..', '..', 'pw_rpc_protos', 'packet.proto'))
-
-PacketType = packet_pb2.PacketType
-RpcPacket = packet_pb2.RpcPacket
+from pw_rpc import packet_pb2
 
 DecodeError = message.DecodeError
 Message = message.Message
 
+PacketType = packet_pb2.PacketType
+
 
 def decode(data: bytes):
-    packet = RpcPacket()
+    packet = packet_pb2.RpcPacket()
     packet.MergeFromString(data)
     return packet
 
@@ -48,37 +42,40 @@
 def encode_request(rpc: tuple, request: message.Message) -> bytes:
     channel, service, method = _ids(rpc)
 
-    return RpcPacket(type=PacketType.REQUEST,
-                     channel_id=channel,
-                     service_id=service,
-                     method_id=method,
-                     payload=request.SerializeToString()).SerializeToString()
+    return packet_pb2.RpcPacket(
+        type=packet_pb2.PacketType.REQUEST,
+        channel_id=channel,
+        service_id=service,
+        method_id=method,
+        payload=request.SerializeToString()).SerializeToString()
 
 
 def encode_response(rpc: tuple, response: message.Message) -> bytes:
     channel, service, method = _ids(rpc)
 
-    return RpcPacket(type=PacketType.RESPONSE,
-                     channel_id=channel,
-                     service_id=service,
-                     method_id=method,
-                     payload=response.SerializeToString()).SerializeToString()
+    return packet_pb2.RpcPacket(
+        type=packet_pb2.PacketType.RESPONSE,
+        channel_id=channel,
+        service_id=service,
+        method_id=method,
+        payload=response.SerializeToString()).SerializeToString()
 
 
 def encode_client_error(packet, status: Status) -> bytes:
-    return RpcPacket(type=PacketType.CLIENT_ERROR,
-                     channel_id=packet.channel_id,
-                     service_id=packet.service_id,
-                     method_id=packet.method_id,
-                     status=status.value).SerializeToString()
+    return packet_pb2.RpcPacket(type=packet_pb2.PacketType.CLIENT_ERROR,
+                                channel_id=packet.channel_id,
+                                service_id=packet.service_id,
+                                method_id=packet.method_id,
+                                status=status.value).SerializeToString()
 
 
 def encode_cancel(rpc: tuple) -> bytes:
     channel, service, method = _ids(rpc)
-    return RpcPacket(type=PacketType.CANCEL_SERVER_STREAM,
-                     channel_id=channel,
-                     service_id=service,
-                     method_id=method).SerializeToString()
+    return packet_pb2.RpcPacket(
+        type=packet_pb2.PacketType.CANCEL_SERVER_STREAM,
+        channel_id=channel,
+        service_id=service,
+        method_id=method).SerializeToString()
 
 
 def for_server(packet):
diff --git a/pw_rpc/py/setup.py b/pw_rpc/py/setup.py
index 0d792bb..44779c9 100644
--- a/pw_rpc/py/setup.py
+++ b/pw_rpc/py/setup.py
@@ -26,6 +26,5 @@
     install_requires=[
         'protobuf',
         'pw_protobuf',
-        'pw_protobuf_compiler',
     ],
 )