Apache Thrift を使う 4 - Python と連携

Posted Mon Jun 25 2012

今回は前回作成したサンプルのPython版を作ってみます.手順は前回と同じで, thrift ファイルを作成したあとコンパイルを実行しサーバーサイドとクライアントサイドを実装します.まず前回作成した thrift ファイルに下記のように python 用の namespace を追加します.

namespace cpp calc
namespace py calc

service Calculator {
  double plus(1: double arg1, 2: double arg2),
  double minus(1: double arg1, 2: double arg2),
  double multiplies(1: double arg1, 2: double arg2),
  double divides(1: double arg1, 2: double arg2),
}

コマンドラインから下記のコマンドを実行すると gen-py というフォルダが作成されます.

$ thrift.exe -gen py Calculator.thrift

サーバーサイドを実装します.C++ 版とだいたい同じですね.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.path.append('gen-py')

from calc import Calculator
from calc.ttypes import *

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

class CalculatorHandler:
    def __init__(self):
        pass

    def plus(self, arg1, arg2):
        print "plus"
        return arg1 + arg2

    def minus(self, arg1, arg2):
        print "minus"
        return arg1 - arg2

    def multiplies(self, arg1, arg2):
        print "multiplies"
        return arg1 * arg2

    def divides(self, arg1, arg2):
        print "divides"
        return arg1 / arg2

def main():
    handler = CalculatorHandler()
    processor = Calculator.Processor(handler)
    transport = TSocket.TServerSocket(port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

    print 'Starting the server...'
    server.serve()
    print 'done.'

if __name__ == '__main__':
    main()

最後にクライアントサイドを実装します.こちらも C++ 版とだいたい同じです.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.path.append('gen-py')

from calc import Calculator 
from calc.ttypes import *

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

if __name__ == '__main__':
    try:
        transport = TSocket.TSocket('localhost', 9090)
        transport = TTransport.TBufferedTransport(transport)
        protocol = TBinaryProtocol.TBinaryProtocol(transport)
        client = Calculator.Client(protocol)

        transport.open()

        print "2 + 3 = %f" % (client.plus(2, 3),)
        print "6 - 3 = %f" % (client.minus(6, 3),)
        print "8 * 3 = %f" % (client.multiplies(8, 3),)
        print "16 / 5 = %f" % (client.divides(16, 5),)

        transport.close()

    except Thrift.TException, tx:
        print "%s" % (tx.message)

両方できたら,是非クライアント/サーバーサイドを C++,Python 入れ替えて 実行してみて下さい.入れ替えても実行できるはずです.便利ですよね.