Notice
Recent Posts
Recent Comments
Link
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Tags
more
Archives
Today
Total
관리 메뉴

니삼 블로그

Protobuf python 본문

네트워크

Protobuf python

Nisam 2016. 7. 16. 21:25

Protobuf로 통신하는 애플리케이션을 분석 할 일이 생겼다. 분석에 앞서 Protobuf를 먼저 사용해보려고 한다.


Protocol Buffers는 구글에서 개발한 데이터 교환 포맷이다. 그냥 데이터 직렬화 도구이다. 자세한 내용은 깃허브에서 확인하자.

Protobuf는 다양한 언어를 지원하고 있지만 python으로 진행하였다.


설치(apt-get)

# apt-get install protobuf-compiler

$ protoc --version

libprotoc 2.5.0


$sudo pip install protobuf



설치가 끝났으면 직렬화할 데이터 포맷을 정의할 proto파일을 만들어야한다. 


샘플 - addressbook.proto

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;

}

proto의 포맷은 링크에서 자세히 볼 수 있다.


proto 파일을 빌드한다.

protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto 

python_out 옵션을 통해서 파이썬에서 사용할 수 있는 클래스로 바꿔준다. 성공적으로 빌드가 되었다면 addressbook_pb2.py가 생성 된다.


작성했던 addressbook.proto 포맷을 이용하여 데이터를 직렬화 해보겠다.

빌드해서 생성된 addressbook_pb2를 import하고 이를 이용하여 데이터를 파일로 생성하는 예제이다.


write_adrress.py

#! /usr/bin/python


import addressbook_pb2

import sys


# This function fills in a Person message based on user input.

def PromptForAddress(person):

  person.id = int(raw_input("Enter person ID number: "))

  person.name = raw_input("Enter name: ")


  email = raw_input("Enter email address (blank for none): ")

  if email != "":

    person.email = email


  while True:

    number = raw_input("Enter a phone number (or leave blank to finish): ")

    if number == "":

      break


    phone_number = person.phone.add()

    phone_number.number = number


    type = raw_input("Is this a mobile, home, or work phone? ")

    if type == "mobile":

      phone_number.type = addressbook_pb2.Person.MOBILE

    elif type == "home":

      phone_number.type = addressbook_pb2.Person.HOME

    elif type == "work":

      phone_number.type = addressbook_pb2.Person.WORK

    else:

      print "Unknown phone type; leaving as default value."


# Main procedure:  Reads the entire address book from a file,

#   adds one person based on user input, then writes it back out to the same

#   file.

if len(sys.argv) != 2:

  print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE"

  sys.exit(-1)


address_book = addressbook_pb2.AddressBook()


# Read the existing address book.

try:

  f = open(sys.argv[1], "rb")

  address_book.ParseFromString(f.read())

  f.close()

except IOError:

  print sys.argv[1] + ": Could not open file.  Creating a new one."


# Add an address.

PromptForAddress(address_book.person.add())


# Write the new address book back to disk.

f = open(sys.argv[1], "wb")

f.write(address_book.SerializeToString())

f.close() 



write로 생성된 raw데이터를 데이터를 읽는 예제이다.


read_address.py

#! /usr/bin/python


import addressbook_pb2

import sys


# Iterates though all people in the AddressBook and prints info about them.

def ListPeople(address_book):

  for person in address_book.person:

    print "Person ID:", person.id

    print "  Name:", person.name

    if person.HasField('email'):

      print "  E-mail address:", person.email


    for phone_number in person.phone:

      if phone_number.type == addressbook_pb2.Person.MOBILE:

        print "  Mobile phone #: ",

      elif phone_number.type == addressbook_pb2.Person.HOME:

        print "  Home phone #: ",

      elif phone_number.type == addressbook_pb2.Person.WORK:

        print "  Work phone #: ",

      print phone_number.number


# Main procedure:  Reads the entire address book from a file and prints all

#   the information inside.

if len(sys.argv) != 2:

  print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE"

  sys.exit(-1)


address_book = addressbook_pb2.AddressBook()


# Read the existing address book.

f = open(sys.argv[1], "rb")

address_book.ParseFromString(f.read())

f.close()


ListPeople(address_book) 

예제 코드를 실행하면 내가 작성했던 정보들을 읽을 수 있다.


Comments