Skip to content

Commit bbbaeba

Browse files
Fix #64: use examples array and enum values in auto-generated schema examples (#73)
- get_example_from_schema now checks for the JSON Schema draft 6+ 'examples' array (plural) and uses its first element as a fallback after 'example' (singular) but before dispatching to the type handler. - Moved enum handling from StringExampleHandler up to ScalarExampleHandler so that integer, number, and boolean properties with an 'enum' field also render the first enum value instead of falling through to the type default (0, 10.12, True). - 'example' (singular) still takes precedence over 'examples' (plural) which takes precedence over enum which takes precedence over type/format defaults. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 75108ce commit bbbaeba

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
- Fix [#60](https://github.com/Neoteroi/essentials-openapi/issues/60): resolve `$ref`
2727
values in response headers pointing to `#/components/headers/...` to avoid
2828
`UndefinedError` when rendering response tables, reported by @copiousfreetime.
29+
- Fix [#64](https://github.com/Neoteroi/essentials-openapi/issues/64): use `examples`
30+
array (JSON Schema draft 6+) as a fallback for auto-generated response examples;
31+
also use `enum` values as examples for all scalar types (integer, number, boolean),
32+
reported by @jan-ldwg.
2933

3034
## [1.3.0] - 2025-11-19
3135

openapidocs/mk/v3/examples.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class ScalarExampleHandler(SchemaExampleHandler):
3535
formats: Dict[str, Callable[[], Any]]
3636

3737
def get_example(self, schema) -> str:
38+
enum = schema.get("enum")
39+
if isinstance(enum, list) and enum:
40+
return enum[0]
41+
3842
format = schema.get("format")
3943

4044
if format and format in self.formats:
@@ -56,12 +60,6 @@ class StringExampleHandler(ScalarExampleHandler):
5660
"binary": lambda: "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=",
5761
}
5862

59-
def get_example(self, schema) -> str:
60-
enum = schema.get("enum")
61-
if isinstance(enum, list):
62-
return enum[0]
63-
return super().get_example(schema)
64-
6563

6664
class IntegerExampleHandler(ScalarExampleHandler):
6765
type_name = "integer"
@@ -138,6 +136,10 @@ def get_example_from_schema(schema) -> Any:
138136
if "example" in schema:
139137
return schema["example"]
140138

139+
examples = schema.get("examples")
140+
if isinstance(examples, list) and examples:
141+
return examples[0]
142+
141143
# does it have a type?
142144
handlers_types: List[Type[SchemaExampleHandler]] = list(
143145
get_subclasses(SchemaExampleHandler)

tests/test_oas31.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,34 @@ def test_null_only_type(self):
163163
assert get_example_from_schema({"type": ["null"]}) is None
164164

165165

166-
# ---------------------------------------------------------------------------
167-
# OpenAPIV3DocumentationHandler — OAS 3.1 rendering
168-
# ---------------------------------------------------------------------------
166+
class TestGetExampleFromSchemaAnnotations:
167+
"""Tests for JSON Schema draft 6+ examples array and enum handling."""
168+
169+
@pytest.mark.parametrize(
170+
"schema, expected",
171+
[
172+
# examples array (JSON Schema draft 6+) - first value should be used
173+
({"type": "string", "examples": ["A-DSP", "MON 1"]}, "A-DSP"),
174+
({"type": "integer", "examples": [42, 99]}, 42),
175+
({"type": "number", "examples": [3.14, 2.71]}, 3.14),
176+
({"type": "boolean", "examples": [False, True]}, False),
177+
# example (singular) takes precedence over examples (plural)
178+
(
179+
{"type": "string", "example": "override", "examples": ["A-DSP"]},
180+
"override",
181+
),
182+
# empty examples list falls through to type handler
183+
({"type": "string", "examples": []}, "string"),
184+
# enum on non-string types
185+
({"type": "integer", "enum": [1, 2, 3]}, 1),
186+
({"type": "number", "enum": [1.5, 2.5]}, 1.5),
187+
({"type": "boolean", "enum": [False]}, False),
188+
# enum on string (pre-existing behaviour still works)
189+
({"type": "string", "enum": ["active", "inactive"]}, "active"),
190+
],
191+
)
192+
def test_examples_and_enum(self, schema, expected):
193+
assert get_example_from_schema(schema) == expected
169194

170195

171196
class TestOas31DocumentationHandler:

0 commit comments

Comments
 (0)