diff --git a/superset/annotation_layers/annotations/__init__.py b/superset/annotation_layers/annotations/__init__.py new file mode 100644 index 0000000000..13a83393a9 --- /dev/null +++ b/superset/annotation_layers/annotations/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/superset/annotation_layers/annotations/api.py b/superset/annotation_layers/annotations/api.py index bc39f5c3c1..4ddab2e19d 100644 --- a/superset/annotation_layers/annotations/api.py +++ b/superset/annotation_layers/annotations/api.py @@ -116,7 +116,9 @@ class AnnotationRestApi(BaseSupersetModelRestApi): openapi_spec_methods = openapi_spec_methods_override @staticmethod - def _apply_layered_relation_to_rison(layer_id: int, rison_parameters) -> None: + def _apply_layered_relation_to_rison( # pylint: disable=invalid-name + layer_id: int, rison_parameters: Dict[str, Any] + ) -> None: if "filters" not in rison_parameters: rison_parameters["filters"] = [] rison_parameters["filters"].append( @@ -128,7 +130,9 @@ class AnnotationRestApi(BaseSupersetModelRestApi): @safe @permission_name("get") @rison(get_list_schema) - def get_list(self, pk: int, **kwargs: Dict[str, Any]) -> Response: + def get_list( # pylint: disable=arguments-differ + self, pk: int, **kwargs: Dict[str, Any] + ) -> Response: """Get a list of annotations --- get: @@ -169,7 +173,7 @@ class AnnotationRestApi(BaseSupersetModelRestApi): The result from the get list query type: array items: - $ref: '#/components/schemas/{{self.__class__.__name__}}.get_list' # noqa + $ref: '#/components/schemas/{{self.__class__.__name__}}.get_list' # pylint: disable=line-too-long 400: $ref: '#/components/responses/400' 401: @@ -187,7 +191,9 @@ class AnnotationRestApi(BaseSupersetModelRestApi): @safe @permission_name("get") @rison(get_item_schema) - def get(self, pk: int, annotation_id: int, **kwargs: Dict[str, Any]) -> Response: + def get( # pylint: disable=arguments-differ + self, pk: int, annotation_id: int, **kwargs: Dict[str, Any] + ) -> Response: """Get item from Model --- get: @@ -242,7 +248,7 @@ class AnnotationRestApi(BaseSupersetModelRestApi): @safe @statsd_metrics @permission_name("post") - def post(self, pk: int) -> Response: + def post(self, pk: int) -> Response: # pylint: disable=arguments-differ """Creates a new Annotation --- post: @@ -308,7 +314,9 @@ class AnnotationRestApi(BaseSupersetModelRestApi): @safe @statsd_metrics @permission_name("put") - def put(self, pk: int, annotation_id: int) -> Response: + def put( # pylint: disable=arguments-differ + self, pk: int, annotation_id: int + ) -> Response: """Updates an Annotation --- put: @@ -379,7 +387,9 @@ class AnnotationRestApi(BaseSupersetModelRestApi): @safe @statsd_metrics @permission_name("delete") - def delete(self, pk: int, annotation_id: int) -> Response: + def delete( # pylint: disable=arguments-differ + self, pk: int, annotation_id: int + ) -> Response: """Deletes an Annotation --- delete: diff --git a/superset/annotation_layers/annotations/commands/update.py b/superset/annotation_layers/annotations/commands/update.py index 2e6d568d44..1942bffa7f 100644 --- a/superset/annotation_layers/annotations/commands/update.py +++ b/superset/annotation_layers/annotations/commands/update.py @@ -70,15 +70,15 @@ class UpdateAnnotationCommand(BaseCommand): if not annotation_layer: raise AnnotationLayerNotFoundError() self._properties["layer"] = annotation_layer + + # Validate short descr uniqueness on this layer + if not AnnotationDAO.validate_update_uniqueness( + layer_id, short_descr, annotation_id=self._model_id, + ): + exceptions.append(AnnotationUniquenessValidationError()) else: self._properties["layer"] = self._model.layer - # Validate short descr uniqueness on this layer - if not AnnotationDAO.validate_update_uniqueness( - layer_id, short_descr, annotation_id=self._model_id, - ): - exceptions.append(AnnotationUniquenessValidationError()) - # validate date time sanity start_dttm: Optional[datetime] = self._properties.get("start_dttm") end_dttm: Optional[datetime] = self._properties.get("end_dttm") diff --git a/superset/annotation_layers/annotations/dao.py b/superset/annotation_layers/annotations/dao.py index 293bc24709..50e4bcb29a 100644 --- a/superset/annotation_layers/annotations/dao.py +++ b/superset/annotation_layers/annotations/dao.py @@ -47,7 +47,7 @@ class AnnotationDAO(BaseDAO): @staticmethod def validate_update_uniqueness( layer_id: int, short_descr: str, annotation_id: Optional[int] = None - ): + ) -> bool: """ Validate if this annotation short description is unique. `id` is optional and serves for validating on updates diff --git a/superset/annotation_layers/annotations/schemas.py b/superset/annotation_layers/annotations/schemas.py index 2ae0b91ccf..42af48d61b 100644 --- a/superset/annotation_layers/annotations/schemas.py +++ b/superset/annotation_layers/annotations/schemas.py @@ -14,7 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -import json from typing import Union from marshmallow import fields, Schema, ValidationError