<commit_before># -*- coding: utf-8 -*-
import logging
import os
from lemonway.exceptions import LemonwayError
from lemonway.utils import pythonize, pretty_xml
from suds.client import Client
from time import strftime
from lxml import objectify


logger = logging.getLogger('lemonway')


class ComplexType(object):
    def __init__(self, args):
        self.__dict__.update(args)
        del self.self

    def __str__(self):
        return str({k: v for k, v in self.__dict__.items()
                    if not k.startswith('_')})

    @property
    def soap_dict(self):
        return {v: getattr(self, k) for k, v in self._tr_params.items()}


class Lemonway(object):
    WSDL_URL = ('file://' + os.path.dirname(os.path.realpath(__file__))
                + '/lemonway.wsdl')

    def __init__(self, login, password, location):
        self.wl_login = login
        self.wl_pass = password
        self.language = 'en'
        self._location = location
        self._client = Client(self.WSDL_URL, cachingpolicy=1,
                              username=self.wl_login, password=self.wl_pass)
        self._client.options.cache.setduration(days=90)

    def ws_request(self, method, api_name, **params):
        self._client.set_options(location=self._location)
        log_params = params.copy()
        # Do not log file data
        if 'buffer' in log_params and log_params['buffer']:
            log_params['buffer'] = 'buffer of %dko' % (len(params['buffer'])/1024)
        # Do not log card data (but log 'masked' data)
        if 'cardNumber' in log_params and log_params['cardNumber']:
            log_params['cardNumber'] = (log_params['cardNumber'][:6] + 'X' * 6
                                        + log_params['cardNumber'][-4:])
        if 'cardCrypto' in log_params and log_params['cardCrypto']:
            log_params['cardCrypto'] = 'X' * len(log_params['cardCrypto'])
        if 'cardCode' in log_params and log_params['cardCode']:
            log_params['cardCode'] = 'X' * len(log_params['cardCode'])
        info_msg = 'Calling %s method with params: %s' % (method, log_params)
        logger.info(info_msg)
        try:
            xml = getattr(self._client.service, method)(**params)
            answer = objectify.fromstring(xml)
            answer = pythonize(answer)
            answer.xml = pretty_xml(unicode(xml))
            logger.debug(xml)
        except Exception as e:
            msg = '%s %s - %s' % (e, e.message, info_msg)
            logger.error(msg)
            raise LemonwayError(msg)
        # Detect errors and raise exception
        if 'error' in answer.__dict__:
            msg = '%s (code: %s) - %s' % (answer.msg, answer.code, info_msg)
            logger.error(msg)
            raise LemonwayError(msg, answer.code, answer.msg)
        return answer

    def soap_dict(self, complex_type):
        return complex_type.soap_dict if complex_type else None
<commit_msg>fix error when card_data is not present in clean log<commit_after># -*- coding: utf-8 -*-
import logging
import os
from lemonway.exceptions import LemonwayError
from lemonway.utils import pythonize, pretty_xml
from suds.client import Client
from time import strftime
from lxml import objectify


logger = logging.getLogger('lemonway')


class ComplexType(object):
    def __init__(self, args):
        self.__dict__.update(args)
        del self.self

    def __str__(self):
        return str({k: v for k, v in self.__dict__.items()
                    if not k.startswith('_')})

    @property
    def soap_dict(self):
        return {v: getattr(self, k) for k, v in self._tr_params.items()}


class Lemonway(object):
    WSDL_URL = ('file://' + os.path.dirname(os.path.realpath(__file__))
                + '/lemonway.wsdl')

    def __init__(self, login, password, location):
        self.wl_login = login
        self.wl_pass = password
        self.language = 'en'
        self._location = location
        self._client = Client(self.WSDL_URL, cachingpolicy=1,
                              username=self.wl_login, password=self.wl_pass)
        self._client.options.cache.setduration(days=90)

    def ws_request(self, method, api_name, **params):
        self._client.set_options(location=self._location)
        log_params = params.copy()
        # Do not log file data
        if 'buffer' in log_params:
            log_params['buffer'] = 'buffer of %dko' % (len(params['buffer'])/1024)
        # Do not log card data (but log 'masked' data)
        if 'cardNumber' in log_params:
            log_params['cardNumber'] = (log_params['cardNumber'][:6] + 'X' * 6
                                        + log_params['cardNumber'][-4:])
        if 'cardCrypto' in log_params:
            log_params['cardCrypto'] = 'X' * len(log_params['cardCrypto'])
        if 'cardCode' in log_params:
            log_params['cardCode'] = 'X' * len(log_params['cardCode'])
        info_msg = 'Calling %s method with params: %s' % (method, log_params)
        logger.info(info_msg)
        try:
            xml = getattr(self._client.service, method)(**params)
            answer = objectify.fromstring(xml)
            answer = pythonize(answer)
            answer.xml = pretty_xml(unicode(xml))
            logger.debug(xml)
        except Exception as e:
            msg = '%s %s - %s' % (e, e.message, info_msg)
            logger.error(msg)
            raise LemonwayError(msg)
        # Detect errors and raise exception
        if 'error' in answer.__dict__:
            msg = '%s (code: %s) - %s' % (answer.msg, answer.code, info_msg)
            logger.error(msg)
            raise LemonwayError(msg, answer.code, answer.msg)
        return answer

    def soap_dict(self, complex_type):
        return complex_type.soap_dict if complex_type else None

{'fraction_non_alphanumeric': 0.11774891774891776, 'fraction_numerical': 0.0038095238095238095, 'mean_word_length': 2.3856975381008207, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 16}, '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': '2796953', 'n_tokens_mistral': 1764, 'n_tokens_neox': 1713, 'n_words': 437}