Edited at

Python3 で Protocol Buffers のデータを読み出す

More than 5 years have passed since last update.

今日はいつもの統計や機械学習の話から急に趣向が変わって Python + Protocol Buffers の話です。

Protocol Buffers は便利なシリアライゼーションフォーマットです。これを Python 3 で使おうとすると執筆時点では GitHub の最新のコードを使う必要があります。

Python 2 のサポートが 2020 年まで伸びたニュースは耳に新しく 2 系を使えば良いと言えばそうなのですが最新技術を追うエンジニアとしては Python 3.x 系以外は絶対に書きたくないという強い意志があるケースも多いかと思います。


環境構築

環境としては次のように GitHub から Protocol Buffers をクローンしてビルド、さらに Python でセットアップします。

git clone git://github.com/openx/python3-protobuf.git

cd python3-protobuf
./autogen.sh
./configure --prefix=$PREFIX # protobuf インストール先を指定
make
make check
sudo make install

cd python # Python バインディング
python setup.py build
python setup.py test
sudo
python setup.py install

これで Python3 から Protocol Buffers を利用できるようになりました。簡単ですね。


ファイル構造の定義と変換

Protocol Buffers では .proto という名前のファイルで構造を定義します。 JSON で言うキーは数値に変換されよりデータサイズが小さい形でやりとり可能であると言われています。

protoc -I=. --python_out=. schema.prot

schemaXX.py といったファイルが生成されるのでこれを利用したいスクリプトから import すれば OK です。


Python からの利用

実際にデータを読み出すイメージとしてはこのようになります。

import schema_pb2 # 生成した Python ファイルのインポート

import base64
import json

event = schema_pb2.nb_event()
event.ParseFromString(base64.b64decode(value))
ts = event.timestamp

# 試しに JSON に変換してみる
obj = {}
obj['event_type'] = event.type
obj['seq'] = event.seq
obj['timestamp'] = event.timestamp
obj['op'] = event.op

# 一旦ディクショナリに格納したデータを JSON へ変換
json_dump = json.dumps(obj, ensure_ascii=False)
print(json_dump)