Skip to content
Edit this page
On this page

OpenAPI

sphinxcontrib-openapi generates HTTP API documentation directly from OpenAPI (Swagger) specification files. It builds on sphinxcontrib-httpdomain, which provides HTTP method directives for writing endpoint docs by hand. Lumina styles all HTTP endpoints with color-coded method indicators and adds interactive features when you configure a base URL.

5 min read

Setup

uv add sphinxcontrib-openapi
conf.py
extensions = ["sphinxcontrib.openapi"]
openapi_default_renderer = "httpdomain"

Use the httpdomain renderer for OpenAPI 3 request schemas and examples. The extension’s legacy default renderer can omit request bodies.

This also installs the HTTP domain, so you can write individual endpoints manually with http:get::, http:post::, and other method directives.

Usage

Point the openapi directive at your spec file:

```{eval-rst}
.. openapi:: path/to/openapi.yml
   :generate-examples-from-schemas:
```

See HTTP API Documentation for rendered examples of both auto-generated and manually written HTTP API documentation.

Expanding endpoint details

Endpoints start collapsed. Select a signature to see its description, parameters, examples, and request controls. Expand all and Collapse all apply to every API definition on the page.

To start with all definitions expanded, set "api_expanded": "true" in html_theme_options. This option also applies to Python and JavaScript API documentation. See Configuration.

Interactive Features

Set api_base_url in your theme options to activate two interactive features on every HTTP endpoint:

conf.py
html_theme_options = {
    "api_base_url": "https://api.example.com/v1",
}

Copy as curl

Each endpoint has one Copy as curl button in its request panel. It copies the current server, parameters, headers, authentication, and body. Open Request command to inspect or manually copy the command.

Commands use POSIX shell quoting, including apostrophes in JSON and headers. Fill in required parameters before running them. Treat copied commands as sensitive when they include credentials.

When Try it out is disabled, the signature button copies a template from the documented fields and request example. Replace parameter placeholders before running it.

Try it out

Open an endpoint’s Try it out panel:

  1. Check Server URL. You can change it for this endpoint without rebuilding the docs.

  2. Fill in path parameters and any query parameters marked required.

  3. Open Authentication if needed, then edit headers or the request body.

  4. Choose Send Request or Copy as curl. You can also send with Ctrl+Enter (macOS: ⌘+Enter) from a request field.

The editor supports:

  • Path parameters in OpenAPI {id} and HTTP-domain (int:id) notation, with URL encoding.

  • Query parameters and required markers from rendered documentation.

  • Authentication using Bearer tokens, Basic authentication, or API keys in headers or query strings.

  • Headers, including documented defaults written as inline code, and additional name/value pairs.

  • Request bodies populated from rendered HTTP request examples. Use :generate-examples-from-schemas: to generate nested JSON examples from your specification.

Without an example, documented top-level JSON fields provide a basic template. Check it against your API’s schema. A blank editor sends no body. JSON is checked for valid syntax before sending; it is not validated against the OpenAPI schema. You can change Content type to send raw text, XML, or a manually encoded form body.

Responses show the HTTP status, elapsed time through body download, response URL, exposed headers, and body. JSON is formatted and highlighted. Malformed JSON and non-JSON responses remain visible as text.

Cancel stops waiting for a response; the server may still process the request. Requests time out after 30 seconds. Clear removes the response while retaining your inputs.

Warning

CORS required. Requests go directly from the reader’s browser to the API. Allow the docs origin, request methods, and headers in your API’s CORS configuration. Expose diagnostic response headers such as X-Request-ID with Access-Control-Expose-Headers.

Browser cookies are omitted, browser-controlled headers cannot be overridden, and redirects are rejected to avoid forwarding credentials to another destination. Use the final API URL. If a request fails, check HTTPS, connectivity, and CORS, or use Copy as curl outside the browser.

Authentication and credential lifetime

Choose the authentication type explicitly. Lumina does not infer OpenAPI securitySchemes or run OAuth login flows.

Authentication settings are shared between endpoints with the same full API base URL on the current page. Changing Server URL selects that server’s separate credentials. Clear credentials clears authentication for all endpoints using that server.

Credentials stay in page memory only. Reloading or navigating away clears them; they are not saved in browser storage. Use narrowly scoped test credentials on trusted documentation hosts. API keys sent in query strings also appear in the URL preview and may be recorded in server logs.

When this can replace Swagger UI

Lumina suits documentation sites that need readable endpoint references and interactive testing of ordinary JSON or raw-body REST requests, including Bearer, Basic, and API-key authentication.

It is not a complete OpenAPI execution engine. The editor reads rendered HTTP-domain documentation, so it cannot recover specification details the renderer omits. Use a dedicated OpenAPI client when you need:

  • Automatic server variables, security requirements, or OAuth2/OpenID Connect login flows.

  • Schema-aware validation, enum selectors, or selectable oneOf/anyOf variants.

  • OpenAPI array/object parameter serialization (style, explode, deepObject), repeated query keys, or cookie authentication.

  • Multipart file uploads, binary response downloads, or streaming responses.

For these cases, keep the specification available to download alongside your Lumina reference. Do not assume that a rendered schema implies full interactive support.

Overriding the base URL per block

api_base_url sets a global default for all endpoints on all pages. To use a different server URL for a specific group of endpoints — for example, a staging environment or a separate microservice — wrap those endpoints in a <div> with a data-api-base-url attribute.

The closest ancestor’s data-api-base-url takes precedence over the global setting:

<div data-api-base-url="https://staging.api.example.com/v1">

```{eval-rst}
.. openapi:: staging-api.yml
```

</div>

This works with both .. openapi:: directives and individual .. http:get:: / .. http:post:: directives.

Note

HTML blocks in MyST require html_block in myst_enable_extensions, or use a {raw} html directive pair instead:

```{raw} html
<div data-api-base-url="https://staging.api.example.com/v1">
```

```{eval-rst}
.. openapi:: staging-api.yml
```

```{raw} html
</div>
```

Each signature shows its configured server hostname. The Server URL field and live request preview show the destination used by the request editor, including reader edits.

Disabling Try it out

To keep the “Copy as curl” button but hide the interactive panel:

conf.py
html_theme_options = {
    "api_base_url": "https://api.example.com/v1",
    "try_it_out": "false",
}
esc
↑↓ Navigate ↵ Open esc Close