It look like there is no ready library with my requirements, so a ended up with own implementation:
class ApplicationError(Fault):
    def __init__(self, exc_info):
        Fault.__init__(self, xmlrpclib.APPLICATION_ERROR,
                       u'Application internal error')
class NotWellformedError(Fault):
    def __init__(self, exc):
        Fault.__init__(self, xmlrpclib.NOT_WELLFORMED_ERROR, str(exc))
class UnsupportedEncoding(Fault):
    def __init__(self, exc):
        Fault.__init__(self, xmlrpclib.UNSUPPORTED_ENCODING, str(exc))
# XXX INVALID_ENCODING_CHAR is masked by xmlrpclib, so the error code will be
# INVALID_XMLRPC.
class InvalidRequest(Fault):
    def __init__(self, message):
        ault.__init__(self, xmlrpclib.INVALID_XMLRPC, message)
class MethodNotFound(Fault):
    def __init__(self, name):
        Fault.__init__(self, xmlrpclib.METHOD_NOT_FOUND,
                       u'Method %r is not supported' % name)
class WrongMethodUsage(Fault):
    def __init__(self, message):
        Fault.__init__(self, xmlrpclib.INVALID_METHOD_PARAMS, message)
class WrongType(Fault):
    def __init__(self, arg_name, type_name):
        Fault.__init__(self, xmlrpclib.INVALID_METHOD_PARAMS,
                       u'Parameter %s must be %s' % (arg_name, type_name))
class XMLRPCDispatcher(SimpleXMLRPCDispatcher, XMLRPCDocGenerator):
    server_name = server_title = 'Personalization center RPC interface'
    server_documentation = 'Available methods'
    def __init__(self, methods):
        SimpleXMLRPCDispatcher.__init__(self, allow_none=True, encoding=None)
        self.register_instance(methods)
        self.register_multicall_functions()
        #self.register_introspection_functions()
    def _dispatch(self, method_name, args):
        if self.funcs.has_key(method_name):
            method = self.funcs[method_name]
        else:
            method = self.instance._getMethod(method_name)
        arg_names, args_name, kwargs_name, defaults = \
                                                inspect.getargspec(method)
        assert arg_names[0]=='self'
        arg_names = arg_names[1:]
        n_args = len(args)
        if not (args_name or defaults):
            if n_args!=len(arg_names):
                raise WrongMethodUsage(
                    u'Method %s takes exactly %d parameters (%d given)' % \
                                (method_name, len(arg_names), n_args))
        else:
            min_args = len(arg_names)-len(defaults)
            if len(args)<min_args:
                raise WrongMethodUsage(
                    u'Method %s requires at least %d parameters (%d given)' % \
                                (method_name, min_args, n_args))
            if not args_name and n_args>len(arg_names):
                raise WrongMethodUsage(
                    u'Method %s requires at most %d parameters (%d given)' % \
                                (method_name, len(arg_names), n_args))
        try:
            return method(*args)
        except Fault:
            raise
        except:
            logger.exception('Application internal error for %s%r',
                             method_name, args)
            raise ApplicationError(sys.exc_info())
    def dispatch(self, data):
        try:
            try:
                args, method_name = xmlrpclib.loads(data)
            except ExpatError, exc:
                raise NotWellformedError(exc)
            except LookupError, exc:
                raise UnsupportedEncoding(exc)
            except xmlrpclib.ResponseError:
                raise InvalidRequest('Request structure is invalid')
            method_name = method_name.encode('ascii', 'replace')
            result = self._dispatch(method_name, args)
        except Fault, exc:
            logger.warning('Fault %s: %s', exc.faultCode, exc.faultString)
            return xmlrpclib.dumps(exc)
        else:
            try:
                return xmlrpclib.dumps((result,), methodresponse=1)
            except:
                logger.exception('Application internal error when marshalling'\
                                 ' result for %s%r', method_name, args)
                return xmlrpclib.dumps(ApplicationError(sys.exc_info()))
class InterfaceMethods:
    def _getMethod(self, name):
        if name.startswith('_'):
            raise MethodNotFound(name)
        try:
            method = getattr(self, name)
        except AttributeError:
            raise MethodNotFound(name)
        if not inspect.ismethod(method):
            raise MethodNotFound(name)
        return method