def fetch(self, url, method='GET', headers=None, body=None):
    'Perform a HTTP request and return decoded JSON data'
    request_headers = self.prepare_request_headers(headers)
    url = (self.proxy + url)
    if self.verbose:
        print('\nRequest:', method, url, request_headers, body)
    self.logger.debug('%s %s, Request: %s %s', method, url, request_headers, body)
    if body:
        body = body.encode()
    self.session.cookies.clear()
    response = None
    http_response = None
    json_response = None
    try:
        response = self.session.request(method, url, data=body, headers=request_headers, timeout=int((self.timeout / 1000)), proxies=self.proxies)
        http_response = response.text
        json_response = (self.parse_json(http_response) if self.is_json_encoded_object(http_response) else None)
        headers = response.headers
        if self.enableLastHttpResponse:
            self.last_http_response = http_response
        if self.enableLastJsonResponse:
            self.last_json_response = json_response
        if self.enableLastResponseHeaders:
            self.last_response_headers = headers
        if self.verbose:
            print('\nResponse:', method, url, response.status_code, headers, http_response)
        self.logger.debug('%s %s, Response: %s %s %s', method, url, response.status_code, headers, http_response)
        response.raise_for_status()
    except Timeout as e:
        self.raise_error(RequestTimeout, method, url, e)
    except TooManyRedirects as e:
        self.raise_error(ExchangeError, url, method, e)
    except SSLError as e:
        self.raise_error(ExchangeError, url, method, e)
    except HTTPError as e:
        self.handle_errors(response.status_code, response.reason, url, method, headers, http_response, json_response)
        self.handle_rest_errors(e, response.status_code, http_response, url, method)
        self.raise_error(ExchangeError, url, method, e, http_response)
    except RequestException as e:
        error_string = str(e)
        if (('ECONNRESET' in error_string) or ('Connection aborted.' in error_string)):
            self.raise_error(NetworkError, url, method, e)
        else:
            self.raise_error(ExchangeError, url, method, e)
    self.handle_errors(response.status_code, response.reason, url, method, headers, http_response, json_response)
    self.handle_rest_response(http_response, json_response, url, method, headers, body)
    if (json_response is not None):
        return json_response
    return http_response
Perform a HTTP request and return decoded JSON data
def fetch(self, url, method='GET', headers=None, body=None):
    
    request_headers = self.prepare_request_headers(headers)
    url = (self.proxy + url)
    if self.verbose:
        print('\nRequest:', method, url, request_headers, body)
    self.logger.debug('%s %s, Request: %s %s', method, url, request_headers, body)
    if body:
        body = body.encode()
    self.session.cookies.clear()
    response = None
    http_response = None
    json_response = None
    try:
        response = self.session.request(method, url, data=body, headers=request_headers, timeout=int((self.timeout / 1000)), proxies=self.proxies)
        http_response = response.text
        json_response = (self.parse_json(http_response) if self.is_json_encoded_object(http_response) else None)
        headers = response.headers
        if self.enableLastHttpResponse:
            self.last_http_response = http_response
        if self.enableLastJsonResponse:
            self.last_json_response = json_response
        if self.enableLastResponseHeaders:
            self.last_response_headers = headers
        if self.verbose:
            print('\nResponse:', method, url, response.status_code, headers, http_response)
        self.logger.debug('%s %s, Response: %s %s %s', method, url, response.status_code, headers, http_response)
        response.raise_for_status()
    except Timeout as e:
        self.raise_error(RequestTimeout, method, url, e)
    except TooManyRedirects as e:
        self.raise_error(ExchangeError, url, method, e)
    except SSLError as e:
        self.raise_error(ExchangeError, url, method, e)
    except HTTPError as e:
        self.handle_errors(response.status_code, response.reason, url, method, headers, http_response, json_response)
        self.handle_rest_errors(e, response.status_code, http_response, url, method)
        self.raise_error(ExchangeError, url, method, e, http_response)
    except RequestException as e:
        error_string = str(e)
        if (('ECONNRESET' in error_string) or ('Connection aborted.' in error_string)):
            self.raise_error(NetworkError, url, method, e)
        else:
            self.raise_error(ExchangeError, url, method, e)
    self.handle_errors(response.status_code, response.reason, url, method, headers, http_response, json_response)
    self.handle_rest_response(http_response, json_response, url, method, headers, body)
    if (json_response is not None):
        return json_response
    return http_response