Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions labelbox/data/serialization/ndjson/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,38 +74,37 @@ def serialize(
]] = []
# First pass to get all RelatiohnshipAnnotaitons
# and update the UUIDs of the source and target annotations
for relationship_annotation in (
annotation for annotation in label.annotations
if isinstance(annotation, RelationshipAnnotation)):
if relationship_annotation in uuid_safe_annotations:
relationship_annotation = copy.deepcopy(
relationship_annotation)
new_source_uuid = uuid.uuid4()
new_target_uuid = uuid.uuid4()
relationship_uuids[relationship_annotation.value.source.
_uuid].append(new_source_uuid)
relationship_uuids[relationship_annotation.value.target.
_uuid].append(new_target_uuid)
relationship_annotation.value.source._uuid = new_source_uuid
relationship_annotation.value.target._uuid = new_target_uuid
if relationship_annotation._uuid in used_uuids:
relationship_annotation._uuid = uuid.uuid4()
used_uuids.add(relationship_annotation._uuid)
uuid_safe_annotations.append(relationship_annotation)
for annotation in label.annotations:
if isinstance(annotation, RelationshipAnnotation):
annotation = copy.deepcopy(annotation)
new_source_uuid = uuid.uuid4()
new_target_uuid = uuid.uuid4()
relationship_uuids[annotation.value.source._uuid].append(
new_source_uuid)
relationship_uuids[annotation.value.target._uuid].append(
new_target_uuid)
annotation.value.source._uuid = new_source_uuid
annotation.value.target._uuid = new_target_uuid
if annotation._uuid in used_uuids:
annotation._uuid = uuid.uuid4()
used_uuids.add(annotation._uuid)
uuid_safe_annotations.append(annotation)
# Second pass to update UUIDs for annotations referenced by RelationshipAnnotations
for annotation in label.annotations:
if not isinstance(annotation, RelationshipAnnotation):
if hasattr(annotation, "_uuid"):
if annotation in uuid_safe_annotations:
annotation = copy.deepcopy(annotation)
next_uuids = relationship_uuids[annotation._uuid]
if len(next_uuids) > 0:
annotation._uuid = next_uuids.popleft()
if (not isinstance(annotation, RelationshipAnnotation) and
hasattr(annotation, "_uuid")):
annotation = copy.deepcopy(annotation)
next_uuids = relationship_uuids[annotation._uuid]
if len(next_uuids) > 0:
annotation._uuid = next_uuids.popleft()

if annotation._uuid in used_uuids:
annotation._uuid = uuid.uuid4()
used_uuids.add(annotation._uuid)
if annotation._uuid in used_uuids:
annotation._uuid = uuid.uuid4()
used_uuids.add(annotation._uuid)
uuid_safe_annotations.append(annotation)
else:
if not isinstance(annotation, RelationshipAnnotation):
uuid_safe_annotations.append(annotation)
label.annotations = uuid_safe_annotations
for example in NDLabel.from_common([label]):
annotation_uuid = getattr(example, "uuid", None)
Expand Down
40 changes: 40 additions & 0 deletions tests/data/assets/ndjson/relationship_import.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,45 @@
"target": "d8813907-b15d-4374-bbe6-b9877fb42ccd",
"type": "unidirectional"
}
},
{
"uuid": "d8813907-b15d-4374-bbe6-b9877fb42ccd",
"dataRow": {
"id": "clf98gj90000qp38ka34yhptl-DIFFERENT"
},
"name": "cat",
"classifications": [],
"bbox": {
"top": 200.0,
"left": 100.0,
"height": 100.0,
"width": 100.0
}
},
{
"uuid": "9b1e1249-36b4-4665-b60a-9060e0d18660",
"dataRow": {
"id": "clf98gj90000qp38ka34yhptl-DIFFERENT"
},
"name": "dog",
"classifications": [],
"bbox": {
"top": 500.0,
"left": 400.0,
"height": 200.0,
"width": 200.0
}
},
{
"uuid": "0e6354eb-9adb-47e5-8e52-217ed016d948",
"dataRow": {
"id": "clf98gj90000qp38ka34yhptl-DIFFERENT"
},
"name": "is chasing",
"relationship": {
"source": "9b1e1249-36b4-4665-b60a-9060e0d18660",
"target": "d8813907-b15d-4374-bbe6-b9877fb42ccd",
"type": "unidirectional"
}
}
]
16 changes: 14 additions & 2 deletions tests/data/serialization/ndjson/test_relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def test_relationship():
res = list(NDJsonConverter.serialize(res))
assert len(res) == len(data)

res_relationship_annotation = [
res_relationship_annotation, res_relationship_second_annotation = [
annot for annot in res if "relationship" in annot
][0]
]
res_source_and_target = [
annot for annot in res if "relationship" not in annot
]
Expand All @@ -29,6 +29,18 @@ def test_relationship():
annot["uuid"] for annot in res_source_and_target
]

assert res_relationship_second_annotation
assert res_relationship_second_annotation["relationship"][
"source"] != res_relationship_annotation["relationship"]["source"]
assert res_relationship_second_annotation["relationship"][
"target"] != res_relationship_annotation["relationship"]["target"]
assert res_relationship_second_annotation["relationship"]["source"] in [
annot["uuid"] for annot in res_source_and_target
]
assert res_relationship_second_annotation["relationship"]["target"] in [
annot["uuid"] for annot in res_source_and_target
]


def test_relationship_nonexistent_object():
with open("tests/data/assets/ndjson/relationship_import.json", "r") as file:
Expand Down