公式で quick start が用意されていたので、実際に手を動かして試してみました。
環境構築
まずは gRPC を試す環境をつくります。
手元の環境:
- os: windows 10
> python -m pip install virtualenv
> virtualenv venv
> .\venv\Scripts\activate.ps1
(venv) > python -m pip install --upgrade pip
gRPC をとツールをインストール
(venv) > python -m pip install grpcio
(venv) > python -m pip install grpcio-tools
サービスを定義
gRPC の最初のステップはサービス定義です。リクエストとレスポンスを書いていきます。
syntax = "proto3";
package hello;
service Hello {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
クライアントとサーバサイドのコード生成
.proto
ファイルからクライアントとサーバのインターフェースのコードが生成できます。
(venv) > cd src/hello
(venv) > python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/hello.proto
上記のコマンドを実行すると、以下のコードが生成されます。
- hello_pb2_grpc.py
- hello_pb2.py
hello_pb2_grpc.py
は RPC を実行するときに使用されて、hello_pb2.py
はリクエストとレスポンスのインターフェースとして使用されている感じ(ただのイメージ。ここらへんはもう少しさわってみて確認してみる)。
サーバ側のコードを作成
quick start のコードを真似して作成。python hello_server.py
を実行するとサーバとして起動されます。
from concurrent import futures
import logging
import grpc
import hello_pb2
import hello_pb2_grpc
class Hello(hello_pb2_grpc.HelloServicer):
def SayHello(self, request, context):
return hello_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
hello_pb2_grpc.add_HelloServicer_to_server(Hello(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
クライアント側のコード作成
サービスメソッドを呼び出すためにスタブを作成します。スタブと呼ぶあたり疎結合システム、マイクロサービスと相性が良さそうです。
import logging
import grpc
import hello_pb2
import hello_pb2_grpc
def run():
with grpc.insecure_channel('localhost:50051') as channel:
stub = hello_pb2_grpc.HelloStub(channel)
response = stub.SayHello(hello_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
実行
gRPC の動作を確認するだけなら以上のコードだけで十分です。
まずはサーバ側のコードを実行します。
(venv) > hello_server.py
別のターミナルを立ち上げて、クライアント側のコードを実行します。
(venv) > hello_client.py
Greeter client received: Hello, you!
REST な API に慣れていたので gRPC のような API の呼び出しは中々理解できませんしたが、実際に手を動かして実装することによって大雑把にですが理解できるようになりました。
gRPC にはリクエストとレスポンスに stream 形式も扱えるらしいので、次はここら辺を試してみます。