Esempio n. 1
0
 def _send_request(self):
     if not self.queue:
         if self.request_loop.running:
             self.request_loop.stop()
         return
     now = time.time() - 1  # 1 second buffer
     if (self.rate_remaining < 1+1 and self.rate_reset > now or 
             DiscordRestApiLoop.global_wait > now):
         self.log.warn("Rate limited: {}".format(self.channel_id))
         return
     payload = self.queue.pop()
     method = payload['method']
     url = payload['url']
     content = payload['content']
    # url = '{}/channels/{}/messages'.format(HOST, self.channel_id)
     content = json.dumps({"content": content})
     self.log.debug('at _send_request: {} url {}'.format(self.channel_id,
                                                         url))
     if method == 'post':
         d = treq.post(url, content, headers=HEADERS)
     elif method == 'patch':
         d = treq.patch(url, content, headers=HEADERS)
     elif method == 'delete':
         d = treq.delete(url, headers=HEADERS)
     elif method == 'get':
         d = treq.get(url, headers=HEADERS)
     d.addCallback(self.update_rate_limits)
     if not self.queue:
         self.request_loop.stop()
Esempio n. 2
0
    def request(self, method, uri, data=None, name=''):
        """
        Send a REST request to the Adtran device

        :param method: (string) HTTP method
        :param uri: (string) fully URL to perform method on
        :param data: (string) optional data for the request body
        :param name: (string) optional name of the request, useful for logging purposes
        :return: (deferred)
        """

        if method.upper() not in self._valid_methods:
            raise NotImplementedError(
                "REST method '{}' is not supported".format(method))

        url = 'http://{}:{}{}{}'.format(self.ip, self.rest_port,
                                        '/' if uri[0] != '/' else '', uri)
        try:
            if method.upper() == 'GET':
                response = yield treq.get(url,
                                          auth=(self.username, self.password),
                                          timeout=self.timeout,
                                          headers=self.REST_GET_REQUEST_HEADER)
            elif method.upper() == 'POST' or method.upper() == 'PUT':
                response = yield treq.post(
                    url,
                    data=data,
                    auth=(self.username, self.password),
                    timeout=self.timeout,
                    headers=self.REST_POST_REQUEST_HEADER)
            elif method.upper() == 'PATCH':
                response = yield treq.patch(
                    url,
                    data=data,
                    auth=(self.username, self.password),
                    timeout=self.timeout,
                    headers=self.REST_PATCH_REQUEST_HEADER)
            elif method.upper() == 'DELETE':
                response = yield treq.delete(
                    url,
                    auth=(self.username, self.password),
                    timeout=self.timeout,
                    headers=self.REST_DELETE_REQUEST_HEADER)
            else:
                raise NotImplementedError(
                    "REST method '{}' is not supported".format(method))

        except NotImplementedError:
            raise

        except ConnectionClosed:
            returnValue(None)

        except Exception, e:
            log.exception("REST {} '{}' request to '{}' failed: {}".format(
                method, name, url, str(e)))
            raise
Esempio n. 3
0
 def _patch(self, path, headers, data):
     # print("yapi patch called. path: %s... headers: %s... data: %s" % (path, headers, data))
     response = yield treq.patch(path,
                                 data=data,
                                 agent=self.custom_agent,
                                 headers=headers)
     content = yield treq.content(response)
     final_response = self.decode_results(content,
                                          self.response_headers(response),
                                          response.code, response.phrase)
     return final_response
Esempio n. 4
0
    def request(self,
                method,
                uri,
                data=None,
                name='',
                timeout=None,
                is_retry=False,
                suppress_error=False):
        """
        Send a REST request to the Adtran device

        :param method: (string) HTTP method
        :param uri: (string) fully URL to perform method on
        :param data: (string) optional data for the request body
        :param name: (string) optional name of the request, useful for logging purposes
        :param timeout: (int) Number of seconds to wait for a response before timing out
        :param is_retry: (boolean) True if this method called recursively in order to recover
                                   from a connection loss. Can happen sometimes in debug sessions
                                   and in the real world.
        :param suppress_error: (boolean) If true, do not output ERROR message on REST request failure
        :return: (dict) On success with the proper results
        """
        log.debug('request', method=method, uri=uri, data=data, retry=is_retry)

        if method.upper() not in self._valid_methods:
            raise NotImplementedError(
                "REST method '{}' is not supported".format(method))

        url = 'http://{}:{}{}{}'.format(self._ip, self._port,
                                        '/' if uri[0] != '/' else '', uri)
        response = None
        timeout = timeout or self._timeout

        try:
            if method.upper() == 'GET':
                response = yield treq.get(url,
                                          auth=(self._username,
                                                self._password),
                                          timeout=timeout,
                                          headers=self.REST_GET_REQUEST_HEADER)
            elif method.upper() == 'POST' or method.upper() == 'PUT':
                response = yield treq.post(
                    url,
                    data=data,
                    auth=(self._username, self._password),
                    timeout=timeout,
                    headers=self.REST_POST_REQUEST_HEADER)
            elif method.upper() == 'PATCH':
                response = yield treq.patch(
                    url,
                    data=data,
                    auth=(self._username, self._password),
                    timeout=timeout,
                    headers=self.REST_PATCH_REQUEST_HEADER)
            elif method.upper() == 'DELETE':
                response = yield treq.delete(
                    url,
                    auth=(self._username, self._password),
                    timeout=timeout,
                    headers=self.REST_DELETE_REQUEST_HEADER)
            else:
                raise NotImplementedError(
                    "REST method '{}' is not supported".format(method))

        except NotImplementedError:
            raise

        except (ConnectionDone, ConnectionLost) as e:
            if is_retry:
                raise
            returnValue(
                self.request(method,
                             uri,
                             data=data,
                             name=name,
                             timeout=timeout,
                             is_retry=True))

        except ConnectionClosed:
            returnValue(ConnectionClosed)

        except Exception as e:
            log.exception("rest-request",
                          method=method,
                          url=url,
                          name=name,
                          e=e)
            raise

        if response.code not in self._valid_results[method.upper()]:
            message = "REST {} '{}' request to '{}' failed with status code {}".format(
                method, name, url, response.code)
            if not suppress_error:
                log.error(message)
            raise RestInvalidResponseCode(message, url, response.code)

        if response.code == self.HTTP_NO_CONTENT:
            returnValue(None)

        else:
            # TODO: May want to support multiple body encodings in the future

            headers = response.headers
            type_key = 'content-type'
            type_val = 'application/json'

            if not headers.hasHeader(
                    type_key) or type_val not in headers.getRawHeaders(
                        type_key, []):
                raise Exception(
                    "REST {} '{}' request response from '{}' was not JSON",
                    method, name, url)

            content = yield response.content()
            try:
                result = json.loads(content)

            except Exception as e:
                log.exception("json-decode",
                              method=method,
                              url=url,
                              name=name,
                              content=content,
                              e=e)
                raise

            returnValue(result)
Esempio n. 5
0
    def request(self, method, uri, data=None, name='', timeout=None, is_retry=False,
                suppress_error=False):
        """
        Send a REST request to the Adtran device

        :param method: (string) HTTP method
        :param uri: (string) fully URL to perform method on
        :param data: (string) optional data for the request body
        :param name: (string) optional name of the request, useful for logging purposes
        :param timeout: (int) Number of seconds to wait for a response before timing out
        :param is_retry: (boolean) True if this method called recursively in order to recover
                                   from a connection loss. Can happen sometimes in debug sessions
                                   and in the real world.
        :return: (dict) On success with the proper results
        """
        log.debug('request', method=method, uri=uri, data=data, retry=is_retry)

        if method.upper() not in self._valid_methods:
            raise NotImplementedError("REST method '{}' is not supported".format(method))

        url = 'http://{}:{}{}{}'.format(self._ip, self._port,
                                        '/' if uri[0] != '/' else '',
                                        uri)
        response = None
        timeout = timeout or self._timeout

        try:
            if method.upper() == 'GET':
                response = yield treq.get(url,
                                          auth=(self._username, self._password),
                                          timeout=timeout,
                                          headers=self.REST_GET_REQUEST_HEADER)
            elif method.upper() == 'POST' or method.upper() == 'PUT':
                response = yield treq.post(url,
                                           data=data,
                                           auth=(self._username, self._password),
                                           timeout=timeout,
                                           headers=self.REST_POST_REQUEST_HEADER)
            elif method.upper() == 'PATCH':
                response = yield treq.patch(url,
                                            data=data,
                                            auth=(self._username, self._password),
                                            timeout=timeout,
                                            headers=self.REST_PATCH_REQUEST_HEADER)
            elif method.upper() == 'DELETE':
                response = yield treq.delete(url,
                                             auth=(self._username, self._password),
                                             timeout=timeout,
                                             headers=self.REST_DELETE_REQUEST_HEADER)
            else:
                raise NotImplementedError("REST method '{}' is not supported".format(method))

        except NotImplementedError:
            raise

        except (ConnectionDone, ConnectionLost) as e:
            if is_retry:
                raise
            returnValue(self.request(method, uri, data=data, name=name,
                                     timeout=timeout, is_retry=True))

        except ConnectionClosed:
            returnValue(ConnectionClosed)

        except Exception as e:
            log.exception("rest-request", method=method, url=url, name=name, e=e)
            raise

        if response.code not in self._valid_results[method.upper()]:
            message = "REST {} '{}' request to '{}' failed with status code {}".format(method, name,
                                                                                       url, response.code)
            if not suppress_error:
                log.error(message)
            raise RestInvalidResponseCode(message, url, response.code)

        if response.code == self.HTTP_NO_CONTENT:
            returnValue(None)

        else:
            # TODO: May want to support multiple body encodings in the future

            headers = response.headers
            type_key = 'content-type'
            type_val = 'application/json'

            if not headers.hasHeader(type_key) or type_val not in headers.getRawHeaders(type_key, []):
                raise Exception("REST {} '{}' request response from '{}' was not JSON",
                                method, name, url)

            content = yield response.content()
            try:
                result = json.loads(content)

            except Exception as e:
                log.exception("json-decode", method=method, url=url, name=name,
                              content=content, e=e)
                raise

            returnValue(result)