Published on

Using Apache Thrift 4: Working with Python

Authors

This time I will create a Python version of the sample from the previous post. The procedure is the same as before: create a thrift file, compile it, then implement the server side and client side. First, add a Python namespace to the thrift file from the previous post, like this.

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),
}

If you run the command below from the command line, a folder called gen-py is created.

$ thrift.exe -gen py Calculator.thrift

Implement the server side. It is almost the same as the C++ version.

#! /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()

Finally, implement the client side. It is also almost the same as the C++ version.

#! /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)

Once both sides are implemented, try running the client and server with C++ and Python swapped. It should still work. That is one of the really nice things about Thrift.