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
1 change: 1 addition & 0 deletions labelbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from labelbox.schema.annotation_import import MALPredictionImport, MEAPredictionImport, LabelImport, MEAToMALPredictionImport
from labelbox.schema.dataset import Dataset
from labelbox.schema.data_row import DataRow
from labelbox.schema.enums import AnnotationImportState
from labelbox.schema.label import Label
from labelbox.schema.batch import Batch
from labelbox.schema.review import Review
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,4 @@ def test_conversation_entity(client, configured_project_without_data_rows,
predictions=labels)
import_annotations.wait_until_done()

assert import_annotations.errors == []

exported_labels = configured_project_without_data_rows.label_generator()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to make it clear that MAL Labels are not part of the exports. This returns zero labels, and the loop below doesn't get run.

for label in exported_labels:
assert len(
label.annotations) == 1 # we have created only 1 annotation above
annotation = label.annotations[0]

assert type(annotation) is ConversationEntity
assert annotation.name == "named-entity"
assert annotation.value.message_id == "4"
assert annotation.value.start == 0
assert annotation.value.end == 8
assert import_annotations.errors == []
146 changes: 146 additions & 0 deletions tests/integration/annotation_import/test_data_types.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,69 @@
import itertools
import pytest
import uuid

import labelbox as lb
import labelbox.types as lb_types
from labelbox.data.annotation_types.data import AudioData, ConversationData, DicomData, DocumentData, HTMLData, ImageData, TextData
from labelbox.data.serialization import NDJsonConverter
from labelbox.schema.annotation_import import AnnotationImportState

radio_annotation = lb_types.ClassificationAnnotation(
name="radio",
value=lb_types.Radio(answer=lb_types.ClassificationAnswer(
name="second_radio_answer")))
checklist_annotation = lb_types.ClassificationAnnotation(
name="checklist",
value=lb_types.Checklist(answer=[
lb_types.ClassificationAnswer(name="option1"),
lb_types.ClassificationAnswer(name="option2")
]))
text_annotation = lb_types.ClassificationAnnotation(
name="text", value=lb_types.Text(answer="sample text"))


def get_annotation_comparison_dicts_from_labels(labels):
labels_ndjson = list(NDJsonConverter.serialize(labels))
for annotation in labels_ndjson:
annotation.pop('uuid')
annotation.pop('dataRow')
return labels_ndjson


def get_annotation_comparison_dicts_from_export(export_result, data_row_id,
project_id):
exported_data_row = [
dr for dr in export_result if dr['data_row']['id'] == data_row_id
][0]
exported_annotations = exported_data_row['projects'][project_id]['labels'][
0]['annotations']
flat_exported_annotations = list(
itertools.chain(*exported_annotations.values()))

converted_annotations = []
for annotation in flat_exported_annotations:
if annotation['name'] == 'radio':
converted_annotations.append({
'name': annotation['name'],
'answer': {
'name': annotation['radio_answer']['name']
}
})
elif annotation['name'] == 'checklist':
converted_annotations.append({
'name':
annotation['name'],
'answer': [{
'name': answer['name']
} for answer in annotation['checklist_answers']]
})
elif annotation['name'] == 'text':
converted_annotations.append({
'name': annotation['name'],
'answer': annotation['text_answer']['content']
})
return converted_annotations


# TODO: Add VideoData. Currently label import job finishes without errors but project.export_labels() returns empty list.
@pytest.mark.parametrize('data_type_class', [
Expand Down Expand Up @@ -44,3 +103,90 @@ def test_import_data_types(client, configured_project,
classifications = exported_labels[0]['Label']['classifications']
assert len(objects) + len(classifications) == len(labels)
data_row.delete()


@pytest.mark.parametrize('data_type, data_class, annotations', [
[
'html', lb_types.HTMLData,
[radio_annotation, checklist_annotation, text_annotation]
],
[
'audio', lb_types.AudioData,
[radio_annotation, checklist_annotation, text_annotation]
],
])
def test_import_label_annotations(client, configured_project,
data_row_json_by_data_type, data_type,
data_class, annotations):

dataset = next(configured_project.datasets())
data_row_json = data_row_json_by_data_type[data_type]
data_row = dataset.create_data_row(data_row_json)

labels = [
lb_types.Label(data=data_class(uid=data_row.uid),
annotations=annotations)
]

label_import = lb.LabelImport.create_from_objects(client,
configured_project.uid,
f'test-import-html',
labels)
label_import.wait_until_done()

assert label_import.state == lb.AnnotationImportState.FINISHED
assert len(label_import.errors) == 0
export_params = {
"attachments": False,
"metadata_fields": False,
"data_row_details": False,
"project_details": False,
"performance_details": False
}
export_task = configured_project.export_v2(params=export_params)
export_task.wait_till_done()
assert export_task.errors is None
expected_annotations = get_annotation_comparison_dicts_from_labels(labels)
actual_annotations = get_annotation_comparison_dicts_from_export(
export_task.result, data_row.uid, configured_project.uid)
assert actual_annotations == expected_annotations
data_row.delete()


@pytest.mark.parametrize('data_type, data_class, annotations', [
[
'html', lb_types.HTMLData,
[radio_annotation, checklist_annotation, text_annotation]
],
[
'audio', lb_types.AudioData,
[radio_annotation, checklist_annotation, text_annotation]
],
])
def test_import_mal_annotations(client, configured_project_without_data_rows,
data_row_json_by_data_type, data_type,
data_class, annotations, rand_gen):

dataset = client.create_dataset(name=rand_gen(str))
data_row_json = data_row_json_by_data_type[data_type]
data_row = dataset.create_data_row(data_row_json)

configured_project_without_data_rows.create_batch(
rand_gen(str),
[data_row.uid],
)

labels = [
lb_types.Label(data=data_class(uid=data_row.uid),
annotations=annotations)
]

import_annotations = lb.MALPredictionImport.create_from_objects(
client=client,
project_id=configured_project_without_data_rows.uid,
name=f"import {str(uuid.uuid4())}",
predictions=labels)
import_annotations.wait_until_done()

assert import_annotations.errors == []
# MAL Labels cannot be exported and compared to input labels