def request(self, method, path, headers=None, data=None, **kwargs):
full_path = self.url + path<EOL>request_headers = {}<EOL>request_headers.update(self.default_headers)<EOL>if headers:<EOL><INDENT>request_headers.update(headers)<EOL><DEDENT>jdata = None<EOL>if data:<EOL><INDENT>jdata = json.dumps(data)<EOL><DEDENT>if self.verbose:<EOL><INDENT>print("<STR_LIT>" % <EOL>(datetime.now().isoformat(), method, full_path), <EOL>file=self.verbose)<EOL><DEDENT>resp = requests.request(method, full_path, auth=self.auth, <EOL>headers=request_headers, data=jdata,<EOL>verify=self.verify, **kwargs)<EOL>if (resp.status_code == <NUM_LIT> and self.auth and <EOL>self.auth.signer._agent_key):<EOL><INDENT>self.auth.signer.swap_keys()<EOL>return self.request(method, path, headers=headers, data=data,<EOL>**kwargs)<EOL><DEDENT>if <NUM_LIT> <= resp.status_code < <NUM_LIT>:<EOL><INDENT>if resp.content:<EOL><INDENT>print(resp.content, file=sys.stderr)<EOL><DEDENT>resp.raise_for_status()<EOL><DEDENT>if resp.content:<EOL><INDENT>if resp.headers['<STR_LIT>'] == '<STR_LIT:application/json>':<EOL><INDENT>return (json.loads(resp.content), resp)<EOL><DEDENT>else:<EOL><INDENT>return (resp.content, resp)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return (None, resp)<EOL><DEDENT>
(Primarily) internal method for making all requests to the datacenter.

:param method: HTTP verb
:type method: :py:class:`str`

:param path: path relative to `login` path
:type path: :py:class:`str`

:param headers: additional headers to send
:type headers: :py:class:`dict`

:Returns: tuple of decoded response body & `Response` object
:raises: client (4xx) errors