Copilot commented on code in PR #40672:
URL: https://github.com/apache/superset/pull/40672#discussion_r3338885722


##########
superset/charts/schemas.py:
##########
@@ -937,6 +945,42 @@ class ChartDataPostProcessingOperationSchema(Schema):
         },
     )
 
+    # Map post-processing operation -> its options schema, for operations that
+    # declare one. Operations without a dedicated schema are not structurally
+    # validated here.
+    _OPTIONS_SCHEMAS: dict[str, type[Schema]] = {
+        "aggregate": ChartDataAggregateOptionsSchema,
+        "rolling": ChartDataRollingOptionsSchema,
+        "select": ChartDataSelectOptionsSchema,
+        "sort": ChartDataSortOptionsSchema,
+        "contribution": ChartDataContributionOptionsSchema,
+        "prophet": ChartDataProphetOptionsSchema,
+        "boxplot": ChartDataBoxplotOptionsSchema,
+        "pivot": ChartDataPivotOptionsSchema,
+        "geohash_decode": ChartDataGeohashDecodeOptionsSchema,
+        "geohash_encode": ChartDataGeohashEncodeOptionsSchema,
+        "geodetic_parse": ChartDataGeodeticParseOptionsSchema,
+    }
+
+    @validates_schema
+    def validate_options(self, data: dict[str, Any], **kwargs: Any) -> None:
+        """Validate ``options`` against the operation's option schema.
+
+        Validation is lenient (unknown keys are ignored) so it surfaces wrong
+        types / out-of-range values on declared fields without rejecting
+        payloads that carry extra keys.
+        """
+        operation = data.get("operation")
+        options = data.get("options")
+        if not isinstance(operation, str) or not isinstance(options, dict):
+            return
+        schema_cls = self._OPTIONS_SCHEMAS.get(operation)
+        if schema_cls is None:
+            return
+        errors = schema_cls(unknown=EXCLUDE).validate(options)
+        if errors:
+            raise ValidationError({"options": errors})

Review Comment:
   `validate_options` currently skips validation when `options` is missing (or 
otherwise not a `dict`). For operations that *do* have a dedicated option 
schema (e.g. `prophet`), this means required option fields are never enforced 
if the client omits `options` entirely, which undermines the intent of wiring 
option schemas into the validation pipeline.



##########
tests/unit_tests/charts/test_schemas.py:
##########
@@ -152,3 +152,53 @@ def 
test_time_grain_validation_with_config_addons(app_context: None) -> None:
     }
     result = schema.load(custom_data)
     assert result["time_grain"] == "PT10M"
+
+
+def test_post_processing_operation_validates_options(app_context: None) -> 
None:
+    """options are validated against the operation's option schema 
(leniently)."""
+    from superset.charts.schemas import ChartDataPostProcessingOperationSchema
+
+    schema = ChartDataPostProcessingOperationSchema()
+
+    # Valid prophet options load.
+    schema.load(
+        {
+            "operation": "prophet",
+            "options": {
+                "time_grain": "P1D",
+                "periods": 7,
+                "confidence_interval": 0.8,
+            },
+        }
+    )

Review Comment:
   The new test suite doesn't cover the case where an operation that has an 
option schema (e.g. `prophet`) is sent without `options`. Adding an assertion 
for this helps prevent regressions and matches the intent of validating 
per-operation required fields.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to