Пример #1
0
    def test_template_renders_with_no_warnings(self):
        """The Tempita tmpl-api.rst template should render for the sample
        annotated API docstring with no errors.
        """
        ds = self.sample_api_annotated_docstring
        template = APITemplateRenderer()
        template_path = (
            "%s/../%s" %
            (os.path.dirname(__file__), self.api_tempita_template))

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds, uri=self.test_uri_plural)

        result = template.apply_template(template_path, api_docstring_parser)

        self.assertThat(result, Not(Contains("API_WARNING")))
Пример #2
0
def render_api_docs():
    """Render ReST documentation for the REST API.


    This module's docstring forms the head of the documentation; details of
    the API methods follow.

    :return: Documentation, in ReST, for the API.
    :rtype: :class:`unicode`
    """
    from maasserver import urls_api as urlconf

    module = sys.modules[__name__]
    output = StringIO()
    line = partial(print, file=output)

    line(getdoc(module))
    line()
    line()
    line("Operations")
    line("``````````")
    line()

    def export_key(export):
        """Return a sortable key for an export.

        `op` is often `None`, which cannot be compared to non-`None`
        operations.
        """
        (http_method, op), function = export
        if op is None:
            return http_method, "", function
        else:
            return http_method, op, function

    annotation_parser = APIDocstringParser()
    templates = APITemplateRenderer()
    resources = find_api_resources(urlconf)
    for doc in generate_api_docs(resources):
        uri_template = doc.resource_uri_template
        exports = doc.handler.exports.items()
        # Derive a section title from the name of the handler class.
        section_name = doc.handler.api_doc_section_name
        line(section_name)
        line("=" * len(section_name))
        # Note:
        # The following dedent is useless in the following situation:
        #
        # def somefunc(foo)
        #     """No indent here
        #
        #     Here, there is an indent, so dedent doesn't do
        #     anything.
        #    """
        #
        # This fixes the problem:
        #
        # def somefunc(foo)
        #     """
        #     Indent here
        #
        #     Now dedent works because the entire docstring appears
        #     to be indented.
        #    """
        #
        # This also works because the dedent version is the same
        # as the non-dented version:
        #
        # def somefunc(foo)
        #     """No indent here"""
        #
        line(dedent(doc.handler.__doc__).strip())
        line()
        line()
        for (http_method, op), function in sorted(exports, key=export_key):
            operation = " op=%s" % op if op is not None else ""
            subsection = "``%s %s%s``" % (http_method, uri_template, operation)
            docstring = getdoc(function)
            if docstring is not None:
                if APIDocstringParser.is_annotated_docstring(docstring):
                    operation = "op=%s" % op if op is not None else ""
                    annotation_parser.parse(
                        docstring, http_method, uri_template, operation
                    )
                    line(
                        templates.apply_template(
                            os.path.dirname(__file__) + "/tmpl-apidoc.rst",
                            annotation_parser,
                        )
                    )
                else:
                    line("%s\n%s\n" % (subsection, "#" * len(subsection)))
                    line()
                    for docline in dedent(docstring).splitlines():
                        if docline.strip() == "":
                            # Blank line.  Don't indent.
                            line()
                        else:
                            # Print documentation line, indented.
                            line(docline)
                line()
            else:
                line("%s\n%s\n" % (subsection, "#" * len(subsection)))
                line()

    line()
    line()
    line(generate_power_types_doc())
    line()
    line()
    line(generate_pod_types_doc())

    return output.getvalue()