def request(self, method, url, params=None, body=None, **kwargs):
url = "<STR_LIT>".format(base_url=self.config.base_url,<EOL>version=self.API_VERSION,<EOL>resource=url)<EOL>headers = {<EOL>'<STR_LIT>': '<STR_LIT:application/json>',<EOL>'<STR_LIT>': "<STR_LIT>".format(self.config.access_token),<EOL>'<STR_LIT>': self.config.user_agent,<EOL>}<EOL>user_headers = {}<EOL>if  '<STR_LIT>' in kwargs and isinstance(kwargs['<STR_LIT>'], dict):<EOL><INDENT>user_headers = kwargs['<STR_LIT>']<EOL><DEDENT>headers.update(user_headers)<EOL>raw = bool(kwargs['<STR_LIT>']) if '<STR_LIT>' in kwargs else False<EOL>if body is not None:<EOL><INDENT>headers['<STR_LIT:Content-Type>'] = '<STR_LIT:application/json>'<EOL>payload = body if raw else self.wrap_envelope(body)<EOL>body = json.dumps(self.wrap_envelope(body), cls=DecimalEncoder)<EOL><DEDENT>resp = requests.request(method, url,<EOL>params=params,<EOL>data=body,<EOL>headers=headers,<EOL>timeout=float(self.config.timeout),<EOL>verify=self.config.verify_ssl)<EOL>if not (<NUM_LIT:200> <= resp.status_code < <NUM_LIT>):<EOL><INDENT>self.handle_error_response(resp)<EOL><DEDENT>if '<STR_LIT:Content-Type>' in resp.headers and '<STR_LIT>' in resp.headers['<STR_LIT:Content-Type>']:<EOL><INDENT>resp_body = munchify(resp.json()) if raw else self.unwrap_envelope(resp.json())<EOL><DEDENT>else:<EOL><INDENT>resp_body = resp.content<EOL><DEDENT>return (resp.status_code, resp.headers, resp_body)<EOL>
Send an HTTP request.

The :param:`params` will be properly encoded, as well as :param:`body` which
will be wrapped with envelope the API expects and json encoded.

When you get a reponse the method will try to json decode the response,
if the media type represents json, unwrap the envelope and munchify what has left,
for JavaScript like access.

:param str url: Sub URL for the request. You MUST not specify neither base url nor api version prefix.
:param dict params: (optional) Dictionary of query parameters.
:param dict body: (optional) Dictionary of body attributes that will be wrapped with envelope and json encoded.
:param dict **kwargs: (optional) Other parameters which are directly passed to :func:`requests.request`.
:raises RequestError: if authentication failed, invalid query parameter etc.
:raises RateLimitError: if rate limit exceeded.
:raises ResourceError: if requests payload included invalid attributes or were missing.
:raises ServerError: if Base CRM backend servers encounterered an unexpected condition.
:return: Tuple of three elements: (http status code, headers, response - either parsed json or plain text)
:rtype: tuple

:Keyword Arguments:
    * :param dict headers: (optional) Dictionary of headers. Default: ``{}``.
    * :param bool raw: (optional) Whether to wrap and uwrap the envelope. Default: ``False``.