def _make_request(
        self, request: Callable[[], requests.Response], json: dict
    ) -> requests.Response:
        """Make a request to the API, retrying if necessary.

        Args:
            request: A function that returns a `requests.Response`.
            json: POST body to be logged on failures.

        Returns:
            The request.Response from the final successful request call.

        Raises:
            IonQException: If there was a not-retriable error from the API.
            IonQNotFoundException: If the api returned not found.
            TimeoutError: If the requests retried for more than `max_retry_seconds`.

        """
        # Initial backoff of 100ms.
        delay_seconds = 0.1

        while True:
            try:
                response = request()
                if response.ok:
                    return response
                if response.status_code == requests.codes.unauthorized:
                    raise ionq_exceptions.IonQException(
                        '"Not authorized" returned by IonQ API. Check to ensure you have supplied '
                        'the correct API key.',
                        response.status_code,
                    )
                if response.status_code == requests.codes.not_found:
                    raise ionq_exceptions.IonQNotFoundException(
                        'IonQ could not find requested resource.'
                    )
                if not _is_retriable(response.status_code, response.request.method):
                    error = {}
                    try:
                        error = response.json()
                    except jd.JSONDecodeError:  # pragma: no cover
                        pass
                    raise ionq_exceptions.IonQException(
                        'Non-retry-able error making request to IonQ API. '
                        f'Request Body: {json} '
                        f'Response Body: {error} '
                        f'Status: {response.status_code} '
                        f'Error:{response.reason}',
                        response.status_code,
                    )
                message = response.reason
                # Fallthrough should retry.
            except requests.RequestException as e:
                # Connection error, timeout at server, or too many redirects.
                # Retry these.
                message = f'RequestException of type {type(e)}.'
            if delay_seconds > self.max_retry_seconds:
                raise TimeoutError(f'Reached maximum number of retries. Last error: {message}')
            if self.verbose:
                print(message, file=sys.stderr)
                print(f'Waiting {delay_seconds} seconds before retrying.')
            time.sleep(delay_seconds)
            delay_seconds *= 2
Make a request to the API, retrying if necessary.

        Args:
            request: A function that returns a `requests.Response`.
            json: POST body to be logged on failures.

        Returns:
            The request.Response from the final successful request call.

        Raises:
            IonQException: If there was a not-retriable error from the API.
            IonQNotFoundException: If the api returned not found.
            TimeoutError: If the requests retried for more than `max_retry_seconds`.

        
cirq-ionq/cirq_ionq/ionq_client.py