def build_query_parameters(self):
        parameter_type = 'query'
        params = self.get_method_parameter_data(parameter_type)
        if params:
            return params

        params = []

        docstring = self.retrieve_docstring() or ''
        docstring += "\n" + get_view_description(self.callback)
        docstring = trim_docstring(docstring)

        if not docstring:
            return params

        split_lines = docstring.split('\n')
        # TODO: use filter_class instead of docstring if available
        for line in split_lines:
            param = line.split(' -- ')
            if len(param) == 2:
                params.append({'paramType': parameter_type,
                               'name': param[0].strip(),
                               'description': param[1].strip(),
                               'dataType': ''})

        return params
    def __get_notes__(self, callback, method=None):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        if method is not None:
            docs = []
            class_docs = self.__get_notes__(callback)
            method_docs = self.__eval_method_docstring_(callback, method)

            if class_docs is not None:
                docs.append(class_docs)
            if method_docs is not None:
                docs.append(method_docs)
            docstring += "\n".join(docs)
        else:
            docstring = trim_docstring(get_view_description(callback))

        docstring = self.__strip_params_from_docstring__(docstring)
        docstring = docstring.replace("\n", "<br/>")

        return docstring
 def get_field_help_text(cls, field):
     help_text = getattr(field, 'help_text')
     if not help_text:
         # attempt to read help text from underlying Model, if any such
         # model exists
         try:
             model = field.parent.Meta.model
             model_source = getattr(model, field.source, None)
             model_source_doc = getattr(model_source, '__doc__', None)
             if model_source_doc:
                 # source is a function or property on the model so use it's
                 # docstring
                 help_text = trim_docstring(model_source_doc)
             else:
                 # source is a Model field instead of callable so attempt
                 # to read help_text from that
                 model_field = model._meta.get_field_by_name(field.source)
                 help_text = model_field[0].help_text
         except (AttributeError, IndexError, TypeError, FieldDoesNotExist):
             pass
     if getattr(field, 'read_only', False):
         help_text = help_text.strip()
         if help_text[-1] == '.':
             help_text = help_text[:-1]
         help_text += u'. Read-only'
     return help_text
示例#4
0
    def get_notes(self):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        sw_notes = self._get_swdocs('notes')
        if sw_notes is not None:
            return sw_notes

        docstring = ""

        class_docs = trim_docstring(get_view_description(self.callback))
        method_docs = self.get_docs()

        if class_docs is not None:
            docstring += class_docs
        if method_docs is not None:
            docstring += '\n' + method_docs

        docstring = IntrospectorHelper.strip_params_from_docstring(docstring)
        docstring = re.sub(r'\n\s+\n', "<br/>", docstring)
        docstring = docstring.replace("\n", " ")

        return docstring
示例#5
0
 def __eval_method_docstring_(self, callback, method):
     """
     Attempts to fetch the docs for a class method. If method does not
     exist tries class based views method name because we might have subclassed
     GenericAPIView and some mixins. Returns None
     if the method does not exist after second try.
     """
     mapping = {
         'post': ['create'],
         'get': ['retrieve', 'list'],
         'put': ['update'],
         'patch': ['partial_update'],
         'delete': ['destroy']
     }
     try:
         doc_str = None
         mapped = mapping[str(method).lower()]
         for m in mapped:
             try:
                 doc_str = eval("callback.%s.__doc__" % (m))
             except AttributeError:
                 pass
             if doc_str:
                 return self.__markdownize_method_docs(
                     trim_docstring(doc_str))
     except AttributeError:
         pass
     try:
         return eval("callback.%s.__doc__" % (str(method).lower()))
     except AttributeError:
         return None
 def __eval_method_docstring_(self, callback, method):
     """
     Attempts to fetch the docs for a class method. If method does not
     exist tries class based views method name because we might have subclassed
     GenericAPIView and some mixins. Returns None
     if the method does not exist after second try.
     """
     mapping = {
         'post': ['create'],
         'get': ['retrieve', 'list'],
         'put': ['update'],
         'patch': ['partial_update'],
         'delete': ['destroy']
     }
     try:
         doc_str = None
         mapped = mapping[str(method).lower()]
         for m in mapped:
             try:
                 doc_str = eval("callback.%s.__doc__" % (m))
             except AttributeError:
                 pass
             if doc_str:
                 return self.__markdownize_method_docs(trim_docstring(doc_str))
     except AttributeError:
         pass
     try:
         return eval("callback.%s.__doc__" % (str(method).lower()))
     except AttributeError:
         return None
    def __build_query_params_from_docstring__(self, callback, method=None):

        params = []
        # Combine class & method level comments. If parameters are specified
        if method is not None:
            try:
                docstring = trim_docstring(eval("callback.%s.__doc__" % (str(method).lower())))
            except:
                if str(method).lower() == 'get':
                    docstring = eval("callback.list.__doc__")
                elif str(method).lower() == 'post':
                    docstring = eval("callback.create.__doc__")
                else:
                    docstring = get_view_description(callback)

            params += self.__build_query_params_from_docstring__(callback)
        else: # Otherwise, get the class level docstring
            docstring = get_view_description(callback)

        split_lines = docstring.split('\n') if docstring else []

        for line in split_lines:
            param = line.split(' -- ')
            if len(param) == 2:
                params.append({
                    'paramType': 'query',
                    'name': param[0].strip(),
                    'description': param[1].strip(),
                    'dataType': '',
                })

        return params
    def __get_notes__(self, callback, method=None):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        if method is not None:
            class_docs = self.__get_notes__(callback)
            try:
                method_docs = eval("callback.%s.__doc__" % (str(method).lower()))
            except:
                if str(method).lower() == 'get':
                    method_docs = eval("callback.list.__doc__")
                elif str(method).lower() == 'post':
                    method_docs = eval("callback.create.__doc__")
                else:
                    method_docs = None
            if class_docs is not None:
                docstring += class_docs
            if method_docs is not None:
                docstring += method_docs
        else:
            docstring = trim_docstring(get_view_description(callback))

        docstring = self.__strip_params_from_docstring__(docstring)
        docstring = docstring.replace("\n", "<br/>")

        return docstring
示例#9
0
    def _get_description(self):
        """Return the view's docstring as a description.

        This method is a customization of Django REST framework's. There are
        two changes:

        - Our parent's docstring is used if we don't have one ourselves. This
          makes it easy to use a base class with proper documentation on which
          items to expect. The documentation is propagated to every API that
          uses the base class.

        - The docstring is parsed with restructuredtext syntax instead of
          markdown (markdown is preferred by Django REST framework).

        """

        description = self.__doc__
        if description is None:
            # Trick to get our parent's docstring as a fallback if we don't
            # have one ourselves. From
            # http://stackoverflow.com/a/13937525/27401 .
            try:
                description = next(
                    cls.__doc__ for cls in inspect.getmro(type(self))
                    if cls.__doc__ is not None)
            except StopIteration:
                pass
        return trim_docstring(description)
示例#10
0
    def _get_description(self):
        """Return the view's docstring as a description.

        This method is a customization of Django REST framework's. There are
        two changes:

        - Our parent's docstring is used if we don't have one ourselves. This
          makes it easy to use a base class with proper documentation on which
          items to expect. The documentation is propagated to every API that
          uses the base class.

        - The docstring is parsed with restructuredtext syntax instead of
          markdown (markdown is preferred by Django REST framework).

        """

        description = self.__doc__
        if description is None:
            # Trick to get our parent's docstring as a fallback if we don't
            # have one ourselves. From
            # http://stackoverflow.com/a/13937525/27401 .
            try:
                description = next(cls.__doc__
                                   for cls in inspect.getmro(type(self))
                                   if cls.__doc__ is not None)
            except StopIteration:
                pass
        return trim_docstring(description)
    def get_notes(self):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        sw_notes = self._get_swdocs('notes')
        if sw_notes is not None:
            return sw_notes

        docstring = ""

        class_docs = trim_docstring(get_view_description(self.callback))
        method_docs = self.get_docs()

        if class_docs is not None:
            docstring += class_docs
        if method_docs is not None:
            docstring += '\n' + method_docs

        docstring = IntrospectorHelper.strip_params_from_docstring(docstring)
        docstring = re.sub(r'\n\s+\n', "<br/>", docstring)
        docstring = docstring.replace("\n", " ")

        return docstring
    def get_method_summary(self, callback, method, path=None):
        docs = self.get_method_docs(callback, method, path)
        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.get_description(callback)
        docs = trim_docstring(docs).split('\n')[0]

        return docs
示例#13
0
    def get_method_summary(self, callback, method, path=None):
        docs = self.get_method_docs(callback, method, path)
        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.get_description(callback)
        docs = trim_docstring(docs).split('\n')[0]

        return docs
示例#14
0
 def user_docs(self):
     for mod_prefix in ('botbot_plugins.plugins.',
                        'botbot.apps.plugins.core.'):
         try:
             docs = import_module(mod_prefix + self.slug).Plugin.__doc__
             return trim_docstring(docs)
         except (ImportError, AttributeError):
             continue
     return ''
示例#15
0
 def user_docs(self):
     for mod_prefix in ('botbot_plugins.plugins.',
                        'botbot.apps.plugins.core.'):
         try:
             docs = import_module(mod_prefix + self.slug).Plugin.__doc__
             return trim_docstring(docs)
         except (ImportError, AttributeError):
             continue
     return ''
示例#16
0
 def retrieve_docstring(self):
     """
     Attempts to fetch the docs for a class method. Returns None
     if the method does not exist
     """
     method = self._get_method_callback()
     if not method:
         return None
     return trim_docstring(method.__doc__)
    def get_summary(self):
        docs = self.get_docs()

        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.parent.get_description()
        docs = trim_docstring(docs).split('\n')[0]

        return docs
示例#18
0
    def get_summary(self):
        docs = self.get_docs()

        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.parent.get_description()
        docs = trim_docstring(docs).split('\n')[0]

        return docs
    def split_docstring(cls, docstring):
        docstring = trim_docstring(docstring)

        splitter_re = "^|\n{}".format(re.escape(cls.SPLITTER))
        ptn = re.compile(splitter_re)
        splitted = ptn.split(docstring, maxsplit=1)  # `rsplit` would be more useful though.

        if len(splitted) != 2:
            return None, None
        return splitted
示例#20
0
 def test_trim_docstring(self):
     trim_docstring_output = utils.trim_docstring(self.docstring)
     trimmed_docstring = (
         'This __doc__ output is required for testing. I copied this '
         'example from\n`admindocs` documentation. (TITLE)\n\n'
         'Display an individual :model:`myapp.MyModel`.\n\n'
         '**Context**\n\n``RequestContext``\n\n``mymodel``\n'
         '    An instance of :model:`myapp.MyModel`.\n\n'
         '**Template:**\n\n:template:`myapp/my_template.html` '
         '(DESCRIPTION)\n\nsome_metadata: some data')
     self.assertEqual(trim_docstring_output, trimmed_docstring)
示例#21
0
    def get_notes(self):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        class_docs = trim_docstring(get_view_description(self.callback))
        method_docs = trim_docstring(self.get_docs())

        if class_docs is not None:
            docstring += class_docs
        if method_docs is not None:
            docstring += '\n\n' + method_docs

        docstring = IntrospectorHelper.strip_params_from_docstring(docstring)
        docstring = markdown.markdown(escape(docstring))

        return docstring
示例#22
0
def doc_functions(request):
    group_list = []
    for group_name, functions in AVAILABLE_API_FUNCTIONS.items():
        function_list = []
        for name, function in functions.items():
            heading, body, metadata = parse_docstring(function.__doc__)
            body = trim_docstring(body)
            function_list.append({
                'name':
                name,
                'description':
                build_function_description(function),
                'docstring':
                trim_docstring('{0}\n\n{1}'.format(heading, body)),
            })
        function_list.sort(key=itemgetter('name'))

        group_list.append({'name': group_name, 'function_list': function_list})
    group_list.sort(key=itemgetter('name'))
    return TemplateResponse(request, 'api/list_functions.html',
                            {'group_list': group_list})
示例#23
0
    def get_summary(self):
        docs = self.get_docs()

        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.parent.get_description()
        docs = trim_docstring(docs).split("\n")[0].split(".")[0]
        if apply_markdown:
            from .compat import strip_tags
            docs = strip_tags(do_markdown(docs))

        return docs
示例#24
0
    def get_summary(self):
        docs = self.get_docs()

        # If there is no docstring on the method, get class docs
        if docs is None:
            docs = self.parent.get_description()
        docs = trim_docstring(docs).split("\n")[0].split(".")[0]
        if apply_markdown:
            from .compat import strip_tags
            docs = strip_tags(do_markdown(docs))

        return docs
    def test_strip_params_from_docstring(self):
        class AnAPIView(APIView):
            """
            My comments are here

            param -- my param
            """
            pass

        docstring = IntrospectorHelper.strip_params_from_docstring(trim_docstring(AnAPIView.__doc__))

        self.assertEqual("My comments are here<br/>", docstring)
示例#26
0
 def test_trim_docstring(self):
     trim_docstring_output = utils.trim_docstring(self.docstring)
     trimmed_docstring = (
         'This __doc__ output is required for testing. I copied this '
         'example from\n`admindocs` documentation. (TITLE)\n\n'
         'Display an individual :model:`myapp.MyModel`.\n\n'
         '**Context**\n\n``RequestContext``\n\n``mymodel``\n'
         '    An instance of :model:`myapp.MyModel`.\n\n'
         '**Template:**\n\n:template:`myapp/my_template.html` '
         '(DESCRIPTION)\n\nsome_metadata: some data'
     )
     self.assertEqual(trim_docstring_output, trimmed_docstring)
示例#27
0
 def create_yaml_object(self, docstring):
     """Create YAML object from docstring"""
     docstring = trim_docstring(docstring)
     p = re.compile('^|\n{}'.format(YAMLDocstringParser.SPLITTER))
     splitted = p.split(docstring)
     if len(splitted) < 2:
         return None
     yaml_string = splitted[1]
     yaml_string = formatting.dedent(yaml_string)
     try:
         return yaml.load(yaml_string)
     except yaml.YAMLError as e:
         return None
示例#28
0
    def test_strip_params_from_docstring(self):
        class AnAPIView(APIView):
            """
            My comments are here

            param -- my param
            """
            pass

        docgen = DocumentationGenerator()
        docstring = docgen.__strip_params_from_docstring__(trim_docstring(AnAPIView.__doc__))

        self.assertEqual("My comments are here<br/><br/>", docstring)
示例#29
0
    def __get_method_docs__(self, callback, method):
        """
        Attempts to retrieve method specific docs for an
        endpoint. If none are available, the class docstring
        will be used
        """
        docs = self.__eval_method_docstring_(callback, method)

        if docs is None:
            docs = self.__get_description__(callback)
        docs = trim_docstring(docs).split('\n')[0]

        return docs
示例#30
0
    def test_strip_yaml_from_docstring(self):
        class AnAPIView(APIView):
            """
            My comments are here
            ---
            # This is YAML
            param: my param
            """
            pass

        docstring = IntrospectorHelper.strip_yaml_from_docstring(trim_docstring(AnAPIView.__doc__))

        self.assertEqual("My comments are here", docstring)
示例#31
0
    def __get_method_docs__(self, callback, method):
        """
        Attempts to retrieve method specific docs for an
        endpoint. If none are available, the class docstring
        will be used
        """
        docs = self.__eval_method_docstring_(callback, method)

        if docs is None:
            docs = self.__get_description__(callback)
        docs = trim_docstring(docs).split('\n')[0]

        return docs
示例#32
0
    def test_strip_params_from_docstring(self):
        class AnAPIView(APIView):
            """
            My comments are here

            param -- my param
            """
            pass

        docgen = DocumentationGenerator()
        docstring = docgen.__strip_params_from_docstring__(trim_docstring(AnAPIView.__doc__))

        self.assertEqual("My comments are here<br/>", docstring)
示例#33
0
    def load_obj_from_docstring(self, docstring):
        """Loads YAML from docstring"""

        # update one dict by other recursively
        def recursive_update(obj, other):
            for key, value in other.iteritems():
                if key in obj and key != 'overwrite':
                    # if value is dictionary we need to update it
                    if isinstance(value,
                                  dict) and not value.get('overwrite', False):
                        recursive_update(obj[key], other[key])
                    # if value is a list we need to extend it
                    elif isinstance(value, list):
                        obj[key].extend(value)
                    else:
                        obj[key] = value
                else:
                    obj[key] = value

        if not docstring:
            return {}

        split_lines = trim_docstring(docstring).split('\n')

        # Cut YAML from rest of docstring
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_from = index
                break
        else:
            return {}
        yaml_string = formatting.dedent("\n".join(split_lines[cut_from:]))

        try:
            yaml_obj = yaml.load(yaml_string)
            # if is parent view specified, we need to get docs from parent view
            if 'inherit_docs_from' in yaml_obj:
                parent_class = self._load_class(
                    yaml_obj['inherit_docs_from'],
                    self.method_introspector.callback)
                parent_docs = self.method_introspector.get_inherited_docs(
                    parent_class)
                parent_obj = self.load_obj_from_docstring(
                    docstring=parent_docs)
                recursive_update(parent_obj, yaml_obj)
                yaml_obj = parent_obj
        except yaml.YAMLError as e:
            self.yaml_error = e
            return {}
        return yaml_obj
示例#34
0
    def test_strip_yaml_from_docstring(self):
        class AnAPIView(APIView):
            """
            My comments are here
            ---
            # This is YAML
            param: my param
            """
            pass

        docstring = IntrospectorHelper.strip_yaml_from_docstring(
            trim_docstring(AnAPIView.__doc__))

        self.assertEqual("My comments are here", docstring)
示例#35
0
    def strip_yaml_from_docstring(docstring):
        """
        Strips YAML from the docstring.
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#36
0
    def strip_yaml_from_docstring(docstring):
        """
        Strips YAML from the docstring.
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#37
0
    def strip_params_from_docstring(docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param)
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.find('--') != -1:
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return u'\n'.join(split_lines)
示例#38
0
    def __strip_params_from_docstring__(self, docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param) will
        not be removed from the text body
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.find('--') != -1:
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "<br/>".join(split_lines)
示例#39
0
    def strip_params_from_docstring(docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param) will
        not be removed from the text body
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if PARAMS_PATTERN.search(line):
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#40
0
    def strip_params_from_docstring(self, docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param) will
        not be removed from the text body
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.find('--') != -1:
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "<br/>".join(split_lines)
示例#41
0
    def strip_yaml_from_docstring(docstring):
        """
        Strips YAML from the docstring.
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index in range(len(split_lines) - 1, -1, -1):
            line = split_lines[index]
            line = line.strip()
            if line == '---':
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
    def strip_yaml_from_docstring(docstring):
        """
        Strips YAML from the docstring.
        """
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index in range(len(split_lines) - 1, -1, -1):
            line = split_lines[index]
            line = line.strip()
            if line == '---':
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#43
0
    def load_obj_from_docstring(self, docstring):
        """Loads YAML from docstring"""

        # update one dict by other recursively
        def recursive_update(obj, other):
            for key, value in other.iteritems():
                if key in obj and key != 'overwrite':
                    # if value is dictionary we need to update it
                    if isinstance(value, dict) and not value.get('overwrite', False):
                        recursive_update(obj[key], other[key])
                    # if value is a list we need to extend it
                    elif isinstance(value, list):
                        obj[key].extend(value)
                    else:
                        obj[key] = value
                else:
                    obj[key] = value

        if not docstring:
            return {}

        split_lines = trim_docstring(docstring).split('\n')

        # Cut YAML from rest of docstring
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_from = index
                break
        else:
            return {}
        yaml_string = formatting.dedent("\n".join(split_lines[cut_from:]))

        try:
            yaml_obj = yaml.load(yaml_string)
            # if is parent view specified, we need to get docs from parent view
            if 'inherit_docs_from' in yaml_obj:
                parent_class = self._load_class(yaml_obj['inherit_docs_from'], self.method_introspector.callback)
                parent_docs = self.method_introspector.get_inherited_docs(parent_class)
                parent_obj = self.load_obj_from_docstring(docstring=parent_docs)
                recursive_update(parent_obj, yaml_obj)
                yaml_obj = parent_obj
        except yaml.YAMLError as e:
            self.yaml_error = e
            return {}
        return yaml_obj
示例#44
0
    def get_parsed_docstring(docstring):

        docstring = trim_docstring(docstring)
        split_lines = docstring.split('\n')
        trimmed = False  # Flag if string needs to be trimmed
        _params = []
        description = docstring
        version = '0'
        auth_req = False
        output_method = ''
        attr_found = False

        for line in split_lines:
            if not trimmed:
                needle = line.find('--')
                if needle != -1:
                    trim_at = docstring.find(line)
                    description = docstring[:trim_at]
                    trimmed = True

            params = line.split(' -- ')
            if len(params) == 2:
                param = params[0]
                optional = False
                if params[0].startswith('!'):
                    optional = True
                    param = param[1:]
                _params.append([param.strip(), params[1].strip(), optional])
            if line.find('version:') != -1:
                version = line.split(':')[1].strip()
                attr_found = True
            if line.find('auth_req:') != -1:
                auth_req = str2bool(line.split(':')[1].strip())
                attr_found = True
            if line.find('output_method:') != -1:
                output_method = line.split(':', 1)[1].strip()
                attr_found = True

            if attr_found and not trimmed:
                trim_at = docstring.find(line)
                description = docstring[:trim_at - 1]
                trimmed = True

        return {'description': description, 'params': _params, 'version': version, 'auth_req': auth_req,
                'output_method': output_method}
示例#45
0
    def strip_params_from_docstring(docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param) will
        not be removed from the text body
        """
        params_pattern = re.compile(r'(?:^|[^-])--(?:$|[^-])')
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if params_pattern.search(line):
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#46
0
    def strip_params_from_docstring(docstring):
        """
        Strips the params from the docstring (ie. myparam -- Some param) will
        not be removed from the text body
        """
        params_pattern = re.compile(r' -- ')
        split_lines = trim_docstring(docstring).split('\n')

        cut_off = None
        for index, line in enumerate(split_lines):
            line = line.strip()
            if params_pattern.search(line):
                cut_off = index
                break
        if cut_off is not None:
            split_lines = split_lines[0:cut_off]

        return "\n".join(split_lines)
示例#47
0
    def get_callback_property_data(cls, callback, property_name):
        """
        Returns the data parsed from the docstring defined for the given
        property attached to the callback. Returns None if no such
        docstring has been defined.
        """
        doc = getattr(callback, property_name, '')
        doc = trim_docstring(doc)

        data = None
        if doc:
            try:
                data = yaml.load(StringIO(doc))
            except yaml.ScannerError:
                logger.exception('Failed to parse docstring defined for %s',
                                 property_name)

        return data
    def load_obj_from_docstring(self, docstring):
        """Loads YAML from docstring"""
        split_lines = trim_docstring(docstring).split('\n')

        # Cut YAML from rest of docstring
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_from = index
                break
        else:
            return None

        yaml_string = "\n".join(split_lines[cut_from:])
        yaml_string = formatting.dedent(yaml_string)
        try:
            return yaml.load(yaml_string)
        except yaml.YAMLError as e:
            self.yaml_error = e
            return None
示例#49
0
    def load_obj_from_docstring(self, docstring):
        """Loads YAML from docstring"""
        split_lines = trim_docstring(docstring).split('\n')

        # Cut YAML from rest of docstring
        for index, line in enumerate(split_lines):
            line = line.strip()
            if line.startswith('---'):
                cut_from = index
                break
        else:
            return None

        yaml_string = "\n".join(split_lines[cut_from:])
        yaml_string = formatting.dedent(yaml_string)
        try:
            return yaml.load(yaml_string)
        except yaml.YAMLError as e:
            self.yaml_error = e
            return None
示例#50
0
    def get_docstring_fields(self, description):
        # bubble modify(add) 
        fields = []
        split_lines = trim_docstring(description).split('\n')
        temp_lines = []

        for line in split_lines:
            param = line.split(' -- ')
            if len(param) == 2:
                fields.append(coreapi.Field(name=param[0].strip(),
                                            required=False,
                                            location='query',
                                            description=param[1].strip()))
            else:
                temp_lines.append(line)
                temp_lines.append('\n')

        description = ''.join(temp_lines)

        return fields, description
示例#51
0
    def __get_notes__(self, callback, method=None):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        if method is not None:
            class_docs = self.__get_notes__(callback)
            method_docs = self.__eval_method_docstring_(callback, method)

            if class_docs is not None:
                docstring += class_docs
            if method_docs is not None:
                docstring += method_docs
        else:
            docstring = trim_docstring(get_view_description(callback, html=True))

        docstring = self.__strip_params_from_docstring__(docstring)

        return docstring
示例#52
0
    def get_notes(self, callback, method=None, path=None):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        if method is not None:
            class_docs = self.get_notes(callback)
            method_docs = self.get_method_docs(callback, method, path)

            if class_docs is not None:
                docstring += class_docs
            if method_docs is not None:
                docstring = '%s \n %s' % (class_docs, method_docs)
        else:
            docstring = trim_docstring(get_view_description(callback))

        docstring = self.strip_params_from_docstring(docstring)
        docstring = docstring.replace("\n\n", "<br/>")

        return docstring
示例#53
0
    def __get_notes__(self, callback, method=None):
        """
        Returns the body of the docstring trimmed before any parameters are
        listed. First, get the class docstring and then get the method's. The
        methods will always inherit the class comments.
        """
        docstring = ""

        if method is not None:
            class_docs = self.__get_notes__(callback)
            method_docs = self.__eval_method_docstring_(callback, method)

            if class_docs is not None:
                docstring += class_docs
            if method_docs is not None:
                docstring += method_docs
        else:
            docstring = trim_docstring(get_view_description(callback))

        docstring = self.__strip_params_from_docstring__(docstring)
        docstring = docstring.replace("\n", "<br/>")

        return docstring
示例#54
0
def model_detail(request, app_label, model_name):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    # Get the model class.
    try:
        app_mod = models.get_app(app_label)
    except ImproperlyConfigured:
        raise Http404, _("App %r not found") % app_label
    model = None
    for m in models.get_models(app_mod):
        if m._meta.object_name.lower() == model_name:
            model = m
            break
    if model is None:
        raise Http404, _(
            "Model %(model_name)r not found in app %(app_label)r") % {
                'model_name': model_name,
                'app_label': app_label
            }

    opts = model._meta

    # Gather fields/field descriptions.
    fields = []
    for field in opts.fields:
        # ForeignKey is a special case since the field will actually be a
        # descriptor that returns the other object
        if isinstance(field, models.ForeignKey):
            data_type = related_object_name = field.rel.to.__name__
            app_label = field.rel.to._meta.app_label
            verbose = utils.parse_rst(
                (_("the related `%(app_label)s.%(data_type)s` object") % {
                    'app_label': app_label,
                    'data_type': data_type
                }), 'model',
                _('model:') + data_type)
        else:
            data_type = get_readable_field_data_type(field)
            verbose = field.verbose_name
        fields.append({
            'name': field.name,
            'data_type': data_type,
            'verbose': verbose,
            'help_text': field.help_text,
        })

    # Gather model methods.
    for func_name, func in model.__dict__.items():
        if (inspect.isfunction(func)
                and len(inspect.getargspec(func)[0]) == 1):
            try:
                for exclude in MODEL_METHODS_EXCLUDE:
                    if func_name.startswith(exclude):
                        raise StopIteration
            except StopIteration:
                continue
            verbose = func.__doc__
            if verbose:
                verbose = utils.parse_rst(utils.trim_docstring(verbose),
                                          'model',
                                          _('model:') + opts.module_name)
            fields.append({
                'name': func_name,
                'data_type': get_return_data_type(func_name),
                'verbose': verbose,
            })

    # Gather related objects
    for rel in opts.get_all_related_objects():
        verbose = _("related `%(app_label)s.%(object_name)s` objects") % {
            'app_label': rel.opts.app_label,
            'object_name': rel.opts.object_name
        }
        accessor = rel.get_accessor_name()
        fields.append({
            'name':
            "%s.all" % accessor,
            'data_type':
            'List',
            'verbose':
            utils.parse_rst(
                _("all %s") % verbose, 'model',
                _('model:') + opts.module_name),
        })
        fields.append({
            'name':
            "%s.count" % accessor,
            'data_type':
            'Integer',
            'verbose':
            utils.parse_rst(
                _("number of %s") % verbose, 'model',
                _('model:') + opts.module_name),
        })
    return render_to_response(
        'admin_doc/model_detail.html', {
            'root_path': get_root_path(),
            'name': '%s.%s' % (opts.app_label, opts.object_name),
            'summary': _("Fields on %s objects") % opts.object_name,
            'description': model.__doc__,
            'fields': fields,
        },
        context_instance=RequestContext(request))
示例#55
0
    def get_context_data(self, **kwargs):
        model_name = self.kwargs['model_name']
        # Get the model class.
        try:
            app_config = apps.get_app_config(self.kwargs['app_label'])
        except LookupError:
            raise Http404(_("App %(app_label)r not found") % self.kwargs)
        try:
            model = app_config.get_model(model_name)
        except LookupError:
            raise Http404(
                _("Model %(model_name)r not found in app %(app_label)r") %
                self.kwargs)

        opts = model._meta

        title, body, metadata = utils.parse_docstring(model.__doc__)
        if title:
            title = utils.parse_rst(title, 'model', _('model:') + model_name)
        if body:
            body = utils.parse_rst(body, 'model', _('model:') + model_name)

        # Gather fields/field descriptions.
        fields = []
        for field in opts.fields:
            # ForeignKey is a special case since the field will actually be a
            # descriptor that returns the other object
            if isinstance(field, models.ForeignKey):
                data_type = field.rel.to.__name__
                app_label = field.rel.to._meta.app_label
                verbose = utils.parse_rst(
                    (_("the related `%(app_label)s.%(data_type)s` object") % {
                        'app_label': app_label,
                        'data_type': data_type,
                    }),
                    'model',
                    _('model:') + data_type,
                )
            else:
                data_type = get_readable_field_data_type(field)
                verbose = field.verbose_name
            fields.append({
                'name': field.name,
                'data_type': data_type,
                'verbose': verbose,
                'help_text': field.help_text,
            })

        # Gather many-to-many fields.
        for field in opts.many_to_many:
            data_type = field.rel.to.__name__
            app_label = field.rel.to._meta.app_label
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {
                'app_label': app_label,
                'object_name': data_type,
            }
            fields.append({
                'name':
                "%s.all" % field.name,
                "data_type":
                'List',
                'verbose':
                utils.parse_rst(
                    _("all %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
            fields.append({
                'name':
                "%s.count" % field.name,
                'data_type':
                'Integer',
                'verbose':
                utils.parse_rst(
                    _("number of %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })

        # Gather model methods.
        for func_name, func in model.__dict__.items():
            if (inspect.isfunction(func)
                    and len(inspect.getargspec(func)[0]) == 1):
                try:
                    for exclude in MODEL_METHODS_EXCLUDE:
                        if func_name.startswith(exclude):
                            raise StopIteration
                except StopIteration:
                    continue
                verbose = func.__doc__
                if verbose:
                    verbose = utils.parse_rst(utils.trim_docstring(verbose),
                                              'model',
                                              _('model:') + opts.model_name)
                fields.append({
                    'name': func_name,
                    'data_type': get_return_data_type(func_name),
                    'verbose': verbose,
                })

        # Gather related objects
        for rel in opts.related_objects:
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {
                'app_label': rel.related_model._meta.app_label,
                'object_name': rel.related_model._meta.object_name,
            }
            accessor = rel.get_accessor_name()
            fields.append({
                'name':
                "%s.all" % accessor,
                'data_type':
                'List',
                'verbose':
                utils.parse_rst(
                    _("all %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
            fields.append({
                'name':
                "%s.count" % accessor,
                'data_type':
                'Integer',
                'verbose':
                utils.parse_rst(
                    _("number of %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
        kwargs.update({
            'name': '%s.%s' % (opts.app_label, opts.object_name),
            'summary': title,
            'description': body,
            'fields': fields,
        })
        return super(ModelDetailView, self).get_context_data(**kwargs)
 def __trim(self, docstring):
     """
     Trims whitespace from docstring
     """
     return trim_docstring(docstring)
示例#57
0
文件: views.py 项目: 0x008800/Sandbox
    def get_context_data(self, **kwargs):
        model_name = self.kwargs['model_name']
        # Get the model class.
        try:
            app_config = apps.get_app_config(self.kwargs['app_label'])
        except LookupError:
            raise Http404(_("App %(app_label)r not found") % self.kwargs)
        try:
            model = app_config.get_model(model_name)
        except LookupError:
            raise Http404(
                _("Model %(model_name)r not found in app %(app_label)r") %
                self.kwargs)

        opts = model._meta

        title, body, metadata = utils.parse_docstring(model.__doc__)
        if title:
            title = utils.parse_rst(title, 'model', _('model:') + model_name)
        if body:
            body = utils.parse_rst(body, 'model', _('model:') + model_name)

        # Gather fields/field descriptions.
        fields = []
        for field in opts.fields:
            # ForeignKey is a special case since the field will actually be a
            # descriptor that returns the other object
            if isinstance(field, models.ForeignKey):
                data_type = field.remote_field.model.__name__
                app_label = field.remote_field.model._meta.app_label
                verbose = utils.parse_rst(
                    (_("the related `%(app_label)s.%(data_type)s` object") % {
                        'app_label': app_label,
                        'data_type': data_type,
                    }),
                    'model',
                    _('model:') + data_type,
                )
            else:
                data_type = get_readable_field_data_type(field)
                verbose = field.verbose_name
            fields.append({
                'name': field.name,
                'data_type': data_type,
                'verbose': verbose or '',
                'help_text': field.help_text,
            })

        # Gather many-to-many fields.
        for field in opts.many_to_many:
            data_type = field.remote_field.model.__name__
            app_label = field.remote_field.model._meta.app_label
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {
                'app_label': app_label,
                'object_name': data_type,
            }
            fields.append({
                'name':
                "%s.all" % field.name,
                "data_type":
                'List',
                'verbose':
                utils.parse_rst(
                    _("all %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
            fields.append({
                'name':
                "%s.count" % field.name,
                'data_type':
                'Integer',
                'verbose':
                utils.parse_rst(
                    _("number of %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })

        methods = []
        # Gather model methods.
        for func_name, func in model.__dict__.items():
            if inspect.isfunction(func):
                try:
                    for exclude in MODEL_METHODS_EXCLUDE:
                        if func_name.startswith(exclude):
                            raise StopIteration
                except StopIteration:
                    continue
                verbose = func.__doc__
                if verbose:
                    verbose = utils.parse_rst(utils.trim_docstring(verbose),
                                              'model',
                                              _('model:') + opts.model_name)
                # If a method has no arguments, show it as a 'field', otherwise
                # as a 'method with arguments'.
                if func_has_no_args(func) and not func_accepts_kwargs(
                        func) and not func_accepts_var_args(func):
                    fields.append({
                        'name': func_name,
                        'data_type': get_return_data_type(func_name),
                        'verbose': verbose or '',
                    })
                else:
                    arguments = get_func_full_args(func)
                    # Join arguments with ', ' and in case of default value,
                    # join it with '='. Use repr() so that strings will be
                    # correctly displayed.
                    print_arguments = ', '.join([
                        '='.join(
                            list(arg_el[:1]) + [repr(el) for el in arg_el[1:]])
                        for arg_el in arguments
                    ])
                    methods.append({
                        'name': func_name,
                        'arguments': print_arguments,
                        'verbose': verbose or '',
                    })

        # Gather related objects
        for rel in opts.related_objects:
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {
                'app_label': rel.related_model._meta.app_label,
                'object_name': rel.related_model._meta.object_name,
            }
            accessor = rel.get_accessor_name()
            fields.append({
                'name':
                "%s.all" % accessor,
                'data_type':
                'List',
                'verbose':
                utils.parse_rst(
                    _("all %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
            fields.append({
                'name':
                "%s.count" % accessor,
                'data_type':
                'Integer',
                'verbose':
                utils.parse_rst(
                    _("number of %s") % verbose, 'model',
                    _('model:') + opts.model_name),
            })
        kwargs.update({
            'name': '%s.%s' % (opts.app_label, opts.object_name),
            'summary': title,
            'description': body,
            'fields': fields,
            'methods': methods,
        })
        return super(ModelDetailView, self).get_context_data(**kwargs)