<commit_before>import pprint
import types
import yaml
import logging
from bravado_core.spec import Spec
from klue.swagger.server import spawn_server_api
from klue.swagger.client import generate_client_callers
from klue.swagger.spec import ApiSpec
from klue.exceptions import KlueException
from klue.utils import get_function

log = logging.getLogger(__name__)


class APIClient():
    """Object gathering the API's client side code.
    Offers client-side methods to call every server endpoint declared in the API.
    """
    pass


class APIModels():
    """Object mapping constructors of API models to their names"""
    pass


def generate_model_instantiator(model_name, definitions):
    # We need this to localize the value of model_class
    def instantiate_model(*args, **kwargs):
        return definitions.get(model_name)(*args, **kwargs)
    return instantiate_model


def default_error_callback(e):
    """The default callback for handling exceptions caught in the client and server stubs:
    just raise the exception."""
    raise e


class API():
    """Describes a REST client/server API, with sugar coating:
    - easily instantiating the objects defined in the API
    - auto-generation of client code

    usage: See apipool.py
    """

    # The API's swagger representation
    api_spec = None

    # Object holding the client side code to call the API
    client = APIClient()

    # Object holding constructors for the API's objects
    model = APIModels()

    # Default timeout when calling server endpoint, in sec
    client_timeout = 10

    # Callback to handle exceptions
    error_callback = default_error_callback

    # Flag: true if this api has spawned_api
    is_server = False

    # The api's name
    name = None

    def __init__(self, name, yaml_str=None, yaml_path=None, timeout=None, error_callback=None, formats=None):
        """An API Specification"""

        self.name = name

        if yaml_path:
            log.info("Loading swagger file at %s" % yaml_path)
            swagger_dict = yaml.load(open(yaml_path))
        elif yaml_str:
            swagger_dict = yaml.load(yaml_str)
        else:
            raise Exception("No swagger file specified")

        self.api_spec = ApiSpec(swagger_dict, formats)

        if timeout:
            self.client_timeout = timeout

        if error_callback:
            self.error_callback = error_callback

        # Auto-generate class methods for every object model defined
        # in the swagger spec, calling that model's constructor
        # Ex:
        #     klue_api.Version(version='1.2.3')   => return a Version object
        for model_name in self.api_spec.definitions:
            model_generator = generate_model_instantiator(model_name, self.api_spec.definitions)

            # Associate model generator to ApiPool().<api_name>.model.<model_name>
            setattr(self.model, model_name, model_generator)

            # Make this bravado-core model persistent?
            spec = swagger_dict['definitions'][model_name]
            if 'x-persist' in spec:
                self._make_persistent(model_name, spec['x-persist'])


        # Auto-generate client callers
        # so we can write
        # api.call.login(param)  => call /v1/login/ on server with param as json parameter
        callers_dict = generate_client_callers(self.api_spec, self.client_timeout, self.error_callback)
        for method, caller in callers_dict.items():
            setattr(self.client, method, caller)


    #
    # WARNING: ugly piece of monkey-patching below. Hopefully will replace
    # with native bravado-core code in the future...
    #
    def _make_persistent(self, model_name, pkg_name):
        """Monkey-patch object persistence (ex: to/from database) into a
        bravado-core model class"""
<commit_msg>Add do_persist optional argument to API constructor<commit_after>import pprint
import types
import yaml
import logging
from bravado_core.spec import Spec
from klue.swagger.server import spawn_server_api
from klue.swagger.client import generate_client_callers
from klue.swagger.spec import ApiSpec
from klue.exceptions import KlueException
from klue.utils import get_function

log = logging.getLogger(__name__)


class APIClient():
    """Object gathering the API's client side code.
    Offers client-side methods to call every server endpoint declared in the API.
    """
    pass


class APIModels():
    """Object mapping constructors of API models to their names"""
    pass


def generate_model_instantiator(model_name, definitions):
    # We need this to localize the value of model_class
    def instantiate_model(*args, **kwargs):
        return definitions.get(model_name)(*args, **kwargs)
    return instantiate_model


def default_error_callback(e):
    """The default callback for handling exceptions caught in the client and server stubs:
    just raise the exception."""
    raise e


class API():
    """Describes a REST client/server API, with sugar coating:
    - easily instantiating the objects defined in the API
    - auto-generation of client code

    usage: See apipool.py
    """

    # The API's swagger representation
    api_spec = None

    # Object holding the client side code to call the API
    client = APIClient()

    # Object holding constructors for the API's objects
    model = APIModels()

    # Default timeout when calling server endpoint, in sec
    client_timeout = 10

    # Callback to handle exceptions
    error_callback = default_error_callback

    # Flag: true if this api has spawned_api
    is_server = False

    # The api's name
    name = None

    def __init__(self, name, yaml_str=None, yaml_path=None, timeout=None, error_callback=None, formats=None, do_persist=True):
        """An API Specification"""

        self.name = name

        if yaml_path:
            log.info("Loading swagger file at %s" % yaml_path)
            swagger_dict = yaml.load(open(yaml_path))
        elif yaml_str:
            swagger_dict = yaml.load(yaml_str)
        else:
            raise Exception("No swagger file specified")

        self.api_spec = ApiSpec(swagger_dict, formats)

        if timeout:
            self.client_timeout = timeout

        if error_callback:
            self.error_callback = error_callback

        # Auto-generate class methods for every object model defined
        # in the swagger spec, calling that model's constructor
        # Ex:
        #     klue_api.Version(version='1.2.3')   => return a Version object
        for model_name in self.api_spec.definitions:
            model_generator = generate_model_instantiator(model_name, self.api_spec.definitions)

            # Associate model generator to ApiPool().<api_name>.model.<model_name>
            setattr(self.model, model_name, model_generator)

            # Make this bravado-core model persistent?
            if do_persist:
                spec = swagger_dict['definitions'][model_name]
                if 'x-persist' in spec:
                    self._make_persistent(model_name, spec['x-persist'])

        # Auto-generate client callers
        # so we can write
        # api.call.login(param)  => call /v1/login/ on server with param as json parameter
        callers_dict = generate_client_callers(self.api_spec, self.client_timeout, self.error_callback)
        for method, caller in callers_dict.items():
            setattr(self.client, method, caller)


    #
    # WARNING: ugly piece of monkey-patching below. Hopefully will replace
    # with native bravado-core code in the future...
    #
    def _make_persistent(self, model_name, pkg_name):
        """Monkey-patch object persistence (ex: to/from database) into a
        bravado-core model class"""

{'fraction_non_alphanumeric': 0.07564981249191775, 'fraction_numerical': 0.001551791025475236, 'mean_word_length': 2.8805820371299546, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3470613', 'n_tokens_mistral': 2196, 'n_tokens_neox': 2102, 'n_words': 699}