prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Partial update not working correctly because of custom validation
  The validation rule in `app/grandchallenge/annotations/serializers.py:31` is breaking the partial update functionality.
  If you try to do a partial update PATCH request to the endpoint, it will try to find the `annotation_set` attribute in the request data. If this is not present it will throw a KeyError. 
  
  This should be fixed by first checking if the key exists in the request data and only then running the validation check. The validation check is not needed if the key does not exist because it will then either not change (for partial update request) or throw a `field is required` validation error (for every other type of request).
  
  I will fix this and add a test for it.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `app/grandchallenge/annotations/serializers.py`
  Content:
  ```
  1 from rest_framework import serializers
  2 
  3 from .models import (
  4     ETDRSGridAnnotation,
  5     MeasurementAnnotation,
  6     BooleanClassificationAnnotation,
  7     PolygonAnnotationSet,
  8     SinglePolygonAnnotation,
  9     LandmarkAnnotationSet,
  10     SingleLandmarkAnnotation,
  11 )
  12 from .validators import validate_grader_is_current_retina_user
  13 
  14 
  15 class AbstractAnnotationSerializer(serializers.ModelSerializer):
  16     def validate_grader(self, value):
  17         """
  18         Validate that grader is the user creating the object for retina_graders group
  19         """
  20         validate_grader_is_current_retina_user(value, self.context)
  21         return value
  22 
  23     class Meta:
  24         abstract = True
  25 
  26 
  27 class AbstractSingleAnnotationSerializer(serializers.ModelSerializer):
  28     def validate(self, data):
  29         """
  30         Validate that the user that is creating this object equals the annotation_set.grader for retina_graders
  31         """
  32         validate_grader_is_current_retina_user(
  33             data["annotation_set"].grader, self.context
  34         )
  35         return data
  36 
  37     class Meta:
  38         abstract = True
  39 
  40 
  41 class ETDRSGridAnnotationSerializer(AbstractAnnotationSerializer):
  42     class Meta:
  43         model = ETDRSGridAnnotation
  44         fields = ("grader", "created", "image", "fovea", "optic_disk")
  45 
  46 
  47 class MeasurementAnnotationSerializer(AbstractAnnotationSerializer):
  48     class Meta:
  49         model = MeasurementAnnotation
  50         fields = ("image", "grader", "created", "start_voxel", "end_voxel")
  51 
  52 
  53 class BooleanClassificationAnnotationSerializer(AbstractAnnotationSerializer):
  54     class Meta:
  55         model = BooleanClassificationAnnotation
  56         fields = ("image", "grader", "created", "name", "value")
  57 
  58 
  59 class SinglePolygonAnnotationSerializer(AbstractSingleAnnotationSerializer):
  60     annotation_set = serializers.PrimaryKeyRelatedField(
  61         queryset=PolygonAnnotationSet.objects.all()
  62     )
  63 
  64     class Meta:
  65         model = SinglePolygonAnnotation
  66         fields = ("id", "value", "annotation_set")
  67 
  68 
  69 class PolygonAnnotationSetSerializer(AbstractAnnotationSerializer):
  70     singlepolygonannotation_set = SinglePolygonAnnotationSerializer(
  71         many=True, read_only=True
  72     )
  73 
  74     class Meta:
  75         model = PolygonAnnotationSet
  76         fields = (
  77             "id",
  78             "image",
  79             "grader",
  80             "created",
  81             "name",
  82             "singlepolygonannotation_set",
  83         )
  84 
  85 
  86 class LandmarkAnnotationSetSerializer(AbstractAnnotationSerializer):
  87     class Meta:
  88         model = LandmarkAnnotationSet
  89         fields = ("grader", "created")
  90 
  91 
  92 class SingleLandmarkAnnotationSerializer(AbstractSingleAnnotationSerializer):
  93     class Meta:
  94         model = SingleLandmarkAnnotation
  95         fields = ("image", "annotation_set", "landmarks")
  96
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/app/grandchallenge/annotations/serializers.py b/app/grandchallenge/annotations/serializers.py
  --- a/app/grandchallenge/annotations/serializers.py
  +++ b/app/grandchallenge/annotations/serializers.py
  @@ -27,11 +27,14 @@
   class AbstractSingleAnnotationSerializer(serializers.ModelSerializer):
       def validate(self, data):
           """
  -        Validate that the user that is creating this object equals the annotation_set.grader for retina_graders
  +        Validate that the user that is creating this object equals the
  +        annotation_set.grader for retina_graders
           """
  -        validate_grader_is_current_retina_user(
  -            data["annotation_set"].grader, self.context
  -        )
  +        if data.get("annotation_set") is None:
  +            return data
  +
  +        grader = data["annotation_set"].grader
  +        validate_grader_is_current_retina_user(grader, self.context)
           return data
   
       class Meta:
  
verification_info: {"golden_diff": "diff --git a/app/grandchallenge/annotations/serializers.py b/app/grandchallenge/annotations/serializers.py\n--- a/app/grandchallenge/annotations/serializers.py\n+++ b/app/grandchallenge/annotations/serializers.py\n@@ -27,11 +27,14 @@\n class AbstractSingleAnnotationSerializer(serializers.ModelSerializer):\n     def validate(self, data):\n         \"\"\"\n-        Validate that the user that is creating this object equals the annotation_set.grader for retina_graders\n+        Validate that the user that is creating this object equals the\n+        annotation_set.grader for retina_graders\n         \"\"\"\n-        validate_grader_is_current_retina_user(\n-            data[\"annotation_set\"].grader, self.context\n-        )\n+        if data.get(\"annotation_set\") is None:\n+            return data\n+\n+        grader = data[\"annotation_set\"].grader\n+        validate_grader_is_current_retina_user(grader, self.context)\n         return data\n \n     class Meta:\n", "issue": "Partial update not working correctly because of custom validation\nThe validation rule in `app/grandchallenge/annotations/serializers.py:31` is breaking the partial update functionality.\r\nIf you try to do a partial update PATCH request to the endpoint, it will try to find the `annotation_set` attribute in the request data. If this is not present it will throw a KeyError. \r\n\r\nThis should be fixed by first checking if the key exists in the request data and only then running the validation check. The validation check is not needed if the key does not exist because it will then either not change (for partial update request) or throw a `field is required` validation error (for every other type of request).\r\n\r\nI will fix this and add a test for it.\n", "before_files": [{"content": "from rest_framework import serializers\n\nfrom .models import (\n    ETDRSGridAnnotation,\n    MeasurementAnnotation,\n    BooleanClassificationAnnotation,\n    PolygonAnnotationSet,\n    SinglePolygonAnnotation,\n    LandmarkAnnotationSet,\n    SingleLandmarkAnnotation,\n)\nfrom .validators import validate_grader_is_current_retina_user\n\n\nclass AbstractAnnotationSerializer(serializers.ModelSerializer):\n    def validate_grader(self, value):\n        \"\"\"\n        Validate that grader is the user creating the object for retina_graders group\n        \"\"\"\n        validate_grader_is_current_retina_user(value, self.context)\n        return value\n\n    class Meta:\n        abstract = True\n\n\nclass AbstractSingleAnnotationSerializer(serializers.ModelSerializer):\n    def validate(self, data):\n        \"\"\"\n        Validate that the user that is creating this object equals the annotation_set.grader for retina_graders\n        \"\"\"\n        validate_grader_is_current_retina_user(\n            data[\"annotation_set\"].grader, self.context\n        )\n        return data\n\n    class Meta:\n        abstract = True\n\n\nclass ETDRSGridAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = ETDRSGridAnnotation\n        fields = (\"grader\", \"created\", \"image\", \"fovea\", \"optic_disk\")\n\n\nclass MeasurementAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = MeasurementAnnotation\n        fields = (\"image\", \"grader\", \"created\", \"start_voxel\", \"end_voxel\")\n\n\nclass BooleanClassificationAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = BooleanClassificationAnnotation\n        fields = (\"image\", \"grader\", \"created\", \"name\", \"value\")\n\n\nclass SinglePolygonAnnotationSerializer(AbstractSingleAnnotationSerializer):\n    annotation_set = serializers.PrimaryKeyRelatedField(\n        queryset=PolygonAnnotationSet.objects.all()\n    )\n\n    class Meta:\n        model = SinglePolygonAnnotation\n        fields = (\"id\", \"value\", \"annotation_set\")\n\n\nclass PolygonAnnotationSetSerializer(AbstractAnnotationSerializer):\n    singlepolygonannotation_set = SinglePolygonAnnotationSerializer(\n        many=True, read_only=True\n    )\n\n    class Meta:\n        model = PolygonAnnotationSet\n        fields = (\n            \"id\",\n            \"image\",\n            \"grader\",\n            \"created\",\n            \"name\",\n            \"singlepolygonannotation_set\",\n        )\n\n\nclass LandmarkAnnotationSetSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = LandmarkAnnotationSet\n        fields = (\"grader\", \"created\")\n\n\nclass SingleLandmarkAnnotationSerializer(AbstractSingleAnnotationSerializer):\n    class Meta:\n        model = SingleLandmarkAnnotation\n        fields = (\"image\", \"annotation_set\", \"landmarks\")\n", "path": "app/grandchallenge/annotations/serializers.py"}], "after_files": [{"content": "from rest_framework import serializers\n\nfrom .models import (\n    ETDRSGridAnnotation,\n    MeasurementAnnotation,\n    BooleanClassificationAnnotation,\n    PolygonAnnotationSet,\n    SinglePolygonAnnotation,\n    LandmarkAnnotationSet,\n    SingleLandmarkAnnotation,\n)\nfrom .validators import validate_grader_is_current_retina_user\n\n\nclass AbstractAnnotationSerializer(serializers.ModelSerializer):\n    def validate_grader(self, value):\n        \"\"\"\n        Validate that grader is the user creating the object for retina_graders group\n        \"\"\"\n        validate_grader_is_current_retina_user(value, self.context)\n        return value\n\n    class Meta:\n        abstract = True\n\n\nclass AbstractSingleAnnotationSerializer(serializers.ModelSerializer):\n    def validate(self, data):\n        \"\"\"\n        Validate that the user that is creating this object equals the\n        annotation_set.grader for retina_graders\n        \"\"\"\n        if data.get(\"annotation_set\") is None:\n            return data\n\n        grader = data[\"annotation_set\"].grader\n        validate_grader_is_current_retina_user(grader, self.context)\n        return data\n\n    class Meta:\n        abstract = True\n\n\nclass ETDRSGridAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = ETDRSGridAnnotation\n        fields = (\"grader\", \"created\", \"image\", \"fovea\", \"optic_disk\")\n\n\nclass MeasurementAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = MeasurementAnnotation\n        fields = (\"image\", \"grader\", \"created\", \"start_voxel\", \"end_voxel\")\n\n\nclass BooleanClassificationAnnotationSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = BooleanClassificationAnnotation\n        fields = (\"image\", \"grader\", \"created\", \"name\", \"value\")\n\n\nclass SinglePolygonAnnotationSerializer(AbstractSingleAnnotationSerializer):\n    annotation_set = serializers.PrimaryKeyRelatedField(\n        queryset=PolygonAnnotationSet.objects.all()\n    )\n\n    class Meta:\n        model = SinglePolygonAnnotation\n        fields = (\"id\", \"value\", \"annotation_set\")\n\n\nclass PolygonAnnotationSetSerializer(AbstractAnnotationSerializer):\n    singlepolygonannotation_set = SinglePolygonAnnotationSerializer(\n        many=True, read_only=True\n    )\n\n    class Meta:\n        model = PolygonAnnotationSet\n        fields = (\n            \"id\",\n            \"image\",\n            \"grader\",\n            \"created\",\n            \"name\",\n            \"singlepolygonannotation_set\",\n        )\n\n\nclass LandmarkAnnotationSetSerializer(AbstractAnnotationSerializer):\n    class Meta:\n        model = LandmarkAnnotationSet\n        fields = (\"grader\", \"created\")\n\n\nclass SingleLandmarkAnnotationSerializer(AbstractSingleAnnotationSerializer):\n    class Meta:\n        model = SingleLandmarkAnnotation\n        fields = (\"image\", \"annotation_set\", \"landmarks\")\n", "path": "app/grandchallenge/annotations/serializers.py"}]}