Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 5 additions & 35 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,9 @@ repos:
- id: check-yaml
- id: debug-statements

- repo: https://github.com/psf/black
rev: 26.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.0
hooks:
- id: black
args: [--line-length=88, --target-version=py35]
exclude: >
(?x)(
# black defaults
\.eggs
| \.git\
| \.hg
| \.mypy_cache
| \.nox
| \.tox
| \.venv
| _build
| buck-out
| build
| dist

# sphinxcontrib-openapi
| sphinxcontrib/openapi/__init__.py
| sphinxcontrib/openapi/__main__.py
| sphinxcontrib/openapi/openapi20.py
| sphinxcontrib/openapi/openapi30.py
| sphinxcontrib/openapi/directive.py
| sphinxcontrib/openapi/utils.py
| tests/test_openapi.py
| tests/conftest.py
| tests/test_spec_examples.py
)

- repo: https://github.com/pycqa/flake8
rev: 7.3.0
hooks:
- id: flake8
- id: ruff-check
args: ['--fix', '--unsafe-fixes']
- id: ruff-format
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,10 @@ include-package-data = true
include = ["sphinxcontrib.*"]

[tool.setuptools_scm]

[tool.ruff.format]
docstring-code-format = true

[tool.ruff.lint]
select = ["E4", "E5", "E7", "E9", "F", "RUF", "UP", "W"]
ignore = ["RUF012"]
28 changes: 14 additions & 14 deletions sphinxcontrib/openapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
sphinxcontrib.openapi
---------------------
sphinxcontrib.openapi
---------------------

The OpenAPI spec renderer for Sphinx. It's a new way to document your
RESTful API. Based on ``sphinxcontrib-httpdomain``.
The OpenAPI spec renderer for Sphinx. It's a new way to document your
RESTful API. Based on ``sphinxcontrib-httpdomain``.

:copyright: (c) 2016, Ihor Kalnytskyi.
:license: BSD, see LICENSE for details.
:copyright: (c) 2016, Ihor Kalnytskyi.
:license: BSD, see LICENSE for details.
"""

from importlib.metadata import distribution, PackageNotFoundError
Expand Down Expand Up @@ -34,14 +34,14 @@ def _register_rendering_directives(app, conf):

for renderer_name, renderer_cls in renderers_map.items():
app.add_directive(
"openapi:%s" % renderer_name,
f"openapi:{renderer_name}",
directive.create_directive_from_renderer(renderer_cls),
)

if conf.openapi_default_renderer not in renderers_map:
raise ValueError(
"invalid 'openapi_default_renderer' value: "
"no such renderer: '%s'" % conf.openapi_default_renderer
f"no such renderer: '{conf.openapi_default_renderer}'"
)

app.add_directive(
Expand All @@ -59,22 +59,22 @@ def setup(app):
from sphinxcontrib import httpdomain

for idx, fieldtype in enumerate(httpdomain.HTTPResource.doc_field_types):
if fieldtype.name == 'requestheader':
if fieldtype.name == "requestheader":
httpdomain.HTTPResource.doc_field_types[idx] = httpdomain.TypedField(
fieldtype.name,
label=fieldtype.label,
names=fieldtype.names,
typerolename='header',
typenames=('reqheadertype', ),
typerolename="header",
typenames=("reqheadertype",),
)

if fieldtype.name == 'responseheader':
if fieldtype.name == "responseheader":
httpdomain.HTTPResource.doc_field_types[idx] = httpdomain.TypedField(
fieldtype.name,
label=fieldtype.label,
names=fieldtype.names,
typerolename='header',
typenames=('resheadertype', ),
typerolename="header",
typenames=("resheadertype",),
)

app.setup_extension("sphinxcontrib.httpdomain")
Expand Down
77 changes: 39 additions & 38 deletions sphinxcontrib/openapi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,68 @@

def main():
parser = argparse.ArgumentParser(
prog='oas2rst',
description='Export OpenAPI Specification files to reStructuredText \
files')
prog="oas2rst",
description="Export OpenAPI Specification files to reStructuredText \
files",
)
parser.add_argument(
"-l", "--level",
action='store',
"-l",
"--level",
action="store",
default=logging.INFO,
dest='level',
help="Logging level")
dest="level",
help="Logging level",
)
parser.add_argument(
"-e", "--encoding",
action='store',
"-e",
"--encoding",
action="store",
default="UTF-8",
dest='encoding',
help="Source file encoding")
dest="encoding",
help="Source file encoding",
)
parser.add_argument(
"-p", "--paths",
action='append',
dest='paths',
help="Endpoints to be rendered")
"-p", "--paths", action="append", dest="paths", help="Endpoints to be rendered"
)
parser.add_argument(
"-x", "--examples",
action='store_true',
dest='examples',
help="Include examples")
"-x",
"--examples",
action="store_true",
dest="examples",
help="Include examples",
)
parser.add_argument(
"-g", "--group",
action='store_true',
dest='group',
help="Group paths by tag")
"-g", "--group", action="store_true", dest="group", help="Group paths by tag"
)
parser.add_argument("-i", "--input", dest="input", required=True, help="Input file")
parser.add_argument(
"-i", "--input",
dest='input',
"-o",
"--output",
type=argparse.FileType("w"),
required=True,
help="Input file")
parser.add_argument(
"-o", "--output",
type=argparse.FileType('w'),
required=True,
dest='output',
help="Output file")
dest="output",
help="Output file",
)

options = parser.parse_args()
logging.getLogger().setLevel(options.level)

openapi_options = {}
if options.paths:
openapi_options['paths'] = options.paths
openapi_options["paths"] = options.paths
if options.examples:
openapi_options['examples'] = True
openapi_options["examples"] = True
if options.group:
openapi_options['group'] = True
openapi_options["group"] = True

openapi_options.setdefault('uri', 'file://%s' % options.input)
openapi_options.setdefault("uri", f"file://{options.input}")
spec = directive._get_spec(options.input, options.encoding)
renderer = renderers.HttpdomainOldRenderer(None, openapi_options)

for line in renderer.render_restructuredtext_markup(spec):
options.output.write(line+'\n')
options.output.write(line + "\n")
logging.debug(line)


if __name__ == '__main__':
if __name__ == "__main__":
main()
26 changes: 13 additions & 13 deletions sphinxcontrib/openapi/directive.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""
sphinxcontrib.openapi.directive
-------------------------------
sphinxcontrib.openapi.directive
-------------------------------

The main directive for the extension.
The main directive for the extension.

:copyright: (c) 2016, Ihor Kalnytskyi.
:license: BSD, see LICENSE for details.
:copyright: (c) 2016, Ihor Kalnytskyi.
:license: BSD, see LICENSE for details.
"""

import functools
Expand All @@ -17,23 +17,23 @@

# Locally cache spec to speedup processing of same spec file in multiple
# openapi directives
@functools.lru_cache()
@functools.lru_cache
def _get_spec(abspath, encoding):
with open(abspath, 'rt', encoding=encoding) as stream:
with open(abspath, encoding=encoding) as stream:
return yaml.safe_load(stream)


def create_directive_from_renderer(renderer_cls):
"""Create rendering directive from a renderer class."""

class _RenderingDirective(SphinxDirective):
required_arguments = 1 # path to openapi spec
final_argument_whitespace = True # path may contain whitespaces
required_arguments = 1 # path to openapi spec
final_argument_whitespace = True # path may contain whitespaces
option_spec = dict(
{
'encoding': directives.encoding, # useful for non-ascii cases :)
"encoding": directives.encoding, # useful for non-ascii cases :)
},
**renderer_cls.option_spec
**renderer_cls.option_spec,
)

def run(self):
Expand All @@ -42,7 +42,7 @@ def run(self):
# URI parameter is crucial for resolving relative references. So we
# need to set this option properly as it's used later down the
# stack.
self.options.setdefault('uri', 'file://%s' % abspath)
self.options.setdefault("uri", f"file://{abspath}")

# Add a given OpenAPI spec as a dependency of the referring
# reStructuredText document, so the document is rebuilt each time
Expand All @@ -51,7 +51,7 @@ def run(self):

# Read the spec using encoding passed to the directive or fallback to
# the one specified in Sphinx's config.
encoding = self.options.get('encoding', self.config.source_encoding)
encoding = self.options.get("encoding", self.config.source_encoding)
spec = _get_spec(abspath, encoding)
return renderer_cls(self.state, self.options).render(spec)

Expand Down
Loading