iMind Developers Blog

iMind開発者ブログ

Pythonでgoogle.protobuf.message.Messageをjsonに変換する

概要

GCPのAPIを使っているとprotobuf形式で結果が返ってくることがあるけど、そのままだと扱いづらいケースもあるのでJSONに変換する方法を確認する。

バージョン情報

  • protobuf==3.10.0

サンプルデータ

公式サイトによく出ているサンプルデータを生成して利用する。

addressbook.proto というファイル名で下記を記述。

syntax = "proto3";
package tutorial;

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

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

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;

  google.protobuf.Timestamp last_updated = 5;
}

message AddressBook {
  repeated Person people = 1;
}

勇気と愛気

$ protoc -I=. --python_out=. addressbook.proto

これで addressbook_pb2.py というファイルが生成される。

生成されたpythonファイルをimportしてサンプルデータを生成する。

import addressbook_pb2

def create_person(person_id, name, email, phone_number):
    person = addressbook_pb2.Person()
    person.id = person_id
    person.name = name
    person.email = email
    number = addressbook_pb2.Person.PhoneNumber()
    number.number = phone_number
    person.phones.append(number)
    return person

address_book = addressbook_pb2.AddressBook()
address_book.people.append(create_person(1, 'foo', 'foo@example.com', '000-0000-0000'))
address_book.people.append(create_person(2, 'bar', 'foo@example.com', '111-1111-1111'))

    # こんなデータが出来上がります
    #=> people {
    #=>   name: "foo"
    #=>   id: 1
    #=>   email: "foo@example.com"
    #=>   phones {
    #=>     number: "000-0000-0000"
    #=>   }
    #=> }
    #=> people {
    #=>   name: "bar"
    #=>   id: 2
    #=>   email: "foo@example.com"
    #=>   phones {
    #=>     number: "111-1111-1111"
    #=>   }
    #=> }

jsonへの変換

google.protobuf.json_format というモジュールが用意されているのでこれを使ってjsonへ変換する。

from google.protobuf import json_format

js = json_format.MessageToJson(address_book)
print(js)

    #=> {
    #=>   "people": [
    #=>     {
    #=>       "name": "foo",
    #=>       "id": 1,
    #=>       "email": "foo@example.com",
    #=>       "phones": [
    #=>         {
    #=>           "number": "000-0000-0000"
    #=>         }
    #=>       ]
    #=>     },
    #=>     {
    #=>       "name": "bar",
    #=>       "id": 2,
    #=>       "email": "foo@example.com",
    #=>       "phones": [
    #=>         {
    #=>           "number": "111-1111-1111"
    #=>         }
    #=>       ]
    #=>     }
    #=>   ]
    #=> }

dictへの変換

どうモジュールには MessageToDict というdictに変換する機能も用意されている。

from google.protobuf import json_format

dct = json_format.MessageToDict(address_book)
print(dct)

    #=> {'people': [{'name': 'foo',
    #=>    'id': 1,
    #=>    'email': 'foo@example.com',
    #=>    'phones': [{'number': '000-0000-0000'}]},
    #=>   {'name': 'bar',
    #=>    'id': 2,
    #=>    'email': 'foo@example.com',
    #=>    'phones': [{'number': '111-1111-1111'}]}]}

改定履歴

Author: Masato Watanabe, Date: 2019-12-28, 記事投稿