import json
import inspect
from django.contrib.admindocs.views import simplify_regex
from django.utils.encoding import force_str
from rest_framework.serializers import BaseSerializer


class ApiEndpoint(object):

    def __init__(self, pattern, parent_pattern=None):
        self.pattern = pattern
        self.callback = pattern.callback
        # self.name = pattern.name
        self.docstring = self.__get_docstring__()
        self.name_parent = simplify_regex(parent_pattern.regex.pattern).strip('/') if parent_pattern else None
        self.path = self.__get_path__(parent_pattern)
        self.allowed_methods = self.__get_allowed_methods__()
        # self.view_name = pattern.callback.__name__
        self.errors = None
        self.serializer_class = self.__get_serializer_class__()
        if self.serializer_class:
            self.serializer = self.serializer_class()
            self.fields = self.__get_serializer_fields__(self.serializer)
            self.fields_json = self.__get_serializer_fields_json__()

        self.permissions = self.__get_permissions_class__()

    def __get_path__(self, parent_pattern):
        if parent_pattern:
            return "/{0}{1}".format(self.name_parent, simplify_regex(self.pattern.regex.pattern))
        return simplify_regex(self.pattern.regex.pattern)

    def __get_allowed_methods__(self):
        return [force_str(m).upper() for m in self.callback.cls.http_method_names if hasattr(self.callback.cls, m)]

    def __get_docstring__(self):
        return inspect.getdoc(self.callback)

    def __get_permissions_class__(self):
        for perm_class in self.pattern.callback.cls.permission_classes:
            return perm_class.__name__

    def __get_serializer_class__(self):
        if hasattr(self.callback.cls, 'serializer_class'):
            return self.callback.cls.serializer_class

        if hasattr(self.callback.cls, 'get_serializer_class'):
            return self.callback.cls.get_serializer_class(self.pattern.callback.cls())

    def __get_serializer_fields__(self, serializer):
        fields = []

        if hasattr(serializer, 'get_fields'):
            try:
                for key, field in serializer.get_fields().items():
                    sub_fields = self.__get_serializer_fields__(field) if isinstance(field, BaseSerializer) else None
                    fields.append({
                        "name": key,
                        "type": str(field.__class__.__name__),
                        "sub_fields": sub_fields,
                        "required": field.required
                    })
            except KeyError as e:
                self.errors = e
                fields = []

            # FIXME:
            # Show more attibutes of `field`?

        return fields

    def __get_serializer_fields_json__(self):
        # FIXME:
        # Return JSON or not?
        return json.dumps(self.fields)

@@ -853,24 +853,30 @@
 izer = self.
+__get_
 serializer_c
@@ -874,21 +874,17 @@
 ializer_
-class
+_
 ()%0A     
@@ -1699,16 +1699,165 @@
 name__%0A%0A
+    def __get_serializer__(self):%0A        try:%0A            return self.serializer_class()%0A        except KeyError as e:%0A            self.errors = e%0A%0A
     def 
@@ -2277,29 +2277,8 @@
 '):%0A
-            try:%0A    
     
@@ -2336,20 +2336,16 @@
 tems():%0A
-    
         
@@ -2462,28 +2462,24 @@
             
-    
 fields.appen
@@ -2502,20 +2502,16 @@
         
-    
 %22name%22: 
@@ -2535,20 +2535,16 @@
         
-   
- 
 %22type%22: 
@@ -2594,20 +2594,16 @@
         
-    
 %22sub_fie
@@ -2620,20 +2620,16 @@
 fields,%0A
-    
         
@@ -2687,109 +2687,10 @@
     
-    %7D)%0A            except KeyError as e:%0A                self.errors = e%0A                fields = %5B%5D%0A
+%7D)
 %0A   

Handle KeyError in ApiEndpoint