Skip to content

Commit 8bb20aa

Browse files
committed
added integration test
1 parent c73472e commit 8bb20aa

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
import datetime
2+
import labelbox as lb
3+
from labelbox.client import Client
4+
from labelbox.data.serialization.ndjson.converter import NDJsonConverter
5+
from labelbox.schema.enums import AnnotationImportState
6+
from labelbox.schema.media_type import MediaType
7+
from labelbox.schema.project import Project
8+
from labelbox.types import (
9+
Label,
10+
ObjectAnnotation,
11+
RelationshipAnnotation,
12+
Relationship,
13+
TextEntity,
14+
)
15+
import pytest
16+
17+
18+
def validate_iso_format(date_string: str):
19+
parsed_t = datetime.datetime.fromisoformat(
20+
date_string
21+
) # this will blow up if the string is not in iso format
22+
assert parsed_t.hour is not None
23+
assert parsed_t.minute is not None
24+
assert parsed_t.second is not None
25+
26+
27+
def _get_text_relationship_label():
28+
ner_source = ObjectAnnotation(
29+
name="e1",
30+
value=TextEntity(start=10, end=12),
31+
)
32+
ner_source2 = ObjectAnnotation(
33+
name="e4",
34+
value=TextEntity(start=40, end=70),
35+
)
36+
ner_target = ObjectAnnotation(
37+
name="e2",
38+
value=TextEntity(start=30, end=35),
39+
)
40+
ner_target2 = ObjectAnnotation(
41+
name="e3",
42+
value=TextEntity(start=40, end=60),
43+
)
44+
45+
ner_relationship1 = RelationshipAnnotation(
46+
name="rel",
47+
value=Relationship(
48+
source=ner_source, # UUID is not required for annotation types
49+
target=ner_target,
50+
type=Relationship.Type.UNIDIRECTIONAL,
51+
),
52+
)
53+
54+
ner_relationship2 = RelationshipAnnotation(
55+
name="rel2",
56+
value=Relationship(
57+
source=ner_source, # UUID is not required for annotation types
58+
target=ner_target2,
59+
type=Relationship.Type.UNIDIRECTIONAL,
60+
),
61+
)
62+
63+
ner_relationship3 = RelationshipAnnotation(
64+
name="rel3",
65+
value=Relationship(
66+
source=ner_target, # UUID is not required for annotation types
67+
target=ner_source2,
68+
type=Relationship.Type.BIDIRECTIONAL,
69+
),
70+
)
71+
72+
return [
73+
ner_source,
74+
ner_source2,
75+
ner_target,
76+
ner_target2,
77+
ner_relationship1,
78+
ner_relationship2,
79+
ner_relationship3,
80+
]
81+
82+
83+
@pytest.fixture(scope="module", autouse=True)
84+
def normalized_ontology_by_media_type_relationship():
85+
"""Returns NDJSON of ontology based on media type"""
86+
87+
entity_source_tool = {
88+
"required": False,
89+
"name": "e1",
90+
"tool": "named-entity",
91+
"color": "#006FA6",
92+
"classifications": [],
93+
}
94+
entity_target_tool = {
95+
"required": False,
96+
"name": "e2",
97+
"tool": "named-entity",
98+
"color": "#006FA6",
99+
"classifications": [],
100+
}
101+
entity_target_2_tool = {
102+
"required": False,
103+
"name": "e3",
104+
"tool": "named-entity",
105+
"color": "#006FA6",
106+
"classifications": [],
107+
}
108+
entity_source_2_tool = {
109+
"required": False,
110+
"name": "e4",
111+
"tool": "named-entity",
112+
"color": "#006FA6",
113+
"classifications": [],
114+
}
115+
relationship_1 = {
116+
"name": "rel",
117+
"tool": "edge",
118+
}
119+
relationship_2 = {
120+
"name": "rel2",
121+
"tool": "edge",
122+
}
123+
relationship_3 = {
124+
"name": "rel3",
125+
"tool": "edge",
126+
}
127+
128+
return {
129+
MediaType.Text: {
130+
"tools": [
131+
entity_source_tool,
132+
entity_source_2_tool,
133+
entity_target_tool,
134+
entity_target_2_tool,
135+
relationship_1,
136+
relationship_2,
137+
relationship_3,
138+
],
139+
},
140+
}
141+
142+
143+
@pytest.fixture
144+
def configured_project(
145+
client: Client,
146+
rand_gen,
147+
data_row_json_by_media_type,
148+
normalized_ontology_by_media_type_relationship,
149+
):
150+
"""Configure project for test. Request.param will contain the media type if not present will use Image MediaType. The project will have 10 data rows."""
151+
152+
media_type = MediaType.Text
153+
154+
dataset = None
155+
156+
dataset = client.create_dataset(name=rand_gen(str))
157+
158+
project = client.create_project(
159+
name=f"{media_type}-{rand_gen(str)}", media_type=media_type
160+
)
161+
162+
ontology = client.create_ontology(
163+
name=f"{media_type}-{rand_gen(str)}",
164+
normalized=normalized_ontology_by_media_type_relationship[media_type],
165+
media_type=media_type,
166+
)
167+
168+
project.connect_ontology(ontology)
169+
data_row_data = []
170+
171+
for _ in range(3):
172+
data_row_data.append(
173+
data_row_json_by_media_type[media_type](rand_gen(str))
174+
)
175+
176+
task = dataset.create_data_rows(data_row_data)
177+
task.wait_till_done()
178+
global_keys = [row["global_key"] for row in task.result]
179+
data_row_ids = [row["id"] for row in task.result]
180+
181+
project.create_batch(
182+
rand_gen(str),
183+
data_row_ids, # sample of data row objects
184+
5, # priority between 1(Highest) - 5(lowest)
185+
)
186+
project.data_row_ids = data_row_ids
187+
project.global_keys = global_keys
188+
189+
yield project
190+
191+
192+
@pytest.mark.parametrize(
193+
"configured_project",
194+
[MediaType.Text],
195+
indirect=["configured_project"],
196+
)
197+
def test_import_media_types(
198+
client: Client,
199+
configured_project: Project,
200+
):
201+
labels = []
202+
media_type = configured_project.media_type
203+
for data_row in configured_project.data_row_ids:
204+
annotations = _get_text_relationship_label()
205+
206+
label = Label(
207+
data={"uid": data_row},
208+
annotations=annotations,
209+
)
210+
labels.append(label)
211+
212+
label_import = lb.MALPredictionImport.create_from_objects(
213+
client, configured_project.uid, f"test-import-{media_type}", labels
214+
)
215+
label_import.wait_until_done()
216+
217+
assert label_import.state == AnnotationImportState.FINISHED
218+
assert len(label_import.errors) == 0

0 commit comments

Comments
 (0)