OpenAPI UI Plugins ------------------ .. versionadded:: 2.8.0 OpenAPI UI Plugins are designed to allow easy integration with your OpenAPI UI framework of choice. These plugins facilitate the creation of interactive, user-friendly API documentation, making it easier for developers and end-users to understand and interact with your API. Litestar maintains and ships with UI plugins for a range of popular popular OpenAPI documentation tools: - `Scalar `_ - `RapiDoc `_ - `ReDoc `_ - `Stoplight Elements `_ - `Swagger UI `_ - `YAML `_ Each plugin is easily configurable, allowing developers to customize aspects like version, paths, CSS and JavaScript resources. Using OpenAPI UI Plugins ------------------------ Using OpenAPI UI Plugins is as simple as importing the plugin, instantiating it, and adding it to the OpenAPIConfig. .. tab-set:: .. tab-item:: scalar :sync: scalar .. literalinclude:: /examples/openapi/plugins/scalar_simple.py :language: python .. tab-item:: rapidoc :sync: rapidoc .. literalinclude:: /examples/openapi/plugins/rapidoc_simple.py :language: python .. tab-item:: redoc :sync: redoc .. literalinclude:: /examples/openapi/plugins/redoc_simple.py :language: python .. tab-item:: stoplight :sync: stoplight .. literalinclude:: /examples/openapi/plugins/stoplight_simple.py :language: python .. tab-item:: swagger :sync: swagger .. literalinclude:: /examples/openapi/plugins/swagger_ui_simple.py :language: python .. tab-item:: yaml :sync: yaml .. literalinclude:: /examples/openapi/plugins/yaml_simple.py :language: python .. tip:: Rendering YAML requires the `PyYAML `_ library, which can be installed via the ``litestar[yaml]`` package extra .. tab-item:: multiple .. literalinclude:: /examples/openapi/plugins/serving_multiple_uis.py :caption: Any combination of UIs can be served. :language: python Configuring OpenAPI UI Plugins ------------------------------ Each plugin can be tailored to meet your unique requirements by passing options at instantiation. For full details on each plugin's options, see the :doc:`API Reference `. All plugins support: - ``path``: Each plugin has its own default, e.g., ``/rapidoc`` for RapiDoc. This can be overridden to serve the UI at a different path. - ``media_type``: The default media type for the plugin, typically the default is ``text/html``. - ``favicon``: A string that should be a valid ```` tag, e.g., ````. - ``style``: A string that should be a valid ``.`` Most plugins support the following additional options: - ``version``: The version of the UIs JS and (in some cases) CSS bundle to use. We use the ``version`` to construct the URL to retrieve the bundle from ``unpkg``, e.g., ``https://unpkg.com/rapidoc@/dist/rapidoc-min.js`` - ``js_url``: The URL to the JS bundle. If provided, this will override the ``version`` option. - ``css_url``: The URL to the CSS bundle. If provided, this will override the ``version`` option. Here's some example plugin configurations: .. tab-set:: .. tab-item:: scalar :sync: scalar .. literalinclude:: /examples/openapi/plugins/scalar_config.py :language: python .. tab-item:: rapidoc :sync: rapidoc .. literalinclude:: /examples/openapi/plugins/rapidoc_config.py :language: python .. tab-item:: redoc :sync: redoc .. literalinclude:: /examples/openapi/plugins/redoc_config.py :language: python .. tip:: Setting ``js_url`` lets you point the ReDoc bundle to any CDN or internal host. In ``redoc_config.py`` we override it to ``https://cdn.company.internal/redoc/custom-redoc.js``. When provided, ``js_url`` takes precedence over ``version``. .. tab-item:: stoplight :sync: stoplight .. literalinclude:: /examples/openapi/plugins/stoplight_config.py :language: python .. tab-item:: swagger :sync: swagger .. literalinclude:: /examples/openapi/plugins/swagger_ui_config.py :language: python Configuring the OpenAPI Root Path --------------------------------- The OpenAPI root path is the path at which the OpenAPI representations are served. By default, this is ``/schema``. This can be changed by setting the :attr:`OpenAPIConfig.path` attribute. In the following example, we configure the OpenAPI root path to be ``/docs``: .. literalinclude:: /examples/openapi/customize_path.py :language: python This will result in any of the OpenAPI endpoints being served at ``/docs`` instead of ``/schema``, e.g., ``/docs/openapi.json``. Building your own OpenAPI UI Plugin ----------------------------------- If Litestar does not have built-in support for your OpenAPI UI framework of choice, you can easily create your own plugin by subclassing :class:`OpenAPIRenderPlugin` and implementing the :meth:`OpenAPIRenderPlugin.render` method. To demonstrate building a custom plugin, we'll look at a plugin very similar to the :class:`ScalarRenderPlugin` that is maintained by Litestar. Here's the finished product: .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python Class definition ~~~~~~~~~~~~~~~~ The class ``ScalarRenderPlugin`` inherits from :class:`OpenAPIRenderPlugin`: .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 10 ``__init__`` Constructor ~~~~~~~~~~~~~~~~~~~~~~~~ .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 11-22 We support configuration via the following arguments: - ``version``: Specifies the version of RapiDoc to use. - ``js_url``: Custom URL to the RapiDoc JavaScript bundle. - ``css_url``: Custom URL to the RapiDoc CSS bundle. - ``path``: The URL path where the RapiDoc UI will be served. - ``**kwargs``: Captures additional arguments to pass to the superclass. And we construct a url for the Scalar JavaScript bundle if one is not provided: .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 20 ``render()`` ~~~~~~~~~~~~ .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 24 Finally we define the ``render`` method, which is called by Litestar to render the UI. It receives the a :class:`Request` object and the ``openapi_schema`` as a dictionary. Inside the ``render`` method, we construct the HTML to render the UI, and return it as a string. - ``head``: Defines the HTML ```` section, including the title from ``openapi_schema``, any additional styles (``self.style``), the favicon and custom style sheet if one is provided: .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 25-35 - ``body``: Constructs the HTML ````, including a link to the OpenAPI JSON, and the JavaScript bundle: .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 37-43 - Finally, returns a complete HTML document (as a byte string), combining head and body. .. literalinclude:: /examples/openapi/plugins/custom_plugin.py :language: python :lines: 45-51 Interacting with the ``Router`` ------------------------------- An instance of :class:`Router` is used to serve the OpenAPI endpoints and is made available to plugins via the :meth:`OpenAPIRenderPlugin.receive_router` method. This can be used for a variety of purposes, including adding additional routes to the ``Router``. .. literalinclude:: /examples/openapi/plugins/receive_router.py :language: python OAuth2 in Swagger UI -------------------- When using Swagger, OAuth2 settings can be configured via the :paramref:`~.openapi.plugins.SwaggerRenderPlugin.init_oauth` param of :meth:`SwaggerRenderPlugin `, which can be set to a dictionary containing the parameters described in the Swagger UI documentation for OAuth2 `here `_. With that, you can preset your clientId or enable PKCE support. .. literalinclude:: /examples/openapi/plugins/swagger_ui_oauth.py :language: python CDN and offline file support ---------------------------- Each plugin supports ``js_url`` and ``css_url`` attributes, which can be used to specify a custom URL to the JavaScript. These can be used to serve the JavaScript and CSS from a CDN, or to serve the files from a local directory.