Skip to content

Commit

Permalink
Merge pull request #159 from lsst-sqre/tickets/DM-37525
Browse files Browse the repository at this point in the history
DM-37525: Add openapi generator extension
  • Loading branch information
jonathansick authored Jun 7, 2023
2 parents 38d4039 + d81e981 commit 62de299
Show file tree
Hide file tree
Showing 13 changed files with 640 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Temporarily pin pydata-sphinx-theme < 0.13 on account of a change in logo path checking (affects user guide projects).
- Add a new `sphinx.exclude` field to `documenteer.toml` to list files for exclusion from a documentation project.
More files and directories like `.venv` and `requirements.txt` are now excluded, as well.
- New support for embedding OpenAPI documentation in a Redoc-generated subsite. The `documenteer.ext.openapi` extension can call a user-specified function to generate and install the OpenAPI specification the Sphinx source. For user guide projects, the `[project.openapi]` table in `documenteer.toml` can be used to configure both the `documenteer.ext.openapi` and `sphinxcontrib-redoc` extensions. [sphinxcontrib-redoc](https://sphinxcontrib-redoc.readthedocs.io/en/stable/) is installed and configured by default for all Rubin user guide projects (projects that use `documenteer.conf.guide`).

## 0.7.0 (2022-10-20)

Expand Down
5 changes: 4 additions & 1 deletion docs/_rst_epilog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
.. _Doxygen: http://www.doxygen.nl
.. _Doxylink: https://sphinxcontrib-doxylink.readthedocs.io/en/stable/
.. _FastAPI: https://fastapi.tiangolo.com
.. _Intersphinx: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
.. _LSST Science Pipelines:
.. _SCons: https://scons.org
.. _Sphinx extensions: https://www.sphinx-doc.org/en/master/develop.html
.. _Sphinx: https://www.sphinx-doc.org/en/master/
Expand All @@ -31,6 +31,7 @@
.. _`pex_config`: https://github.com/lsst/pex_config
.. _`pipe_base`: https://github.com/lsst/pipe_base
.. _`pipe_supertask`: https://github.com/lsst/pipe_supertask
.. _LSST Science Pipelines:
.. _`pipelines.lsst.io`: https://pipelines.lsst.io
.. _`pipelines_lsst_io`: https://github.com/lsst/pipelines_lsst_io
.. _`sconsUtils`: https://github.com/lsst/sconsUtils
Expand All @@ -47,10 +48,12 @@
.. _pytest: https://pytest.org
.. _toctree: http://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-toctree
.. _linkcheck: https://www.sphinx-doc.org/en/master/usage/configuration.html?#options-for-the-linkcheck-builder
.. _Redoc: https://redocly.com/redoc/
.. _rst_epilog: https://www.sphinx-doc.org/en/master/usage/configuration.html?highlight=rst_epilog#confval-rst_epilog
.. _napoleon: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html
.. _autodoc: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html
.. _sphinx_autodoc_typehints: https://github.com/tox-dev/sphinx-autodoc-typehints
.. _sphinxcontrib-redoc: https://sphinxcontrib-redoc.readthedocs.io/en/stable/
.. _tox: https://tox.wiki/en/latest/
.. _Technote: https://technote.lsst.io/

Expand Down
2 changes: 2 additions & 0 deletions docs/dev/api/documenteer.ext.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ documenteer.ext
.. automodapi:: documenteer.ext.autocppapi

.. automodapi:: documenteer.ext.autodocreset

.. automodapi:: documenteer.ext.openapi
1 change: 1 addition & 0 deletions docs/guides/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Documenteer provides a configuration profile for creating branded user guides wi
:name: toc-guides-advanced-config

pyproject-configuration
openapi
rst-epilog
extend-conf-py

Expand Down
118 changes: 118 additions & 0 deletions docs/guides/openapi.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
##############################################################
Embedding a Redoc subsite for OpenAPI (HTTP API) documentation
##############################################################

FastAPI_, the Python framework for building web applications, automatically generates OpenAPI specifications.
Documenteer provides built-in support for embedding a Redoc_ subsite for this OpenAPI documentation in a Rubin user guide.
This solution combines the Documenteer Sphinx extension :doc:`documenteer.ext.openapi </sphinx-extensions/openapi>` to install the OpenAPI specification into the docs from your FastAPI application and the third-party extension sphinxcontrib-redoc_ to embed the Redoc subsite into your Sphinx documentation site.

.. _guides-openapi-generator-function:

1. Create a function to generate the OpenAPI docs
=================================================

The first step is to create or identify a function that generates an OpenAPI specification for your application as a JSON-serialized string.
This function must be importable from the Sphinx build process.
For SQuaRE/Safir-standardized FastAPI applications, it may make sense to add this function to the :file:`main.py` module where the FastAPI application is defined:

.. code-block:: python
:caption: src/main.py
import json
from fastapi import FastAPI
app = FastAPI()
def create_openapi() -> str:
"""Create the OpenAPI spec for static documentation."""
spec = get_openapi(
title=app.title,
version=app.version,
description=app.description,
routes=app.routes,
)
return json.dumps(spec)
.. note::

This step is not necessary if the OpenAPI specification is already available in the source repository or is generated by a separate build process.
See the note in :ref:`step 3 <guides-openapi-config>` on configuring an existing OpenAPI specification.

.. _guides-openapi-stub:

2. Add a stub page for the Redoc subsite
========================================

In your Sphinx documentation project, add a stub page for the Redoc subsite.
This step adds the Redoc page to the Sphinx toctree and therefore to the Sphinx site navigation.

First, create the stub file:

.. code-block:: rst
:caption: docs/api.rst
########
REST API
########
This is a stub page for the API.
Then add this page to the site's toctree:

.. code-block:: rst
:caption: docs/index.rst
.. toctree::
api
.. _guides-openapi-config:

3. Configuration in documenteer.toml
====================================

In the Sphinx project's :file:`documenteer.toml` configuration file, add a :ref:`[project.openapi] <guide-project-openapi>` table:

.. code-block:: toml
:caption: docs/documenteer.toml
[project.openapi]
openapi_path = "_static/openapi.json"
doc_path = "api"
[project.openapi.generator]
function = "example.main:create_openapi"
The :ref:`openapi_path <guide-project-openapi-openapi-path>` key specifies the path to the OpenAPI specification file, relative to the Sphinx project root.
The :ref:`doc_path <guide-project-openapi-doc-path>` key specifies the path to the Redoc subsite, relative to the Sphinx project root, and should match the path of the stub page created in :ref:`step 2 <guides-openapi-stub>`.

The :ref:`function <guide-project-openapi-generator-function>` key specifies the import path to the function in your app that generates the OpenAPI specification.
This field is formatted as ``<module>:<function>``.
For example, if the function called ``create_openapi`` is in the :file:`main.py` module of the :file:`example` package, the value would be ``"example.main:create_openapi"``.

If the function takes positional or keyword arguments, you can specify them in the :ref:`positional_args <guide-project-openapi-generator-positional-args>` and :ref:`keyword_args <guide-project-openapi-generator-keyword-args>` keys, respectively.

.. code-block:: toml
:caption: docs/documenteer.toml
[project.openapi.generator]
function = "example.main:create_openapi"
positional_args = ["arg1", "arg2"]
keyword_args = {kwarg1 = "value1", kwarg2 = "value2"}
.. note::

If the OpenAPI specification is already available, you don't need to specify the :ref:`[project.openapi.generator] <guide-project-openapi-generator>` table.
Ensure that the ``openapi_path`` key is set to the OpenAPI specification file's path, relative to the Sphinx project root.
If necessary, you can create a symlink to ensure the OpenAPI specification is available within the documentation source directory.

Additional resources
====================

- Find reference documentation for the :ref:`[project.openapi] table <guide-project-openapi>` in the :doc:`documenteer.toml configuration file <toml-reference>`.
- Learn more about the :doc:`documenteer.ext.openapi </sphinx-extensions/openapi>` extension.
- Learn more about the `sphinxcontrib-redoc`_ extension.
- Learn more about the FastAPI_ framework.
87 changes: 87 additions & 0 deletions docs/guides/toml-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,93 @@ version

The project's version, which is set to the standard Sphinx ``version`` and ``release`` configuration variables.

.. _guide-project-openapi:

[project.openapi]
=================

|optional|

Web applications that use OpenAPI can include a ``[project.openapi]`` table in :file:`documenteer.toml` to embed a Redoc_ subsite of the API documentation (see :doc:`openapi`).

.. _guide-project-openapi-doc-path:

doc\_path
---------

|optional|

The docname (without extension) of the page in the Sphinx documentation tree where the Redoc HTML page is built.
Default is ``api``.

.. _guide-project-openapi-openapi-path:

openapi\_path
-------------

|optional|

The path to the OpenAPI specification file, relative to the Sphinx configuration file, :file:`conf.py`.
If ``[project.openapi.generator]`` is set, this is the path where the OpenAPI specification file is generated.

.. _guide-project-openapi-generator:

[project.openapi.generator]
===========================

|optional|

If this table is provided, the OpenAPI specification file is generated from a user-specified Python function.
This is useful for FastAPI and similar applications where the OpenAPI specification is generated from the application code.

.. _guide-project-openapi-generator-function:

function
--------

|required|

The Python function that generates the OpenAPI specification file.
This function must return the OpenAPI specification as a JSON-serialized string.

Specify the function as ``<module>:<function>``.
For example, if the function called ``create_openapi`` is in the :file:`main.py` module of the :file:`example` package, the value would be ``"example.main:create_openapi"``.

.. code-block:: toml
[project.openapi.generator]
function = "example.main:create_openapi"
.. _guide-project-openapi-generator-positional-args:

positional\_args
----------------

|optional|

Positional arguments to pass to the function, if required.

.. code-block:: toml
[project.openapi.generator]
function = "example.main:create_openapi"
positional_args = ["arg1", "arg2"]
.. _guide-project-openapi-generator-keyword-args:

keyword\_args
-------------

|optional|

Keyword arguments to pass to the function, if required.

.. code-block:: toml
[project.openapi.generator]
function = "example.main:create_openapi"
keyword_args = {kwarg1 = "value1", kwarg2 = "value2"}
[project.python]
================

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Documenteer
**Sphinx extensions, configurations, and tooling for Rubin Observatory documentation projects.**

Documenteer is developed on GitHub at https://github.com/lsst-sqre/documenteer.
Find other version of the documentation at https://documenteer.lsst.io/v
Find other versions of the documentation at https://documenteer.lsst.io/v

.. _pip-install:
.. _installation:
Expand Down
1 change: 1 addition & 0 deletions docs/sphinx-extensions/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Sphinx extensions
package-toctree
lsst-pybtex-style
autodocreset
openapi
Loading

0 comments on commit 62de299

Please sign in to comment.