docs: def request(self, method, path, query=None, content=None):
          """
          Sends an HTTP request.
  
          This constructs a full URL, encodes and decodes HTTP bodies, and
          handles invalid responses in a pythonic way.
  
          @type method: string
          @param method: HTTP method to use
          @type path: string
          @param path: HTTP URL path
          @type query: list of two-tuples
          @param query: query arguments to pass to urllib.urlencode
          @type content: str or None
          @param content: HTTP body content
  
          @rtype: object
          @return: JSON-Decoded response
  
          @raises GanetiApiError: If an invalid response is returned
          """
  
          if not path.startswith("/"):
              raise ClientError("Implementation error: Called with bad path %s"
                                % path)
  
          body = None
  
          if content is not None:
              data = self._json_encoder.encode(content)
              body = StringProducer(data)
  
          url = self._base_url + path
  
          if query:
              prepare_query(query)
              params = urlencode(query, doseq=True)
              url += "?%s" % params
  
          log.msg("Sending request to %s %s %s" % (url, self.headers, body),
                  system="Gentleman")
  
          d = self._agent.request(method, url, headers=self.headers,
                                  bodyProducer=body)
  
          protocol = JsonResponseProtocol(d)
  
          @d.addErrback
          def connectionFailed(failure):
              failure.trap(ConnectionRefusedError)
              raise GanetiApiError("Connection refused!")
  
          @d.addCallback
          def cb(response):
              if response.code != 200:
                  raise NotOkayError(code=response.code)
              response.deliverBody(protocol)
  
          return protocol.getData()