Skip to content

Commit 831d287

Browse files
author
Nicolas Hervé
committed
feat: handle annotations conversion to json reponse for geospatial projects
1 parent 5b019d8 commit 831d287

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

src/kili/adapters/authentification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def is_api_key_valid(
2020
"""
2121
response = http_client.post(
2222
url=api_endpoint,
23-
data='{"query":"{ me { id email } }"}',
23+
data='{"query":"{ viewer { id email } }"}',
2424
timeout=30,
2525
headers={
2626
"Authorization": f"X-API-Key: {api_key}",

src/kili/adapters/kili_api_gateway/label/annotation_to_json_response.py

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from kili.domain.annotation import (
88
ClassicAnnotation,
99
ClassificationAnnotation,
10+
ObjectDetectionAnnotation,
1011
RankingAnnotation,
1112
TranscriptionAnnotation,
1213
Vertice,
@@ -53,7 +54,7 @@ def patch_label_json_response(
5354
5455
Modifies the input label.
5556
"""
56-
if self._project_input_type in {"VIDEO", "LLM_RLHF"}:
57+
if self._project_input_type in {"VIDEO", "LLM_RLHF", "GEOSPATIAL"}:
5758
if not annotations and self._label_has_json_response_data(label):
5859
return
5960

@@ -63,8 +64,11 @@ def patch_label_json_response(
6364
annotations=annotations, json_interface=self._project_json_interface
6465
)
6566
else:
67+
print("converting annotations")
6668
annotations = cast(List[ClassicAnnotation], annotations)
67-
converted_json_resp = _classic_annotations_to_json_response(annotations=annotations)
69+
converted_json_resp = _classic_annotations_to_json_response(
70+
annotations=annotations, json_interface=self._project_json_interface
71+
)
6872

6973
label["jsonResponse"] = converted_json_resp
7074

@@ -150,7 +154,7 @@ def _video_annotations_to_json_response(
150154

151155

152156
def _classic_annotations_to_json_response(
153-
annotations: List[ClassicAnnotation],
157+
annotations: List[ClassicAnnotation], json_interface: Dict
154158
) -> Dict[str, Dict[JobName, Dict]]:
155159
"""Convert label annotations to a json response."""
156160
json_resp = defaultdict(dict)
@@ -183,6 +187,18 @@ def _classic_annotations_to_json_response(
183187
for job_name, job_resp in ann_json_resp.items():
184188
json_resp.setdefault(job_name, {}).setdefault("text", job_resp["text"])
185189

190+
elif ann["__typename"] == "ObjectDetectionAnnotation":
191+
ann = cast(ObjectDetectionAnnotation, ann)
192+
ann_json_resp = _object_detection_annotation_to_json_response(
193+
ann,
194+
other_annotations,
195+
json_interface,
196+
)
197+
for job_name, job_resp in ann_json_resp.items():
198+
json_resp.setdefault(job_name, {}).setdefault("annotations", []).extend(
199+
job_resp["annotations"]
200+
)
201+
186202
else:
187203
raise NotImplementedError(f"Cannot convert classic annotation to json response: {ann}")
188204

@@ -350,6 +366,46 @@ def _transcription_annotation_to_json_response(
350366
return json_resp
351367

352368

369+
def _object_detection_annotation_to_json_response(
370+
annotation: ObjectDetectionAnnotation,
371+
other_annotations: List[ClassicAnnotation],
372+
json_interface: Dict,
373+
) -> Dict[JobName, Dict]:
374+
"""Convert object detection annotation to a json response."""
375+
child_annotations = _get_child_annotations(annotation, other_annotations)
376+
json_resp_child_jobs = (
377+
_compute_children_json_resp(child_annotations, other_annotations)
378+
if child_annotations
379+
else {}
380+
)
381+
382+
annotation_dict = {
383+
"children": json_resp_child_jobs,
384+
"categories": [{"name": annotation["category"]}],
385+
"mid": annotation["mid"],
386+
"type": json_interface["jobs"][annotation["job"]]["tools"][0],
387+
}
388+
389+
norm_vertices = annotation["annotationValue"]["vertices"]
390+
391+
if json_interface["jobs"][annotation["job"]]["tools"][0] == "marker":
392+
annotation_dict["point"] = norm_vertices[0][0][0]
393+
394+
elif json_interface["jobs"][annotation["job"]]["tools"][0] in {"polygon", "rectangle"}:
395+
annotation_dict["boundingPoly"] = [{"normalizedVertices": norm_vertices[0][0]}]
396+
397+
elif json_interface["jobs"][annotation["job"]]["tools"][0] == "semantic":
398+
annotation_dict["boundingPoly"] = [
399+
{"normalizedVertices": norm_vert} for norm_vert in norm_vertices[0]
400+
]
401+
402+
return {
403+
annotation["job"]: {
404+
"annotations": [annotation_dict],
405+
},
406+
}
407+
408+
353409
def _video_transcription_annotation_to_json_response(
354410
annotation: VideoTranscriptionAnnotation,
355411
) -> Dict[str, Dict[JobName, Dict]]:

src/kili/domain/annotation.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ class Annotation(TypedDict):
9393
path: List[List[str]]
9494

9595

96+
class ObjectDetectionAnnotation(TypedDict):
97+
"""Object detection annotation."""
98+
99+
# pylint: disable=unused-private-member
100+
__typename: Literal["ObjectDetectionAnnotation"]
101+
id: AnnotationId
102+
labelId: LabelId
103+
job: JobName
104+
path: List[List[str]]
105+
annotationValue: ObjectDetectionAnnotationValue
106+
name: Optional[str]
107+
mid: str
108+
category: str
109+
110+
96111
class FrameInterval(TypedDict):
97112
"""Frame interval."""
98113

@@ -174,6 +189,7 @@ class VideoTranscriptionAnnotation(TypedDict):
174189

175190
ClassicAnnotation = Union[
176191
ClassificationAnnotation,
192+
ObjectDetectionAnnotation,
177193
RankingAnnotation,
178194
TranscriptionAnnotation,
179195
]

tests/unit/adapters/kili_api_gateway/label/test_label_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def test_given_classic_label_annotations_when_converting_to_json_resp_it_works(
173173
_ = annotations
174174

175175
# When
176-
json_resp = _classic_annotations_to_json_response(annotations)
176+
json_resp = _classic_annotations_to_json_response(annotations, {})
177177

178178
# Then
179179
assert json_resp == expected_json_resp

0 commit comments

Comments
 (0)