Skip to content

Commit 2edc4bc

Browse files
authored
Merge pull request #388 from superannotateai/update_tag_tests
Update tag tests
2 parents 17e37e4 + 3b22865 commit 2edc4bc

20 files changed

+245
-225
lines changed

src/superannotate/lib/app/interface/sdk_interface.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
from lib.core.enums import ImageQuality
4040
from lib.core.exceptions import AppException
4141
from lib.core.types import AttributeGroup
42-
from lib.core.types import ClassesJson
4342
from lib.core.types import MLModel
4443
from lib.core.types import Project
4544
from pydantic import conlist
@@ -1607,7 +1606,7 @@ def download_annotation_classes_json(project: NotEmptyStr, folder: Union[str, Pa
16071606
@validate_arguments
16081607
def create_annotation_classes_from_classes_json(
16091608
project: Union[NotEmptyStr, dict],
1610-
classes_json: Union[List[ClassesJson], str, Path],
1609+
classes_json: Union[List[AnnotationClassEntity], str, Path],
16111610
from_s3_bucket=False,
16121611
):
16131612
"""Creates annotation classes in project from a SuperAnnotate format
@@ -1623,6 +1622,7 @@ def create_annotation_classes_from_classes_json(
16231622
:return: list of created annotation class metadatas
16241623
:rtype: list of dicts
16251624
"""
1625+
classes_json_initial = classes_json
16261626
if isinstance(classes_json, str) or isinstance(classes_json, Path):
16271627
if from_s3_bucket:
16281628
from_session = boto3.Session()
@@ -1637,7 +1637,7 @@ def create_annotation_classes_from_classes_json(
16371637
classes_json = json.load(data)
16381638
annotation_classes = parse_obj_as(List[AnnotationClassEntity], classes_json)
16391639
logger.info(
1640-
"Creating annotation classes in project %s from %s.", project, classes_json,
1640+
"Creating annotation classes in project %s from %s.", project, classes_json_initial,
16411641
)
16421642
response = controller.create_annotation_classes(
16431643
project_name=project, annotation_classes=annotation_classes,

src/superannotate/lib/core/data_handlers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ def __init__(self, annotation_classes: List[AnnotationClass]):
4040

4141
@lru_cache()
4242
def get_annotation_class(
43-
self, name: str, class_type: ClassTypeEnum = ClassTypeEnum.OBJECT
43+
self, name: str, class_type: ClassTypeEnum
4444
) -> AnnotationClass:
4545
for annotation_class in self._annotation_classes:
46-
if annotation_class.name == name and annotation_class.type == class_type:
46+
if annotation_class.name == name and class_type.equals(annotation_class.type):
4747
return annotation_class
4848

4949
@lru_cache()
@@ -162,8 +162,8 @@ def validate_existing_classes(self, annotation_classes: List[AnnotationClass]):
162162

163163
def _get_class_type(self, annotation_type: str):
164164
if annotation_type == ClassTypeEnum.TAG.name:
165-
return annotation_type
166-
return ClassTypeEnum.OBJECT.name
165+
return ClassTypeEnum.TAG
166+
return ClassTypeEnum.OBJECT
167167

168168
def handle(self, annotation: dict):
169169
if "instances" not in annotation:
@@ -287,7 +287,7 @@ def convert_timestamp(timestamp):
287287
"locked": False,
288288
}
289289
if class_name:
290-
annotation_class = self.get_annotation_class(class_name)
290+
annotation_class = self.get_annotation_class(class_name,ClassTypeEnum.OBJECT)
291291
if annotation_class:
292292
editor_instance["classId"] = annotation_class.id
293293
else:
@@ -322,7 +322,7 @@ def convert_timestamp(timestamp):
322322
] = timestamp_data["points"]
323323
if not class_name:
324324
continue
325-
annotation_class = self.get_annotation_class(class_name)
325+
annotation_class = self.get_annotation_class(class_name,ClassTypeEnum.OBJECT)
326326
if not annotation_class:
327327
self.reporter.store_message(
328328
"missing_classes", meta["className"]

src/superannotate/lib/core/enums.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ def values(cls):
3131
def titles(cls):
3232
return [enum.name for enum in list(cls)]
3333

34+
def equals(self, other: Enum):
35+
return self.name.lower() == other.lower()
36+
3437

3538
class ProjectType(BaseTitledEnum):
3639
VECTOR = "Vector", 1

src/superannotate/lib/core/types.py

Lines changed: 3 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
from pydantic import validator
1212
from pydantic.error_wrappers import ErrorWrapper
1313
from pydantic.error_wrappers import ValidationError
14+
from superannotate_schemas.schemas.classes import AttributeGroup as AttributeGroupSchema
1415

1516
NotEmptyStr = constr(strict=True, min_length=1)
1617

18+
AttributeGroup = AttributeGroupSchema
19+
1720

1821
class AnnotationType(StrictStr):
1922
@classmethod
@@ -25,160 +28,6 @@ def validate(cls, value: str) -> Union[str]:
2528
return value
2629

2730

28-
class Attribute(BaseModel):
29-
name: NotEmptyStr
30-
31-
32-
class AttributeGroup(BaseModel):
33-
name: StrictStr
34-
is_multiselect: Optional[int] = False
35-
attributes: List[Attribute]
36-
37-
38-
class ClassesJson(BaseModel):
39-
name: StrictStr
40-
color: StrictStr
41-
attribute_groups: List[AttributeGroup]
42-
43-
44-
class Metadata(BaseModel):
45-
name: Optional[NotEmptyStr]
46-
width: Optional[int]
47-
height: Optional[int]
48-
49-
50-
class PointLabels(BaseModel):
51-
__root__: Dict[constr(regex=r"^[0-9]+$"), str] # noqa: F722
52-
53-
54-
class BaseInstance(BaseModel):
55-
type: AnnotationType
56-
classId: Optional[int]
57-
groupId: Optional[int]
58-
attributes: List[Attribute]
59-
# point_labels: Optional[PointLabels]
60-
61-
class Config:
62-
error_msg_templates = {
63-
"value_error.missing": "field required for annotation",
64-
}
65-
66-
67-
class Point(BaseInstance):
68-
x: float
69-
y: float
70-
71-
72-
class PolyLine(BaseInstance):
73-
points: List[float]
74-
75-
76-
class Polygon(BaseInstance):
77-
points: List[float]
78-
79-
80-
class BboxPoints(BaseModel):
81-
x1: float
82-
x2: float
83-
y1: float
84-
y2: float
85-
86-
87-
class Bbox(BaseInstance):
88-
points: BboxPoints
89-
90-
91-
class Ellipse(BaseInstance):
92-
cx: float
93-
cy: float
94-
rx: float
95-
ry: float
96-
97-
98-
class TemplatePoint(BaseModel):
99-
id: Optional[int]
100-
x: float
101-
y: float
102-
103-
104-
class TemplateConnection(BaseModel):
105-
id: Optional[int]
106-
to: int
107-
108-
109-
class Template(BaseInstance):
110-
points: List[TemplatePoint]
111-
connections: List[Optional[TemplateConnection]]
112-
templateId: Optional[int]
113-
114-
115-
class EmptyPoint(BaseModel):
116-
x: float
117-
y: float
118-
119-
120-
class CuboidPoint(BaseModel):
121-
f1: EmptyPoint
122-
f2: EmptyPoint
123-
r1: EmptyPoint
124-
r2: EmptyPoint
125-
126-
127-
class Cuboid(BaseInstance):
128-
points: CuboidPoint
129-
130-
131-
class PixelAnnotationPart(BaseModel):
132-
color: NotEmptyStr
133-
134-
135-
class PixelAnnotationInstance(BaseModel):
136-
classId: Optional[int]
137-
groupId: Optional[int]
138-
parts: List[PixelAnnotationPart]
139-
attributes: List[Attribute]
140-
141-
142-
class VectorInstance(BaseModel):
143-
__root__: Union[Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse]
144-
145-
146-
ANNOTATION_TYPES = {
147-
"bbox": Bbox,
148-
"ellipse": Ellipse,
149-
"template": Template,
150-
"cuboid": Cuboid,
151-
"polyline": PolyLine,
152-
"polygon": Polygon,
153-
"point": Point,
154-
}
155-
156-
157-
class VectorAnnotation(BaseModel):
158-
metadata: Metadata
159-
instances: Optional[
160-
List[Union[Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse]]
161-
]
162-
163-
@validator("instances", pre=True, each_item=True)
164-
def check_instances(cls, instance):
165-
annotation_type = AnnotationType.validate(instance.get("type"))
166-
if not annotation_type:
167-
raise ValidationError(
168-
[ErrorWrapper(TypeError("value not specified"), "type")], cls
169-
)
170-
result = validate_model(ANNOTATION_TYPES[annotation_type], instance)
171-
if result[2]:
172-
raise ValidationError(
173-
result[2].raw_errors, model=ANNOTATION_TYPES[annotation_type]
174-
)
175-
return instance
176-
177-
178-
class PixelAnnotation(BaseModel):
179-
metadata: Metadata
180-
instances: List[PixelAnnotationInstance]
181-
18231

18332
class Project(BaseModel):
18433
name: NotEmptyStr
@@ -198,40 +47,3 @@ class Config:
19847
extra = Extra.allow
19948

20049

201-
class VideoMetaData(BaseModel):
202-
name: StrictStr
203-
width: Optional[int]
204-
height: Optional[int]
205-
duration: Optional[int]
206-
207-
208-
class VideoInstanceMeta(BaseModel):
209-
type: NotEmptyStr
210-
classId: Optional[int]
211-
212-
213-
class VideoTimeStamp(BaseModel):
214-
timestamp: int
215-
attributes: List[Attribute]
216-
217-
218-
class VideoInstanceParameter(BaseModel):
219-
start: int
220-
end: int
221-
timestamps: List[VideoTimeStamp]
222-
223-
224-
class VideoInstance(BaseModel):
225-
meta: VideoInstanceMeta
226-
parameters: List[VideoInstanceParameter]
227-
228-
229-
class VideoAnnotation(BaseModel):
230-
metadata: VideoMetaData
231-
instances: Optional[List[VideoInstance]]
232-
tags: Optional[List[str]]
233-
234-
235-
class DocumentAnnotation(BaseModel):
236-
instances: list
237-
tags: Optional[List[str]]

src/superannotate/lib/infrastructure/repositories.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def dict2entity(data: dict) -> AnnotationClassEntity:
360360
createdAt=data["createdAt"],
361361
updatedAt=data["updatedAt"],
362362
attribute_groups=data["attribute_groups"],
363-
type=ClassTypeEnum.get_name(data["type"]),
363+
type=ClassTypeEnum.get_name(data.get('type')),
364364
)
365365

366366

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[
2+
{
3+
"id": 55920,
4+
"project_id": 11979,
5+
"name": "Weather",
6+
"color": "#46ccb2",
7+
"type": "tag",
8+
"count": 0,
9+
"createdAt": "2020-10-12T11:35:20.000Z",
10+
"updatedAt": "2020-10-12T11:35:20.000Z",
11+
"attribute_groups": [
12+
{
13+
"id": 17245,
14+
"class_id": 55917,
15+
"name": "g1",
16+
"is_multiselect": 0,
17+
"createdAt": "2020-10-12T11:35:20.000Z",
18+
"updatedAt": "2020-10-12T11:35:20.000Z",
19+
"attributes": [
20+
{
21+
"id": 62792,
22+
"group_id": 17245,
23+
"project_id": 11979,
24+
"name": "1",
25+
"count": 1,
26+
"createdAt": "2020-10-12T11:35:20.000Z",
27+
"updatedAt": "2020-10-12T11:46:28.000Z"
28+
},
29+
{
30+
"id": 62793,
31+
"group_id": 17245,
32+
"project_id": 11979,
33+
"name": "2",
34+
"count": 1,
35+
"createdAt": "2020-10-12T11:35:20.000Z",
36+
"updatedAt": "2020-10-12T11:35:20.000Z"
37+
}
38+
]
39+
}
40+
]
41+
}
42+
]
209 KB
Loading
15.4 KB
Loading

0 commit comments

Comments
 (0)