Thursday, June 23, 2016

ProtoBuff Compilation

Documentation is available for python: Google developers 

 Lets create a file with .proto extension with the following code:

package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}
 
After creating addressbook.proto, to compile and to generate python file

protoc -I=$SOURCE_DIR --python_out=$DESTINATION_DIR $SOURCE_DIR/addressbook.proto
 


Example: i have a addressbook.proto in home directory, and compile it using the following command in terminal,

protoc -I=/home/arun  --python_out=/home/arun  ~/addressbook.proto 
 
 Because we want Python classes, you use the --python_out option – similar options are provided for other supported languages. 

The output .py file will be save in the directory mentioned as destination directory (which is again home in the above command)


Unlike when you generate Java and C++ protocol buffer code, the Python protocol buffer compiler doesn't generate your data access code for you directly. Instead (as you'll see if you look at addressbook_pb2.py) it generates special descriptors for all your messages, enums, and fields, and some mysteriously empty classes, one for each message type: 

class Person(message.Message):                                                    
  __metaclass__ = reflection.GeneratedProtocolMessageType                         
                                                                                  
  class PhoneNumber(message.Message):                                             
    __metaclass__ = reflection.GeneratedProtocolMessageType                       
    DESCRIPTOR = _PERSON_PHONENUMBER                                              
  DESCRIPTOR = _PERSON                                                            
                                                                                  
class AddressBook(message.Message):                                               
  __metaclass__ = reflection.GeneratedProtocolMessageType                         
  DESCRIPTOR = _ADDRESSBOOK                                                       


The important line in each class is __metaclass__ = reflection.GeneratedProtocolMessageType
At load time, the GeneratedProtocolMessageType metaclass uses the specified descriptors to create all the Python methods you need to work with each message type and adds them to the relevant classes. You can then use the fully-populated classes in your code.
The end effect of all this is that you can use the Person class as if it defined each field of the Message base class as a regular field. For example, you could write:

import addressbook_pb2              
person = addressbook_pb2.Person()   
person.id = 1234                    
person.name = "John Doe"            
person.email = "jdoe@example.com"   
phone = person.phone.add()          
phone.number = "555-4321"           
phone.type = addressbook_pb2.Person.HOME

Parsing and Serialization

Finally, each protocol buffer class has methods for writing and reading messages of your chosen type using the protocol buffer binary format. These include:
  • SerializeToString(): serializes the message and returns it as a string. Note that the bytes are binary, not text; we only use the str type as a convenient container.
  • ParseFromString(data): parses a message from the given string.
These are just a couple of the options provided for parsing and serialization. Again, see the Message API reference for a complete list.

No comments:

Post a Comment