def perform(cls, session, *args, **kwargs):
        """Send, parse, validate and check success of this call.
        *args and **kwargs are passed to protocol.build_transaction.

        :param session: a PlaySession used to send this request.
        """
        #TODO link up these docs

        call_name = cls.__name__

        if cls.gets_logged:
            log.debug(
                "%s(args=%s, kwargs=%s)", call_name,
                [utils.truncate(a) for a in args],
                dict((k, utils.truncate(v)) for (k, v) in kwargs.items()))
        else:
            log.debug("%s(<does not get logged>)", call_name)

        req_kwargs = cls.build_request(*args, **kwargs)

        response = session.send(req_kwargs, cls.required_auth)

        #TODO check return code

        try:
            msg = cls.parse_response(response)
        except ParseException:
            if cls.gets_logged:
                log.exception("couldn't parse %s response: %r", call_name,
                              response.content)
            raise CallFailure(
                "the server's response could not be understood."
                " The call may still have succeeded, but it's unlikely.",
                call_name)

        if cls.gets_logged:
            log.debug(cls.filter_response(msg))

        try:
            #order is important; validate only has a schema for a successful response
            cls.check_success(response, msg)
            cls.validate(response, msg)
        except CallFailure:
            raise
        except ValidationException:
            #TODO trim the response if it's huge
            if cls.gets_logged:
                msg_fmt = (
                    "the following response format for %s was not recognized."
                    "\nIf there has not been a compatibility update reported"
                    "[here](http://goo.gl/jTKNb),"
                    " please [create an issue](http://goo.gl/qbAW8) that includes"
                    " the following raw response:\n%r\n"
                    "\nA traceback follows:\n")
                log.exception(msg_fmt, call_name, msg)

        return msg
    def perform(cls, session, *args, **kwargs):
        """Send, parse, validate and check success of this call.
        *args and **kwargs are passed to protocol.build_transaction.

        :param session: a PlaySession used to send this request.
        """
        #TODO link up these docs

        call_name = cls.__name__

        if cls.gets_logged:
            log.debug("%s(args=%s, kwargs=%s)",
                      call_name,
                      [utils.truncate(a) for a in args],
                      dict((k, utils.truncate(v)) for (k, v) in kwargs.items())
                      )
        else:
            log.debug("%s(<does not get logged>)", call_name)

        req_kwargs = cls.build_request(*args, **kwargs)

        response = session.send(req_kwargs, cls.required_auth)

        #TODO check return code

        try:
            msg = cls.parse_response(response)
        except ParseException:
            if cls.gets_logged:
                log.exception("couldn't parse %s response: %r", call_name, response.content)
            raise CallFailure("the server's response could not be understood."
                              " The call may still have succeeded, but it's unlikely.",
                              call_name)

        if cls.gets_logged:
            log.debug(cls.filter_response(msg))

        try:
            #order is important; validate only has a schema for a successful response
            cls.check_success(response, msg)
            cls.validate(response, msg)
        except CallFailure:
            raise
        except ValidationException:
            #TODO trim the response if it's huge
            if cls.gets_logged:
                msg_fmt = ("the following response format for %s was not recognized."
                           "\nIf there has not been a compatibility update reported"
                           "[here](http://goo.gl/jTKNb),"
                           " please [create an issue](http://goo.gl/qbAW8) that includes"
                           " the following raw response:\n%r\n"
                           "\nA traceback follows:\n")
                log.exception(msg_fmt, call_name, msg)

        return msg
Example #3
0
    def _make_call(self, protocol, *args, **kwargs):
        """Returns the response of a protocol.Call.
        Additional kw/args are passed to protocol.build_transaction."""
        #TODO link up these docs

        call_name = protocol.__name__

        self.log.debug("%s(args=%s, kwargs=%s)", call_name,
                       [utils.truncate(a) for a in args],
                       {k: utils.truncate(v)
                        for (k, v) in kwargs.items()})

        request = protocol.build_request(*args, **kwargs)

        response = self.session.send(request, protocol.get_auth(),
                                     protocol.session_options)

        #TODO check return code

        try:
            msg = protocol.parse_response(response)
        except ParseException:
            self.log.exception("couldn't parse %s response: %r", call_name,
                               response.content)
            raise CallFailure(
                "the server's response could not be understood."
                " The call may still have succeeded, but it's unlikely.",
                call_name)

        self.log.debug(protocol.filter_response(msg))

        try:
            #order is important; validate only has a schema for a successful response
            protocol.check_success(msg)
            protocol.validate(msg)
        except CallFailure:
            raise
        except ValidationException:
            #TODO link to some protocol for reporting this
            self.log.exception(
                "please report the following unknown response format for %s: %r",
                call_name, msg)

        return msg
    def _make_call(self, protocol, *args, **kwargs):
        """Returns the response of a protocol.Call.
        Additional kw/args are passed to protocol.build_transaction."""
        #TODO link up these docs

        call_name = protocol.__name__

        log.debug("%s(args=%s, kwargs=%s)",
                  call_name,
                  [utils.truncate(a) for a in args],
                  dict((k, utils.truncate(v)) for (k, v) in kwargs.items())
                  )

        request = protocol.build_request(*args, **kwargs)

        response = self.session.send(request, protocol.get_auth(), protocol.session_options)

        #TODO check return code

        try:
            msg = protocol.parse_response(response)
        except ParseException:
            log.exception("couldn't parse %s response: %r", call_name, response.content)
            raise CallFailure("the server's response could not be understood."
                              " The call may still have succeeded, but it's unlikely.",
                              call_name)

        log.debug(protocol.filter_response(msg))

        try:
            #order is important; validate only has a schema for a successful response
            protocol.check_success(msg)
            protocol.validate(msg)
        except CallFailure:
            raise
        except ValidationException:
            #TODO link to some protocol for reporting this
            log.exception(
                "please report the following unknown response format for %s: %r",
                call_name, msg
            )

        return msg
Example #5
0
    def perform(cls, session, validate, *args, **kwargs):
        """Send, parse, validate and check success of this call.
        *args and **kwargs are passed to protocol.build_transaction.

        :param session: a PlaySession used to send this request.
        :param validate: if False, do not validate
        """
        # TODO link up these docs

        call_name = cls.__name__

        if cls.gets_logged:
            log.debug("%s(args=%s, kwargs=%s)",
                      call_name,
                      [utils.truncate(a) for a in args],
                      dict((k, utils.truncate(v)) for (k, v) in kwargs.items())
                      )
        else:
            log.debug("%s(<omitted>)", call_name)

        req_kwargs = cls.build_request(*args, **kwargs)

        response = session.send(req_kwargs, cls.required_auth)
        # TODO trim the logged response if it's huge?

        safe_req_kwargs = req_kwargs.copy()
        if safe_req_kwargs.get('headers', {}).get('Authorization', None) is not None:
            safe_req_kwargs['headers']['Authorization'] = '<omitted>'

        if cls.fail_on_non_200:
            try:
                response.raise_for_status()
            except requests.HTTPError as e:
                err_msg = str(e)

                if cls.gets_logged:
                    err_msg += "\n(requests kwargs: %r)" % (safe_req_kwargs)
                    err_msg += "\n(response was: %r)" % response.text

                raise CallFailure(err_msg, call_name)

        try:
            parsed_response = cls.parse_response(response)
        except ParseException:
            err_msg = ("the server's response could not be understood."
                       " The call may still have succeeded, but it's unlikely.")
            if cls.gets_logged:
                err_msg += "\n(requests kwargs: %r)" % (safe_req_kwargs)
                err_msg += "\n(response was: %r)" % response.text
                log.exception("could not parse %s response: %r", call_name, response.text)
            else:
                log.exception("could not parse %s response: (omitted)", call_name)

            raise CallFailure(err_msg, call_name)

        if cls.gets_logged:
            log.debug(cls.filter_response(parsed_response))

        try:
            # order is important; validate only has a schema for a successful response
            cls.check_success(response, parsed_response)
            if validate:
                cls.validate(response, parsed_response)
        except CallFailure as e:
            if not cls.gets_logged:
                raise

            # otherwise, reraise a new exception with our req/res context
            err_msg = ("{e_message}\n"
                       "(requests kwargs: {req_kwargs!r})\n"
                       "(response was: {content!r})").format(
                           e_message=str(e),
                           req_kwargs=safe_req_kwargs,
                           content=response.text)
            raise_from(CallFailure(err_msg, e.callname), e)

        except ValidationException as e:
            # TODO shouldn't be using formatting
            err_msg = "the response format for %s was not recognized." % call_name
            err_msg += "\n\n%s\n" % e

            if cls.gets_logged:
                raw_response = response.text

                if len(raw_response) > 10000:
                    raw_response = raw_response[:10000] + '...'

                err_msg += ("\nFirst, try the develop branch."
                            " If you can recreate this error with the most recent code"
                            " please [create an issue](http://goo.gl/qbAW8) that includes"
                            " the above ValidationException"
                            " and the following request/response:\n%r\n\n%r\n"
                            "\nA traceback follows:\n") % (safe_req_kwargs, raw_response)

            log.exception(err_msg)

        return parsed_response
    def perform(cls, session, validate, *args, **kwargs):
        """Send, parse, validate and check success of this call.
        *args and **kwargs are passed to protocol.build_transaction.

        :param session: a PlaySession used to send this request.
        :param validate: if False, do not validate
        """
        #TODO link up these docs

        call_name = cls.__name__

        if cls.gets_logged:
            log.debug("%s(args=%s, kwargs=%s)",
                      call_name,
                      [utils.truncate(a) for a in args],
                      dict((k, utils.truncate(v)) for (k, v) in kwargs.items())
                      )
        else:
            log.debug("%s(<omitted>)", call_name)

        req_kwargs = cls.build_request(*args, **kwargs)

        log.debug(req_kwargs)

        response = session.send(req_kwargs, cls.required_auth)
        #TODO trim the logged response if it's huge?

        safe_req_kwargs = req_kwargs.copy()
        if safe_req_kwargs.get('headers', {}).get('Authorization', None) is not None:
            safe_req_kwargs['headers']['Authorization'] = '<omitted>'

        # check response code
        try:
            response.raise_for_status()
        except requests.HTTPError as e:
            err_msg = str(e)

            if cls.gets_logged:
                err_msg += "\n(requests kwargs: %r)" % (safe_req_kwargs)
                err_msg += "\n(response was: %r)" % response.content

            raise CallFailure(err_msg, call_name)

        try:
            parsed_response = cls.parse_response(response)
        except ParseException:
            err_msg = ("the server's response could not be understood."
                       " The call may still have succeeded, but it's unlikely.")
            if cls.gets_logged:
                err_msg += "\n(requests kwargs: %r)" % (safe_req_kwargs)
                err_msg += "\n(response was: %r)" % response.content
                log.exception("could not parse %s response: %r", call_name, response.content)
            else:
                log.exception("could not parse %s response: (omitted)", call_name)

            raise CallFailure(err_msg, call_name)

        if cls.gets_logged:
            log.debug(cls.filter_response(parsed_response))

        try:
            #order is important; validate only has a schema for a successful response
            cls.check_success(response, parsed_response)
            if validate:
                cls.validate(response, parsed_response)
        except CallFailure as e:
            if not cls.gets_logged:
                raise

            # otherwise, reraise a new exception with our req/res context
            trace = sys.exc_info()[2]
            err_msg = ("{e_message}\n"
                       "(requests kwargs: {req_kwargs!r})\n"
                       "(response was: {content!r})").format(
                           e_message=e.message,
                           req_kwargs=safe_req_kwargs,
                           content=response.content)
            raise CallFailure(err_msg, e.callname), None, trace

        except ValidationException as e:
            #TODO shouldn't be using formatting
            err_msg = "the response format for %s was not recognized." % call_name
            err_msg += "\n\n%s\n" % e

            if cls.gets_logged:
                raw_response = response.content

                if len(raw_response) > 1000:
                    raw_response = raw_response[:1000] + '...'

                err_msg += ("\nFirst, try the develop branch."
                            " If you can recreate this error with the most recent code"
                            " please [create an issue](http://goo.gl/qbAW8) that includes"
                            " the above ValidationException"
                            " and the following request/response:\n%r\n\n%r\n"
                            "\nA traceback follows:\n") % (safe_req_kwargs, raw_response)

            log.exception(err_msg)

        return parsed_response