gRPCとProtocol Buffersによるアプリケーション間通信 / Python
「gRPC」でアプリケーション間通信を行い、別アプリからテキストと画像を取得するスクリプトを作ります。
1. gRPC
「RPC」は、アプリケーション間通信のひとつで、プログラミングのメソッドを呼び出す手順で、別のプログラムを操作できます。
「gRPC」は、Googleが開発した「RPC」で、高速かつ低容量、様々な言語に対応しています。
・gRPC - A high performance, open-source universal RPC framework
2. Protocol Buffers
「Protocol Buffers」(protobuf)は、構造化データをシリアライズするインタフェース記述言語のひとつです。「JSON」や「XML」などと比べ、高速かつ低容量で、様々な言語に対応しています。
「protoファイル」で構造化データを定義し、コンパイルすることで各言語のコードを生成します。
・Protocol Buffers | Google Developers
3. 開発ツールのインストール
Macで「Protocol Buffers」のコンパイラをインストールするコマンドは、次のとおりです。
$ brew install protobuf
Pythonで「gRPC」を実装するためのパッケージ「grpcio-tools」をインストールするコマンドは、次のとおりです。
$ pip install grpcio-tools
4. protoファイルの生成
構造化データを定義する「protoファイル」を生成します。「image」の型は「bytes」もありますが、byte[]で渡せるのがGoのみだったので、シンプルにstringにしてます。
【simple.proto】
syntax = "proto3";
package simple;
//リクエスト
message SimpleRequest{
}
//レスポンス
message SimpleResponse{
string text = 1;
string image = 2;
}
//RPCインタフェースの定義
service SimpleService{
rpc SimpleSend (SimpleRequest) returns (SimpleResponse) {}
}
5. protoファイルのコンパイル
「protoファイル」をコンパイルするには、以下のPythonコードを実行します。
【codegen.py】
from grpc.tools import protoc
protoc.main(
(
'',
'-I.',
'--python_out=.',
'--grpc_python_out=.',
'simple.proto',
)
)
以下の2つのファイルが生成されます。
・simple_pb2.py : シリアライズのインタフェース
・simple_pb2_grpc.py : gRPCのインタフェース
6. サーバーの実装
サーバーを実装します。
【simple_server.py】
import time
import grpc
import simple_pb2
import simple_pb2_grpc
import base64
from concurrent import futures
# シンプルサービスサーバーの定義
class SimpleServiceServicer(simple_pb2_grpc.SimpleServiceServicer):
# 初期化
def __init__(self):
pass
# 受信時の処理
def SimpleSend(self, request, context):
text = 'This is TEST!'
b64 = base64.encodestring(open('image.jpg', 'rb').read()).decode('utf8')
return simple_pb2.SimpleResponse(text=text, image=b64)
# サーバーの開始
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
simple_pb2_grpc.add_SimpleServiceServicer_to_server(SimpleServiceServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
print('サーバーの開始')
# 待機
try:
while True:
time.sleep(3600)
except KeyboardInterrupt:
# サーバーの停止
server.stop(0)
◎ サーバーの処理の実装
「simple_pb2_grpc.SimpleServiceServicer」を継承して、SimpleSend()を実装します。クライアントからの「SimpleRequest」を受信し、それに応じて「SimpleResponse」を返しています。
◎ サーバーの開始
「SimpleServiceServicer」でサーバーを生成し、ワーカー数「10」、ポート番号「50051」を指定して、開始しています。
◎ サーバーの停止
キー割り込みがあった場合は、サーバーを停止しています。
7. クライアントの実装
クライアントを実装します。
【simple_client.py】
import grpc
import simple_pb2
import simple_pb2_grpc
import base64
# サーバーとの接続
with grpc.insecure_channel('localhost:50051') as channel:
stub = simple_pb2_grpc.SimpleServiceStub(channel)
# データの取得
response = stub.SimpleSend(simple_pb2.SimpleRequest())
print('text:', response.text)
with open('client.jpg', mode='wb') as f:
f.write(base64.b64decode(response.image))
◎ サーバーとの接続
サーバーとの接続は、grpc.insecure_channel()でチャンネルを取得し、「SimpleServiceStub」でサーバースタブを生成し、SimpleSend()を呼んでいます。「ChatRequest」を送信し、「ChatResponse」を受信します。
8. サーバーとクライアントの実行
サーバーとクライアントを実行します。サーバー側に「image.jpg」も必要になります。
$ python simple_server.py
$ python simple_client.py
クライアント側でテキストと画像が取得できます。
この記事が気に入ったらサポートをしてみませんか?