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
動いた!
- 関連記事
-
- Debian + Nginx 0.7.x + mod_wsgi + pythonでthriftを動かす
- プロキシサーバー越しにPythonでThriftのTHttpClientを使用する
- Google App Engine(Python)でThriftを動作させる
- ThriftのサーバーにTomcatを使用する
- ThriftをWindowsのPythonで使用する(Pythonエクステンションのビルド)
コメント