We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] Setting "mask_targets" for Segmentation Dataset does not show labels in App
### System information

-   **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Windows 10
-   **FiftyOne installed from (pip or source)**: pip
-   **FiftyOne version (run `fiftyone --version`)**: v0.16.5
-   **Python version**: 3.9.1

### Describe the problem

The [docs](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#storing-mask-targets) say:
When you load datasets with [Segmentation](https://voxel51.com/docs/fiftyone/api/fiftyone.core.labels.html#fiftyone.core.labels.Segmentation) fields in the App that have corresponding mask targets, the label strings will appear in the App’s tooltip when you hover over pixels.

But the mask_targets are not used as can be seen here:
![grafik](https://user-images.githubusercontent.com/39338429/179057642-cfded6e6-e41a-4d0b-b46e-efa52aa9917e.png)

### Code to reproduce issue

```python
import fiftyone as fo
import numpy as np
import cv2

dataset = fo.Dataset()

# Set default mask targets
dataset.default_mask_targets = {1: "cat", 2: "dog"}
dataset.mask_targets = {
    "segmentation": {1: "cat", 2: "dog"},
}
dataset.save()  # must save after edits

data = np.random.randint(255, size=(2000, 2000))
cv2.imwrite("data.png", data)


mask = np.random.randint(3, size=(2000, 2000))

sample = fo.Sample(filepath="data.png")

sample["segmentation"] = fo.Segmentation(mask=mask)
dataset.add_sample(sample)

if __name__ == "__main__":
    session = fo.launch_app(dataset)
    session.wait()

```

### What areas of FiftyOne does this bug affect?

-   [x] `App`: FiftyOne application issue
-   [x] `Core`: Core `fiftyone` Python library issue
-   [ ] `Server`: Fiftyone server issue

### Willingness to contribute

The FiftyOne Community encourages bug fix contributions. Would you or another
member of your organization be willing to contribute a fix for this bug to the
FiftyOne codebase?

-   [ ] Yes. I can contribute a fix for this bug independently.
-   [x] Yes. I would be willing to contribute a fix for this bug with guidance
        from the FiftyOne community.
-   [ ] No. I cannot contribute a bug fix at this time.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `fiftyone/server/query.py`
Content:
```
1 """
2 FiftyOne Server queries
3 
4 | Copyright 2017-2022, Voxel51, Inc.
5 | `voxel51.com <https://voxel51.com/>`_
6 |
7 """
8 import typing as t
9 from dataclasses import asdict
10 from datetime import date, datetime
11 from enum import Enum
12 import os
13 
14 import eta.core.serial as etas
15 import eta.core.utils as etau
16 import strawberry as gql
17 from bson import ObjectId
18 from dacite import Config, from_dict
19 
20 
21 import fiftyone as fo
22 import fiftyone.constants as foc
23 import fiftyone.core.context as focx
24 import fiftyone.core.dataset as fod
25 import fiftyone.core.media as fom
26 import fiftyone.core.uid as fou
27 import fiftyone.core.view as fov
28 
29 from fiftyone.server.data import Info
30 from fiftyone.server.dataloader import get_dataloader_resolver
31 from fiftyone.server.mixins import HasCollection
32 from fiftyone.server.paginator import Connection, get_paginator_resolver
33 from fiftyone.server.scalars import BSONArray
34 
35 ID = gql.scalar(
36     t.NewType("ID", str),
37     serialize=lambda v: str(v),
38     parse_value=lambda v: ObjectId(v),
39 )
40 DATASET_FILTER = [{"sample_collection_name": {"$regex": "^samples\\."}}]
41 DATASET_FILTER_STAGE = [{"$match": DATASET_FILTER[0]}]
42 
43 
44 @gql.enum
45 class MediaType(Enum):
46     image = "image"
47     video = "video"
48 
49 
50 @gql.type
51 class Target:
52     target: int
53     value: str
54 
55 
56 @gql.type
57 class NamedTargets:
58     name: str
59     targets: t.List[Target]
60 
61 
62 @gql.type
63 class SampleField:
64     ftype: str
65     path: str
66     subfield: t.Optional[str]
67     embedded_doc_type: t.Optional[str]
68     db_field: t.Optional[str]
69 
70 
71 @gql.interface
72 class RunConfig:
73     cls: str
74 
75 
76 @gql.interface
77 class Run:
78     key: str
79     version: t.Optional[str]
80     timestamp: t.Optional[datetime]
81     config: t.Optional[RunConfig]
82     view_stages: t.Optional[t.List[str]]
83 
84 
85 @gql.type
86 class BrainRunConfig(RunConfig):
87     embeddings_field: t.Optional[str]
88     method: t.Optional[str]
89     patches_field: t.Optional[str]
90 
91 
92 @gql.type
93 class BrainRun(Run):
94     config: t.Optional[BrainRunConfig]
95 
96 
97 @gql.type
98 class EvaluationRunConfig(RunConfig):
99     gt_field: t.Optional[str]
100     pred_field: t.Optional[str]
101     method: t.Optional[str]
102 
103 
104 @gql.type
105 class EvaluationRun(Run):
106     config: t.Optional[EvaluationRunConfig]
107 
108 
109 @gql.type
110 class SidebarGroup:
111     name: str
112     paths: t.List[str]
113 
114 
115 @gql.type
116 class KeypointSkeleton:
117     labels: t.Optional[t.List[str]]
118     edges: t.List[t.List[int]]
119 
120 
121 @gql.type
122 class NamedKeypointSkeleton(KeypointSkeleton):
123     name: str
124 
125 
126 @gql.type
127 class Dataset(HasCollection):
128     id: gql.ID
129     name: str
130     created_at: t.Optional[date]
131     last_loaded_at: t.Optional[datetime]
132     persistent: bool
133     media_type: t.Optional[MediaType]
134     mask_targets: t.List[NamedTargets]
135     default_mask_targets: t.Optional[t.List[Target]]
136     sample_fields: t.List[SampleField]
137     frame_fields: t.List[SampleField]
138     brain_methods: t.List[BrainRun]
139     evaluations: t.List[EvaluationRun]
140     app_sidebar_groups: t.Optional[t.List[SidebarGroup]]
141     version: t.Optional[str]
142     view_cls: t.Optional[str]
143     default_skeleton: t.Optional[KeypointSkeleton]
144     skeletons: t.List[NamedKeypointSkeleton]
145 
146     @staticmethod
147     def get_collection_name() -> str:
148         return "datasets"
149 
150     @staticmethod
151     def modifier(doc: dict) -> dict:
152 
153         doc["id"] = doc.pop("_id")
154         doc["mask_targets"] = []
155         doc["default_mask_targets"] = []
156         doc["sample_fields"] = _flatten_fields([], doc["sample_fields"])
157         doc["frame_fields"] = _flatten_fields([], doc["frame_fields"])
158         doc["brain_methods"] = list(doc.get("brain_methods", {}).values())
159         doc["evaluations"] = list(doc.get("evaluations", {}).values())
160         doc["skeletons"] = list(
161             dict(name=name, **data)
162             for name, data in doc.get("skeletons", {}).items()
163         )
164         doc["default_skeletons"] = doc.get("default_skeletons", None)
165         return doc
166 
167     @classmethod
168     async def resolver(
169         cls, name: str, view: t.Optional[BSONArray], info: Info
170     ) -> t.Optional["Dataset"]:
171         assert info is not None
172         dataset = await dataset_dataloader(name, info)
173         if dataset is None:
174             return dataset
175 
176         ds = fo.load_dataset(name)
177         ds.reload()
178         view = fov.DatasetView._build(ds, view or [])
179         if view._dataset != ds:
180             d = view._dataset._serialize()
181             dataset.id = view._dataset._doc.id
182             dataset.media_type = d["media_type"]
183             dataset.sample_fields = [
184                 from_dict(SampleField, s)
185                 for s in _flatten_fields([], d["sample_fields"])
186             ]
187             dataset.frame_fields = [
188                 from_dict(SampleField, s)
189                 for s in _flatten_fields([], d["frame_fields"])
190             ]
191 
192             dataset.view_cls = etau.get_class_name(view)
193 
194         # old dataset docs, e.g. from imports have frame fields attached even for
195         # image datasets. we need to remove them
196         if dataset.media_type != fom.VIDEO:
197             dataset.frame_fields = []
198 
199         return dataset
200 
201 
202 dataset_dataloader = get_dataloader_resolver(Dataset, "name", DATASET_FILTER)
203 
204 
205 @gql.enum
206 class ColorBy(Enum):
207     field = "field"
208     instance = "instance"
209     label = "label"
210 
211 
212 @gql.type
213 class AppConfig:
214     color_by: ColorBy
215     color_pool: t.List[str]
216     colorscale: str
217     grid_zoom: int
218     loop_videos: bool
219     notebook_height: int
220     show_confidence: bool
221     show_index: bool
222     show_label: bool
223     show_skeletons: bool
224     show_tooltip: bool
225     timezone: t.Optional[str]
226     use_frame_number: bool
227 
228 
229 @gql.type
230 class Query:
231     @gql.field
232     def colorscale(self) -> t.Optional[t.List[t.List[int]]]:
233         if fo.app_config.colorscale:
234             return fo.app_config.get_colormap()
235 
236         return None
237 
238     @gql.field
239     def config(self) -> AppConfig:
240         d = fo.app_config.serialize()
241         d["timezone"] = fo.config.timezone
242         return from_dict(AppConfig, d, config=Config(check_types=False))
243 
244     @gql.field
245     def context(self) -> str:
246         return focx._get_context()
247 
248     @gql.field
249     def dev(self) -> bool:
250         return foc.DEV_INSTALL or foc.RC_INSTALL
251 
252     @gql.field
253     def do_not_track(self) -> bool:
254         return fo.config.do_not_track
255 
256     dataset = gql.field(resolver=Dataset.resolver)
257     datasets: Connection[Dataset] = gql.field(
258         resolver=get_paginator_resolver(
259             Dataset,
260             "created_at",
261             DATASET_FILTER_STAGE,
262         )
263     )
264 
265     @gql.field
266     def teams_submission(self) -> bool:
267         isfile = os.path.isfile(foc.TEAMS_PATH)
268         if isfile:
269             submitted = etas.load_json(foc.TEAMS_PATH)["submitted"]
270         else:
271             submitted = False
272 
273         return submitted
274 
275     @gql.field
276     def uid(self) -> str:
277         uid, _ = fou.get_user_id()
278         return uid
279 
280     @gql.field
281     def version(self) -> str:
282         return foc.VERSION
283 
284 
285 def serialize_dataset(dataset: fod.Dataset, view: fov.DatasetView) -> t.Dict:
286     doc = dataset._doc.to_dict()
287     Dataset.modifier(doc)
288     data = from_dict(Dataset, doc, config=Config(check_types=False))
289     data.view_cls = None
290 
291     if view is not None and view._dataset != dataset:
292         d = view._dataset._serialize()
293         data.media_type = d["media_type"]
294         data.id = view._dataset._doc.id
295         data.sample_fields = [
296             from_dict(SampleField, s)
297             for s in _flatten_fields([], d["sample_fields"])
298         ]
299         data.frame_fields = [
300             from_dict(SampleField, s)
301             for s in _flatten_fields([], d["frame_fields"])
302         ]
303 
304         data.view_cls = etau.get_class_name(view)
305 
306     # old dataset docs, e.g. from imports have frame fields attached even for
307     # image datasets. we need to remove them
308     if dataset.media_type != fom.VIDEO:
309         data.frame_fields = []
310 
311     return asdict(data)
312 
313 
314 def _flatten_fields(
315     path: t.List[str], fields: t.List[t.Dict]
316 ) -> t.List[t.Dict]:
317     result = []
318     for field in fields:
319         key = field.pop("name")
320         field_path = path + [key]
321         field["path"] = ".".join(field_path)
322         result.append(field)
323 
324         fields = field.pop("fields", None)
325         if fields:
326             result = result + _flatten_fields(field_path, fields)
327 
328     return result
329
```
--- 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/fiftyone/server/query.py b/fiftyone/server/query.py
--- a/fiftyone/server/query.py
+++ b/fiftyone/server/query.py
@@ -149,10 +149,14 @@
 
     @staticmethod
     def modifier(doc: dict) -> dict:
-
         doc["id"] = doc.pop("_id")
-        doc["mask_targets"] = []
-        doc["default_mask_targets"] = []
+        doc["default_mask_targets"] = _convert_targets(
+            doc.get("default_mask_targets", [])
+        )
+        doc["mask_targets"] = [
+            NamedTargets(name, _convert_targets(targets))
+            for name, targets in doc.get("mask_targets", []).items()
+        ]
         doc["sample_fields"] = _flatten_fields([], doc["sample_fields"])
         doc["frame_fields"] = _flatten_fields([], doc["frame_fields"])
         doc["brain_methods"] = list(doc.get("brain_methods", {}).values())
@@ -326,3 +330,7 @@
             result = result + _flatten_fields(field_path, fields)
 
     return result
+
+
+def _convert_targets(targets: t.Dict[str, str]) -> Target:
+    return [Target(value=v, target=int(k)) for k, v in targets.items()]

{"golden_diff": "diff --git a/fiftyone/server/query.py b/fiftyone/server/query.py\n--- a/fiftyone/server/query.py\n+++ b/fiftyone/server/query.py\n@@ -149,10 +149,14 @@\n \n     @staticmethod\n     def modifier(doc: dict) -> dict:\n-\n         doc[\"id\"] = doc.pop(\"_id\")\n-        doc[\"mask_targets\"] = []\n-        doc[\"default_mask_targets\"] = []\n+        doc[\"default_mask_targets\"] = _convert_targets(\n+            doc.get(\"default_mask_targets\", [])\n+        )\n+        doc[\"mask_targets\"] = [\n+            NamedTargets(name, _convert_targets(targets))\n+            for name, targets in doc.get(\"mask_targets\", []).items()\n+        ]\n         doc[\"sample_fields\"] = _flatten_fields([], doc[\"sample_fields\"])\n         doc[\"frame_fields\"] = _flatten_fields([], doc[\"frame_fields\"])\n         doc[\"brain_methods\"] = list(doc.get(\"brain_methods\", {}).values())\n@@ -326,3 +330,7 @@\n             result = result + _flatten_fields(field_path, fields)\n \n     return result\n+\n+\n+def _convert_targets(targets: t.Dict[str, str]) -> Target:\n+    return [Target(value=v, target=int(k)) for k, v in targets.items()]\n", "issue": "[BUG] Setting \"mask_targets\" for Segmentation Dataset does not show labels in App\n### System information\r\n\r\n-   **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Windows 10\r\n-   **FiftyOne installed from (pip or source)**: pip\r\n-   **FiftyOne version (run `fiftyone --version`)**: v0.16.5\r\n-   **Python version**: 3.9.1\r\n\r\n### Describe the problem\r\n\r\nThe [docs](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#storing-mask-targets) say:\r\nWhen you load datasets with [Segmentation](https://voxel51.com/docs/fiftyone/api/fiftyone.core.labels.html#fiftyone.core.labels.Segmentation) fields in the App that have corresponding mask targets, the label strings will appear in the App\u2019s tooltip when you hover over pixels.\r\n\r\nBut the mask_targets are not used as can be seen here:\r\n![grafik](https://user-images.githubusercontent.com/39338429/179057642-cfded6e6-e41a-4d0b-b46e-efa52aa9917e.png)\r\n\r\n### Code to reproduce issue\r\n\r\n```python\r\nimport fiftyone as fo\r\nimport numpy as np\r\nimport cv2\r\n\r\ndataset = fo.Dataset()\r\n\r\n# Set default mask targets\r\ndataset.default_mask_targets = {1: \"cat\", 2: \"dog\"}\r\ndataset.mask_targets = {\r\n    \"segmentation\": {1: \"cat\", 2: \"dog\"},\r\n}\r\ndataset.save()  # must save after edits\r\n\r\ndata = np.random.randint(255, size=(2000, 2000))\r\ncv2.imwrite(\"data.png\", data)\r\n\r\n\r\nmask = np.random.randint(3, size=(2000, 2000))\r\n\r\nsample = fo.Sample(filepath=\"data.png\")\r\n\r\nsample[\"segmentation\"] = fo.Segmentation(mask=mask)\r\ndataset.add_sample(sample)\r\n\r\nif __name__ == \"__main__\":\r\n    session = fo.launch_app(dataset)\r\n    session.wait()\r\n\r\n```\r\n\r\n### What areas of FiftyOne does this bug affect?\r\n\r\n-   [x] `App`: FiftyOne application issue\r\n-   [x] `Core`: Core `fiftyone` Python library issue\r\n-   [ ] `Server`: Fiftyone server issue\r\n\r\n### Willingness to contribute\r\n\r\nThe FiftyOne Community encourages bug fix contributions. Would you or another\r\nmember of your organization be willing to contribute a fix for this bug to the\r\nFiftyOne codebase?\r\n\r\n-   [ ] Yes. I can contribute a fix for this bug independently.\r\n-   [x] Yes. I would be willing to contribute a fix for this bug with guidance\r\n        from the FiftyOne community.\r\n-   [ ] No. I cannot contribute a bug fix at this time.\r\n\n", "before_files": [{"content": "\"\"\"\nFiftyOne Server queries\n\n| Copyright 2017-2022, Voxel51, Inc.\n| `voxel51.com <https://voxel51.com/>`_\n|\n\"\"\"\nimport typing as t\nfrom dataclasses import asdict\nfrom datetime import date, datetime\nfrom enum import Enum\nimport os\n\nimport eta.core.serial as etas\nimport eta.core.utils as etau\nimport strawberry as gql\nfrom bson import ObjectId\nfrom dacite import Config, from_dict\n\n\nimport fiftyone as fo\nimport fiftyone.constants as foc\nimport fiftyone.core.context as focx\nimport fiftyone.core.dataset as fod\nimport fiftyone.core.media as fom\nimport fiftyone.core.uid as fou\nimport fiftyone.core.view as fov\n\nfrom fiftyone.server.data import Info\nfrom fiftyone.server.dataloader import get_dataloader_resolver\nfrom fiftyone.server.mixins import HasCollection\nfrom fiftyone.server.paginator import Connection, get_paginator_resolver\nfrom fiftyone.server.scalars import BSONArray\n\nID = gql.scalar(\n    t.NewType(\"ID\", str),\n    serialize=lambda v: str(v),\n    parse_value=lambda v: ObjectId(v),\n)\nDATASET_FILTER = [{\"sample_collection_name\": {\"$regex\": \"^samples\\\\.\"}}]\nDATASET_FILTER_STAGE = [{\"$match\": DATASET_FILTER[0]}]\n\n\n@gql.enum\nclass MediaType(Enum):\n    image = \"image\"\n    video = \"video\"\n\n\n@gql.type\nclass Target:\n    target: int\n    value: str\n\n\n@gql.type\nclass NamedTargets:\n    name: str\n    targets: t.List[Target]\n\n\n@gql.type\nclass SampleField:\n    ftype: str\n    path: str\n    subfield: t.Optional[str]\n    embedded_doc_type: t.Optional[str]\n    db_field: t.Optional[str]\n\n\n@gql.interface\nclass RunConfig:\n    cls: str\n\n\n@gql.interface\nclass Run:\n    key: str\n    version: t.Optional[str]\n    timestamp: t.Optional[datetime]\n    config: t.Optional[RunConfig]\n    view_stages: t.Optional[t.List[str]]\n\n\n@gql.type\nclass BrainRunConfig(RunConfig):\n    embeddings_field: t.Optional[str]\n    method: t.Optional[str]\n    patches_field: t.Optional[str]\n\n\n@gql.type\nclass BrainRun(Run):\n    config: t.Optional[BrainRunConfig]\n\n\n@gql.type\nclass EvaluationRunConfig(RunConfig):\n    gt_field: t.Optional[str]\n    pred_field: t.Optional[str]\n    method: t.Optional[str]\n\n\n@gql.type\nclass EvaluationRun(Run):\n    config: t.Optional[EvaluationRunConfig]\n\n\n@gql.type\nclass SidebarGroup:\n    name: str\n    paths: t.List[str]\n\n\n@gql.type\nclass KeypointSkeleton:\n    labels: t.Optional[t.List[str]]\n    edges: t.List[t.List[int]]\n\n\n@gql.type\nclass NamedKeypointSkeleton(KeypointSkeleton):\n    name: str\n\n\n@gql.type\nclass Dataset(HasCollection):\n    id: gql.ID\n    name: str\n    created_at: t.Optional[date]\n    last_loaded_at: t.Optional[datetime]\n    persistent: bool\n    media_type: t.Optional[MediaType]\n    mask_targets: t.List[NamedTargets]\n    default_mask_targets: t.Optional[t.List[Target]]\n    sample_fields: t.List[SampleField]\n    frame_fields: t.List[SampleField]\n    brain_methods: t.List[BrainRun]\n    evaluations: t.List[EvaluationRun]\n    app_sidebar_groups: t.Optional[t.List[SidebarGroup]]\n    version: t.Optional[str]\n    view_cls: t.Optional[str]\n    default_skeleton: t.Optional[KeypointSkeleton]\n    skeletons: t.List[NamedKeypointSkeleton]\n\n    @staticmethod\n    def get_collection_name() -> str:\n        return \"datasets\"\n\n    @staticmethod\n    def modifier(doc: dict) -> dict:\n\n        doc[\"id\"] = doc.pop(\"_id\")\n        doc[\"mask_targets\"] = []\n        doc[\"default_mask_targets\"] = []\n        doc[\"sample_fields\"] = _flatten_fields([], doc[\"sample_fields\"])\n        doc[\"frame_fields\"] = _flatten_fields([], doc[\"frame_fields\"])\n        doc[\"brain_methods\"] = list(doc.get(\"brain_methods\", {}).values())\n        doc[\"evaluations\"] = list(doc.get(\"evaluations\", {}).values())\n        doc[\"skeletons\"] = list(\n            dict(name=name, **data)\n            for name, data in doc.get(\"skeletons\", {}).items()\n        )\n        doc[\"default_skeletons\"] = doc.get(\"default_skeletons\", None)\n        return doc\n\n    @classmethod\n    async def resolver(\n        cls, name: str, view: t.Optional[BSONArray], info: Info\n    ) -> t.Optional[\"Dataset\"]:\n        assert info is not None\n        dataset = await dataset_dataloader(name, info)\n        if dataset is None:\n            return dataset\n\n        ds = fo.load_dataset(name)\n        ds.reload()\n        view = fov.DatasetView._build(ds, view or [])\n        if view._dataset != ds:\n            d = view._dataset._serialize()\n            dataset.id = view._dataset._doc.id\n            dataset.media_type = d[\"media_type\"]\n            dataset.sample_fields = [\n                from_dict(SampleField, s)\n                for s in _flatten_fields([], d[\"sample_fields\"])\n            ]\n            dataset.frame_fields = [\n                from_dict(SampleField, s)\n                for s in _flatten_fields([], d[\"frame_fields\"])\n            ]\n\n            dataset.view_cls = etau.get_class_name(view)\n\n        # old dataset docs, e.g. from imports have frame fields attached even for\n        # image datasets. we need to remove them\n        if dataset.media_type != fom.VIDEO:\n            dataset.frame_fields = []\n\n        return dataset\n\n\ndataset_dataloader = get_dataloader_resolver(Dataset, \"name\", DATASET_FILTER)\n\n\n@gql.enum\nclass ColorBy(Enum):\n    field = \"field\"\n    instance = \"instance\"\n    label = \"label\"\n\n\n@gql.type\nclass AppConfig:\n    color_by: ColorBy\n    color_pool: t.List[str]\n    colorscale: str\n    grid_zoom: int\n    loop_videos: bool\n    notebook_height: int\n    show_confidence: bool\n    show_index: bool\n    show_label: bool\n    show_skeletons: bool\n    show_tooltip: bool\n    timezone: t.Optional[str]\n    use_frame_number: bool\n\n\n@gql.type\nclass Query:\n    @gql.field\n    def colorscale(self) -> t.Optional[t.List[t.List[int]]]:\n        if fo.app_config.colorscale:\n            return fo.app_config.get_colormap()\n\n        return None\n\n    @gql.field\n    def config(self) -> AppConfig:\n        d = fo.app_config.serialize()\n        d[\"timezone\"] = fo.config.timezone\n        return from_dict(AppConfig, d, config=Config(check_types=False))\n\n    @gql.field\n    def context(self) -> str:\n        return focx._get_context()\n\n    @gql.field\n    def dev(self) -> bool:\n        return foc.DEV_INSTALL or foc.RC_INSTALL\n\n    @gql.field\n    def do_not_track(self) -> bool:\n        return fo.config.do_not_track\n\n    dataset = gql.field(resolver=Dataset.resolver)\n    datasets: Connection[Dataset] = gql.field(\n        resolver=get_paginator_resolver(\n            Dataset,\n            \"created_at\",\n            DATASET_FILTER_STAGE,\n        )\n    )\n\n    @gql.field\n    def teams_submission(self) -> bool:\n        isfile = os.path.isfile(foc.TEAMS_PATH)\n        if isfile:\n            submitted = etas.load_json(foc.TEAMS_PATH)[\"submitted\"]\n        else:\n            submitted = False\n\n        return submitted\n\n    @gql.field\n    def uid(self) -> str:\n        uid, _ = fou.get_user_id()\n        return uid\n\n    @gql.field\n    def version(self) -> str:\n        return foc.VERSION\n\n\ndef serialize_dataset(dataset: fod.Dataset, view: fov.DatasetView) -> t.Dict:\n    doc = dataset._doc.to_dict()\n    Dataset.modifier(doc)\n    data = from_dict(Dataset, doc, config=Config(check_types=False))\n    data.view_cls = None\n\n    if view is not None and view._dataset != dataset:\n        d = view._dataset._serialize()\n        data.media_type = d[\"media_type\"]\n        data.id = view._dataset._doc.id\n        data.sample_fields = [\n            from_dict(SampleField, s)\n            for s in _flatten_fields([], d[\"sample_fields\"])\n        ]\n        data.frame_fields = [\n            from_dict(SampleField, s)\n            for s in _flatten_fields([], d[\"frame_fields\"])\n        ]\n\n        data.view_cls = etau.get_class_name(view)\n\n    # old dataset docs, e.g. from imports have frame fields attached even for\n    # image datasets. we need to remove them\n    if dataset.media_type != fom.VIDEO:\n        data.frame_fields = []\n\n    return asdict(data)\n\n\ndef _flatten_fields(\n    path: t.List[str], fields: t.List[t.Dict]\n) -> t.List[t.Dict]:\n    result = []\n    for field in fields:\n        key = field.pop(\"name\")\n        field_path = path + [key]\n        field[\"path\"] = \".\".join(field_path)\n        result.append(field)\n\n        fields = field.pop(\"fields\", None)\n        if fields:\n            result = result + _flatten_fields(field_path, fields)\n\n    return result\n", "path": "fiftyone/server/query.py"}], "after_files": [{"content": "\"\"\"\nFiftyOne Server queries\n\n| Copyright 2017-2022, Voxel51, Inc.\n| `voxel51.com <https://voxel51.com/>`_\n|\n\"\"\"\nimport typing as t\nfrom dataclasses import asdict\nfrom datetime import date, datetime\nfrom enum import Enum\nimport os\n\nimport eta.core.serial as etas\nimport eta.core.utils as etau\nimport strawberry as gql\nfrom bson import ObjectId\nfrom dacite import Config, from_dict\n\n\nimport fiftyone as fo\nimport fiftyone.constants as foc\nimport fiftyone.core.context as focx\nimport fiftyone.core.dataset as fod\nimport fiftyone.core.media as fom\nimport fiftyone.core.uid as fou\nimport fiftyone.core.view as fov\n\nfrom fiftyone.server.data import Info\nfrom fiftyone.server.dataloader import get_dataloader_resolver\nfrom fiftyone.server.mixins import HasCollection\nfrom fiftyone.server.paginator import Connection, get_paginator_resolver\nfrom fiftyone.server.scalars import BSONArray\n\nID = gql.scalar(\n    t.NewType(\"ID\", str),\n    serialize=lambda v: str(v),\n    parse_value=lambda v: ObjectId(v),\n)\nDATASET_FILTER = [{\"sample_collection_name\": {\"$regex\": \"^samples\\\\.\"}}]\nDATASET_FILTER_STAGE = [{\"$match\": DATASET_FILTER[0]}]\n\n\n@gql.enum\nclass MediaType(Enum):\n    image = \"image\"\n    video = \"video\"\n\n\n@gql.type\nclass Target:\n    target: int\n    value: str\n\n\n@gql.type\nclass NamedTargets:\n    name: str\n    targets: t.List[Target]\n\n\n@gql.type\nclass SampleField:\n    ftype: str\n    path: str\n    subfield: t.Optional[str]\n    embedded_doc_type: t.Optional[str]\n    db_field: t.Optional[str]\n\n\n@gql.interface\nclass RunConfig:\n    cls: str\n\n\n@gql.interface\nclass Run:\n    key: str\n    version: t.Optional[str]\n    timestamp: t.Optional[datetime]\n    config: t.Optional[RunConfig]\n    view_stages: t.Optional[t.List[str]]\n\n\n@gql.type\nclass BrainRunConfig(RunConfig):\n    embeddings_field: t.Optional[str]\n    method: t.Optional[str]\n    patches_field: t.Optional[str]\n\n\n@gql.type\nclass BrainRun(Run):\n    config: t.Optional[BrainRunConfig]\n\n\n@gql.type\nclass EvaluationRunConfig(RunConfig):\n    gt_field: t.Optional[str]\n    pred_field: t.Optional[str]\n    method: t.Optional[str]\n\n\n@gql.type\nclass EvaluationRun(Run):\n    config: t.Optional[EvaluationRunConfig]\n\n\n@gql.type\nclass SidebarGroup:\n    name: str\n    paths: t.List[str]\n\n\n@gql.type\nclass KeypointSkeleton:\n    labels: t.Optional[t.List[str]]\n    edges: t.List[t.List[int]]\n\n\n@gql.type\nclass NamedKeypointSkeleton(KeypointSkeleton):\n    name: str\n\n\n@gql.type\nclass Dataset(HasCollection):\n    id: gql.ID\n    name: str\n    created_at: t.Optional[date]\n    last_loaded_at: t.Optional[datetime]\n    persistent: bool\n    media_type: t.Optional[MediaType]\n    mask_targets: t.List[NamedTargets]\n    default_mask_targets: t.Optional[t.List[Target]]\n    sample_fields: t.List[SampleField]\n    frame_fields: t.List[SampleField]\n    brain_methods: t.List[BrainRun]\n    evaluations: t.List[EvaluationRun]\n    app_sidebar_groups: t.Optional[t.List[SidebarGroup]]\n    version: t.Optional[str]\n    view_cls: t.Optional[str]\n    default_skeleton: t.Optional[KeypointSkeleton]\n    skeletons: t.List[NamedKeypointSkeleton]\n\n    @staticmethod\n    def get_collection_name() -> str:\n        return \"datasets\"\n\n    @staticmethod\n    def modifier(doc: dict) -> dict:\n        doc[\"id\"] = doc.pop(\"_id\")\n        doc[\"default_mask_targets\"] = _convert_targets(\n            doc.get(\"default_mask_targets\", [])\n        )\n        doc[\"mask_targets\"] = [\n            NamedTargets(name, _convert_targets(targets))\n            for name, targets in doc.get(\"mask_targets\", []).items()\n        ]\n        doc[\"sample_fields\"] = _flatten_fields([], doc[\"sample_fields\"])\n        doc[\"frame_fields\"] = _flatten_fields([], doc[\"frame_fields\"])\n        doc[\"brain_methods\"] = list(doc.get(\"brain_methods\", {}).values())\n        doc[\"evaluations\"] = list(doc.get(\"evaluations\", {}).values())\n        doc[\"skeletons\"] = list(\n            dict(name=name, **data)\n            for name, data in doc.get(\"skeletons\", {}).items()\n        )\n        doc[\"default_skeletons\"] = doc.get(\"default_skeletons\", None)\n        return doc\n\n    @classmethod\n    async def resolver(\n        cls, name: str, view: t.Optional[BSONArray], info: Info\n    ) -> t.Optional[\"Dataset\"]:\n        assert info is not None\n        dataset = await dataset_dataloader(name, info)\n        if dataset is None:\n            return dataset\n\n        ds = fo.load_dataset(name)\n        ds.reload()\n        view = fov.DatasetView._build(ds, view or [])\n        if view._dataset != ds:\n            d = view._dataset._serialize()\n            dataset.id = view._dataset._doc.id\n            dataset.media_type = d[\"media_type\"]\n            dataset.sample_fields = [\n                from_dict(SampleField, s)\n                for s in _flatten_fields([], d[\"sample_fields\"])\n            ]\n            dataset.frame_fields = [\n                from_dict(SampleField, s)\n                for s in _flatten_fields([], d[\"frame_fields\"])\n            ]\n\n            dataset.view_cls = etau.get_class_name(view)\n\n        # old dataset docs, e.g. from imports have frame fields attached even for\n        # image datasets. we need to remove them\n        if dataset.media_type != fom.VIDEO:\n            dataset.frame_fields = []\n\n        return dataset\n\n\ndataset_dataloader = get_dataloader_resolver(Dataset, \"name\", DATASET_FILTER)\n\n\n@gql.enum\nclass ColorBy(Enum):\n    field = \"field\"\n    instance = \"instance\"\n    label = \"label\"\n\n\n@gql.type\nclass AppConfig:\n    color_by: ColorBy\n    color_pool: t.List[str]\n    colorscale: str\n    grid_zoom: int\n    loop_videos: bool\n    notebook_height: int\n    show_confidence: bool\n    show_index: bool\n    show_label: bool\n    show_skeletons: bool\n    show_tooltip: bool\n    timezone: t.Optional[str]\n    use_frame_number: bool\n\n\n@gql.type\nclass Query:\n    @gql.field\n    def colorscale(self) -> t.Optional[t.List[t.List[int]]]:\n        if fo.app_config.colorscale:\n            return fo.app_config.get_colormap()\n\n        return None\n\n    @gql.field\n    def config(self) -> AppConfig:\n        d = fo.app_config.serialize()\n        d[\"timezone\"] = fo.config.timezone\n        return from_dict(AppConfig, d, config=Config(check_types=False))\n\n    @gql.field\n    def context(self) -> str:\n        return focx._get_context()\n\n    @gql.field\n    def dev(self) -> bool:\n        return foc.DEV_INSTALL or foc.RC_INSTALL\n\n    @gql.field\n    def do_not_track(self) -> bool:\n        return fo.config.do_not_track\n\n    dataset = gql.field(resolver=Dataset.resolver)\n    datasets: Connection[Dataset] = gql.field(\n        resolver=get_paginator_resolver(\n            Dataset,\n            \"created_at\",\n            DATASET_FILTER_STAGE,\n        )\n    )\n\n    @gql.field\n    def teams_submission(self) -> bool:\n        isfile = os.path.isfile(foc.TEAMS_PATH)\n        if isfile:\n            submitted = etas.load_json(foc.TEAMS_PATH)[\"submitted\"]\n        else:\n            submitted = False\n\n        return submitted\n\n    @gql.field\n    def uid(self) -> str:\n        uid, _ = fou.get_user_id()\n        return uid\n\n    @gql.field\n    def version(self) -> str:\n        return foc.VERSION\n\n\ndef serialize_dataset(dataset: fod.Dataset, view: fov.DatasetView) -> t.Dict:\n    doc = dataset._doc.to_dict()\n    Dataset.modifier(doc)\n    data = from_dict(Dataset, doc, config=Config(check_types=False))\n    data.view_cls = None\n\n    if view is not None and view._dataset != dataset:\n        d = view._dataset._serialize()\n        data.media_type = d[\"media_type\"]\n        data.id = view._dataset._doc.id\n        data.sample_fields = [\n            from_dict(SampleField, s)\n            for s in _flatten_fields([], d[\"sample_fields\"])\n        ]\n        data.frame_fields = [\n            from_dict(SampleField, s)\n            for s in _flatten_fields([], d[\"frame_fields\"])\n        ]\n\n        data.view_cls = etau.get_class_name(view)\n\n    # old dataset docs, e.g. from imports have frame fields attached even for\n    # image datasets. we need to remove them\n    if dataset.media_type != fom.VIDEO:\n        data.frame_fields = []\n\n    return asdict(data)\n\n\ndef _flatten_fields(\n    path: t.List[str], fields: t.List[t.Dict]\n) -> t.List[t.Dict]:\n    result = []\n    for field in fields:\n        key = field.pop(\"name\")\n        field_path = path + [key]\n        field[\"path\"] = \".\".join(field_path)\n        result.append(field)\n\n        fields = field.pop(\"fields\", None)\n        if fields:\n            result = result + _flatten_fields(field_path, fields)\n\n    return result\n\n\ndef _convert_targets(targets: t.Dict[str, str]) -> Target:\n    return [Target(value=v, target=int(k)) for k, v in targets.items()]\n", "path": "fiftyone/server/query.py"}]}