diff options
author | Chris Piro <cpiro@apache.org> | 2013-03-07 11:32:48 -0500 |
---|---|---|
committer | Chris Piro <cpiro@apache.org> | 2013-03-07 11:32:48 -0500 |
commit | 20c81ad74c53c102692adec0e3c68d413899cabd (patch) | |
tree | 0da5aa00eada8c48106b08b07ff29077d3449d2b /tutorial/py.tornado | |
parent | 92e3860cfbaab5132439b9bac2e18dba06494bcc (diff) | |
download | thrift-20c81ad74c53c102692adec0e3c68d413899cabd.tar.gz |
THRIFT-1704: Tornado support (Python)
Diffstat (limited to 'tutorial/py.tornado')
-rwxr-xr-x | tutorial/py.tornado/Makefile.am | 38 | ||||
-rwxr-xr-x | tutorial/py.tornado/PythonClient.py | 116 | ||||
-rwxr-xr-x | tutorial/py.tornado/PythonServer.py | 104 |
3 files changed, 258 insertions, 0 deletions
diff --git a/tutorial/py.tornado/Makefile.am b/tutorial/py.tornado/Makefile.am new file mode 100755 index 000000000..6ac60234c --- /dev/null +++ b/tutorial/py.tornado/Makefile.am @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +THRIFT = $(top_builddir)/compiler/cpp/thrift + +gen-py.tornado/tutorial/Calculator.py gen-py.tornado/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift + $(THRIFT) --gen py:tornado -r $< + +all-local: gen-py.tornado/tutorial/Calculator.py + +tutorialserver: all + ${PYTHON} PythonServer.py + +tutorialclient: all + ${PYTHON} PythonClient.py + +clean-local: + $(RM) -r gen-* + +EXTRA_DIST = \ + PythonServer.py \ + PythonClient.py diff --git a/tutorial/py.tornado/PythonClient.py b/tutorial/py.tornado/PythonClient.py new file mode 100755 index 000000000..95d78b867 --- /dev/null +++ b/tutorial/py.tornado/PythonClient.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys +import glob +sys.path.append('gen-py.tornado') +sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0]) + +import logging + +from tutorial import Calculator +from tutorial.ttypes import Operation, Work, InvalidOperation + +from thrift import TTornado +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol + +from tornado import gen +from tornado import ioloop + + +@gen.engine +def communicate(callback=None): + # create client + transport = TTornado.TTornadoStreamTransport('localhost', 9090) + pfactory = TBinaryProtocol.TBinaryProtocolFactory() + client = Calculator.Client(transport, pfactory) + + # open the transport, bail on error + try: + yield gen.Task(transport.open) + except TTransport.TTransportException as ex: + logging.error(ex) + if callback: + callback() + return + + # ping + yield gen.Task(client.ping) + print "ping()" + + # add + sum_ = yield gen.Task(client.add, 1, 1) + print "1 + 1 = {}".format(sum_) + + # make a oneway call without a callback (schedule the write and continue + # without blocking) + client.zip() + print "zip() without callback" + + # make a oneway call with a callback (we'll wait for the stream write to + # complete before continuing) + yield gen.Task(client.zip) + print "zip() with callback" + + # calculate 1/0 + work = Work() + work.op = Operation.DIVIDE + work.num1 = 1 + work.num2 = 0 + + try: + quotient = yield gen.Task(client.calculate, 1, work) + print "Whoa? You know how to divide by zero?" + except InvalidOperation as io: + print "InvalidOperation: {}".format(io) + + # calculate 15-10 + work.op = Operation.SUBTRACT + work.num1 = 15 + work.num2 = 10 + + diff = yield gen.Task(client.calculate, 1, work) + print "15 - 10 = {}".format(diff) + + # getStruct + log = yield gen.Task(client.getStruct, 1) + print "Check log: {}".format(log.value) + + # close the transport + client._transport.close() + + if callback: + callback() + + +def main(): + # create an ioloop, do the above, then stop + io_loop = ioloop.IOLoop.instance() + def this_joint(): + communicate(callback=io_loop.stop) + io_loop.add_callback(this_joint) + io_loop.start() + + +if __name__ == "__main__": + main() diff --git a/tutorial/py.tornado/PythonServer.py b/tutorial/py.tornado/PythonServer.py new file mode 100755 index 000000000..52932ff80 --- /dev/null +++ b/tutorial/py.tornado/PythonServer.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys +import glob +sys.path.append('gen-py.tornado') +sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0]) + +from tutorial import Calculator +from tutorial.ttypes import Operation, InvalidOperation + +from shared.ttypes import SharedStruct + +from thrift import TTornado +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from thrift.server import TServer + +from tornado import ioloop + + +class CalculatorHandler(object): + def __init__(self): + self.log = {} + + def ping(self, callback): + print "ping()" + callback() + + def add(self, n1, n2, callback): + print "add({}, {})".format(n1, n2) + callback(n1 + n2) + + def calculate(self, logid, work, callback): + print "calculate({}, {})".format(logid, work) + + if work.op == Operation.ADD: + val = work.num1 + work.num2 + elif work.op == Operation.SUBTRACT: + val = work.num1 - work.num2 + elif work.op == Operation.MULTIPLY: + val = work.num1 * work.num2 + elif work.op == Operation.DIVIDE: + if work.num2 == 0: + x = InvalidOperation() + x.what = work.op + x.why = "Cannot divide by 0" + raise x + val = work.num1 / work.num2 + else: + x = InvalidOperation() + x.what = work.op + x.why = "Invalid operation" + raise x + + log = SharedStruct() + log.key = logid + log.value = '%d' % (val) + self.log[logid] = log + callback(val) + + def getStruct(self, key, callback): + print "getStruct({})".format(key) + callback(self.log[key]) + + def zip(self, callback): + print "zip()" + callback() + + +def main(): + handler = CalculatorHandler() + processor = Calculator.Processor(handler) + pfactory = TBinaryProtocol.TBinaryProtocolFactory() + server = TTornado.TTornadoServer(processor, pfactory) + + print "Starting the server..." + server.bind(9090) + server.start(1) + ioloop.IOLoop.instance().start() + print "done." + + +if __name__ == "__main__": + main() |