# Path: rest_pandas/renderers.py
# class PandasBaseRenderer(BaseRenderer):
#     """
#     Renders DataFrames using their built in pandas implementation.
#     Only works with serializers that return DataFrames as their data object.
#     Uses a StringIO to capture the output of dataframe.to_[format]()
#     """
#     def render(self, data, accepted_media_type=None, renderer_context=None):
#         if renderer_context and 'response' in renderer_context:
#             status_code = renderer_context['response'].status_code
#             if not status.is_success(status_code):
#                 return "Error: %s" % data.get('detail', status_code)
# 
#         if not isinstance(data, DataFrame):
#             raise Exception(
#                 RESPONSE_ERROR % type(data).__name__
#             )
# 
#         name = getattr(self, 'function', "to_%s" % self.format)
#         if not hasattr(data, name):
#             raise Exception("Data frame is missing %s property!" % name)
# 
#         self.init_output()
#         args = self.get_pandas_args(data)
#         kwargs = self.get_pandas_kwargs(data, renderer_context)
#         self.render_dataframe(data, name, *args, **kwargs)
#         return self.get_output()
# 
#     def render_dataframe(self, data, name, *args, **kwargs):
#         function = getattr(data, name)
#         function(*args, **kwargs)
# 
#     def init_output(self):
#         self.output = StringIO()
# 
#     def get_output(self):
#         return self.output.getvalue()
# 
#     def get_pandas_args(self, data):
#         return [self.output]
# 
#     def get_pandas_kwargs(self, data, renderer_context):
#         return {}
# 
# Path: rest_pandas/serializers.py
# class SimpleSerializer(serializers.Serializer):
#     """
#     Simple serializer for non-model (simple) views
#     """
#     def to_representation(self, obj):
#         return obj
# 
# class PandasSerializer(serializers.ListSerializer):
#     """
#     Transforms dataset into a dataframe and applies an index
#     """
#     read_only = True
#     index_none_value = None
#     wq_chart_type = None
# 
#     def get_index(self, dataframe):
#         return self.get_index_fields()
# 
#     def get_dataframe(self, data):
#         dataframe = DataFrame(data)
#         index = self.get_index(dataframe)
#         if index:
#             if self.index_none_value is not None:
#                 for key in index:
#                     try:
#                         dataframe[key].fillna(
#                             self.index_none_value, inplace=True
#                         )
#                     except ValueError:
#                         pass
#             dataframe.set_index(index, inplace=True)
#         else:
#             # Name auto-index column to ensure valid CSV output
#             dataframe.index.name = 'row'
#         return dataframe
# 
#     def transform_dataframe(self, dataframe):
#         view = self.context.get('view', None)
#         if view and hasattr(view, 'transform_dataframe'):
#             return self.context['view'].transform_dataframe(dataframe)
#         return dataframe
# 
#     @property
#     def data(self):
#         data = super(serializers.ListSerializer, self).data
#         if isinstance(data, DataFrame) or data:
#             dataframe = self.get_dataframe(data)
#             return self.transform_dataframe(dataframe)
#         else:
#             return DataFrame([])
# 
#     def to_representation(self, data):
#         if isinstance(data, DataFrame):
#             return data
#         return super(PandasSerializer, self).to_representation(data)
# 
#     @property
#     def model_serializer(self):
#         serializer = type(self.child)
#         if serializer.__name__ == 'SerializerWithListSerializer':
#             return serializer.__bases__[0]
#         return serializer
# 
#     @property
#     def model_serializer_meta(self):
#         return getattr(self.model_serializer, 'Meta', object())
# 
#     def get_index_fields(self):
#         """
#         List of fields to use for index
#         """
#         index_fields = self.get_meta_option('index', [])
#         if index_fields:
#             return index_fields
# 
#         model = getattr(self.model_serializer_meta, 'model', None)
#         if model:
#             pk_name = model._meta.pk.name
#             if pk_name in self.child.get_fields():
#                 return [pk_name]
# 
#         return []
# 
#     def get_meta_option(self, name, default=None):
#         meta_name = 'pandas_' + name
#         value = getattr(self.model_serializer_meta, meta_name, None)
# 
#         if value is None:
#             if default is not None:
#                 return default
#             else:
#                 raise ImproperlyConfigured(
#                     "%s should be specified on %s.Meta" %
#                     (meta_name, self.model_serializer.__name__)
#                 )
#         return value


from .renderers import PandasBaseRenderer
    from rest_framework.views import APIView
from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from django.conf import settings
from rest_framework.settings import perform_import
from .serializers import (
    SimpleSerializer, PandasSerializer
)

class PandasMixin(object):
    pandas_serializer_class = PandasSerializer

    def with_list_serializer(self, cls):
        meta = getattr(cls, 'Meta', object)
        if getattr(meta, 'list_serializer_class', None):
            return cls

        class SerializerWithListSerializer(cls):
            class Meta(meta):
                list_serializer_class = self.pandas_serializer_class

        return SerializerWithListSerializer

    def get_serializer_class(self):

        # c.f rest_framework.generics.GenericAPIView
        # (not using super() since this is a mixin class)
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer_class()` method."
            % self.__class__.__name__
        )

        renderer = self.request.accepted_renderer
        if hasattr(renderer, 'get_default_renderer'):
            # BrowsableAPIRenderer
            renderer = renderer.get_default_renderer(self)


# Path: rest_pandas/renderers.py
# class PandasBaseRenderer(BaseRenderer):
#     """
#     Renders DataFrames using their built in pandas implementation.
#     Only works with serializers that return DataFrames as their data object.
#     Uses a StringIO to capture the output of dataframe.to_[format]()
#     """
#     def render(self, data, accepted_media_type=None, renderer_context=None):
#         if renderer_context and 'response' in renderer_context:
#             status_code = renderer_context['response'].status_code
#             if not status.is_success(status_code):
#                 return "Error: %s" % data.get('detail', status_code)
# 
#         if not isinstance(data, DataFrame):
#             raise Exception(
#                 RESPONSE_ERROR % type(data).__name__
#             )
# 
#         name = getattr(self, 'function', "to_%s" % self.format)
#         if not hasattr(data, name):
#             raise Exception("Data frame is missing %s property!" % name)
# 
#         self.init_output()
#         args = self.get_pandas_args(data)
#         kwargs = self.get_pandas_kwargs(data, renderer_context)
#         self.render_dataframe(data, name, *args, **kwargs)
#         return self.get_output()
# 
#     def render_dataframe(self, data, name, *args, **kwargs):
#         function = getattr(data, name)
#         function(*args, **kwargs)
# 
#     def init_output(self):
#         self.output = StringIO()
# 
#     def get_output(self):
#         return self.output.getvalue()
# 
#     def get_pandas_args(self, data):
#         return [self.output]
# 
#     def get_pandas_kwargs(self, data, renderer_context):
#         return {}
# 
# Path: rest_pandas/serializers.py
# class SimpleSerializer(serializers.Serializer):
#     """
#     Simple serializer for non-model (simple) views
#     """
#     def to_representation(self, obj):
#         return obj
# 
# class PandasSerializer(serializers.ListSerializer):
#     """
#     Transforms dataset into a dataframe and applies an index
#     """
#     read_only = True
#     index_none_value = None
#     wq_chart_type = None
# 
#     def get_index(self, dataframe):
#         return self.get_index_fields()
# 
#     def get_dataframe(self, data):
#         dataframe = DataFrame(data)
#         index = self.get_index(dataframe)
#         if index:
#             if self.index_none_value is not None:
#                 for key in index:
#                     try:
#                         dataframe[key].fillna(
#                             self.index_none_value, inplace=True
#                         )
#                     except ValueError:
#                         pass
#             dataframe.set_index(index, inplace=True)
#         else:
#             # Name auto-index column to ensure valid CSV output
#             dataframe.index.name = 'row'
#         return dataframe
# 
#     def transform_dataframe(self, dataframe):
#         view = self.context.get('view', None)
#         if view and hasattr(view, 'transform_dataframe'):
#             return self.context['view'].transform_dataframe(dataframe)
#         return dataframe
# 
#     @property
#     def data(self):
#         data = super(serializers.ListSerializer, self).data
#         if isinstance(data, DataFrame) or data:
#             dataframe = self.get_dataframe(data)
#             return self.transform_dataframe(dataframe)
#         else:
#             return DataFrame([])
# 
#     def to_representation(self, data):
#         if isinstance(data, DataFrame):
#             return data
#         return super(PandasSerializer, self).to_representation(data)
# 
#     @property
#     def model_serializer(self):
#         serializer = type(self.child)
#         if serializer.__name__ == 'SerializerWithListSerializer':
#             return serializer.__bases__[0]
#         return serializer
# 
#     @property
#     def model_serializer_meta(self):
#         return getattr(self.model_serializer, 'Meta', object())
# 
#     def get_index_fields(self):
#         """
#         List of fields to use for index
#         """
#         index_fields = self.get_meta_option('index', [])
#         if index_fields:
#             return index_fields
# 
#         model = getattr(self.model_serializer_meta, 'model', None)
#         if model:
#             pk_name = model._meta.pk.name
#             if pk_name in self.child.get_fields():
#                 return [pk_name]
# 
#         return []
# 
#     def get_meta_option(self, name, default=None):
#         meta_name = 'pandas_' + name
#         value = getattr(self.model_serializer_meta, meta_name, None)
# 
#         if value is None:
#             if default is not None:
#                 return default
#             else:
#                 raise ImproperlyConfigured(
#                     "%s should be specified on %s.Meta" %
#                     (meta_name, self.model_serializer.__name__)
#                 )
#         return value


# Path: rest_pandas/views.py
from .renderers import PandasBaseRenderer
    from rest_framework.views import APIView
from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from django.conf import settings
from rest_framework.settings import perform_import
from .serializers import (
    SimpleSerializer, PandasSerializer
)


class PandasMixin(object):
    pandas_serializer_class = PandasSerializer

    def with_list_serializer(self, cls):
        meta = getattr(cls, 'Meta', object)
        if getattr(meta, 'list_serializer_class', None):
            return cls

        class SerializerWithListSerializer(cls):
            class Meta(meta):
                list_serializer_class = self.pandas_serializer_class

        return SerializerWithListSerializer

    def get_serializer_class(self):

        # c.f rest_framework.generics.GenericAPIView
        # (not using super() since this is a mixin class)
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer_class()` method."
            % self.__class__.__name__
        )

        renderer = self.request.accepted_renderer
        if hasattr(renderer, 'get_default_renderer'):
            # BrowsableAPIRenderer
            renderer = renderer.get_default_renderer(self)


        if isinstance(renderer, PandasBaseRenderer):