Browse Source

fix(docs): Follow schema component reference paths manually in post hook (#57639)

### Fix ordering for body params
- Manually dereference JSON (easily done b/c the dereferencing keys
follow a pattern)
- Note: There's still a bug here. ModelSerializers for some reason don't
keep body params in the same order in the JSON as they are in the
serializer fields.
My hypothesis is they're being sorted by the ordering of fields on the
model, but it's difficult to confirm. Not a huge deal b/c required
params are still being sorted to the top, but it makes it harder for
customers to follow the body params
Seiji Chew 1 year ago
parent
commit
129903f663
1 changed files with 17 additions and 0 deletions
  1. 17 0
      src/sentry/apidocs/hooks.py

+ 17 - 0
src/sentry/apidocs/hooks.py

@@ -194,7 +194,21 @@ def custom_preprocessing_hook(endpoints: Any) -> Any:  # TODO: organize method,
     return filtered
 
 
+def dereference_schema(schema: dict, schema_components: dict) -> dict:
+    """
+    Dereferences the schema reference if it exists. Otherwise, returns the schema as is.
+    """
+    if len(schema) == 1 and "$ref" in schema:
+        # The reference always takes the form of #/components/schemas/{schema_name}
+        schema_name = schema["$ref"].split("/")[-1]
+        schema = schema_components[schema_name]
+    return schema
+
+
 def custom_postprocessing_hook(result: Any, generator: Any, **kwargs: Any) -> Any:
+    # Fetch schema component references
+    schema_components = result["components"]["schemas"]
+
     for path, endpoints in result["paths"].items():
         for method_info in endpoints.values():
             _check_tag(path, method_info)
@@ -222,6 +236,9 @@ def custom_postprocessing_hook(result: Any, generator: Any, **kwargs: Any) -> An
                     else:
                         schema = content["application/json"]["schema"]
 
+                    # Dereference schema if needed
+                    schema = dereference_schema(schema, schema_components)
+
                     # Required params are stored in a list and not in the param itself
                     required = set(schema.get("required", []))
                     if required: