From 6209766da56960b9a00abfba921042980cf4cd80 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 18 Jan 2024 17:50:56 +0000 Subject: [PATCH 1/4] Bump action versions Signed-off-by: Stephen Finucane --- .github/workflows/tests.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 20cddf5..f9c2853 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,10 +8,10 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.13 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.13' @@ -28,10 +28,10 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -47,10 +47,10 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.13 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.13' @@ -63,10 +63,10 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'push' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.13 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.13' From 25f343b4260304788cda7e697393a06e52f1e918 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 19 Jan 2024 11:46:27 +0000 Subject: [PATCH 2/4] docs: Trivial fixes Ahead of rework for switch to new directive. Signed-off-by: Stephen Finucane --- docs/index.rst | 51 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 5f60b6f..0840e2b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,13 +4,10 @@ sphinxcontrib-openapi .. hint:: - Check out `sphinxcontrib-redoc`_ if you are interested in separate - three-panel OpenAPI spec rendering. + Check out `sphinxcontrib-redoc`_ if you are interested in separate three-panel OpenAPI spec rendering. -**sphinxcontrib-openapi** is a `Sphinx`_ extension to generate APIs docs from -`OpenAPI`_ (fka Swagger) spec. It depends on `sphinxcontrib-httpdomain`_ that -provides an HTTP domain for describing RESTful HTTP APIs, so we don't need to -reinvent the wheel. +**sphinxcontrib-openapi** is a `Sphinx`_ extension to generate APIs docs from `OpenAPI`_ (fka Swagger) spec. +It depends on `sphinxcontrib-httpdomain`_, which provides an HTTP domain for describing RESTful HTTP APIs so we don't need to reinvent the wheel. .. code:: bash @@ -42,8 +39,7 @@ Options The ``openapi`` directive supports the following options: ``encoding`` - Encoding to be used to read an OpenAPI spec. If not passed, Sphinx's - source encoding will be used. + Encoding to be used to read an OpenAPI spec. If not passed, Sphinx's source encoding will be used. ``paths`` A comma separated list of paths to filter the included OpenAPI spec by. @@ -57,25 +53,23 @@ The ``openapi`` directive supports the following options: /evidence :encoding: utf-8 - Would only render the endpoints at ``/persons`` and ``/evidence``, - ignoring all others. + Would only render the endpoints at ``/persons`` and ``/evidence``, ignoring all others. ``examples`` - If passed, both request and response examples will be rendered. Please - note, if examples are not provided in a spec, they will be generated - by internal logic based on a corresponding schema. + If passed, both request and response examples will be rendered. + Please note, if examples are not provided in a spec, they will be generated by internal logic based on a corresponding schema. ``group`` - If passed, paths will be grouped by tags. If a path has no tag assigned, it - will be grouped in a ``default`` group. + If passed, paths will be grouped by tags. + If a path has no tag assigned, it will be grouped in a ``default`` group. ``format`` - The format of text in the spec, either ``rst`` or ``markdown``. If - not supplied, ReStructured Text is assumed. + The format of text in the spec, either ``rst`` or ``markdown``. + If not supplied, reStructuredText is assumed. ``include`` - A line separated list of regular expressions to filter the included openapi - spec by. For example: + A line separated list of regular expressions to filter the included OpenAPI spec by. + For example: .. code:: restructuredtext @@ -84,11 +78,11 @@ The ``openapi`` directive supports the following options: /evid.* :encoding: utf-8 - Would render the endpoints at ``/evidence`` and ``/evidence/{pk}`` + would render the endpoints at ``/evidence`` and ``/evidence/{pk}`` ``exclude`` - A line separated list of regular expressions to filter the included openapi - spec by (excluding matches). For example: + A line separated list of regular expressions to filter the included OpenAPI spec by (excluding matches). + For example: .. code:: restructuredtext @@ -97,12 +91,11 @@ The ``openapi`` directive supports the following options: /evidence/{pk} :encoding: utf-8 - Would render ``/persons`` and ``/evidence`` endpoints, but not - ``/evidence/{pk}`` endpoints + would render ``/persons`` and ``/evidence`` endpoints, but not ``/evidence/{pk}`` endpoints ``methods`` - A line separated list of http methods to filter included openapi - spec. For example: + A line separated list of http methods to filter included OpenAPI spec. + For example: .. code:: restructuredtext @@ -113,10 +106,10 @@ The ``openapi`` directive supports the following options: put :encoding: utf-8 - Would render paths with get, post or put method + Would render paths with get, post or put method. -``exclude``, ``include`` and ``paths`` can also be used together (``exclude`` -taking precedence over ``include`` and ``paths``) +``exclude``, ``include`` and ``paths`` can also be used together. +When used together, ``exclude`` takes precedence over ``include`` and ``paths``. ``http-methods-order`` A whitespace delimited list of HTTP methods to render first. For example: From 2b2cb6360b0e699d658ff32417afa68774ead3e1 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 19 Jan 2024 12:15:56 +0000 Subject: [PATCH 3/4] docs: Add docs for new renderer Signed-off-by: Stephen Finucane --- docs/index.rst | 97 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 0840e2b..b95460b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,8 +14,8 @@ It depends on `sphinxcontrib-httpdomain`_, which provides an HTTP domain for des pip install sphinxcontrib-openapi -How To Use? -=========== +Usage +===== Consider you have the following OpenAPI spec saved at ``specs/openapi.yml``: @@ -33,10 +33,100 @@ and it will be rendered into something like: .. openapi:: specs/openapi.yml +Configuration +============= + +The extension provides two configuration options. + +``openapi_renderers`` + A mapping of renderer aliases to the classes. + Two renderer classes are provided but it is possible to define your own renderer class. + This allows you to add support for things like additional type formats or custom extensions (``x``-prefixed attributes). + + :Type: A mapping of renderer aliases to the implementation class. + :Default: ``{'httpdomain': sphinxcontrib.openapi.renderers.HttpdomainRenderer, 'httpdomain:old': sphinxcontrib.openapi.renderers.HttpdomainOldRenderer}`` + +``openapi_default_renderer`` + The renderer to use. + This must be one of the renderers defined in ``openapi_renderers``. + + :Type: A string corresponding to the alias of a registered renderer. + :Default: ``'httpdomain:old'`` + + Options ======= -The ``openapi`` directive supports the following options: +The ``openapi`` directive supports different options depending on the renderer in use. + +Options for the ``httpdomain`` renderer +--------------------------------------- + +The following options take a value. + +``encoding`` + Encoding to be used to read an OpenAPI spec. If not passed, Sphinx's source encoding will be used. + +``markup`` + The format to use when parsing markup. + + :Type: One of ``commonmark``, ``restructuredtext`` + :Default: ``commonmark`` + +``http-methods-order`` + The preferred order in which to output HTTP methods. + + :Type: An CSV string of HTTP methods. + :Default: ``None`` + +``response-examples-for`` + The response codes to render samples for. + + :Type: A sequence of strings, with each string corresponding to a `HTTP status code `__ that response examples should be rendered for. + :Default: ``["200", "201", "202", "2XX"]`` + +``request-parameters-order`` + The preferred order in which to output parameters. + + :Type: An ordered sequence of strings, with each string corresponding to a `supported parameter type `__. + :Default: ``None`` + +``example-preference`` + The preferred example format to render for requests and responses. + + :Type: An ordered sequence of strings, with each string corresponding to a `supported media type `__. + :Default: ``None`` + +``request-example-preference`` + The preferred example format to render for requests. This takes precedence over ``example-preference``. + + :Type: An ordered sequence of strings, with each string corresponding to a `supported media type `__. + :Default: ``None`` + +``response-example-preference`` + The preferred example format to render for responses. This takes precedence over ``example-preference``. + + :Type: An ordered sequence of strings, with each string corresponding to a `supported media type `__. + :Default: ``None`` + +The following options are boolean flags. + +``generate-examples-from-schemas`` + + Whether examples should be generated from the schema if they are not provided in the spec. If unset, examples will not be generated. + + :Type: Flag. + +``no-json-schema-description`` + + Whether to disable rendering of JSON schema hints. + + :Type: Flag. + +Options for the ``httpdomain:old`` renderer +------------------------------------------- + +The following options are supported when using the ``httpdomain:old`` renderer: ``encoding`` Encoding to be used to read an OpenAPI spec. If not passed, Sphinx's source encoding will be used. @@ -123,7 +213,6 @@ When used together, ``exclude`` takes precedence over ``include`` and ``paths``. Would render the ``head`` method, followed by the ``get`` method, followed by the rest of the methods in their declared ordered. - .. _Sphinx: https://www.sphinx-doc.org/en/master/ .. _OpenAPI: https://github.com/OAI/OpenAPI-Specification .. _sphinxcontrib-httpdomain: https://sphinxcontrib-httpdomain.readthedocs.io/ From 6cb06ec4b29841cf33252825942cce9de08d4ec5 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 18 Jan 2024 17:44:54 +0000 Subject: [PATCH 4/4] Switch default renderer to new renderer We add the ability to use the old renderer in some tests. Signed-off-by: Stephen Finucane --- docs/index.rst | 2 +- sphinxcontrib/openapi/__init__.py | 2 +- tests/conftest.py | 25 ++++++++++++++----------- tests/test_openapi.py | 12 ++++++++++-- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index b95460b..f8eed51 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -51,7 +51,7 @@ The extension provides two configuration options. This must be one of the renderers defined in ``openapi_renderers``. :Type: A string corresponding to the alias of a registered renderer. - :Default: ``'httpdomain:old'`` + :Default: ``'httpdomain'`` Options diff --git a/sphinxcontrib/openapi/__init__.py b/sphinxcontrib/openapi/__init__.py index 33908c0..420de0d 100644 --- a/sphinxcontrib/openapi/__init__.py +++ b/sphinxcontrib/openapi/__init__.py @@ -27,7 +27,7 @@ "httpdomain": renderers.HttpdomainRenderer, "httpdomain:old": renderers.HttpdomainOldRenderer, } -_DEFAULT_RENDERER_NAME = "httpdomain:old" +_DEFAULT_RENDERER_NAME = "httpdomain" def _register_rendering_directives(app, conf): diff --git a/tests/conftest.py b/tests/conftest.py index d102a4a..411c641 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -45,23 +45,26 @@ def run_sphinx(tmpdir): src = tmpdir.ensure('src', dir=True) out = tmpdir.ensure('out', dir=True) - def run(spec, options={}): + def run(spec, *, options={}, openapi_default_renderer=None): options_raw = '\n'.join([ ' %s' % _format_option_raw(key, val) for key, val in options.items()]) - src.join('conf.py').write_text( - textwrap.dedent(''' - import os + conf_py = textwrap.dedent(''' + import os - project = 'sphinxcontrib-openapi-test' - copyright = '2017, Ihor Kalnytskyi' + project = 'sphinxcontrib-openapi-test' + copyright = '2017, Ihor Kalnytskyi' - extensions = ['sphinxcontrib.openapi'] - source_suffix = '.rst' - master_doc = 'index' - '''), - encoding='utf-8') + extensions = ['sphinxcontrib.openapi'] + source_suffix = '.rst' + master_doc = 'index' + ''') + + if openapi_default_renderer is not None: + conf_py += f"openapi_default_renderer = '{openapi_default_renderer}'\n" + + src.join('conf.py').write_text(conf_py, encoding='utf-8') src.join('index.rst').write_text( '.. openapi:: %s\n%s' % (spec, options_raw), diff --git a/tests/test_openapi.py b/tests/test_openapi.py index 551f6a6..8f12582 100644 --- a/tests/test_openapi.py +++ b/tests/test_openapi.py @@ -1865,7 +1865,11 @@ def test_openapi2_examples(tmpdir, run_sphinx): py.path.local(spec).copy(tmpdir.join('src', 'test-spec.yml')) with pytest.raises(ValueError) as excinfo: - run_sphinx('test-spec.yml', options={'examples': True}) + run_sphinx( + 'test-spec.yml', + options={'examples': True}, + openapi_default_renderer='httpdomain:old', + ) assert str(excinfo.value) == ( 'Rendering examples is not supported for OpenAPI v2.x specs.') @@ -1880,7 +1884,11 @@ def test_openapi3_examples(tmpdir, run_sphinx, render_examples): 'v3.0', 'petstore.yaml') py.path.local(spec).copy(tmpdir.join('src', 'test-spec.yml')) - run_sphinx('test-spec.yml', options={'examples': render_examples}) + run_sphinx( + 'test-spec.yml', + options={'examples': render_examples}, + openapi_default_renderer='httpdomain:old', + ) rendered_html = tmpdir.join('out', 'index.html').read_text('utf-8')