File: ui_plugins.rst

package info (click to toggle)
litestar 2.19.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,500 kB
  • sloc: python: 70,169; makefile: 254; javascript: 105; sh: 60
file content (311 lines) | stat: -rw-r--r-- 11,700 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
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 <https://github.com/scalar/scalar/>`_
- `RapiDoc <https://rapidocweb.com/>`_
- `ReDoc <https://redocly.com/>`_
- `Stoplight Elements <https://stoplight.io/open-source/elements>`_
- `Swagger UI <https://swagger.io/tools/swagger-ui/>`_
- `YAML <https://yaml.org/>`_

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

    .. 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 </reference/openapi/plugins>`.

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 ``<link>`` tag, e.g.,
  ``<link rel="icon" href="https://example.com/favicon.ico">``.
- ``style``: A string that should be a valid ``<style>`` tag, e.g., ``<style>body { margin: 0; padding: 0; }``</style>.``

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@<version>/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``.

Backward Compatibility
----------------------

OpenAPI UI plugins are a new feature introduced in ``v2.8.0``.

Providing a subclass of OpenAPIController
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: v2.8.0

The previous method of configuring elements such as the root path and styling was to subclass
:class:`OpenAPIController`, and set it on the :attr:`OpenAPIConfig.openapi_controller` attribute. This approach is now
deprecated and slated for removal in ``v3.0.0``, but if you are using it, there should be no change in behavior.

To maintain backward compatibility with the previous approach, if neither the :attr:`OpenAPIConfig.openapi_controller`
or :attr:`OpenAPIConfig.render_plugins` attributes are set, we will automatically add the plugins to respect the also
deprecated :attr:`OpenAPIConfig.enabled_endpoints` attribute. By default, this will result in the following endpoints
being enabled:

- ``/schema/openapi.json``
- ``/schema/redoc``
- ``/schema/rapidoc``
- ``/schema/elements``
- ``/schema/swagger``
- ``/schema/openapi.yml``
- ``/schema/openapi.yaml``

In ``v3.0.0``, the :attr:`OpenAPIConfig.enabled_endpoints` attribute will be removed, and only a single UI plugin will be
enabled by default, in addition to the ``openapi.json`` endpoint which will always be enabled. ``Scalar`` will also
become the default UI plugin in ``v3.0.0``.

To adopt the future behavior, explicitly set the :attr:`OpenAPIConfig.render_plugins` field to an instance of
:class:`ScalarRenderPlugin`:

.. literalinclude:: /examples/openapi/plugins/scalar_simple.py
    :language: python
    :lines: 13-21

Backward compatibility with ``root_schema_site``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Litestar has always supported a ``root_schema_site`` attribute on the :class:`OpenAPIConfig` class. This attribute
allows you to elect to serve a UI at the OpenAPI root path, e.g., by default ``redoc`` would be served at both
``/schema`` and ``/schema/redoc``.

In ``v3.0.0``, the ``root_schema_site`` attribute will be removed, and the first :class:`OpenAPIRenderPlugin` in the
:attr:`OpenAPIConfig.render_plugins` list will be assigned to the ``/schema`` endpoint.

As of ``v2.8.0``, if you explicitly use the new :attr:`OpenAPIConfig.render_plugins` attribute, you will be
automatically opted in to the new behavior, and the ``root_schema_site`` attribute will be ignored.

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 ``<head>`` 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 ``<body>``, 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
:attr:`swagger_ui_init_oauth <litestar.openapi.controller.OpenAPIController.swagger_ui_init_oauth>`, which can be set to
a dictionary containing the parameters described in the Swagger UI documentation for OAuth2
`here <https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/>`_.

With that, you can preset your clientId or enable PKCE support.

.. literalinclude:: /examples/openapi/plugins/swagger_ui_oauth.py
    :language: python

Customizing the OpenAPI UI
--------------------------

Style and behavior of the OpenAPI UI can be customized by overriding the default ``css_url`` and ``js_url`` attributes
on the render plugin class, for example:

.. literalinclude:: /examples/openapi/plugins/scalar_customized.py
    :language: python

To learn more about customizing the ``Scalar`` UI, see the `Scalar documentation <https://docs.scalar.com/>`_.

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.