Google App Engine(Python)でThriftを動作させる

ThriftのサーバーにTomcatを使用する
Javaでできたんだから、Pythonでもできるのでは?

Pythonで有名なアプリケーションサーバーといえば
Google App Engineでしょ。

ということで、Thriftのサーバー機能をGoogle App Engineで動作に挑戦です。



thriftモジュールの準備



http://incubator.apache.org/thrift/
thrift本体をダウンロードし、解凍したフォルダの中の
lib\py\src
の中身をgoogle app engineのソースフォルダ(app.yaml)があるフォルダに
thriftというフォルダを作成してコピーします。

また、javaの時使用したTIOStreamTransportというクラスは無いので、
自作しました。

以下の内容をTIOStreamTransport.pyという名前で、
thrift\transportに保存します。

■TIOStreamTransport.py


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

from TTransport import TTransportBase

class TIOStreamTransport(TTransportBase):

    def __init__(self, input_stream, output_stream):
        self.input_stream = input_stream
        self.output_stream = output_stream
        
    def isOpen(self):
        return True

    def close(self):
        pass

    def read(self, sz):
        return self.input_stream.read(sz)

    def write(self, buf):
        self.output_stream.write(buf)

    def flush(self):
        pass




※javaのクラスを参考に作成しました。



gen-py



thriftコマンドで生成したソースもコピーしておきます。
使用したthriftファイルはこんな感じ。

■sample.thrift

service Calculator {
i32 add(1:i32 num1, 2:i32 num2)
}



これまでの調査に使用したのと同様、引数を2つとり、
引数を加算した値を返却します。



main.py



google app engineで実行するソースはこんな感じ。

■main.py

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

import wsgiref.handlers
from google.appengine.ext import webapp

#Thriftを使用するため、importを追加
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.transport import TIOStreamTransport

#thriftコマンドで生成したファイルを追加
import sys
sys.path.append('./gen-py')

from sample import Calculator
from sample.ttypes import *

#Calculatorの実装
class CalculatorHandler:
    def add(self, n1, n2):
        return n1+n2


class MainHandler(webapp.RequestHandler):
    
    def get(self):
        print "post only"
    
    def post(self):
        
        self.response.headers['Content-Type'] = 'application/x-thrift'
        
        handler = CalculatorHandler()
        processor = Calculator.Processor(handler)
        
        #自作したTIOStreamTransportをtransportとして指定する
        input_stream = self.request.environ['wsgi.input']
        output_stream = self.response.out
        transport = TIOStreamTransport.TIOStreamTransport(input_stream, output_stream)
        
        protocol = TBinaryProtocol.TBinaryProtocol(transport, True, True)
        transport.open()
        processor.process(protocol, protocol)
        transport.close()
        
def main():
    application = webapp.WSGIApplication([('/', MainHandler)],
                                     debug=True)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()




一番はまったのは

input_stream = self.request.environ['wsgi.input']
output_stream = self.response.out



出力に使用するoutput_streamはself.response.outでよいだろうと
すぐに見当がついたのですが、input_streamに使用する
オブジェクトのあたりがつかず・・・

基本に立ち返って、wsgiアプリケーションについて調べ、
第2回 WSGIを使ったもう少し複雑なアプリケーションの作成
ここを見て気が付きました。


environ['wsgi.input']


これで取得したオブジェクトをinput_streamとして与えます。



クライアントアプリケーション



http://symfoware.appspot.com/
このURLにアップロードしました。

クライアント側のpythonソースはこんな感じになります。


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

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

#sampleは雛形に指定したthriftファイルの名前になる模様
from sample import Calculator
from sample.ttypes import *

#お決まりのimport
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.transport import THttpClient

try:
    
    #アップロードしたgoogle app engineのURLを指定
    transport = THttpClient.THttpClient("http://symfoware.appspot.com/")
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    
    client = Calculator.Client(protocol)
    transport.open()
    
    #指定したaddメソッドを呼び出す
    num1 = 15
    num2 = 47
    
    sum = client.add(num1, num2)
    #計算結果を表示
    print '[client print] %d + %d = %d' % (num1, num2, sum)
    
    #後始末
    transport.close()

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





実行してみると・・・


c:\>python client.py
[client print] 15 + 47 = 62




動いた!




関連記事

コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
https://symfo.web.fc2.com/

PR

検索フォーム

月別アーカイブ