<commit_before>import logging

import requests

logger = logging.getLogger(__name__)


class RESTApiJWTClient:
    """
    REST Client Base Class With JWT enabled authentication

    Can be either extended through inheritance or created using the params `service_base` and `login_url`

    :param service_base: the base url
    :param login_url: the relative path to the login url
    """

    service_base = 'http://localhost/api/'
    login_url = '/jwt-auth/'

    def __init__(self, service_base=None, login_url=None):
        if service_base:
            self.service_base = service_base
        if login_url:
            self.login_url = login_url
        self.headers = {
            'Content-Type': 'application/json; charset=UTF-8',
        }
        self.client = requests.session()
        self.token = None

    def get(self, url, params=None, **kwargs):
        response = requests.get(self._to_fully_qualified_url(url), params=params, **self._data_dict(**kwargs))
        response.raise_for_status()
        return response

    def post(self, url, json_data=None, **kwargs):
        response = requests.post(self._to_fully_qualified_url(url), json=json_data, **self._data_dict(**kwargs))
        response.raise_for_status()
        return response

    def auth(self, username, password):
        login_url = self._to_fully_qualified_url(self.login_url)
        login_data = dict(username=username, password=password, next=self.service_base)
        response = self.post(login_url, json_data=login_data, headers=dict(Referer=login_url))
        self.token = response.json().get('token')
        return response

    def authorized_get(self, url, params=None, **kwargs):
        self._make_request_authorized()
        return self.get(url, params, **kwargs)

    def authorized_post(self, url, json_data=None, **kwargs):
        self._make_request_authorized()
        return self.post(url, json_data, **kwargs)

    def _data_dict(self, **kwargs):
        headers = self.headers.copy()
        if 'headers' in kwargs:
            headers.update(kwargs.pop('headers'))
        return dict(headers=headers, **kwargs)

    def _is_colliding_slashes(self, url):
        return self.service_base.endswith('/') and url.startswith('/')

    def _to_fully_qualified_url(self, url):
        if url.startswith('http'):
            return url
        base_url = self.service_base[:-1] if (self._is_colliding_slashes(url)) else self.service_base
        return base_url + url

    def _make_request_authorized(self):
        if not self.token:
            raise Exception('Unauthorized request. Assure you call `auth()` before making a request.')
        # TODO: comply to jwt and check if key is valid, if it needs reinitialization etc
        self.headers['Authorization'] = 'JWT {token}'.format(token=self.token)


def reasons_for(http_error):
    return http_error.response.json()
<commit_msg>remove duplication in REST API client HTTP verb methods<commit_after>import logging

import requests

logger = logging.getLogger(__name__)


class RESTApiJWTClient:
    """
    REST Client Base Class With JWT enabled authentication

    Can be either extended through inheritance or created using the params `service_base` and `login_url`

    :param service_base: the base url
    :param login_url: the relative path to the login url
    """

    service_base = 'http://localhost/api/'
    login_url = '/jwt-auth/'

    def __init__(self, service_base=None, login_url=None):
        if service_base:
            self.service_base = service_base
        if login_url:
            self.login_url = login_url
        self.headers = {
            'Content-Type': 'application/json; charset=UTF-8',
        }
        self.client = requests.session()
        self.token = None

    def get(self, url, params=None, **kwargs):
        return self._request(requests.get, url, dict(params=params), kwargs)

    def post(self, url, json_data=None, **kwargs):
        return self._request(requests.post, url, dict(json=json_data), kwargs)

    def _request(self, method, url, payload, kwargs):
        kwargs = self._data_dict(**kwargs)
        kwargs.update(payload)
        response = method(self._to_fully_qualified_url(url), **kwargs)
        response.raise_for_status()
        return response

    def auth(self, username, password):
        login_url = self._to_fully_qualified_url(self.login_url)
        login_data = dict(username=username, password=password, next=self.service_base)
        response = self.post(login_url, json_data=login_data, headers=dict(Referer=login_url))
        self.token = response.json().get('token')
        return response

    def authorized_get(self, url, params=None, **kwargs):
        self._make_request_authorized()
        return self.get(url, params, **kwargs)

    def authorized_post(self, url, json_data=None, **kwargs):
        self._make_request_authorized()
        return self.post(url, json_data, **kwargs)

    def _data_dict(self, **kwargs):
        headers = self.headers.copy()
        if 'headers' in kwargs:
            headers.update(kwargs.pop('headers'))
        return dict(headers=headers, **kwargs)

    def _is_colliding_slashes(self, url):
        return self.service_base.endswith('/') and url.startswith('/')

    def _to_fully_qualified_url(self, url):
        if url.startswith('http'):
            return url
        base_url = self.service_base[:-1] if (self._is_colliding_slashes(url)) else self.service_base
        return base_url + url

    def _make_request_authorized(self):
        if not self.token:
            raise Exception('Unauthorized request. Assure you call `auth()` before making a request.')
        # TODO: comply to jwt and check if key is valid, if it needs reinitialization etc
        self.headers['Authorization'] = 'JWT {token}'.format(token=self.token)


def reasons_for(http_error):
    return http_error.response.json()

{'fraction_non_alphanumeric': 0.10791610284167795, 'fraction_numerical': 0.0006765899864682003, 'mean_word_length': 3.1263084438241453, 'pattern_counts': {'":': 0, '<': 3, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2623515', 'n_tokens_mistral': 1745, 'n_tokens_neox': 1696, 'n_words': 427}