sphinx-contrib / sphinx-contrib/openapi

Schema-derived string/enum example is emitted unencoded as an application/json body, failing the http lexer

Open
#172 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
126
Forks
88
PR merge metrics
No merged PRs in 30d

Description

With :examples:, a response whose schema is a bare type: string (for example an enum) produces an example body that isn't valid JSON, even though the block is emitted under Content-Type: application/json. Pygments then fails to lex it and Sphinx warns. Under sphinx-build -W that's fatal.

Minimal reproducer

spec.yml:

openapi: 3.0.3
info:
  title: Minimal
  version: 1.0.0
paths:
  /thing:
    get:
      summary: Get thing
      responses:
        200:
          description: A thing.
          content:
            application/json:
              schema:
                type: string
                enum:
                  - PENDING
                  - DONE

index.rst:

Page
====

.. openapi:: spec.yml
   :examples:
Actual
$ sphinx-build -W -b html src out
<openapi>:1: WARNING: Lexing literal_block 'HTTP/1.1 200 OK\nContent-Type: application/json\n\nPENDING' as "http" resulted in an error at token: 'P'. Retrying in relaxed mode

The generated example body is the bare token PENDING:

HTTP/1.1 200 OK
Content-Type: application/json

PENDING
Expected

Either a JSON-encoded body, "PENDING", which is a valid JSON document and lexes cleanly, or no example emitted for a scalar schema.

Cause

Two pieces combine, both in sphinxcontrib/openapi/openapi30.py.

_parse_schema returns the raw first enum value, a Python str:

108:    if 'enum' in schema:
109:        # we only show the first one since we can't show everything
110:        return schema['enum'][0]

_example then skips JSON encoding for anything that's already a str:

208:        for example in examples.values():
209:            # According to OpenAPI v3 specs, string examples should be left unchanged
210:            if not isinstance(example['value'], str):
211:                example['value'] = json.dumps(
212:                    example['value'], indent=4, separators=(',', ': '))

The "leave strings unchanged" rule is right for an author-supplied example: value, where the string is meant literally. But a schema-derived example for a type: string schema still needs JSON encoding to be a valid application/json document. The two paths converge on the same isinstance check, so the derived case inherits behavior intended for the literal case.

A fix would need to distinguish schema-derived examples from author-supplied ones, rather than switching on the value's Python type.

Possibly related
  • #168 is the inverse failure at the same line 211: a value that isn't a str (a datetime from YAML) reaches json.dumps and raises. Same function, adjacent concern, different fix.
  • #160 reports an unserializable sentinel escaping _parse_schema in the 3.1 path.

All three suggest the example-generation path would benefit from a single place that decides how a derived value becomes a rendered body.

Environment
  • sphinxcontrib-openapi 0.9.0
  • sphinxcontrib-httpdomain 2.0.0
  • Sphinx 8.2.3
  • Pygments 2.20.0
  • docutils 0.21.2
  • Python 3.12.13

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in sphinxcontrib/openapi/openapi30.py by reading _parse_schema and _example, then reproduce the issue with the supplied spec.yml and sphinx-build -W. Trace how schema-derived and author-supplied examples reach rendering. Done means the scalar application/json example is valid JSON or is omitted, without the Pygments lexer warning.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.