<commit_before>#
# Copyright (c) 2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
"""
Along with apiutils, implements an API-validating and versioning scheme for 
xmlrpc calls.

The ApiProxy is instantiated with a reference to the class of the server it is 
communicating with, and uses that information to determine the expected format 
of the parameters to the class.  It freezes classes appropriately, and then
calls the server.

The ApiProxy also passes in as its first parameter a list of information.
that includes the ApiProxy version, and the version information about the 
server and the method.

The XMLApiServer is a wrapper around an XMLRPC server that manages the 
information passed in by an API Proxy.  It also validated and transforms the 
method parameters

A server class's public interface should be decorated with decorators
from apiutils that describe how to convert its parameters.

Server methods also will be passed in callData that includes the
calling version of the method.
"""
import itertools
import select
import socket
import sys
import time
import traceback
import xmlrpclib

from conary.lib import log
from conary.lib import coveragehook

from rmake import errors
from rmake.lib import apiutils
from rmake.lib import localrpc
from rmake.lib import auth
from rmake.lib.apiutils import api, api_parameters, api_return

# This version describes the current iteration of the API protocol.
_API_VERSION = 1


class ApiProxy(localrpc.ServerProxy):

    def __init__(self, apiClass, uri):
        self.apiClass = apiClass
        self.clientVersion = self.apiClass._CLASS_API_VERSION
        self.uri = uri
        localrpc.ServerProxy.__init__(self, uri)

    def __repr__(self):
        return "<ApiProxy>"

    def __str__(self):
        return "<ApiProxy>"

    def __getattr__(self, name):
        """ Get a proxy for an individual method.  """
        try:
            methodApi = getattr(self.apiClass, name)
        except AttributeError:
            raise ApiError, 'cannot find method %s in api' % name

        return _ApiMethod(self._ServerProxy__request, name, self.uri,
                          _API_VERSION, self.clientVersion, methodApi)

class _ApiMethod(xmlrpclib._Method):
    """ Api-aware method proxy for xmlrpc.  """

    def __init__(self, request, name, uri, metaApiVersion, clientVersion, 
                 methodApi): 
        """
            @param metaApiVersion: version of apirpc data.
            @param clientVersion: client's version the whole server API
            @param methodApi: client's description of this method's API
        """
        xmlrpclib._Method.__init__(self, request, name)
        self.__metaApiVersion = metaApiVersion
        self.__clientVersion = clientVersion
        self.__methodApi = methodApi
        self.__uri = uri

    def __call__(self, *args):
        """ 
            Calls the remote method with args.  Passes in extra first tuple
            of API callData.
        """
        methodVersion = self.__methodApi.version

        args = list(_freezeParams(self.__methodApi, args, methodVersion))
        callData = (self.__metaApiVersion, self.__clientVersion, methodVersion)

        try:
            passed, rv = xmlrpclib._Method.__call__(self, callData, *args)
        except socket.error, err:
            raise errors.OpenError(
                'Error communicating to server at %s: %s' % (self.__uri,
                                                             err.args[1]))
        if passed:
            return _thawReturn(self.__methodApi, rv, methodVersion)
        else:
            raise apiutils.thaw(rv[0], rv[1:])

class XMLApiServer:
    """ API-aware server wrapper for XMLRPC. """

    # if set to True, will try to send exceptions to a debug prompt on 
    # the console before returning them across the wire
    debug = False

    def __init__(self, uri=None, logRequests=True):
        """ @param serverObj: The XMLRPCServer that will serve data to 
            the _dispatch method.  If None, caller is responsible for 
            giving information to be dispatched.
        """
        self.uri = uri
        if uri:
            if isinstance(uri, str):
                import urllib
                type, url = urllib.splittype(uri)
                if type == 'unix':
                    serverObj = auth.AuthAwareUnixDomainXMLRPCServer(url, logRequests=logRequests)
                elif type == 'http':
                    # path is ignored with simple server.
                    host, path = urllib.splithost(url)
                    if ':' in host:
                        host, port = urllib.splitport(host)
                        port = int(port)
                    else:
                        port = 80<commit_msg>errors have all their data in a list in the second element of the return value - rv[1], not rv[1:]<commit_after>#
# Copyright (c) 2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
"""
Along with apiutils, implements an API-validating and versioning scheme for 
xmlrpc calls.

The ApiProxy is instantiated with a reference to the class of the server it is 
communicating with, and uses that information to determine the expected format 
of the parameters to the class.  It freezes classes appropriately, and then
calls the server.

The ApiProxy also passes in as its first parameter a list of information.
that includes the ApiProxy version, and the version information about the 
server and the method.

The XMLApiServer is a wrapper around an XMLRPC server that manages the 
information passed in by an API Proxy.  It also validated and transforms the 
method parameters

A server class's public interface should be decorated with decorators
from apiutils that describe how to convert its parameters.

Server methods also will be passed in callData that includes the
calling version of the method.
"""
import itertools
import select
import socket
import sys
import time
import traceback
import xmlrpclib

from conary.lib import log
from conary.lib import coveragehook

from rmake import errors
from rmake.lib import apiutils
from rmake.lib import localrpc
from rmake.lib import auth
from rmake.lib.apiutils import api, api_parameters, api_return

# This version describes the current iteration of the API protocol.
_API_VERSION = 1


class ApiProxy(localrpc.ServerProxy):

    def __init__(self, apiClass, uri):
        self.apiClass = apiClass
        self.clientVersion = self.apiClass._CLASS_API_VERSION
        self.uri = uri
        localrpc.ServerProxy.__init__(self, uri)

    def __repr__(self):
        return "<ApiProxy>"

    def __str__(self):
        return "<ApiProxy>"

    def __getattr__(self, name):
        """ Get a proxy for an individual method.  """
        try:
            methodApi = getattr(self.apiClass, name)
        except AttributeError:
            raise ApiError, 'cannot find method %s in api' % name

        return _ApiMethod(self._ServerProxy__request, name, self.uri,
                          _API_VERSION, self.clientVersion, methodApi)

class _ApiMethod(xmlrpclib._Method):
    """ Api-aware method proxy for xmlrpc.  """

    def __init__(self, request, name, uri, metaApiVersion, clientVersion, 
                 methodApi): 
        """
            @param metaApiVersion: version of apirpc data.
            @param clientVersion: client's version the whole server API
            @param methodApi: client's description of this method's API
        """
        xmlrpclib._Method.__init__(self, request, name)
        self.__metaApiVersion = metaApiVersion
        self.__clientVersion = clientVersion
        self.__methodApi = methodApi
        self.__uri = uri

    def __call__(self, *args):
        """ 
            Calls the remote method with args.  Passes in extra first tuple
            of API callData.
        """
        methodVersion = self.__methodApi.version

        args = list(_freezeParams(self.__methodApi, args, methodVersion))
        callData = (self.__metaApiVersion, self.__clientVersion, methodVersion)

        try:
            passed, rv = xmlrpclib._Method.__call__(self, callData, *args)
        except socket.error, err:
            raise errors.OpenError(
                'Error communicating to server at %s: %s' % (self.__uri,
                                                             err.args[1]))
        if passed:
            return _thawReturn(self.__methodApi, rv, methodVersion)
        else:
            raise apiutils.thaw(rv[0], rv[1])

class XMLApiServer:
    """ API-aware server wrapper for XMLRPC. """

    # if set to True, will try to send exceptions to a debug prompt on 
    # the console before returning them across the wire
    debug = False

    def __init__(self, uri=None, logRequests=True):
        """ @param serverObj: The XMLRPCServer that will serve data to 
            the _dispatch method.  If None, caller is responsible for 
            giving information to be dispatched.
        """
        self.uri = uri
        if uri:
            if isinstance(uri, str):
                import urllib
                type, url = urllib.splittype(uri)
                if type == 'unix':
                    serverObj = auth.AuthAwareUnixDomainXMLRPCServer(url, logRequests=logRequests)
                elif type == 'http':
                    # path is ignored with simple server.
                    host, path = urllib.splithost(url)
                    if ':' in host:
                        host, port = urllib.splitport(host)
                        port = int(port)
                    else:
                        port = 80
{'fraction_non_alphanumeric': 0.0658366345972458, 'fraction_numerical': 0.002452367477834371, 'mean_word_length': 2.4391826143366853, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2805769', 'n_tokens_mistral': 2755, 'n_tokens_neox': 2666, 'n_words': 1107}