Skip to content

Commit 5e7180e

Browse files
committed
add ontology.from_dict and updated tests
1 parent 07388cb commit 5e7180e

File tree

2 files changed

+112
-35
lines changed

2 files changed

+112
-35
lines changed

labelbox/schema/ontology_generator.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,7 @@ class Ontology:
155155
@classmethod
156156
def from_project(cls, project: Project):
157157
ontology = project.ontology().normalized
158-
return_ontology = Ontology()
159-
160-
for tool in ontology["tools"]:
161-
return_ontology.tools.append(Tool.from_dict(tool))
162-
163-
for classification in ontology["classifications"]:
164-
return_ontology.classifications.append(Classification.from_dict(classification))
165-
166-
return return_ontology
158+
return Ontology.from_dict(ontology)
167159

168160
def add_tool(self, tool: Tool) -> Tool:
169161
if tool.name in (t.name for t in self.tools):
@@ -181,4 +173,10 @@ def add_classification(self, classification: Classification) -> Classification:
181173
def asdict(self):
182174
return {
183175
"tools": [t.asdict() for t in self.tools],
184-
"classifications": [c.asdict() for c in self.classifications]}
176+
"classifications": [c.asdict() for c in self.classifications]}
177+
178+
@classmethod
179+
def from_dict(cls, dictionary: Dict[str,Any]):
180+
return Ontology(
181+
tools = [Tool.from_dict(t) for t in dictionary["tools"]],
182+
classifications = [Classification.from_dict(c) for c in dictionary["classifications"]])

tests/integration/test_ontology.py

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,129 @@
99

1010
_SAMPLE_ONTOLOGY = {
1111
"tools": [{
12+
"schemaNodeId": None,
13+
"featureSchemaId": None,
1214
"required": False,
13-
"name": "Dog",
15+
"name": "poly",
16+
"color": "#FF0000",
17+
"tool": "polygon",
18+
"classifications": []
19+
}, {
20+
"schemaNodeId": None,
21+
"featureSchemaId": None,
22+
"required": False,
23+
"name": "segment",
24+
"color": "#FF0000",
25+
"tool": "superpixel",
26+
"classifications": []
27+
}, {
28+
"schemaNodeId": None,
29+
"featureSchemaId": None,
30+
"required": False,
31+
"name": "bbox",
1432
"color": "#FF0000",
1533
"tool": "rectangle",
34+
"classifications": [{
35+
"schemaNodeId": None,
36+
"featureSchemaId": None,
37+
"required": True,
38+
"instructions": "nested classification",
39+
"name": "nested classification",
40+
"type": "radio",
41+
"options": [{
42+
"schemaNodeId": None,
43+
"featureSchemaId": None,
44+
"label": "first",
45+
"value": "first",
46+
"options": [{
47+
"schemaNodeId": None,
48+
"featureSchemaId": None,
49+
"required": False,
50+
"instructions": "nested nested text",
51+
"name": "nested nested text",
52+
"type": "text",
53+
"options": []
54+
}]
55+
}, {
56+
"schemaNodeId": None,
57+
"featureSchemaId": None,
58+
"label": "second",
59+
"value": "second",
60+
"options": []
61+
}]
62+
}, {
63+
"schemaNodeId": None,
64+
"featureSchemaId": None,
65+
"required": True,
66+
"instructions": "nested text",
67+
"name": "nested text",
68+
"type": "text",
69+
"options": []
70+
}]
71+
}, {
72+
"schemaNodeId": None,
73+
"featureSchemaId": None,
74+
"required": False,
75+
"name": "dot",
76+
"color": "#FF0000",
77+
"tool": "point",
78+
"classifications": []
79+
}, {
80+
"schemaNodeId": None,
81+
"featureSchemaId": None,
82+
"required": False,
83+
"name": "polyline",
84+
"color": "#FF0000",
85+
"tool": "line",
86+
"classifications": []
87+
}, {
88+
"schemaNodeId": None,
89+
"featureSchemaId": None,
90+
"required": False,
91+
"name": "ner",
92+
"color": "#FF0000",
93+
"tool": "named-entity",
1694
"classifications": []
1795
}],
1896
"classifications": [{
97+
"schemaNodeId": None,
98+
"featureSchemaId": None,
1999
"required": True,
20100
"instructions": "This is a question.",
21101
"name": "This is a question.",
22102
"type": "radio",
23103
"options": [{
104+
"schemaNodeId": None,
105+
"featureSchemaId": None,
24106
"label": "yes",
25-
"value": "yes"
107+
"value": "yes",
108+
"options": []
26109
}, {
110+
"schemaNodeId": None,
111+
"featureSchemaId": None,
27112
"label": "no",
28-
"value": "no"
113+
"value": "no",
114+
"options": []
29115
}]
30116
}]
31117
}
32118

33119
@pytest.mark.parametrize("tool_type", list(Tool.Type))
34-
@pytest.mark.parametrize("tool_name", ["tool"])
35-
def test_create_tool(tool_type, tool_name) -> None:
36-
t = Tool(tool = tool_type, name = tool_name)
120+
def test_create_tool(tool_type) -> None:
121+
t = Tool(tool = tool_type, name = "tool")
37122
assert(t.tool == tool_type)
38-
assert(t.name == tool_name)
39123

40124
@pytest.mark.parametrize("class_type", list(Classification.Type))
41-
@pytest.mark.parametrize("class_instr", ["classification"])
42-
def test_create_classification(class_type, class_instr) -> None:
43-
c = Classification(class_type = class_type, instructions = class_instr)
125+
def test_create_classification(class_type) -> None:
126+
c = Classification(class_type = class_type, instructions = "classification")
44127
assert(c.class_type == class_type)
45-
assert(c.instructions == class_instr)
46-
assert(c.name == c.instructions)
47128

48129
@pytest.mark.parametrize(
49130
"value, expected_value, typing",[(3,3, int),("string","string", str)])
50131
def test_create_option(value, expected_value, typing) -> None:
51132
o = Option(value = value)
52133
assert(o.value == expected_value)
53134
assert(o.value == o.label)
54-
assert(type(o.value) == typing)
55135

56136
def test_create_empty_ontology() -> None:
57137
o = Ontology()
@@ -66,6 +146,9 @@ def test_add_ontology_tool() -> None:
66146
o.add_tool(second_tool)
67147
assert len(o.tools) == 2
68148

149+
for tool in o.tools:
150+
assert(type(tool) == Tool)
151+
69152
with pytest.raises(InconsistentOntologyException) as exc:
70153
o.add_tool(Tool(tool=Tool.Type.BBOX, name = "bounding box"))
71154
assert "Duplicate tool name" in str(exc.value)
@@ -80,6 +163,9 @@ def test_add_ontology_classification() -> None:
80163
o.add_classification(second_classification)
81164
assert len(o.classifications) == 2
82165

166+
for classification in o.classifications:
167+
assert(type(classification) == Classification)
168+
83169
with pytest.raises(InconsistentOntologyException) as exc:
84170
o.add_classification(Classification(
85171
class_type = Classification.Type.TEXT, instructions = "text"))
@@ -90,7 +176,7 @@ def test_tool_add_classification() -> None:
90176
c = Classification(
91177
class_type = Classification.Type.TEXT, instructions = "text")
92178
t.add_classification(c)
93-
assert t.classifications[0] == c
179+
assert t.classifications == [c]
94180

95181
with pytest.raises(Exception) as exc:
96182
t.add_classification(c)
@@ -101,7 +187,7 @@ def test_classification_add_option() -> None:
101187
class_type = Classification.Type.RADIO, instructions = "radio")
102188
o = Option(value = "option")
103189
c.add_option(o)
104-
assert c.options[0] == o
190+
assert c.options == [o]
105191

106192
with pytest.raises(InconsistentOntologyException) as exc:
107193
c.add_option(Option(value = "option"))
@@ -112,22 +198,15 @@ def test_option_add_option() -> None:
112198
c = Classification(
113199
class_type = Classification.Type.TEXT, instructions = "text")
114200
o.add_option(c)
115-
assert o.options[0] == c
201+
assert o.options == [c]
116202

117203
with pytest.raises(InconsistentOntologyException) as exc:
118204
o.add_option(c)
119205
assert "Duplicate nested classification" in str(exc.value)
120206

121207
def test_ontology_asdict(project) -> None:
122-
o = Ontology.from_project(project)
123-
assert o.asdict() == project.ontology().normalized
208+
assert Ontology.from_dict(_SAMPLE_ONTOLOGY).asdict() == _SAMPLE_ONTOLOGY
124209

125210
def test_from_project_ontology(client, project) -> None:
126-
frontend = list(client.get_labeling_frontends(
127-
where=LabelingFrontend.name == "Editor"))[0]
128-
project.setup(frontend, _SAMPLE_ONTOLOGY)
129211
o = Ontology.from_project(project)
130-
131-
assert o.tools[0].tool == Tool.Type.BBOX
132-
assert o.classifications[0].class_type == Classification.Type.RADIO
133-
assert o.classifications[0].options[0].value.lower() == "yes"
212+
assert o.asdict() == project.ontology().normalized

0 commit comments

Comments
 (0)