<commit_before>import json
import logging
from random import Random
import requests
import time

logger = logging.getLogger('qai_helper')


class Session(requests.Session):
    def login(self, qai_path, qai_user, password):
        """ Login to QAI before calling post_json or get_json.

        @raise RuntimeError: when the QAI server rejects the user and password.
        """
        self.qai_path = qai_path

        try:
            response = self.post(qai_path + "/account/login",
                                data={'user_login': qai_user,
                                    'user_password': password})
        except Exception as e:
            # from None is added to reduce logging overhead
            # original traceback is quite long and stems from the login issue
            raise ConnectionError('Could not log in to QAI') from None
        if response.status_code == requests.codes.forbidden:  # @UndefinedVariable
            raise RuntimeError("Login failed for QAI user '{}'.".format(qai_user))

    def _retry_json(self, method, path, data=None, retries=3):
        json_data = data and json.dumps(data)
        headers = {'Accept': 'application/json'}
        if json_data:
            headers['Content-Type'] = 'application/json'
        retries_remaining = retries
        average_delay = 20
        while True:
            try:
                response = method(
                    self.qai_path + path,
                    data=json_data,
                    headers=headers)
                response.raise_for_status()
                return response.json()
            except Exception:
                if retries_remaining <= 0:
                    logger.error('JSON request failed for %s',
                                 path,
                                 exc_info=True)
                    raise

                # ten minutes with some noise
                sleep_seconds = average_delay + Random().uniform(-10, 10)
                logger.warn(
                    'JSON request failed. Sleeping for %ss before retry.',
                    sleep_seconds,
                    exc_info=True)
                time.sleep(sleep_seconds)
                retries_remaining -= 1
                average_delay += 600

    def post_json(self, path, data, retries=3):
        """ Post a JSON object to the web server, and return a JSON object.

        @param path the relative path to add to the qai_path used in login()
        @param data a JSON object that will be converted to a JSON string
        @param retries: the number of times to retry the request before failing.
        @return the response body, parsed as a JSON object
        """
        return self._retry_json(self.post, path, data, retries)

    def get_json(self, path, retries=3):
        """ Get a JSON object from the web server.

        @param session an open HTTP session
        @param path the relative path to add to QAI server path
        @param retries: the number of times to retry the request before failing.
        @return the response body, parsed as a JSON object
        """
        return self._retry_json(self.get, path, retries=retries)
<commit_msg>Changed caught Exception to RequestException<commit_after>import json
import logging
from random import Random
import requests
import time

logger = logging.getLogger('qai_helper')


class Session(requests.Session):
    def login(self, qai_path, qai_user, password):
        """ Login to QAI before calling post_json or get_json.

        @raise RuntimeError: when the QAI server rejects the user and password.
        """
        self.qai_path = qai_path

        try:
            response = self.post(qai_path + "/account/login",
                                data={'user_login': qai_user,
                                    'user_password': password})
        except requests.exceptions.RequestException as e:
            # from None is added to reduce logging overhead
            # original traceback is quite long and stems from the login issue
            raise ConnectionError('Could not log in to QAI') from None
        if response.status_code == requests.codes.forbidden:  # @UndefinedVariable
            raise RuntimeError("Login failed for QAI user '{}'.".format(qai_user))

    def _retry_json(self, method, path, data=None, retries=3):
        json_data = data and json.dumps(data)
        headers = {'Accept': 'application/json'}
        if json_data:
            headers['Content-Type'] = 'application/json'
        retries_remaining = retries
        average_delay = 20
        while True:
            try:
                response = method(
                    self.qai_path + path,
                    data=json_data,
                    headers=headers)
                response.raise_for_status()
                return response.json()
            except Exception:
                if retries_remaining <= 0:
                    logger.error('JSON request failed for %s',
                                 path,
                                 exc_info=True)
                    raise

                # ten minutes with some noise
                sleep_seconds = average_delay + Random().uniform(-10, 10)
                logger.warn(
                    'JSON request failed. Sleeping for %ss before retry.',
                    sleep_seconds,
                    exc_info=True)
                time.sleep(sleep_seconds)
                retries_remaining -= 1
                average_delay += 600

    def post_json(self, path, data, retries=3):
        """ Post a JSON object to the web server, and return a JSON object.

        @param path the relative path to add to the qai_path used in login()
        @param data a JSON object that will be converted to a JSON string
        @param retries: the number of times to retry the request before failing.
        @return the response body, parsed as a JSON object
        """
        return self._retry_json(self.post, path, data, retries)

    def get_json(self, path, retries=3):
        """ Get a JSON object from the web server.

        @param session an open HTTP session
        @param path the relative path to add to QAI server path
        @param retries: the number of times to retry the request before failing.
        @return the response body, parsed as a JSON object
        """
        return self._retry_json(self.get, path, retries=retries)

{'fraction_non_alphanumeric': 0.07171811661989398, 'fraction_numerical': 0.004365450576863112, 'mean_word_length': 1.7927731824118416, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4368073', 'n_tokens_mistral': 1634, 'n_tokens_neox': 1559, 'n_words': 580}