Exemple #1
0
    def __request(
            self,
            method: str,
            path: str,
            payload: Optional[Union[dict, str, Base, pd.DataFrame]] = None,
            request_headers: Optional[dict] = None,
            cls: Optional[type] = None,
            try_auth=True,
            include_version: bool = True,
            timeout: int = DEFAULT_TIMEOUT
    ) -> Union[Base, tuple, dict]:
        is_dataframe = isinstance(payload, pd.DataFrame)
        if not is_dataframe:
            payload = payload or {}

        url = '{}{}{}'.format(self.domain, '/' + self.api_version if include_version else '', path)

        kwargs = {
            'timeout': timeout
        }
        if method in ['GET', 'DELETE']:
            kwargs['params'] = payload
        elif method in ['POST', 'PUT']:
            headers = self._session.headers.copy()
            if request_headers:
                headers.update({**{'Content-Type': 'application/json'}, **request_headers})
            else:
                headers.update({'Content-Type': 'application/json'})
            kwargs['headers'] = headers
            if is_dataframe or payload:
                kwargs['data'] = payload if isinstance(payload, str) else json.dumps(payload, cls=JSONEncoder)
        else:
            raise MqError('not implemented')

        response = self._session.request(method, url, **kwargs)
        if response.status_code == 401:
            # Expired token or other authorization issue
            if not try_auth:
                raise MqRequestError(response.status_code, response.text, context='{} {}'.format(method, url))
            self._authenticate()
            return self.__request(method, path, payload=payload, cls=cls, try_auth=False)
        elif not 199 < response.status_code < 300:
            raise MqRequestError(response.status_code, response.text, context='{} {}'.format(method, url))
        elif 'application/x-msgpack' in response.headers['content-type']:
            res = msgpack.unpackb(response.content, raw=False)

            if cls:
                if isinstance(res, dict) and 'results' in res:
                    res['results'] = self.__unpack(res['results'], cls)
                else:
                    res = self.__unpack(res, cls)

            return res
        elif 'application/json' in response.headers['content-type']:
            res = json.loads(response.text)

            if cls:
                if isinstance(res, dict) and 'results' in res:
                    res['results'] = self.__unpack(res['results'], cls)
                else:
                    res = self.__unpack(res, cls)

            return res
        else:
            return {'raw': response}
Exemple #2
0
    def __request(
            self,
            method: str,
            path: str,
            payload: Optional[Union[dict, str, bytes, Base,
                                    pd.DataFrame]] = None,
            request_headers: Optional[dict] = None,
            cls: Optional[type] = None,
            try_auth: Optional[bool] = True,
            include_version: Optional[bool] = True,
            timeout: Optional[int] = DEFAULT_TIMEOUT,
            return_request_id: Optional[bool] = False
    ) -> Union[Base, tuple, dict]:
        is_dataframe = isinstance(payload, pd.DataFrame)
        if not is_dataframe:
            payload = payload or {}

        url = '{}{}{}'.format(
            self.domain, '/' + self.api_version if include_version else '',
            path)

        kwargs = {'timeout': timeout}
        if method in ['GET', 'DELETE']:
            kwargs['params'] = payload
        elif method in ['POST', 'PUT']:
            headers = self._session.headers.copy()

            if request_headers:
                headers.update(request_headers)

            if 'Content-Type' not in headers:
                headers.update(
                    {'Content-Type': 'application/json; charset=utf-8'})

            use_msgpack = headers.get(
                'Content-Type') == 'application/x-msgpack'
            kwargs['headers'] = headers

            if is_dataframe or payload:
                kwargs['data'] = payload if isinstance(payload, (str, bytes)) else \
                    msgpack.dumps(payload, default=encode_default) if use_msgpack else \
                    json.dumps(payload, cls=JSONEncoder)
        else:
            raise MqError('not implemented')

        response = self._session.request(method, url, **kwargs)
        request_id = response.headers.get('x-dash-requestid')

        if response.status_code == 401:
            # Expired token or other authorization issue
            if not try_auth:
                raise MqRequestError(response.status_code,
                                     response.text,
                                     context='{} {}'.format(method, url))
            self._authenticate()
            return self.__request(method,
                                  path,
                                  payload=payload,
                                  cls=cls,
                                  try_auth=False)
        elif not 199 < response.status_code < 300:
            raise MqRequestError(
                response.status_code,
                response.text,
                context=f'{response.headers.get("")}: {method} {url}')
        elif 'Content-Type' in response.headers:
            if 'application/x-msgpack' in response.headers['Content-Type']:
                res = msgpack.unpackb(response.content, raw=False)

                if cls:
                    if isinstance(res, dict) and 'results' in res:
                        res['results'] = self.__unpack(res['results'], cls)
                    else:
                        res = self.__unpack(res, cls)

                return (res, request_id) if return_request_id else res
            elif 'application/json' in response.headers['Content-Type']:
                res = json.loads(response.text)

                if cls:
                    if isinstance(res, dict) and 'results' in res:
                        res['results'] = self.__unpack(res['results'], cls)
                    else:
                        res = self.__unpack(res, cls)

                return (res, request_id) if return_request_id else res
        else:
            ret = {'raw': response}
            if return_request_id:
                ret['request_id'] = request_id

            return ret