openapi: Rewrite recursive #/components/schemas/ references

When a schema referenced another schema as #/components/schemas/...
that wasn't properly rewritten into #/$defs/..
This commit is contained in:
Owen W. Taylor 2025-06-20 14:30:55 -04:00
commit 14d1b8a94d
2 changed files with 27 additions and 3 deletions

View file

@ -262,16 +262,18 @@ class OpenAPIParser(
if isinstance(resolved_schema, (self.schema_cls)):
# Convert schema to dictionary
return resolved_schema.model_dump(
result = resolved_schema.model_dump(
mode="json", by_alias=True, exclude_none=True
)
elif isinstance(resolved_schema, dict):
return resolved_schema
result = resolved_schema
else:
logger.warning(
f"Expected Schema after resolving, got {type(resolved_schema)}. Returning empty dict."
)
return {}
result = {}
return _replace_ref_with_defs(result)
except Exception as e:
logger.error(f"Failed to extract schema as dict: {e}", exc_info=False)
return {}

View file

@ -294,6 +294,28 @@ def test_complex_schema_route_count(parsed_complex_routes):
assert len(parsed_complex_routes) == 3
def test_complex_schema_ref_rewriting(parsed_complex_routes):
"""Test that all #/components references have been rewritten."""
def no_components(value):
if isinstance(value, dict):
for k, v in value.items():
if k == "$ref":
assert not v.startswith("#/components/"), (
f"reference '{v}' was not rewritten"
)
else:
no_components(v)
elif isinstance(value, list):
for v in value:
no_components(v)
for route in parsed_complex_routes:
no_components(route.schema_definitions)
for param in route.parameters:
no_components(param.schema_)
def test_complex_schema_list_users_query_param_limit(complex_route_map):
"""Test that a reference to a limit query parameter is correctly resolved."""
list_users = complex_route_map["listUsers"]