# Path: ckan_api_client/exceptions.py
# class HTTPError(Exception):
#     """
#     Exception representing an HTTP response error.
# 
#     .. attribute:: status_code
# 
#         HTTP status code
# 
#     .. attribute:: message
# 
#         Informative error message, if available
#     """
# 
#     def __init__(self, status_code, message, original=None):
#         self.args = (status_code, message, original)
# 
#     @property
#     def status_code(self):
#         return self.args[0]
# 
#     @property
#     def message(self):
#         return self.args[1]
# 
#     @property
#     def original(self):
#         return self.args[2]
# 
#     def __str__(self):
#         return ("{0}({1!r}, {2!r}, original={3!r})"
#                 .format(self.__class__.__name__,
#                         self.status_code, self.message, self.original))
# 
# class BadApiError(Exception):
#     """Exception used to mark bad behavior from the API"""
#     pass
# 
# Path: ckan_api_client/utils.py
# class SuppressExceptionIf(object):
#     """
#     Context manager used to suppress exceptions if they match
#     a given condition.
# 
#     Usage example::
# 
#         is_404 = lambda x: isinstance(x, HTTPError) and x.status_code == 404
#         with SuppressExceptionIf(is_404):
#             client.request(...)
#     """
# 
#     def __init__(self, cond):
#         self.cond = cond
# 
#     def __enter__(self):
#         pass
# 
#     def __exit__(self, exc_type, exc_value, traceback):
#         if exc_value is None:
#             return
#         if callable(self.cond):
#             # If the callable returns True, exception
#             # will be suppressed
#             return self.cond(exc_value)
#         return self.cond


import json
import urlparse
import requests
from .exceptions import HTTPError, BadApiError
from .utils import SuppressExceptionIf
                return '{0}'.format(data['error']['message'])

        raise ValueError("Unable to find message in JSON data")

    # ============================================================
    # Validation helpers
    # ============================================================

    def _validate_response_idlist(self, response, name='object'):
        if not isinstance(response, list):
            raise BadApiError(
                "Bad {0} id list returned from the api (not a list)"
                .format(name))

        if not all(isinstance(x, basestring) for x in response):
            raise BadApiError(
                "Bad {0} id list returned from the api (an element "
                "is not a string)".format(name))

    def _validate_response_dict(self, response, name='object'):
        if not isinstance(response, dict):
            raise BadApiError("Bad {0} returned from the api (not a dict)"
                              .format(name))

    def _validate_response_list_of_dict(self, response, name='object'):
        if not isinstance(response, list):
            raise BadApiError("Bad {0} list returned from the api (not a list)"
                              .format(name))

        if not all(isinstance(x, dict) for x in response):

# Path: ckan_api_client/exceptions.py
# class HTTPError(Exception):
#     """
#     Exception representing an HTTP response error.
# 
#     .. attribute:: status_code
# 
#         HTTP status code
# 
#     .. attribute:: message
# 
#         Informative error message, if available
#     """
# 
#     def __init__(self, status_code, message, original=None):
#         self.args = (status_code, message, original)
# 
#     @property
#     def status_code(self):
#         return self.args[0]
# 
#     @property
#     def message(self):
#         return self.args[1]
# 
#     @property
#     def original(self):
#         return self.args[2]
# 
#     def __str__(self):
#         return ("{0}({1!r}, {2!r}, original={3!r})"
#                 .format(self.__class__.__name__,
#                         self.status_code, self.message, self.original))
# 
# class BadApiError(Exception):
#     """Exception used to mark bad behavior from the API"""
#     pass
# 
# Path: ckan_api_client/utils.py
# class SuppressExceptionIf(object):
#     """
#     Context manager used to suppress exceptions if they match
#     a given condition.
# 
#     Usage example::
# 
#         is_404 = lambda x: isinstance(x, HTTPError) and x.status_code == 404
#         with SuppressExceptionIf(is_404):
#             client.request(...)
#     """
# 
#     def __init__(self, cond):
#         self.cond = cond
# 
#     def __enter__(self):
#         pass
# 
#     def __exit__(self, exc_type, exc_value, traceback):
#         if exc_value is None:
#             return
#         if callable(self.cond):
#             # If the callable returns True, exception
#             # will be suppressed
#             return self.cond(exc_value)
#         return self.cond


# Path: ckan_api_client/low_level.py
import json
import urlparse
import requests
from .exceptions import HTTPError, BadApiError
from .utils import SuppressExceptionIf

                return '{0}'.format(data['error']['message'])

        raise ValueError("Unable to find message in JSON data")

    # ============================================================
    # Validation helpers
    # ============================================================

    def _validate_response_idlist(self, response, name='object'):
        if not isinstance(response, list):
            raise BadApiError(
                "Bad {0} id list returned from the api (not a list)"
                .format(name))

        if not all(isinstance(x, basestring) for x in response):
            raise BadApiError(
                "Bad {0} id list returned from the api (an element "
                "is not a string)".format(name))

    def _validate_response_dict(self, response, name='object'):
        if not isinstance(response, dict):
            raise BadApiError("Bad {0} returned from the api (not a dict)"
                              .format(name))

    def _validate_response_list_of_dict(self, response, name='object'):
        if not isinstance(response, list):
            raise BadApiError("Bad {0} list returned from the api (not a list)"
                              .format(name))

        if not all(isinstance(x, dict) for x in response):

            raise BadApiError(