Skip to content

Instantly share code, notes, and snippets.

@joshmarshall
Created May 1, 2011 18:57
Show Gist options
  • Save joshmarshall/950744 to your computer and use it in GitHub Desktop.
Save joshmarshall/950744 to your computer and use it in GitHub Desktop.
Tornado XML-RPC Early Test Script
import tornado.httpserver
import tornado.ioloop
import tornado.web
def private(func):
# Decorator to make a method, well, private.
class PrivateMethod(object):
def __init__(self):
self.private = True
__call__ = func
return PrivateMethod()
class XMLRPCHandler(tornado.web.RequestHandler):
"""
Subclass this to add methods -- you can treat them
just like normal methods, this handles the XML formatting.
"""
def post(self):
"""
Later we'll make this compatible with "dot" calls like:
server.namespace.method()
If you implement this, make sure you do something proper
with the Exceptions, i.e. follow the XMLRPC spec.
"""
import xmlrpclib
try:
params, method_name = xmlrpclib.loads(self.request.body)
except:
# Bad request formatting, bad.
raise Exception('Deal with how you want.')
if method_name in dir(tornado.web.RequestHandler):
# Pre-existing, not an implemented attribute
raise AttributeError('%s is not implemented.' % method_name)
try:
method = getattr(self, method_name)
except:
# Attribute doesn't exist
raise AttributeError('%s is not a valid method.' % method_name)
if not callable(method):
# Not callable, so not a method
raise Exception('Attribute %s is not a method.' % method_name)
if method_name.startswith('_') or
('private' in dir(method) and method.private is True):
# No, no. That's private.
raise Exception('Private function %s called.' % method_name)
response = method(*params)
response_xml = xmlrpclib.dumps((response,), methodresponse=True)
self.set_header("Content-Type", "text/xml")
self.write(response_xml)
class TestXMLRPC(XMLRPCHandler):
def add(self, x, y):
return x+y
def ping(self, x):
return x
def _private(self):
# Shouldn't be called
return False
@private
def private(self):
# Also shouldn't be called
return False
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", TestXMLRPC),
(r"/RPC2", TestXMLRPC)
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment