Browse Source

feat(api): Explicitly require body params to have a description (#57885)

Requires https://github.com/getsentry/sentry/pull/57887 (Removes body
params from SCIM endpoints missing documentation)

Our API docs page doesn't display body params if they are missing a
description although they're still present in the OpenApi JSON. This
change explicitly requires all body params to have a description.
Seiji Chew 1 year ago
parent
commit
8494e73401

+ 2 - 1
api-docs/paths/events/issue-details.json

@@ -227,7 +227,8 @@
                 "description": "In case this API call is invoked with a user context this allows changing of the bookmark flag."
               },
               "isSubscribed": {
-                "type": "boolean"
+                "type": "boolean",
+                "description": "In case this API call is invoked with a user context this allows the user to subscribe to workflow notications for this issue."
               },
               "isPublic": {
                 "type": "boolean",

+ 36 - 1
src/sentry/api/endpoints/project_details.py

@@ -100,7 +100,42 @@ class ProjectMemberSerializer(serializers.Serializer):
     )
 
 
-@extend_schema_serializer(exclude_fields=["options"])
+@extend_schema_serializer(
+    exclude_fields=[
+        "options",
+        "team",
+        "digestsMinDelay",
+        "digestsMaxDelay",
+        "securityToken",
+        "securityTokenHeader",
+        "verifySSL",
+        "defaultEnvironment",
+        "dataScrubber",
+        "dataScrubberDefaults",
+        "sensitiveFields",
+        "safeFields",
+        "storeCrashReports",
+        "relayPiiConfig",
+        "builtinSymbolSources",
+        "symbolSources",
+        "scrubIPAddresses",
+        "groupingConfig",
+        "groupingEnhancements",
+        "fingerprintingRules",
+        "secondaryGroupingConfig",
+        "secondaryGroupingExpiry",
+        "groupingAutoUpdate",
+        "scrapeJavaScript",
+        "allowedDomains",
+        "copy_from_project",
+        "dynamicSamplingBiases",
+        "performanceIssueCreationRate",
+        "performanceIssueCreationThroughPlatform",
+        "performanceIssueSendToPlatform",
+        "recapServerUrl",
+        "recapServerToken",
+    ]
+)
 class ProjectAdminSerializer(ProjectMemberSerializer, PreventNumericSlugMixin):
     name = serializers.CharField(
         help_text="The name for the project",

+ 3 - 3
src/sentry/api/serializers/rest_framework/project_key.py

@@ -58,10 +58,10 @@ class DynamicSdkLoaderOptionSerializer(serializers.Serializer):
 
 
 @extend_schema_serializer(
-    exclude_fields=(
+    exclude_fields=[
         "public",
-        "private",
-    ),
+        "secret",
+    ],
 )
 class ProjectKeyPostSerializer(serializers.Serializer):
     name = serializers.CharField(

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

@@ -239,6 +239,23 @@ def custom_postprocessing_hook(result: Any, generator: Any, **kwargs: Any) -> An
                     # Dereference schema if needed
                     schema = dereference_schema(schema, schema_components)
 
+                    for body_param, param_data in schema["properties"].items():
+                        # Ensure body parameters have a description. Our API docs don't
+                        # display body params without a description, so it's easy to miss them.
+                        # We should be explicitly excluding them as better
+                        # practice however.
+
+                        # There is an edge case where a body param might be
+                        # reference that we should ignore for now
+                        if "description" not in param_data and "$ref" not in param_data:
+                            raise SentryApiBuildError(
+                                f"""Body parameter '{body_param}' is missing a description for endpoint {endpoint_name}. You can either:
+                            1. Add a 'help_text' kwarg to the serializer field
+                            2. Remove the field if you're using an inline_serializer
+                            3. For a DRF serializer, you must explicitly exclude this field by decorating the request serializer with
+                            @extend_schema_serializer(exclude_fields=[{body_param}])."""
+                            )
+
                     # Required params are stored in a list and not in the param itself
                     required = set(schema.get("required", []))
                     if required:

+ 3 - 1
src/sentry/monitors/validators.py

@@ -4,7 +4,7 @@ from croniter import CroniterBadDateError, croniter
 from django.core.exceptions import ValidationError
 from django.utils import timezone
 from drf_spectacular.types import OpenApiTypes
-from drf_spectacular.utils import extend_schema_field
+from drf_spectacular.utils import extend_schema_field, extend_schema_serializer
 from rest_framework import serializers
 
 from sentry.api.base import (
@@ -230,6 +230,7 @@ class ConfigValidator(serializers.Serializer):
         return attrs
 
 
+@extend_schema_serializer(exclude_fields=["project", "name", "slug", "config", "alert_rule"])
 class MonitorValidator(CamelSnakeSerializer, PreventNumericSlugMixin):
     project = ProjectField(scope="project:read")
     name = serializers.CharField(max_length=128)
@@ -287,6 +288,7 @@ class ContextsValidator(serializers.Serializer):
     trace = TraceContextValidator(required=False)
 
 
+@extend_schema_serializer(exclude_fields=["duration", "environment", "monitor_config", "contexts"])
 class MonitorCheckInValidator(serializers.Serializer):
     status = serializers.ChoiceField(
         choices=(