# Path: ricloud/compat.py
# PY3 = sys.version_info[0] >= 3
#     def want_bytes(data):
#     def want_text(data):
#     def to_str(data):
#     def want_bytes(data):
#     def want_text(data):
#     def to_str(data):
# 
# Path: ricloud/requests.py
# class RequestHandler(object):
#     def __init__(self):
#         self.session = requests.Session()
# 
#         self.max_retries = conf.getint("api", "max_retries")
#         self.await_for = conf.get("api", "await_for")
# 
#     def set_headers(self, headers):
#         headers = headers or {}
# 
#         headers.setdefault("User-Agent", get_user_agent_header())
#         headers.setdefault("Authorization", get_auth_header())
# 
#         if self.await_for:
#             headers.setdefault("Ricloud-Await", self.await_for)
# 
#         return headers
# 
#     def get(self, url, headers=None, params=None):
#         if params:
#             for param, value in params.items():
#                 encoded_value = encode(value)
#                 params[param] = encoded_value if encoded_value is not None else value
# 
#         return self.send("GET", url, headers=headers, params=params)
# 
#     def post(self, url, headers=None, data=None):
#         json_data = encode_json(data)
# 
#         return self.send("POST", url, headers=headers, data=json_data)
# 
#     def delete(self, url, headers=None):
#         return self.send("DELETE", url, headers=headers)
# 
#     def send(self, method, url, headers=None, data=None, params=None):
#         headers = self.set_headers(headers)
# 
#         response = self._send(
#             method=method,
#             url=url,
#             headers=headers,
#             data=data,
#             params=params,
#             retries_remaining=self.max_retries,
#         )
# 
#         if response.status_code >= 500:
#             raise ServerError(response.status_code, response.content)
#         elif response.status_code >= 400:
#             raise RequestError(response.status_code, response.content)
# 
#         return decode_json(response.content), response.status_code
# 
#     def _send(self, method, url, headers, data, params, retries_remaining=None):
#         try:
#             response = self.session.request(
#                 method=method, url=url, headers=headers, data=data, params=params
#             )
#         except (ConnectionError, Timeout):
#             if not retries_remaining:
#                 raise
# 
#             response = None
# 
#         # Explicit None comparison as bad responses are falsey.
#         if response is None or (response.status_code >= 500):
#             if retries_remaining:
#                 return self._send(
#                     method=method,
#                     url=url,
#                     headers=headers,
#                     data=data,
#                     params=params,
#                     retries_remaining=retries_remaining - 1,
#                 )
# 
#         return response
# 
# Path: ricloud/utils.py
# def pretty_print(data):
#     return json.dumps(data, indent=2, cls=ExpandedDataEncoder, ensure_ascii=False)
# 
# def join_url(base, url, allow_fragments=True):
#     return compat.urljoin(base, url, allow_fragments=allow_fragments)


from collections import OrderedDict
from ricloud.compat import Mapping, MutableMapping, MutableSequence
from ricloud.requests import RequestHandler
from ricloud.utils import pretty_print, join_url
import ricloud
        if ABResource._resources is None:
            ABResource._resources = dict(ABResource.get_resources())
        return ABResource._resources.get(resource_type)

    @classmethod
    def parse_value(cls, value):
        if isinstance(value, Mapping) and not isinstance(value, ABResource):
            resource_type = value.get("resource")
            if resource_type:
                resource = cls.get_resource(resource_type)
                return resource(**value)
        return value

    @classmethod
    def parse_attrs(cls, attrs):
        return dict([(attr, cls.parse_value(value)) for attr, value in attrs.items()])


class Resource(ABResource):
    RESOURCE = ""
    RESOURCE_PATH = ""

    def __init__(self, *args, **attrs):
        if args:
            attrs["id"] = args[0]
        super(Resource, self).__init__(**attrs)

    @classmethod
    def resource_url(cls, resource_path=None):
        resource_path = resource_path or cls.RESOURCE_PATH

# Path: ricloud/compat.py
# PY3 = sys.version_info[0] >= 3
#     def want_bytes(data):
#     def want_text(data):
#     def to_str(data):
#     def want_bytes(data):
#     def want_text(data):
#     def to_str(data):
# 
# Path: ricloud/requests.py
# class RequestHandler(object):
#     def __init__(self):
#         self.session = requests.Session()
# 
#         self.max_retries = conf.getint("api", "max_retries")
#         self.await_for = conf.get("api", "await_for")
# 
#     def set_headers(self, headers):
#         headers = headers or {}
# 
#         headers.setdefault("User-Agent", get_user_agent_header())
#         headers.setdefault("Authorization", get_auth_header())
# 
#         if self.await_for:
#             headers.setdefault("Ricloud-Await", self.await_for)
# 
#         return headers
# 
#     def get(self, url, headers=None, params=None):
#         if params:
#             for param, value in params.items():
#                 encoded_value = encode(value)
#                 params[param] = encoded_value if encoded_value is not None else value
# 
#         return self.send("GET", url, headers=headers, params=params)
# 
#     def post(self, url, headers=None, data=None):
#         json_data = encode_json(data)
# 
#         return self.send("POST", url, headers=headers, data=json_data)
# 
#     def delete(self, url, headers=None):
#         return self.send("DELETE", url, headers=headers)
# 
#     def send(self, method, url, headers=None, data=None, params=None):
#         headers = self.set_headers(headers)
# 
#         response = self._send(
#             method=method,
#             url=url,
#             headers=headers,
#             data=data,
#             params=params,
#             retries_remaining=self.max_retries,
#         )
# 
#         if response.status_code >= 500:
#             raise ServerError(response.status_code, response.content)
#         elif response.status_code >= 400:
#             raise RequestError(response.status_code, response.content)
# 
#         return decode_json(response.content), response.status_code
# 
#     def _send(self, method, url, headers, data, params, retries_remaining=None):
#         try:
#             response = self.session.request(
#                 method=method, url=url, headers=headers, data=data, params=params
#             )
#         except (ConnectionError, Timeout):
#             if not retries_remaining:
#                 raise
# 
#             response = None
# 
#         # Explicit None comparison as bad responses are falsey.
#         if response is None or (response.status_code >= 500):
#             if retries_remaining:
#                 return self._send(
#                     method=method,
#                     url=url,
#                     headers=headers,
#                     data=data,
#                     params=params,
#                     retries_remaining=retries_remaining - 1,
#                 )
# 
#         return response
# 
# Path: ricloud/utils.py
# def pretty_print(data):
#     return json.dumps(data, indent=2, cls=ExpandedDataEncoder, ensure_ascii=False)
# 
# def join_url(base, url, allow_fragments=True):
#     return compat.urljoin(base, url, allow_fragments=allow_fragments)


# Path: ricloud/resources/abase.py
from collections import OrderedDict
from ricloud.compat import Mapping, MutableMapping, MutableSequence
from ricloud.requests import RequestHandler
from ricloud.utils import pretty_print, join_url
import ricloud

        if ABResource._resources is None:
            ABResource._resources = dict(ABResource.get_resources())
        return ABResource._resources.get(resource_type)

    @classmethod
    def parse_value(cls, value):
        if isinstance(value, Mapping) and not isinstance(value, ABResource):
            resource_type = value.get("resource")
            if resource_type:
                resource = cls.get_resource(resource_type)
                return resource(**value)
        return value

    @classmethod
    def parse_attrs(cls, attrs):
        return dict([(attr, cls.parse_value(value)) for attr, value in attrs.items()])


class Resource(ABResource):
    RESOURCE = ""
    RESOURCE_PATH = ""

    def __init__(self, *args, **attrs):
        if args:
            attrs["id"] = args[0]
        super(Resource, self).__init__(**attrs)

    @classmethod
    def resource_url(cls, resource_path=None):
        resource_path = resource_path or cls.RESOURCE_PATH

        return join_url(ricloud.url, resource_path)