Internal handling of requests. Handles Exceptions.

        :param request_obj: a requests session.
        :param str url: url to send request to
        :param str method: type of request (get/put/post/patch/delete)
        :param kwargs: extra params to send to the request api
        :return: Response of the request
        :rtype: requests.Response

def _internal_request(self, request_obj, url, method, **kwargs):
        """ Internal handling of requests. Handles Exceptions.

        :param request_obj: a requests session.
        :param str url: url to send request to
        :param str method: type of request (get/put/post/patch/delete)
        :param kwargs: extra params to send to the request api
        :return: Response of the request
        :rtype: requests.Response
        """

        method = method.lower()
        if method not in self._allowed_methods:
            raise ValueError('Method must be one of the allowed ones')
        if method == 'get':
            kwargs.setdefault('allow_redirects', True)
        elif method in ['post', 'put', 'patch']:
            if 'headers' not in kwargs:
                kwargs['headers'] = {}
            if kwargs.get('headers') is not None and kwargs['headers'].get(
                    'Content-type') is None:
                kwargs['headers']['Content-type'] = 'application/json'
            if 'data' in kwargs and kwargs['data'] is not None and kwargs['headers'].get(
                    'Content-type') == 'application/json':
                kwargs['data'] = json.dumps(kwargs['data'])  # convert to json

        request_done = False
        token_refreshed = False

        while not request_done:
            self._check_delay()  # sleeps if needed
            try:
                log.info('Requesting ({}) URL: {}'.format(method.upper(), url))
                log.info('Request parameters: {}'.format(kwargs))
                # auto_retry will occur inside this function call if enabled
                response = request_obj.request(method, url,
                                               **kwargs)
                response.raise_for_status()  # raise 4XX and 5XX error codes.
                log.info('Received response ({}) from URL {}'.format(
                    response.status_code, response.url))
                request_done = True
                return response
            except TokenExpiredError as e:
                # Token has expired, try to refresh the token and try again on the next loop
                if not self.token_backend.token.is_long_lived:
                    raise e
                if token_refreshed:
                    # Refresh token done but still TokenExpiredError raise
                    raise RuntimeError('Token Refresh Operation not working')
                log.info('Oauth Token is expired, fetching a new token')
                self.refresh_token()
                log.info('New oauth token fetched')
                token_refreshed = True
            except (ConnectionError, ProxyError, SSLError, Timeout) as e:
                # We couldn't connect to the target url, raise error
                log.debug('Connection Error calling: {}.{}'
                          ''.format(url, ('Using proxy: {}'.format(self.proxy)
                                          if self.proxy else '')))
                raise e  # re-raise exception
            except HTTPError as e:
                # Server response with 4XX or 5XX error status codes

                # try to extract the error message:
                try:
                    error = response.json()
                    error_message = error.get('error', {}).get('message', '')
                except ValueError:
                    error_message = ''

                status_code = int(e.response.status_code / 100)
                if status_code == 4:
                    # Client Error
                    # Logged as error. Could be a library error or Api changes
                    log.error('Client Error: {} | Error Message: {}'.format(str(e), error_message))
                else:
                    # Server Error
                    log.debug('Server Error: {}'.format(str(e)))
                if self.raise_http_errors:
                    if error_message:
                        raise HTTPError('{} | Error Message: {}'.format(e.args[0], error_message), response=response) from None
                    else:
                        raise e
                else:
                    return e.response
            except RequestException as e:
                # catch any other exception raised by requests
                log.debug('Request Exception: {}'.format(str(e)))
                raise e