forked from sphinx-contrib/openapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sphinx-contrib#71 from sphinx-contrib/arch/renderers
Add renderers concept
- Loading branch information
Showing
8 changed files
with
237 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"""Here lies OpenAPI renderers.""" | ||
|
||
from . import abc | ||
from ._httpdomain_old import HttpdomainOldRenderer | ||
|
||
|
||
__all__ = [ | ||
"abc", | ||
"HttpdomainOldRenderer", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"""Here lies still breathing and only renderer implementation.""" | ||
|
||
from docutils.parsers.rst import directives | ||
|
||
from . import abc | ||
from .. import openapi20, openapi30, utils | ||
|
||
|
||
class HttpdomainOldRenderer(abc.RestructuredTextRenderer): | ||
|
||
option_spec = { | ||
# A list of endpoints to be rendered. Endpoints must be whitespace | ||
# delimited. | ||
"paths": lambda s: s.split(), | ||
# Regular expression patterns to includes/excludes endpoints to/from | ||
# rendering. Similar to paths, the patterns must be whitespace | ||
# delimited. | ||
"include": lambda s: s.split(), | ||
"exclude": lambda s: s.split(), | ||
# Render the request body structure when passed. | ||
"request": directives.flag, | ||
# Render request/response examples when passed. | ||
"examples": directives.flag, # render examples when passed | ||
# Group endpoints by tags when passed. By default, no grouping is | ||
# applied and endpoints are rendered in the order they met in spec. | ||
"group": directives.flag, | ||
# Markup format to render OpenAPI descriptions. | ||
"format": str, | ||
} | ||
|
||
def __init__(self, state, options): | ||
self._state = state | ||
self._options = options | ||
|
||
def render_restructuredtext_markup(self, spec): | ||
# OpenAPI spec may contain JSON references, common properties, etc. | ||
# Trying to render the spec "As Is" will require to put multiple if-s | ||
# around the code. In order to simplify rendering flow, let's make it | ||
# have only one (expected) schema, i.e. normalize it. | ||
utils.normalize_spec(spec, **self._options) | ||
|
||
# We support both OpenAPI 2.0 (f.k.a. Swagger) and OpenAPI 3.0.0, so | ||
# determine which version we are parsing here. | ||
spec_version = spec.get("openapi", spec.get("swagger", "2.0")) | ||
if spec_version.startswith("2."): | ||
openapihttpdomain = openapi20.openapihttpdomain | ||
elif spec_version.startswith("3."): | ||
openapihttpdomain = openapi30.openapihttpdomain | ||
else: | ||
raise ValueError("Unsupported OpenAPI version (%s)" % spec_version) | ||
|
||
yield from openapihttpdomain(spec, **self._options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
"""Abstract Base Classes (ABCs) for OpenAPI renderers.""" | ||
|
||
import abc | ||
|
||
from docutils import nodes | ||
from docutils.statemachine import ViewList | ||
from sphinx.util.nodes import nested_parse_with_titles | ||
|
||
|
||
class Renderer(metaclass=abc.ABCMeta): | ||
"""Base class for OpenAPI renderers.""" | ||
|
||
def __init__(self, state, options): | ||
self._state = state | ||
self._options = options | ||
|
||
@property | ||
@abc.abstractmethod | ||
def option_spec(self): | ||
"""Renderer options and their converting functions.""" | ||
|
||
@abc.abstractmethod | ||
def render(self, spec): | ||
"""Render a given OpenAPI spec.""" | ||
|
||
|
||
class RestructuredTextRenderer(Renderer): | ||
"""Base class for reStructuredText OpenAPI renderers. | ||
Docutils DOM manipulation is quite a tricky task that requires passing | ||
dozen arguments around. Because of that a lot of Sphinx extensions instead | ||
of constructing DOM nodes directly produce and parse reStructuredText. | ||
This Sphinx extension is not an exception, and that's why this class | ||
exists. It's a convenient extension of :class:`Renderer` that converts | ||
produced markup text into docutils DOM elements. | ||
""" | ||
|
||
def render(self, spec): | ||
viewlist = ViewList() | ||
for line in self.render_restructuredtext_markup(spec): | ||
viewlist.append(line, "<openapi>") | ||
|
||
node = nodes.section() | ||
node.document = self._state.document | ||
nested_parse_with_titles(self._state, viewlist, node) | ||
return node.children |
Oops, something went wrong.