概要
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, 記事投稿