# Path: jsonapi/exceptions.py
# class JSONAPIError(Exception):
# 
#     """ Exception class for JSONAPI.
# 
#     .. versionadded:: 0.6.9
#     .. versionchanged:: 0.8.4
#       Use JSON-API Specification http://jsonapi.org/format/#errors
# 
#     Error codes are from 0 to 32767.
#     Error codes 32000 - 32767 are reserved fro jsonapi usage.
#     It is recommended for user to use codes from 0 to 32000, in this case codes
#     could be stored within django.PositiveSmallIntegerField field
# 
#     """
# 
#     ATTRIBUTES = [
#         "id",
#         "href",
#         "status",
#         "code",
#         "title",
#         "detail",
#         "links",
#         "paths",
#         "data",
#     ]
# 
#     REQUIRED_ATTRIBUTES = ["code", "title"]
#     CODE = 32000
#     STATUS = statuses.HTTP_400_BAD_REQUEST
#     TITLE = "General JSONAPI Error"
# 
#     def __init__(self, **kwargs):
#         kwargs["code"] = self.CODE
#         kwargs["title"] = self.TITLE
#         kwargs["status"] = self.STATUS
#         kwargs["detail"] = kwargs.get("detail", "")
# 
#         for required_attribut in self.REQUIRED_ATTRIBUTES:
#             if required_attribut not in kwargs:
#                 raise ValueError("{} should have {} attribute".format(
#                     self.__class__.__name__, required_attribut
#                 ))
# 
#         for kwarg_key, kwarg_value in kwargs.items():
#             if kwarg_key not in self.ATTRIBUTES:
#                 raise ValueError(
#                     "Attribute {} is not allowed".format(kwarg_key))
# 
#         self.data = kwargs
# 
#     def __str__(self):
#         return json.dumps(self.data)
# 
#     def __getattr__(self, key):
#         if key == "data":
#             return self.data
#         else:
#             return self.data[key]
# 
# Path: jsonapi/serializers.py
# class DatetimeDecimalEncoder(json.JSONEncoder):
# 
#     """ Encoder for datetime and decimal serialization.
# 
#     Usage: json.dumps(object, cls=DatetimeDecimalEncoder)
#     NOTE: _iterencode does not work
# 
#     """
# 
#     def default(self, o):
#         """ Encode JSON.
# 
#         :return str: A JSON encoded string
# 
#         """
#         if isinstance(o, (datetime.datetime, datetime.date, datetime.time)):
#             return o.isoformat()
# 
#         if isinstance(o, decimal.Decimal):
#             return float(o)
# 
#         return json.JSONEncoder.default(self, o)
# 
# Path: jsonapi/signals.py



import json
import logging
import time
from django.http import HttpResponse, HttpResponseNotAllowed
from django.shortcuts import render
from .exceptions import JSONAPIError
from .serializers import DatetimeDecimalEncoder
from .signals import signal_request, signal_response
        from django.conf.urls import url
                permitted_methods=allowed_http_methods)
            signal_response.send(
                sender=self, request=request, response=response,
                duration=time.time() - time_start)
            return response

        if resource.Meta.authenticators and not (
                request.method == "GET" and
                resource.Meta.disable_get_authentication):
            user = resource.authenticate(request)
            if user is None or not user.is_authenticated():
                response = HttpResponse("Not Authenticated", status=401)
                signal_response.send(
                    sender=self, request=request, response=response,
                    duration=time.time() - time_start)
                return response

        kwargs = dict(request=request)
        if ids is not None:
            kwargs['ids'] = ids.split(",")

        try:
            if request.method == "GET":
                response = self.handler_view_get(resource, **kwargs)
            elif request.method == "POST":
                response = self.handler_view_post(resource, **kwargs)
            elif request.method == "PUT":
                response = self.handler_view_put(resource, **kwargs)
            elif request.method == "DELETE":
                response = self.handler_view_delete(resource, **kwargs)

# Path: jsonapi/exceptions.py
# class JSONAPIError(Exception):
# 
#     """ Exception class for JSONAPI.
# 
#     .. versionadded:: 0.6.9
#     .. versionchanged:: 0.8.4
#       Use JSON-API Specification http://jsonapi.org/format/#errors
# 
#     Error codes are from 0 to 32767.
#     Error codes 32000 - 32767 are reserved fro jsonapi usage.
#     It is recommended for user to use codes from 0 to 32000, in this case codes
#     could be stored within django.PositiveSmallIntegerField field
# 
#     """
# 
#     ATTRIBUTES = [
#         "id",
#         "href",
#         "status",
#         "code",
#         "title",
#         "detail",
#         "links",
#         "paths",
#         "data",
#     ]
# 
#     REQUIRED_ATTRIBUTES = ["code", "title"]
#     CODE = 32000
#     STATUS = statuses.HTTP_400_BAD_REQUEST
#     TITLE = "General JSONAPI Error"
# 
#     def __init__(self, **kwargs):
#         kwargs["code"] = self.CODE
#         kwargs["title"] = self.TITLE
#         kwargs["status"] = self.STATUS
#         kwargs["detail"] = kwargs.get("detail", "")
# 
#         for required_attribut in self.REQUIRED_ATTRIBUTES:
#             if required_attribut not in kwargs:
#                 raise ValueError("{} should have {} attribute".format(
#                     self.__class__.__name__, required_attribut
#                 ))
# 
#         for kwarg_key, kwarg_value in kwargs.items():
#             if kwarg_key not in self.ATTRIBUTES:
#                 raise ValueError(
#                     "Attribute {} is not allowed".format(kwarg_key))
# 
#         self.data = kwargs
# 
#     def __str__(self):
#         return json.dumps(self.data)
# 
#     def __getattr__(self, key):
#         if key == "data":
#             return self.data
#         else:
#             return self.data[key]
# 
# Path: jsonapi/serializers.py
# class DatetimeDecimalEncoder(json.JSONEncoder):
# 
#     """ Encoder for datetime and decimal serialization.
# 
#     Usage: json.dumps(object, cls=DatetimeDecimalEncoder)
#     NOTE: _iterencode does not work
# 
#     """
# 
#     def default(self, o):
#         """ Encode JSON.
# 
#         :return str: A JSON encoded string
# 
#         """
#         if isinstance(o, (datetime.datetime, datetime.date, datetime.time)):
#             return o.isoformat()
# 
#         if isinstance(o, decimal.Decimal):
#             return float(o)
# 
#         return json.JSONEncoder.default(self, o)
# 
# Path: jsonapi/signals.py



# Path: jsonapi/api.py
import json
import logging
import time
from django.http import HttpResponse, HttpResponseNotAllowed
from django.shortcuts import render
from .exceptions import JSONAPIError
from .serializers import DatetimeDecimalEncoder
from .signals import signal_request, signal_response
        from django.conf.urls import url

                permitted_methods=allowed_http_methods)
            signal_response.send(
                sender=self, request=request, response=response,
                duration=time.time() - time_start)
            return response

        if resource.Meta.authenticators and not (
                request.method == "GET" and
                resource.Meta.disable_get_authentication):
            user = resource.authenticate(request)
            if user is None or not user.is_authenticated():
                response = HttpResponse("Not Authenticated", status=401)
                signal_response.send(
                    sender=self, request=request, response=response,
                    duration=time.time() - time_start)
                return response

        kwargs = dict(request=request)
        if ids is not None:
            kwargs['ids'] = ids.split(",")

        try:
            if request.method == "GET":
                response = self.handler_view_get(resource, **kwargs)
            elif request.method == "POST":
                response = self.handler_view_post(resource, **kwargs)
            elif request.method == "PUT":
                response = self.handler_view_put(resource, **kwargs)
            elif request.method == "DELETE":
                response = self.handler_view_delete(resource, **kwargs)

        except JSONAPIError as e: