The old renderer's :request: option crashes with KeyError: 'properties' when a request body's schema isn't an object. The 3.1 renderer got a guard for this in cca8fc3, but the 3.0 renderer still has the unguarded call, so the same spec crashes on 3.0 and renders on 3.1.
Minimal reproducer
spec.yml — note the requestBody schema is type: string:
openapi: 3.0.3
info:
title: Minimal
version: 1.0.0
paths:
/thing:
post:
summary: Create thing
requestBody:
content:
application/json:
schema:
type: string
responses:
200:
description: Created.
index.rst:
Page
====
.. openapi:: spec.yml
:request:
conf.py:
extensions = ["sphinxcontrib.openapi"]
Actual
$ sphinx-build -b html src out
...
File "sphinxcontrib/openapi/openapi30.py", line 307, in _httpresource
req_properties = json.dumps(schema['properties'], indent=2,
~~~~~~^^^^^^^^^^^^^^
KeyError: 'properties'
Build aborts, exit 2. Changing only the version to openapi: 3.1.0 makes the same spec render (exit 0), which isolates the cause to the renderer rather than the spec.
Expected
The whole schema dumped as the request body, as the 3.1 renderer already does.
Cause
sphinxcontrib/openapi/openapi30.py line 307 indexes properties unconditionally:
schema = request_content['application/json']['schema']
req_properties = json.dumps(schema['properties'], indent=2,
separators=(',', ':'))
A schema that isn't type: object has no properties key. cca8fc3 "Handle non-object request bodies" fixed exactly this in openapi31.py by branching on the type and dumping the whole schema otherwise, but the change wasn't ported to openapi30.py. The two files carry separate copies of this code path.
Note on the fix
Porting the 3.1 guard verbatim gives 3.0/3.1 parity, which seems like the right scope for this issue. Worth flagging that the guard as written in openapi31.py indexes schema["type"] directly, so a schema with no type at all raises KeyError: 'type' on both renderers once ported. That's a pre-existing condition of the 3.1 code rather than something the port introduces, and schema.get('type') would cover it in both files if you'd prefer that as a follow-up.
Happy to open a PR for the port.
Environment
- sphinxcontrib-openapi 0.9.0
- sphinxcontrib-httpdomain 2.0.0
- Sphinx 9.1.0
- docutils 0.22.4
- Python 3.12.13
The old renderer's
:request:option crashes withKeyError: 'properties'when a request body's schema isn't an object. The 3.1 renderer got a guard for this in cca8fc3, but the 3.0 renderer still has the unguarded call, so the same spec crashes on 3.0 and renders on 3.1.Minimal reproducer
spec.yml— note therequestBodyschema istype: string:index.rst:conf.py:Actual
Build aborts, exit 2. Changing only the version to
openapi: 3.1.0makes the same spec render (exit 0), which isolates the cause to the renderer rather than the spec.Expected
The whole schema dumped as the request body, as the 3.1 renderer already does.
Cause
sphinxcontrib/openapi/openapi30.pyline 307 indexespropertiesunconditionally:A schema that isn't
type: objecthas nopropertieskey. cca8fc3 "Handle non-object request bodies" fixed exactly this inopenapi31.pyby branching on the type and dumping the whole schema otherwise, but the change wasn't ported toopenapi30.py. The two files carry separate copies of this code path.Note on the fix
Porting the 3.1 guard verbatim gives 3.0/3.1 parity, which seems like the right scope for this issue. Worth flagging that the guard as written in
openapi31.pyindexesschema["type"]directly, so a schema with notypeat all raisesKeyError: 'type'on both renderers once ported. That's a pre-existing condition of the 3.1 code rather than something the port introduces, andschema.get('type')would cover it in both files if you'd prefer that as a follow-up.Happy to open a PR for the port.
Environment