2 minute read

Note: This is part 2 of my introduction to protocol buffers. Part 1 provides an overview to protobufs, and writing .proto files. Read it here.

Welcome back. This is a continuation of me following Google’s tutorial on protocol buffers. You can refer to it here.

As mentioned in Part 1, protobufs require compilation. Doing so will generate classes, in a programming language of your choice, to send and receive messages defined in .proto files. In the previous part, we wrote a simple .proto file and compiled it to generate Python code. Here, we’ll take a look at the generated code, and how it’s used.

Compiled Code

You should get a new file called addressbook_pb2.py after running addressbook.proto through the protobuf compiler. Looking at the contents of this new file can be a bit confusing, but the key thing to know is that importing addressbook_pb2.py into a Python program will provide you with functionality to access several objects, methods, and attributes based on the definitions from the .proto file.

In other words, you’ll be able to instantiate a Person object, and set their ID, their name, or email based on the types that were previously defined. Similarly, we’ll be able to create an AddressBook and add several Person objects to it.

We can demonstrate this with a simple program. Here, we’ll import the compiled code, instantiate a new Person object, and add values to its fields:

1
2
3
4
5
6
import addressbook_pb2

person = addressbook_pb2.Person()
person.id = 1234
person.name = "Roger"
print(person)

You should see the following when running the above program:

name: "Roger"
id: 1234

The tutorial makes a really important note here: These assignments are not just adding arbitrary values to some generic Python object. Instead, we are adding values based on the fields that were previously defined. Trying to add some other value that was not defined in addresbook.proto will net you an AttributeError. Similarly, trying to add a field of the wrong type will result in a TypeError.

Let’s try adding a new field called “blah”:

1
2
3
4
5
6
7
import addressbook_pb2

person = addressbook_pb2.Person()
person.id = 1234
person.name = "Roger"
person.blah = "hi"
print(person)

Running this file will show the following error:

Traceback (most recent call last):
  File "protobuf_example.py", line 6, in <module>
    person.blah = "hi"
AttributeError: Protocol message Person has no "blah" field.

As you can see the AttributeError explicitly mentiones “Protocol message Person has no “blah” field.” This is no surprise since no field with the name blah was defined in addressbook.proto.

Class Methods

The resulting classess also include member variables and methods that facilitate working with them. The methods provide comfotable ways to set, get, clear, or test the state of variables.

For example, a Person object would have methods to set the value, HasField() to check if the field’s value has been set, ClearField("id") to clear the content of a field, and more.

Updated: