def _interpret_response(self, response, payload, expected_status):
        # type: (Response, dict, Container[int]) -> dict
        """
        Interprets the HTTP response from the node.

        :param response:
            The response object received from
            :py:meth:`_send_http_request`.

        :param payload:
            The request payload that was sent (used for debugging).

        :param expected_status:
            The response should match one of these status codes to be
            considered valid.
        """
        raw_content = response.text
        if not raw_content:
            raise with_context(
                exc=BadApiResponse(
                    'Empty {status} response from node.'.format(
                        status=response.status_code,
                    ),
                ),

                context={
                    'request': payload,
                },
            )

        try:
            decoded = json.loads(raw_content)  # type: dict
        # :bc: py2k doesn't have JSONDecodeError
        except ValueError:
            raise with_context(
                exc=BadApiResponse(
                    'Non-JSON {status} response from node: '
                    '{raw_content}'.format(
                        status=response.status_code,
                        raw_content=raw_content,
                    )
                ),

                context={
                    'request': payload,
                    'raw_response': raw_content,
                },
            )

        if not isinstance(decoded, dict):
            raise with_context(
                exc=BadApiResponse(
                    'Malformed {status} response from node: {decoded!r}'.format(
                        status=response.status_code,
                        decoded=decoded,
                    ),
                ),

                context={
                    'request': payload,
                    'response': decoded,
                },
            )

        if response.status_code in expected_status:
            return decoded

        error = None
        try:
            if response.status_code == codes['bad_request']:
                error = decoded['error']
            elif response.status_code == codes['internal_server_error']:
                error = decoded['exception']
        except KeyError:
            pass

        raise with_context(
            exc=BadApiResponse(
                '{status} response from node: {error}'.format(
                    error=error or decoded,
                    status=response.status_code,
                ),
            ),

            context={
                'request': payload,
                'response': decoded,
            },
        )
Interprets the HTTP response from the node.

        :param response:
            The response object received from
            :py:meth:`_send_http_request`.

        :param payload:
            The request payload that was sent (used for debugging).

        :param expected_status:
            The response should match one of these status codes to be
            considered valid.