docs: def request(self, url, method, body="", headers={}, retry=True):
          """Execute an HTTP request and return a dict containing the response
          and the response status code.
  
          Keyword arguments:
          url -- The path to execute the result against, not including the API
                 version or project ID, with no leading /. Required.
          method -- The HTTP method to use. Required.
          body -- A string or file object to send as the body of the request.
                  Defaults to an empty string.
          headers -- HTTP Headers to send with the request. Can overwrite the
                     defaults. Defaults to {}.
          retry -- Whether exponential backoff should be employed. Defaults
                   to True.
          """
          if headers:
              headers = dict(list(headers.items()) + list(self.headers.items()))
          else:
              headers = self.headers
  
          if not sys.version_info >= (3,) and headers:
              headers = dict((k.encode('ascii') if isinstance(k, unicode) else k,
                              v.encode('ascii') if isinstance(v, unicode) else v)
                             for k, v in headers.items())
  
          url = self.base_url + url
          if not sys.version_info >= (3,):
              if isinstance(url, unicode):
                  url = url.encode('ascii')
  
          r = self._doRequest(url, method, body, headers)
  
          retry_http_codes = [503, 504]
          if r.status_code in retry_http_codes and retry:
              tries = 5
              delay = .5
              backoff = 2
              while r.status_code in retry_http_codes and tries > 0:
                  tries -= 1
                  time.sleep(delay)
                  delay *= backoff
                  r = self._doRequest(url, method, body, headers)
  
          r.raise_for_status()
  
          result = {}
          contentType = r.headers["Content-Type"]
          if contentType is None:
              contentType = "text/plain"
          else:
              contentType = contentType.split(";")[0]
          if contentType.lower() == "application/json":
              try:
                  result["body"] = json.loads(r.text)
              except:
                  result["body"] = r.text
          else:
              result["body"] = r.text
          result["status"] = r.status_code
          result["resp"] = r
          result["content-type"] = contentType
          return result