Just for the note, if someone is interested, I've attached some module
based on 'repoze.bfg.xmlrpc' package to provide more convenient way
for creating XML-RPC services with repoze.bfg. Here it is, with
example in docstring.
Utilities for creating XML-RPC services.
This module extends 'repoze.bfg.xmlrpc' package. Simple usage:
class MyService(Service):
@method
def my_method(self, a, b):
return a + b
class simple(Namespace):
@method
def another_method(self, a, b):
return a * b
Class MyService is view class now and you can, for example, mount it with rout
/ ZCML directive. Calss to service translates in the following way:
- Call 'my_method' translates to MyService.my_method call.
- call 'simple.my_method' translates to MyService.simple.another_method
call.
If no method found for call, Fault object returns with
xmlrpclib.METHOD_NOT_FOUND code.
import inspect
import xmlrpclib
from repoze.bfg.xmlrpc import parse_xmlrpc_request
from repoze.bfg.xmlrpc import xmlrpc_response
__all__ = [Service,
Namespace,
method]
class Namespace(object):
XML-RPC namespace object.
@classmethod
def traverse(cls, parts):
if not parts:
raise xmlrpclib.Fault(
xmlrpclib.METHOD_NOT_FOUND, Method not found)
current = parts.pop(0)
if not hasattr(cls, current):
raise xmlrpclib.Fault(
xmlrpclib.METHOD_NOT_FOUND, Method not found)
next_obj = getattr(cls, current)
if not hasattr(next_obj, traverse):
raise xmlrpclib.Fault(
xmlrpclib.METHOD_NOT_FOUND, Method not found)
return next_obj.traverse(parts)
class Service(Namespace):
XML-RPC service as view.
def __init__(self, context, request):
self.context = context
self.request = request
def resolve(self, method):
parts = method.split(.)
return self.traverse(parts)
def apply(self, handler, params):
args, varargs, varkw, defaults = inspect.getargspec(handler)
if varargs is None and not len(args) - 1 == len(params):
raise xmlrpclib.Fault(
xmlrpclib.INVALID_METHOD_PARAMS,
Params number must be equal to %d % len(args))
elif not varargs is None and len(params) len(args):
raise xmlrpclib.Fault(
xmlrpclib.INVALID_METHOD_PARAMS,
Params number must be greater or equal to %d % len(args))
return handler(self, *params)
def __call__(self):
params, method = parse_xmlrpc_request(self.request)
try:
handler = self.resolve(method)
value = self.apply(handler, params)
except xmlrpclib.Fault, fault:
value = fault
return xmlrpc_response(value)
def method(func):
def traverse(parts):
if parts:
raise xmlrpclib.Fault(
xmlrpclib.METHOD_NOT_FOUND, Method not found)
return func
func.traverse = traverse
return func
___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev