LoginSignup
36
31

More than 5 years have passed since last update.

Python で gRPC を試す

Last updated at Posted at 2015-07-29

gRPC をインストール

まずは gRPC をインストールします。
gRPCと共に、RPCのシリアライゼーションを担う Protocol Buffers もインストールされるようです。

$ curl -fsSL https://goo.gl/getgrpc | bash -s python

もし、インストール中に以下のようなエラーが出た場合は homebrew が古いので brew update を試してみてください。(Macの場合)

Error: undefined method `desc' for Grpc:Class
Please report this bug:
    http://git.io/brew-troubleshooting
/usr/local/Library/Taps/grpc/homebrew-grpc/Formula/grpc.rb:2:in `<class:Grpc>'
・・・

.proto(IDL)を書く

Protocol Buffers のIDLを書きます。
以下の例ではサーボを動かすRPCを定義しています。

gRPC 自体は Protocol Buffers のプラグインとなっています。
(gRPC 以外にも RPC 実装はたくさんあります)

gateway.proto
syntax = "proto3";

package gateway;

message MoveServoRequest {
  int32 servo_id = 1;
  int32 position = 2;
}

message MoveServoResponse {
  int32 current_position = 1;
}

service AVRGateway {
  rpc MoveServo (MoveServoRequest) returns (MoveServoResponse) {}
}

IDLをコンパイルしてgRPCのpythonスクリプトを生成

以下の protoc コマンドで、gateway_pb2.py が生成されます。

$ protoc --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` gateway.proto

gRPC用のサーバ/クライアントのコードを書く

上記のコマンドで生成されたPythonスクリプトをインポートすれば簡単にサーバ/クライアントが書けます。
gRPCのPythonライブラリ自体まだAlpha版なので、いろんなメソッドにearly_adopter_*というプレフィックスがついています。

gateway_server.py
import time
import gateway_pb2

class AVRGateway(gateway_pb2.EarlyAdopterAVRGatewayServicer):
  def MoveServo(self, request, context):
    print 'servo_id: %d, position: %d' % (request.servo_id, request.position)
    return gateway_pb2.MoveServoResponse(current_position=150)

def serve():
  server = gateway_pb2.early_adopter_create_AVRGateway_server(AVRGateway(), 9494, None, None)
  server.start()
  try:
    while True:
      time.sleep(100000)
  except KeyboardInterrupt:
    server.stop()

if __name__ == '__main__':
  serve()
gateway_client.py
import gateway_pb2

def run():
  with gateway_pb2.early_adopter_create_AVRGateway_stub('localhost', 9494) as stub:
    response = stub.MoveServo(gateway_pb2.MoveServoRequest(servo_id=1, position=200), 10) 
    print "current position: " + str(response.current_position)

if __name__ == '__main__':
  run()

実行

まずサーバを立ち上げます。

$ ls
gateway.proto      gateway_client.py  gateway_pb2.py      gateway_server.py
$ python gateway_server.py

そして別のターミナルでクライアントを。

$ python gateway_client.py
current position: 150
D0729 10:42:14.835677000 140735135564544 iomgr.c:119] Waiting for 1 iomgr objects to be destroyed and executing final callbacks

サーバのほうでは

$ python gateway_server.py 
servo_id: 1, position: 200

という感じで出力されていればOK。

36
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
31