We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Possibly make `thumbnail` null for audio files without artwork
## Description
<!-- Concisely describe the bug. -->

Currently the frontend tries to fetch thumbnails for all audio files regardless of whether the audio file in question has one or not. 
I noticed that the API returns the thumbnail URL for all tracks. That makes sense, but could we improve this to be `null` for audio tracks without artwork? Then we could check the field in the frontend before making a network request.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `api/catalog/api/serializers/audio_serializers.py`
Content:
```
1 from rest_framework import serializers
2 
3 from elasticsearch_dsl.response import Hit
4 
5 from catalog.api.constants.field_order import field_position_map
6 from catalog.api.constants.field_values import AUDIO_CATEGORIES, LENGTHS
7 from catalog.api.docs.media_docs import fields_to_md
8 from catalog.api.models import Audio, AudioReport, AudioSet
9 from catalog.api.serializers.fields import (
10     EnumCharField,
11     SchemableHyperlinkedIdentityField,
12 )
13 from catalog.api.serializers.media_serializers import (
14     MediaReportRequestSerializer,
15     MediaSearchRequestSerializer,
16     MediaSearchSerializer,
17     MediaSerializer,
18     get_hyperlinks_serializer,
19     get_search_request_source_serializer,
20 )
21 
22 
23 #######################
24 # Request serializers #
25 #######################
26 
27 
28 AudioSearchRequestSourceSerializer = get_search_request_source_serializer("audio")
29 
30 
31 class AudioSearchRequestSerializer(
32     AudioSearchRequestSourceSerializer,
33     MediaSearchRequestSerializer,
34 ):
35     """Parse and validate search query string parameters."""
36 
37     fields_names = [
38         *MediaSearchRequestSerializer.fields_names,
39         *AudioSearchRequestSourceSerializer.field_names,
40         "category",
41         "length",
42     ]
43     """
44     Keep the fields names in sync with the actual fields below as this list is
45     used to generate Swagger documentation.
46     """
47 
48     category = EnumCharField(
49         plural="categories",
50         enum_class=AUDIO_CATEGORIES,
51         required=False,
52     )
53     length = EnumCharField(
54         plural="lengths",
55         enum_class=LENGTHS,
56         required=False,
57     )
58 
59 
60 class AudioReportRequestSerializer(MediaReportRequestSerializer):
61     class Meta(MediaReportRequestSerializer.Meta):
62         model = AudioReport
63 
64 
65 ########################
66 # Response serializers #
67 ########################
68 
69 
70 class AudioSetSerializer(serializers.ModelSerializer):
71     """An audio set, rendered as a part of the ``AudioSerializer`` output."""
72 
73     class Meta:
74         model = AudioSet
75         fields = [
76             "title",
77             "foreign_landing_url",
78             "creator",
79             "creator_url",
80             "url",
81             "filesize",
82             "filetype",
83         ]
84 
85 
86 AudioHyperlinksSerializer = get_hyperlinks_serializer("audio")
87 
88 
89 class AudioSerializer(AudioHyperlinksSerializer, MediaSerializer):
90     """A single audio file. Used in search results."""
91 
92     class Meta:
93         model = Audio
94         fields = sorted(  # keep this list ordered logically
95             [
96                 *MediaSerializer.Meta.fields,
97                 *AudioHyperlinksSerializer.field_names,
98                 "genres",
99                 "alt_files",
100                 "audio_set",
101                 "duration",
102                 "bit_rate",
103                 "sample_rate",
104                 "waveform",  # hyperlink to the endpoint that generates the waveform
105                 "peaks",  # waveform peaks, if they have already been generated
106             ],
107             key=lambda val: field_position_map.get(val, 999),
108         )
109         """
110         Keep the fields names in sync with the actual fields below as this list is
111         used to generate Swagger documentation.
112         """
113 
114     audio_set = AudioSetSerializer(
115         allow_null=True,
116         help_text="Reference to set of which this track is a part.",
117         read_only=True,
118     )
119 
120     waveform = SchemableHyperlinkedIdentityField(
121         read_only=True,
122         view_name="audio-waveform",
123         lookup_field="identifier",
124         help_text="A direct link to the waveform peaks.",
125     )
126 
127     # Add-on data
128     peaks = serializers.SerializerMethodField(
129         help_text="The list of peaks used to generate the waveform for the audio."
130     )
131 
132     @staticmethod
133     def get_peaks(obj) -> list[int]:
134         if isinstance(obj, Hit):
135             obj = Audio.objects.get(identifier=obj.identifier)
136         return obj.get_waveform()
137 
138 
139 class AudioSearchSerializer(MediaSearchSerializer):
140     """
141     The full audio search response.
142     This serializer is purely representational and not actually used to
143     serialize the response.
144     """
145 
146     results = AudioSerializer(
147         many=True,
148         help_text=(
149             "An array of audios and their details such as "
150             f"{fields_to_md(AudioSerializer.Meta.fields)}."
151         ),
152     )
153 
154 
155 ##########################
156 # Additional serializers #
157 ##########################
158 
159 
160 class AudioWaveformSerializer(serializers.Serializer):
161     len = serializers.SerializerMethodField()
162     points = serializers.ListField(
163         child=serializers.FloatField(min_value=0, max_value=1)
164     )
165 
166     @staticmethod
167     def get_len(obj) -> int:
168         return len(obj.get("points", []))
169
```
--- 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()

```

diff --git a/api/catalog/api/serializers/audio_serializers.py b/api/catalog/api/serializers/audio_serializers.py
--- a/api/catalog/api/serializers/audio_serializers.py
+++ b/api/catalog/api/serializers/audio_serializers.py
@@ -135,6 +135,18 @@
             obj = Audio.objects.get(identifier=obj.identifier)
         return obj.get_waveform()
 
+    def to_representation(self, instance):
+        # Get the original representation
+        output = super().to_representation(instance)
+
+        if isinstance(instance, Hit):
+            # TODO: Remove when updating ES indexes
+            audio = Audio.objects.get(identifier=instance.identifier)
+            if not audio.thumbnail:
+                output["thumbnail"] = None
+
+        return output
+
 
 class AudioSearchSerializer(MediaSearchSerializer):
     """

{"golden_diff": "diff --git a/api/catalog/api/serializers/audio_serializers.py b/api/catalog/api/serializers/audio_serializers.py\n--- a/api/catalog/api/serializers/audio_serializers.py\n+++ b/api/catalog/api/serializers/audio_serializers.py\n@@ -135,6 +135,18 @@\n             obj = Audio.objects.get(identifier=obj.identifier)\n         return obj.get_waveform()\n \n+    def to_representation(self, instance):\n+        # Get the original representation\n+        output = super().to_representation(instance)\n+\n+        if isinstance(instance, Hit):\n+            # TODO: Remove when updating ES indexes\n+            audio = Audio.objects.get(identifier=instance.identifier)\n+            if not audio.thumbnail:\n+                output[\"thumbnail\"] = None\n+\n+        return output\n+\n \n class AudioSearchSerializer(MediaSearchSerializer):\n     \"\"\"\n", "issue": "Possibly make `thumbnail` null for audio files without artwork\n## Description\r\n<!-- Concisely describe the bug. -->\r\n\r\nCurrently the frontend tries to fetch thumbnails for all audio files regardless of whether the audio file in question has one or not. \r\nI noticed that the API returns the thumbnail URL for all tracks. That makes sense, but could we improve this to be `null` for audio tracks without artwork? Then we could check the field in the frontend before making a network request.\n", "before_files": [{"content": "from rest_framework import serializers\n\nfrom elasticsearch_dsl.response import Hit\n\nfrom catalog.api.constants.field_order import field_position_map\nfrom catalog.api.constants.field_values import AUDIO_CATEGORIES, LENGTHS\nfrom catalog.api.docs.media_docs import fields_to_md\nfrom catalog.api.models import Audio, AudioReport, AudioSet\nfrom catalog.api.serializers.fields import (\n    EnumCharField,\n    SchemableHyperlinkedIdentityField,\n)\nfrom catalog.api.serializers.media_serializers import (\n    MediaReportRequestSerializer,\n    MediaSearchRequestSerializer,\n    MediaSearchSerializer,\n    MediaSerializer,\n    get_hyperlinks_serializer,\n    get_search_request_source_serializer,\n)\n\n\n#######################\n# Request serializers #\n#######################\n\n\nAudioSearchRequestSourceSerializer = get_search_request_source_serializer(\"audio\")\n\n\nclass AudioSearchRequestSerializer(\n    AudioSearchRequestSourceSerializer,\n    MediaSearchRequestSerializer,\n):\n    \"\"\"Parse and validate search query string parameters.\"\"\"\n\n    fields_names = [\n        *MediaSearchRequestSerializer.fields_names,\n        *AudioSearchRequestSourceSerializer.field_names,\n        \"category\",\n        \"length\",\n    ]\n    \"\"\"\n    Keep the fields names in sync with the actual fields below as this list is\n    used to generate Swagger documentation.\n    \"\"\"\n\n    category = EnumCharField(\n        plural=\"categories\",\n        enum_class=AUDIO_CATEGORIES,\n        required=False,\n    )\n    length = EnumCharField(\n        plural=\"lengths\",\n        enum_class=LENGTHS,\n        required=False,\n    )\n\n\nclass AudioReportRequestSerializer(MediaReportRequestSerializer):\n    class Meta(MediaReportRequestSerializer.Meta):\n        model = AudioReport\n\n\n########################\n# Response serializers #\n########################\n\n\nclass AudioSetSerializer(serializers.ModelSerializer):\n    \"\"\"An audio set, rendered as a part of the ``AudioSerializer`` output.\"\"\"\n\n    class Meta:\n        model = AudioSet\n        fields = [\n            \"title\",\n            \"foreign_landing_url\",\n            \"creator\",\n            \"creator_url\",\n            \"url\",\n            \"filesize\",\n            \"filetype\",\n        ]\n\n\nAudioHyperlinksSerializer = get_hyperlinks_serializer(\"audio\")\n\n\nclass AudioSerializer(AudioHyperlinksSerializer, MediaSerializer):\n    \"\"\"A single audio file. Used in search results.\"\"\"\n\n    class Meta:\n        model = Audio\n        fields = sorted(  # keep this list ordered logically\n            [\n                *MediaSerializer.Meta.fields,\n                *AudioHyperlinksSerializer.field_names,\n                \"genres\",\n                \"alt_files\",\n                \"audio_set\",\n                \"duration\",\n                \"bit_rate\",\n                \"sample_rate\",\n                \"waveform\",  # hyperlink to the endpoint that generates the waveform\n                \"peaks\",  # waveform peaks, if they have already been generated\n            ],\n            key=lambda val: field_position_map.get(val, 999),\n        )\n        \"\"\"\n        Keep the fields names in sync with the actual fields below as this list is\n        used to generate Swagger documentation.\n        \"\"\"\n\n    audio_set = AudioSetSerializer(\n        allow_null=True,\n        help_text=\"Reference to set of which this track is a part.\",\n        read_only=True,\n    )\n\n    waveform = SchemableHyperlinkedIdentityField(\n        read_only=True,\n        view_name=\"audio-waveform\",\n        lookup_field=\"identifier\",\n        help_text=\"A direct link to the waveform peaks.\",\n    )\n\n    # Add-on data\n    peaks = serializers.SerializerMethodField(\n        help_text=\"The list of peaks used to generate the waveform for the audio.\"\n    )\n\n    @staticmethod\n    def get_peaks(obj) -> list[int]:\n        if isinstance(obj, Hit):\n            obj = Audio.objects.get(identifier=obj.identifier)\n        return obj.get_waveform()\n\n\nclass AudioSearchSerializer(MediaSearchSerializer):\n    \"\"\"\n    The full audio search response.\n    This serializer is purely representational and not actually used to\n    serialize the response.\n    \"\"\"\n\n    results = AudioSerializer(\n        many=True,\n        help_text=(\n            \"An array of audios and their details such as \"\n            f\"{fields_to_md(AudioSerializer.Meta.fields)}.\"\n        ),\n    )\n\n\n##########################\n# Additional serializers #\n##########################\n\n\nclass AudioWaveformSerializer(serializers.Serializer):\n    len = serializers.SerializerMethodField()\n    points = serializers.ListField(\n        child=serializers.FloatField(min_value=0, max_value=1)\n    )\n\n    @staticmethod\n    def get_len(obj) -> int:\n        return len(obj.get(\"points\", []))\n", "path": "api/catalog/api/serializers/audio_serializers.py"}], "after_files": [{"content": "from rest_framework import serializers\n\nfrom elasticsearch_dsl.response import Hit\n\nfrom catalog.api.constants.field_order import field_position_map\nfrom catalog.api.constants.field_values import AUDIO_CATEGORIES, LENGTHS\nfrom catalog.api.docs.media_docs import fields_to_md\nfrom catalog.api.models import Audio, AudioReport, AudioSet\nfrom catalog.api.serializers.fields import (\n    EnumCharField,\n    SchemableHyperlinkedIdentityField,\n)\nfrom catalog.api.serializers.media_serializers import (\n    MediaReportRequestSerializer,\n    MediaSearchRequestSerializer,\n    MediaSearchSerializer,\n    MediaSerializer,\n    get_hyperlinks_serializer,\n    get_search_request_source_serializer,\n)\n\n\n#######################\n# Request serializers #\n#######################\n\n\nAudioSearchRequestSourceSerializer = get_search_request_source_serializer(\"audio\")\n\n\nclass AudioSearchRequestSerializer(\n    AudioSearchRequestSourceSerializer,\n    MediaSearchRequestSerializer,\n):\n    \"\"\"Parse and validate search query string parameters.\"\"\"\n\n    fields_names = [\n        *MediaSearchRequestSerializer.fields_names,\n        *AudioSearchRequestSourceSerializer.field_names,\n        \"category\",\n        \"length\",\n    ]\n    \"\"\"\n    Keep the fields names in sync with the actual fields below as this list is\n    used to generate Swagger documentation.\n    \"\"\"\n\n    category = EnumCharField(\n        plural=\"categories\",\n        enum_class=AUDIO_CATEGORIES,\n        required=False,\n    )\n    length = EnumCharField(\n        plural=\"lengths\",\n        enum_class=LENGTHS,\n        required=False,\n    )\n\n\nclass AudioReportRequestSerializer(MediaReportRequestSerializer):\n    class Meta(MediaReportRequestSerializer.Meta):\n        model = AudioReport\n\n\n########################\n# Response serializers #\n########################\n\n\nclass AudioSetSerializer(serializers.ModelSerializer):\n    \"\"\"An audio set, rendered as a part of the ``AudioSerializer`` output.\"\"\"\n\n    class Meta:\n        model = AudioSet\n        fields = [\n            \"title\",\n            \"foreign_landing_url\",\n            \"creator\",\n            \"creator_url\",\n            \"url\",\n            \"filesize\",\n            \"filetype\",\n        ]\n\n\nAudioHyperlinksSerializer = get_hyperlinks_serializer(\"audio\")\n\n\nclass AudioSerializer(AudioHyperlinksSerializer, MediaSerializer):\n    \"\"\"A single audio file. Used in search results.\"\"\"\n\n    class Meta:\n        model = Audio\n        fields = sorted(  # keep this list ordered logically\n            [\n                *MediaSerializer.Meta.fields,\n                *AudioHyperlinksSerializer.field_names,\n                \"genres\",\n                \"alt_files\",\n                \"audio_set\",\n                \"duration\",\n                \"bit_rate\",\n                \"sample_rate\",\n                \"waveform\",  # hyperlink to the endpoint that generates the waveform\n                \"peaks\",  # waveform peaks, if they have already been generated\n            ],\n            key=lambda val: field_position_map.get(val, 999),\n        )\n        \"\"\"\n        Keep the fields names in sync with the actual fields below as this list is\n        used to generate Swagger documentation.\n        \"\"\"\n\n    audio_set = AudioSetSerializer(\n        allow_null=True,\n        help_text=\"Reference to set of which this track is a part.\",\n        read_only=True,\n    )\n\n    waveform = SchemableHyperlinkedIdentityField(\n        read_only=True,\n        view_name=\"audio-waveform\",\n        lookup_field=\"identifier\",\n        help_text=\"A direct link to the waveform peaks.\",\n    )\n\n    # Add-on data\n    peaks = serializers.SerializerMethodField(\n        help_text=\"The list of peaks used to generate the waveform for the audio.\"\n    )\n\n    @staticmethod\n    def get_peaks(obj) -> list[int]:\n        if isinstance(obj, Hit):\n            obj = Audio.objects.get(identifier=obj.identifier)\n        return obj.get_waveform()\n\n    def to_representation(self, instance):\n        # Get the original representation\n        output = super().to_representation(instance)\n\n        if isinstance(instance, Hit):\n            # TODO: Remove when updating ES indexes\n            audio = Audio.objects.get(identifier=instance.identifier)\n            if not audio.thumbnail:\n                output[\"thumbnail\"] = None\n\n        return output\n\n\nclass AudioSearchSerializer(MediaSearchSerializer):\n    \"\"\"\n    The full audio search response.\n    This serializer is purely representational and not actually used to\n    serialize the response.\n    \"\"\"\n\n    results = AudioSerializer(\n        many=True,\n        help_text=(\n            \"An array of audios and their details such as \"\n            f\"{fields_to_md(AudioSerializer.Meta.fields)}.\"\n        ),\n    )\n\n\n##########################\n# Additional serializers #\n##########################\n\n\nclass AudioWaveformSerializer(serializers.Serializer):\n    len = serializers.SerializerMethodField()\n    points = serializers.ListField(\n        child=serializers.FloatField(min_value=0, max_value=1)\n    )\n\n    @staticmethod\n    def get_len(obj) -> int:\n        return len(obj.get(\"points\", []))\n", "path": "api/catalog/api/serializers/audio_serializers.py"}]}