😺
pythonでgRPC通信をやってみる
この記事について
gRPC通信に関して知識と経験がない。とりあえずpythonでやってみる。
頭の整理も兼ねて、最もシンプルなgRPC通信でhello worldを返すアプリケーションを書いてみる。
gRPCの利点・詳細・各用語などは他記事などを参考にしてください。
流れ
- (諸々の環境構築)
- gRPCのAPI定義ファイルであるprotoファイルを作成
- protoファイルをコンパイル
- サーバー側のpythonファイルを作成
- サーバーを叩くクライアント側のpythonファイルを作成
- 実行
諸々のコードは下記になる
.
├── Dockerfile
├── README.md
├── docker-compose.yaml
└── src
├── client.py
├── pb
│ ├── __init__.py (ちょっとゴニョゴニョしてる)
│ ├── helloworld_pb2.py
│ ├── helloworld_pb2.pyi
│ └── helloworld_pb2_grpc.py
├── proto
│ └── helloworld.proto
└── server.py
環境構築
dockerで構築
FROM python:3.8-slim
# 今回はpoetryなどは面倒なので使わない
RUN pip install --upgrade pip \
&& pip install grpcio \
&& pip install grpcio-tools
WORKDIR /src
コンテナ内にアクセスするためには下記コマンドを使う
docker exec -it grpc-grpc-demo-1 sh
gRPCのAPI定義ファイルであるprotoファイルを作成
serviceでメソッドをまとめてエンドポイントを作る。
messageで型定義とかをしておく。
syntax = "proto3";
package helloworld;
// エンドポイント定義
service HelloWorldService {
rpc SayHello (HelloWorldRequest) returns (HelloWorldResponse);
}
// 型定義
message HelloWorldRequest {
}
message HelloWorldResponse {
string message = 1;
}
protoファイルのコンパイル
dockerのコンテナ内で、下記のコマンドを実行
(-Iの間にスペースいらないんか、、、)
python -m grpc_tools.protoc -I./proto --python_out=./pb --pyi_out=./pb --grpc_python_out=./pb ./proto/helloworld.proto
いろいろ生成される
サーバー側のpythonファイルを作成
生成されたファイルを使いつつ、
- レスポンスの処理
- サーバー起動処理
を書く
from concurrent import futures
import grpc
from pb import helloworld_pb2
from pb import helloworld_pb2_grpc
# レスポンスの処理
class Greeter(helloworld_pb2_grpc.HelloWorldServiceServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloWorldResponse(message="hello world")
# サーバー起動処理
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_HelloWorldServiceServicer_to_server(Greeter(), server)
# サーバーの立ち上げ
server.add_insecure_port('[::]:5001')
server.start()
print("server started")
server.wait_for_termination()
if __name__ == '__main__':
serve()
サーバーを叩くクライアント側のpythonファイルを作成
生成されたファイルを使いつつ、下記のような形で書く
import grpc
from pb import helloworld_pb2
from pb import helloworld_pb2_grpc
def run():
with grpc.insecure_channel('localhost:5001') as channel:
stub = helloworld_pb2_grpc.HelloWorldServiceStub(channel)
response = stub.SayHello(helloworld_pb2.HelloWorldRequest())
print("Response: %s" % response.message)
if __name__ == '__main__':
run()
実行
python server.pyでサーバー側を立てておいて、
別ウィンドウでクライアント側のスクリプトを実行
うまくいってそう
諸々のコード
Discussion