denkproto 1.0.92__py3-none-any.whl → 1.0.94__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of denkproto might be problematic. Click here for more details.

denkproto/__about__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.0.92"
1
+ __version__ = "1.0.94"
@@ -281,30 +281,46 @@ class ObjectDetectionMarkup:
281
281
 
282
282
 
283
283
  class BoundingBox:
284
+ """A bounding box with optional rotation information"""
285
+
286
+ angle: Optional[float]
287
+ """Optional rotation angle"""
288
+
284
289
  bottom_right_x: float
285
290
  bottom_right_y: float
291
+ full_orientation: Optional[bool]
292
+ """Optional full orientation flag"""
293
+
286
294
  top_left_x: float
287
295
  top_left_y: float
288
296
 
289
- def __init__(self, bottom_right_x: float, bottom_right_y: float, top_left_x: float, top_left_y: float) -> None:
297
+ def __init__(self, angle: Optional[float], bottom_right_x: float, bottom_right_y: float, full_orientation: Optional[bool], top_left_x: float, top_left_y: float) -> None:
298
+ self.angle = angle
290
299
  self.bottom_right_x = bottom_right_x
291
300
  self.bottom_right_y = bottom_right_y
301
+ self.full_orientation = full_orientation
292
302
  self.top_left_x = top_left_x
293
303
  self.top_left_y = top_left_y
294
304
 
295
305
  @staticmethod
296
306
  def from_dict(obj: Any) -> 'BoundingBox':
297
307
  assert isinstance(obj, dict)
308
+ angle = from_union([from_float, from_none], obj.get("angle"))
298
309
  bottom_right_x = from_float(obj.get("bottom_right_x"))
299
310
  bottom_right_y = from_float(obj.get("bottom_right_y"))
311
+ full_orientation = from_union([from_bool, from_none], obj.get("full_orientation"))
300
312
  top_left_x = from_float(obj.get("top_left_x"))
301
313
  top_left_y = from_float(obj.get("top_left_y"))
302
- return BoundingBox(bottom_right_x, bottom_right_y, top_left_x, top_left_y)
314
+ return BoundingBox(angle, bottom_right_x, bottom_right_y, full_orientation, top_left_x, top_left_y)
303
315
 
304
316
  def to_dict(self) -> dict:
305
317
  result: dict = {}
318
+ if self.angle is not None:
319
+ result["angle"] = from_union([to_float, from_none], self.angle)
306
320
  result["bottom_right_x"] = to_float(self.bottom_right_x)
307
321
  result["bottom_right_y"] = to_float(self.bottom_right_y)
322
+ if self.full_orientation is not None:
323
+ result["full_orientation"] = from_union([from_bool, from_none], self.full_orientation)
308
324
  result["top_left_x"] = to_float(self.top_left_x)
309
325
  result["top_left_y"] = to_float(self.top_left_y)
310
326
  return result
@@ -332,20 +348,26 @@ class RingPoint:
332
348
  return result
333
349
 
334
350
 
335
- class AnnotationComparerRequestSchema:
351
+ class GeometrySchema:
352
+ """A single closed loop (ring) of a polygon, defining either an outer boundary or a hole."""
353
+
336
354
  hierarchy: int
355
+ """Nesting level: 0=outer, 1=hole in level 0, 2=poly in level 1 hole, etc. Even levels are
356
+ filled areas, odd levels are holes.
357
+ """
337
358
  points: List[RingPoint]
359
+ """Vertices of the ring."""
338
360
 
339
361
  def __init__(self, hierarchy: int, points: List[RingPoint]) -> None:
340
362
  self.hierarchy = hierarchy
341
363
  self.points = points
342
364
 
343
365
  @staticmethod
344
- def from_dict(obj: Any) -> 'AnnotationComparerRequestSchema':
366
+ def from_dict(obj: Any) -> 'GeometrySchema':
345
367
  assert isinstance(obj, dict)
346
368
  hierarchy = from_int(obj.get("hierarchy"))
347
369
  points = from_list(RingPoint.from_dict, obj.get("points"))
348
- return AnnotationComparerRequestSchema(hierarchy, points)
370
+ return GeometrySchema(hierarchy, points)
349
371
 
350
372
  def to_dict(self) -> dict:
351
373
  result: dict = {}
@@ -355,20 +377,25 @@ class AnnotationComparerRequestSchema:
355
377
 
356
378
 
357
379
  class Polygon:
358
- rings: List[AnnotationComparerRequestSchema]
380
+ """A polygon defined by one or more rings, allowing for holes and nested structures."""
381
+
382
+ rings: List[GeometrySchema]
383
+ """Array of polygon rings. The hierarchy field within each ring determines nesting and
384
+ fill/hole status.
385
+ """
359
386
 
360
- def __init__(self, rings: List[AnnotationComparerRequestSchema]) -> None:
387
+ def __init__(self, rings: List[GeometrySchema]) -> None:
361
388
  self.rings = rings
362
389
 
363
390
  @staticmethod
364
391
  def from_dict(obj: Any) -> 'Polygon':
365
392
  assert isinstance(obj, dict)
366
- rings = from_list(AnnotationComparerRequestSchema.from_dict, obj.get("rings"))
393
+ rings = from_list(GeometrySchema.from_dict, obj.get("rings"))
367
394
  return Polygon(rings)
368
395
 
369
396
  def to_dict(self) -> dict:
370
397
  result: dict = {}
371
- result["rings"] = from_list(lambda x: to_class(AnnotationComparerRequestSchema, x), self.rings)
398
+ result["rings"] = from_list(lambda x: to_class(GeometrySchema, x), self.rings)
372
399
  return result
373
400
 
374
401
 
@@ -408,7 +435,7 @@ class OcrMarkupAnnotation:
408
435
  return result
409
436
 
410
437
 
411
- class OcrMarkup:
438
+ class OCRMarkup:
412
439
  annotations: List[OcrMarkupAnnotation]
413
440
  average_object_widths: List[float]
414
441
  height: int
@@ -421,13 +448,13 @@ class OcrMarkup:
421
448
  self.width = width
422
449
 
423
450
  @staticmethod
424
- def from_dict(obj: Any) -> 'OcrMarkup':
451
+ def from_dict(obj: Any) -> 'OCRMarkup':
425
452
  assert isinstance(obj, dict)
426
453
  annotations = from_list(OcrMarkupAnnotation.from_dict, obj.get("annotations"))
427
454
  average_object_widths = from_list(from_float, obj.get("average_object_widths"))
428
455
  height = from_int(obj.get("height"))
429
456
  width = from_int(obj.get("width"))
430
- return OcrMarkup(annotations, average_object_widths, height, width)
457
+ return OCRMarkup(annotations, average_object_widths, height, width)
431
458
 
432
459
  def to_dict(self) -> dict:
433
460
  result: dict = {}
@@ -634,24 +661,6 @@ class PixelAnnotation:
634
661
  return result
635
662
 
636
663
 
637
- class PolygonAnnotation:
638
- rings: List[AnnotationComparerRequestSchema]
639
-
640
- def __init__(self, rings: List[AnnotationComparerRequestSchema]) -> None:
641
- self.rings = rings
642
-
643
- @staticmethod
644
- def from_dict(obj: Any) -> 'PolygonAnnotation':
645
- assert isinstance(obj, dict)
646
- rings = from_list(AnnotationComparerRequestSchema.from_dict, obj.get("rings"))
647
- return PolygonAnnotation(rings)
648
-
649
- def to_dict(self) -> dict:
650
- result: dict = {}
651
- result["rings"] = from_list(lambda x: to_class(AnnotationComparerRequestSchema, x), self.rings)
652
- return result
653
-
654
-
655
664
  class RectangleAnnotation:
656
665
  bottom_right_x: float
657
666
  bottom_right_y: float
@@ -755,11 +764,11 @@ class SegmentationMarkupAnnotation:
755
764
  magicwand_annotation: Optional[MagicwandAnnotation]
756
765
  pen_annotation: Optional[PenAnnotation]
757
766
  pixel_annotation: Optional[PixelAnnotation]
758
- polygon_annotation: Optional[PolygonAnnotation]
767
+ polygon_annotation: Optional[Polygon]
759
768
  rectangle_annotation: Optional[RectangleAnnotation]
760
769
  sausage_annotation: Optional[SausageAnnotation]
761
770
 
762
- def __init__(self, annotation_type: AnnotationType, average_width: float, circle_annotation: Optional[CircleAnnotation], id: UUID, label_id: UUID, magicwand_annotation: Optional[MagicwandAnnotation], pen_annotation: Optional[PenAnnotation], pixel_annotation: Optional[PixelAnnotation], polygon_annotation: Optional[PolygonAnnotation], rectangle_annotation: Optional[RectangleAnnotation], sausage_annotation: Optional[SausageAnnotation]) -> None:
771
+ def __init__(self, annotation_type: AnnotationType, average_width: float, circle_annotation: Optional[CircleAnnotation], id: UUID, label_id: UUID, magicwand_annotation: Optional[MagicwandAnnotation], pen_annotation: Optional[PenAnnotation], pixel_annotation: Optional[PixelAnnotation], polygon_annotation: Optional[Polygon], rectangle_annotation: Optional[RectangleAnnotation], sausage_annotation: Optional[SausageAnnotation]) -> None:
763
772
  self.annotation_type = annotation_type
764
773
  self.average_width = average_width
765
774
  self.circle_annotation = circle_annotation
@@ -783,7 +792,7 @@ class SegmentationMarkupAnnotation:
783
792
  magicwand_annotation = from_union([MagicwandAnnotation.from_dict, from_none], obj.get("magicwand_annotation"))
784
793
  pen_annotation = from_union([PenAnnotation.from_dict, from_none], obj.get("pen_annotation"))
785
794
  pixel_annotation = from_union([PixelAnnotation.from_dict, from_none], obj.get("pixel_annotation"))
786
- polygon_annotation = from_union([PolygonAnnotation.from_dict, from_none], obj.get("polygon_annotation"))
795
+ polygon_annotation = from_union([Polygon.from_dict, from_none], obj.get("polygon_annotation"))
787
796
  rectangle_annotation = from_union([RectangleAnnotation.from_dict, from_none], obj.get("rectangle_annotation"))
788
797
  sausage_annotation = from_union([SausageAnnotation.from_dict, from_none], obj.get("sausage_annotation"))
789
798
  return SegmentationMarkupAnnotation(annotation_type, average_width, circle_annotation, id, label_id, magicwand_annotation, pen_annotation, pixel_annotation, polygon_annotation, rectangle_annotation, sausage_annotation)
@@ -803,7 +812,7 @@ class SegmentationMarkupAnnotation:
803
812
  if self.pixel_annotation is not None:
804
813
  result["pixel_annotation"] = from_union([lambda x: to_class(PixelAnnotation, x), from_none], self.pixel_annotation)
805
814
  if self.polygon_annotation is not None:
806
- result["polygon_annotation"] = from_union([lambda x: to_class(PolygonAnnotation, x), from_none], self.polygon_annotation)
815
+ result["polygon_annotation"] = from_union([lambda x: to_class(Polygon, x), from_none], self.polygon_annotation)
807
816
  if self.rectangle_annotation is not None:
808
817
  result["rectangle_annotation"] = from_union([lambda x: to_class(RectangleAnnotation, x), from_none], self.rectangle_annotation)
809
818
  if self.sausage_annotation is not None:
@@ -919,10 +928,10 @@ class SegmentationMarkup:
919
928
  class Source:
920
929
  classification_markup: Optional[ClassificationMarkup]
921
930
  object_detection_markup: Optional[ObjectDetectionMarkup]
922
- ocr_markup: Optional[OcrMarkup]
931
+ ocr_markup: Optional[OCRMarkup]
923
932
  segmentation_markup: Optional[SegmentationMarkup]
924
933
 
925
- def __init__(self, classification_markup: Optional[ClassificationMarkup], object_detection_markup: Optional[ObjectDetectionMarkup], ocr_markup: Optional[OcrMarkup], segmentation_markup: Optional[SegmentationMarkup]) -> None:
934
+ def __init__(self, classification_markup: Optional[ClassificationMarkup], object_detection_markup: Optional[ObjectDetectionMarkup], ocr_markup: Optional[OCRMarkup], segmentation_markup: Optional[SegmentationMarkup]) -> None:
926
935
  self.classification_markup = classification_markup
927
936
  self.object_detection_markup = object_detection_markup
928
937
  self.ocr_markup = ocr_markup
@@ -933,7 +942,7 @@ class Source:
933
942
  assert isinstance(obj, dict)
934
943
  classification_markup = from_union([ClassificationMarkup.from_dict, from_none], obj.get("classification_markup"))
935
944
  object_detection_markup = from_union([ObjectDetectionMarkup.from_dict, from_none], obj.get("object_detection_markup"))
936
- ocr_markup = from_union([OcrMarkup.from_dict, from_none], obj.get("ocr_markup"))
945
+ ocr_markup = from_union([OCRMarkup.from_dict, from_none], obj.get("ocr_markup"))
937
946
  segmentation_markup = from_union([SegmentationMarkup.from_dict, from_none], obj.get("segmentation_markup"))
938
947
  return Source(classification_markup, object_detection_markup, ocr_markup, segmentation_markup)
939
948
 
@@ -944,7 +953,7 @@ class Source:
944
953
  if self.object_detection_markup is not None:
945
954
  result["object_detection_markup"] = from_union([lambda x: to_class(ObjectDetectionMarkup, x), from_none], self.object_detection_markup)
946
955
  if self.ocr_markup is not None:
947
- result["ocr_markup"] = from_union([lambda x: to_class(OcrMarkup, x), from_none], self.ocr_markup)
956
+ result["ocr_markup"] = from_union([lambda x: to_class(OCRMarkup, x), from_none], self.ocr_markup)
948
957
  if self.segmentation_markup is not None:
949
958
  result["segmentation_markup"] = from_union([lambda x: to_class(SegmentationMarkup, x), from_none], self.segmentation_markup)
950
959
  return result
@@ -952,6 +961,7 @@ class Source:
952
961
 
953
962
  class AnnotationComparerRequest:
954
963
  created_by_user_id: UUID
964
+ hasura_url: str
955
965
  id: UUID
956
966
  image: Image
957
967
  network_experiment: NetworkExperiment
@@ -961,8 +971,9 @@ class AnnotationComparerRequest:
961
971
  user1_id: Optional[UUID]
962
972
  user2_id: Optional[UUID]
963
973
 
964
- def __init__(self, created_by_user_id: UUID, id: UUID, image: Image, network_experiment: NetworkExperiment, owned_by_group_id: UUID, source: Source, target: Source, user1_id: Optional[UUID], user2_id: Optional[UUID]) -> None:
974
+ def __init__(self, created_by_user_id: UUID, hasura_url: str, id: UUID, image: Image, network_experiment: NetworkExperiment, owned_by_group_id: UUID, source: Source, target: Source, user1_id: Optional[UUID], user2_id: Optional[UUID]) -> None:
965
975
  self.created_by_user_id = created_by_user_id
976
+ self.hasura_url = hasura_url
966
977
  self.id = id
967
978
  self.image = image
968
979
  self.network_experiment = network_experiment
@@ -976,6 +987,7 @@ class AnnotationComparerRequest:
976
987
  def from_dict(obj: Any) -> 'AnnotationComparerRequest':
977
988
  assert isinstance(obj, dict)
978
989
  created_by_user_id = UUID(obj.get("created_by_user_id"))
990
+ hasura_url = from_str(obj.get("hasura_url"))
979
991
  id = UUID(obj.get("id"))
980
992
  image = Image.from_dict(obj.get("image"))
981
993
  network_experiment = NetworkExperiment.from_dict(obj.get("network_experiment"))
@@ -984,11 +996,12 @@ class AnnotationComparerRequest:
984
996
  target = Source.from_dict(obj.get("target"))
985
997
  user1_id = from_union([from_none, lambda x: UUID(x)], obj.get("user1_id"))
986
998
  user2_id = from_union([from_none, lambda x: UUID(x)], obj.get("user2_id"))
987
- return AnnotationComparerRequest(created_by_user_id, id, image, network_experiment, owned_by_group_id, source, target, user1_id, user2_id)
999
+ return AnnotationComparerRequest(created_by_user_id, hasura_url, id, image, network_experiment, owned_by_group_id, source, target, user1_id, user2_id)
988
1000
 
989
1001
  def to_dict(self) -> dict:
990
1002
  result: dict = {}
991
1003
  result["created_by_user_id"] = str(self.created_by_user_id)
1004
+ result["hasura_url"] = from_str(self.hasura_url)
992
1005
  result["id"] = str(self.id)
993
1006
  result["image"] = to_class(Image, self.image)
994
1007
  result["network_experiment"] = to_class(NetworkExperiment, self.network_experiment)
@@ -1,4 +1,4 @@
1
- from typing import Any, List, Optional, TypeVar, Callable, Type, cast
1
+ from typing import Optional, Any, List, TypeVar, Callable, Type, cast
2
2
  from uuid import UUID
3
3
 
4
4
 
@@ -10,6 +10,25 @@ def from_float(x: Any) -> float:
10
10
  return float(x)
11
11
 
12
12
 
13
+ def from_none(x: Any) -> Any:
14
+ assert x is None
15
+ return x
16
+
17
+
18
+ def from_union(fs, x):
19
+ for f in fs:
20
+ try:
21
+ return f(x)
22
+ except:
23
+ pass
24
+ assert False
25
+
26
+
27
+ def from_bool(x: Any) -> bool:
28
+ assert isinstance(x, bool)
29
+ return x
30
+
31
+
13
32
  def to_float(x: Any) -> float:
14
33
  assert isinstance(x, (int, float))
15
34
  return x
@@ -30,50 +49,52 @@ def to_class(c: Type[T], x: Any) -> dict:
30
49
  return cast(Any, x).to_dict()
31
50
 
32
51
 
33
- def from_none(x: Any) -> Any:
34
- assert x is None
35
- return x
36
-
37
-
38
- def from_union(fs, x):
39
- for f in fs:
40
- try:
41
- return f(x)
42
- except:
43
- pass
44
- assert False
45
-
46
-
47
52
  def from_str(x: Any) -> str:
48
53
  assert isinstance(x, str)
49
54
  return x
50
55
 
51
56
 
52
57
  class BoundingBox:
58
+ """A bounding box with optional rotation information"""
59
+
60
+ angle: Optional[float]
61
+ """Optional rotation angle"""
62
+
53
63
  bottom_right_x: float
54
64
  bottom_right_y: float
65
+ full_orientation: Optional[bool]
66
+ """Optional full orientation flag"""
67
+
55
68
  top_left_x: float
56
69
  top_left_y: float
57
70
 
58
- def __init__(self, bottom_right_x: float, bottom_right_y: float, top_left_x: float, top_left_y: float) -> None:
71
+ def __init__(self, angle: Optional[float], bottom_right_x: float, bottom_right_y: float, full_orientation: Optional[bool], top_left_x: float, top_left_y: float) -> None:
72
+ self.angle = angle
59
73
  self.bottom_right_x = bottom_right_x
60
74
  self.bottom_right_y = bottom_right_y
75
+ self.full_orientation = full_orientation
61
76
  self.top_left_x = top_left_x
62
77
  self.top_left_y = top_left_y
63
78
 
64
79
  @staticmethod
65
80
  def from_dict(obj: Any) -> 'BoundingBox':
66
81
  assert isinstance(obj, dict)
82
+ angle = from_union([from_float, from_none], obj.get("angle"))
67
83
  bottom_right_x = from_float(obj.get("bottom_right_x"))
68
84
  bottom_right_y = from_float(obj.get("bottom_right_y"))
85
+ full_orientation = from_union([from_bool, from_none], obj.get("full_orientation"))
69
86
  top_left_x = from_float(obj.get("top_left_x"))
70
87
  top_left_y = from_float(obj.get("top_left_y"))
71
- return BoundingBox(bottom_right_x, bottom_right_y, top_left_x, top_left_y)
88
+ return BoundingBox(angle, bottom_right_x, bottom_right_y, full_orientation, top_left_x, top_left_y)
72
89
 
73
90
  def to_dict(self) -> dict:
74
91
  result: dict = {}
92
+ if self.angle is not None:
93
+ result["angle"] = from_union([to_float, from_none], self.angle)
75
94
  result["bottom_right_x"] = to_float(self.bottom_right_x)
76
95
  result["bottom_right_y"] = to_float(self.bottom_right_y)
96
+ if self.full_orientation is not None:
97
+ result["full_orientation"] = from_union([from_bool, from_none], self.full_orientation)
77
98
  result["top_left_x"] = to_float(self.top_left_x)
78
99
  result["top_left_y"] = to_float(self.top_left_y)
79
100
  return result
@@ -101,7 +122,7 @@ class Point:
101
122
  return result
102
123
 
103
124
 
104
- class OcrMarkupSchema:
125
+ class GeometrySchema:
105
126
  """A single closed loop (ring) of a polygon, defining either an outer boundary or a hole."""
106
127
 
107
128
  hierarchy: int
@@ -116,11 +137,11 @@ class OcrMarkupSchema:
116
137
  self.points = points
117
138
 
118
139
  @staticmethod
119
- def from_dict(obj: Any) -> 'OcrMarkupSchema':
140
+ def from_dict(obj: Any) -> 'GeometrySchema':
120
141
  assert isinstance(obj, dict)
121
142
  hierarchy = from_int(obj.get("hierarchy"))
122
143
  points = from_list(Point.from_dict, obj.get("points"))
123
- return OcrMarkupSchema(hierarchy, points)
144
+ return GeometrySchema(hierarchy, points)
124
145
 
125
146
  def to_dict(self) -> dict:
126
147
  result: dict = {}
@@ -132,23 +153,23 @@ class OcrMarkupSchema:
132
153
  class Polygon:
133
154
  """A polygon defined by one or more rings, allowing for holes and nested structures."""
134
155
 
135
- rings: List[OcrMarkupSchema]
156
+ rings: List[GeometrySchema]
136
157
  """Array of polygon rings. The hierarchy field within each ring determines nesting and
137
158
  fill/hole status.
138
159
  """
139
160
 
140
- def __init__(self, rings: List[OcrMarkupSchema]) -> None:
161
+ def __init__(self, rings: List[GeometrySchema]) -> None:
141
162
  self.rings = rings
142
163
 
143
164
  @staticmethod
144
165
  def from_dict(obj: Any) -> 'Polygon':
145
166
  assert isinstance(obj, dict)
146
- rings = from_list(OcrMarkupSchema.from_dict, obj.get("rings"))
167
+ rings = from_list(GeometrySchema.from_dict, obj.get("rings"))
147
168
  return Polygon(rings)
148
169
 
149
170
  def to_dict(self) -> dict:
150
171
  result: dict = {}
151
- result["rings"] = from_list(lambda x: to_class(OcrMarkupSchema, x), self.rings)
172
+ result["rings"] = from_list(lambda x: to_class(GeometrySchema, x), self.rings)
152
173
  return result
153
174
 
154
175
 
@@ -157,8 +178,6 @@ class Annotation:
157
178
  id: UUID
158
179
  label_id: UUID
159
180
  polygon: Optional[Polygon]
160
- """A polygon defined by one or more rings, allowing for holes and nested structures."""
161
-
162
181
  text: str
163
182
 
164
183
  def __init__(self, bounding_box: Optional[BoundingBox], id: UUID, label_id: UUID, polygon: Optional[Polygon], text: str) -> None:
@@ -458,6 +458,7 @@ class Object:
458
458
 
459
459
  class OcrPredictionRequest:
460
460
  created_by_user_id: UUID
461
+ hasura_url: str
461
462
  id: UUID
462
463
  image: Image
463
464
  network_experiment: NetworkExperiment
@@ -465,8 +466,9 @@ class OcrPredictionRequest:
465
466
  owned_by_group_id: UUID
466
467
  prediction_priority: int
467
468
 
468
- def __init__(self, created_by_user_id: UUID, id: UUID, image: Image, network_experiment: NetworkExperiment, objects: List[Object], owned_by_group_id: UUID, prediction_priority: int) -> None:
469
+ def __init__(self, created_by_user_id: UUID, hasura_url: str, id: UUID, image: Image, network_experiment: NetworkExperiment, objects: List[Object], owned_by_group_id: UUID, prediction_priority: int) -> None:
469
470
  self.created_by_user_id = created_by_user_id
471
+ self.hasura_url = hasura_url
470
472
  self.id = id
471
473
  self.image = image
472
474
  self.network_experiment = network_experiment
@@ -478,17 +480,19 @@ class OcrPredictionRequest:
478
480
  def from_dict(obj: Any) -> 'OcrPredictionRequest':
479
481
  assert isinstance(obj, dict)
480
482
  created_by_user_id = UUID(obj.get("created_by_user_id"))
483
+ hasura_url = from_str(obj.get("hasura_url"))
481
484
  id = UUID(obj.get("id"))
482
485
  image = Image.from_dict(obj.get("image"))
483
486
  network_experiment = NetworkExperiment.from_dict(obj.get("network_experiment"))
484
487
  objects = from_list(Object.from_dict, obj.get("objects"))
485
488
  owned_by_group_id = UUID(obj.get("owned_by_group_id"))
486
489
  prediction_priority = from_int(obj.get("prediction_priority"))
487
- return OcrPredictionRequest(created_by_user_id, id, image, network_experiment, objects, owned_by_group_id, prediction_priority)
490
+ return OcrPredictionRequest(created_by_user_id, hasura_url, id, image, network_experiment, objects, owned_by_group_id, prediction_priority)
488
491
 
489
492
  def to_dict(self) -> dict:
490
493
  result: dict = {}
491
494
  result["created_by_user_id"] = str(self.created_by_user_id)
495
+ result["hasura_url"] = from_str(self.hasura_url)
492
496
  result["id"] = str(self.id)
493
497
  result["image"] = to_class(Image, self.image)
494
498
  result["network_experiment"] = to_class(NetworkExperiment, self.network_experiment)
@@ -1,8 +1,10 @@
1
1
  from uuid import UUID
2
- from typing import Any, Dict, List, TypeVar, Callable, Type, cast
2
+ from typing import Any, Dict, List, Optional, TypeVar, Callable, Type, cast
3
+ from enum import Enum
3
4
 
4
5
 
5
6
  T = TypeVar("T")
7
+ EnumT = TypeVar("EnumT", bound=Enum)
6
8
 
7
9
 
8
10
  def from_int(x: Any) -> int:
@@ -20,6 +22,11 @@ def from_bool(x: Any) -> bool:
20
22
  return x
21
23
 
22
24
 
25
+ def from_str(x: Any) -> str:
26
+ assert isinstance(x, str)
27
+ return x
28
+
29
+
23
30
  def to_class(c: Type[T], x: Any) -> dict:
24
31
  assert isinstance(x, c)
25
32
  return cast(Any, x).to_dict()
@@ -30,11 +37,35 @@ def from_list(f: Callable[[Any], T], x: Any) -> List[T]:
30
37
  return [f(y) for y in x]
31
38
 
32
39
 
33
- def from_str(x: Any) -> str:
34
- assert isinstance(x, str)
40
+ def from_none(x: Any) -> Any:
41
+ assert x is None
42
+ return x
43
+
44
+
45
+ def from_union(fs, x):
46
+ for f in fs:
47
+ try:
48
+ return f(x)
49
+ except:
50
+ pass
51
+ assert False
52
+
53
+
54
+ def from_float(x: Any) -> float:
55
+ assert isinstance(x, (float, int)) and not isinstance(x, bool)
56
+ return float(x)
57
+
58
+
59
+ def to_float(x: Any) -> float:
60
+ assert isinstance(x, (int, float))
35
61
  return x
36
62
 
37
63
 
64
+ def to_enum(c: Type[EnumT], x: Any) -> EnumT:
65
+ assert isinstance(x, c)
66
+ return x.value
67
+
68
+
38
69
  class Image:
39
70
  blob_id: UUID
40
71
  height: int
@@ -65,7 +96,7 @@ class Image:
65
96
  return result
66
97
 
67
98
 
68
- class ClassLabel:
99
+ class ClassLabelElement:
69
100
  id: UUID
70
101
  idx: int
71
102
 
@@ -74,11 +105,11 @@ class ClassLabel:
74
105
  self.idx = idx
75
106
 
76
107
  @staticmethod
77
- def from_dict(obj: Any) -> 'ClassLabel':
108
+ def from_dict(obj: Any) -> 'ClassLabelElement':
78
109
  assert isinstance(obj, dict)
79
110
  id = UUID(obj.get("id"))
80
111
  idx = from_int(obj.get("idx"))
81
- return ClassLabel(id, idx)
112
+ return ClassLabelElement(id, idx)
82
113
 
83
114
  def to_dict(self) -> dict:
84
115
  result: dict = {}
@@ -109,29 +140,59 @@ class Config:
109
140
  return result
110
141
 
111
142
 
112
- class Onnx:
113
- blob_id: UUID
114
- owned_by_group_id: UUID
143
+ class OcrCharacterRestrictionPreset:
144
+ characters: str
145
+ value: str
115
146
 
116
- def __init__(self, blob_id: UUID, owned_by_group_id: UUID) -> None:
117
- self.blob_id = blob_id
118
- self.owned_by_group_id = owned_by_group_id
147
+ def __init__(self, characters: str, value: str) -> None:
148
+ self.characters = characters
149
+ self.value = value
119
150
 
120
151
  @staticmethod
121
- def from_dict(obj: Any) -> 'Onnx':
152
+ def from_dict(obj: Any) -> 'OcrCharacterRestrictionPreset':
122
153
  assert isinstance(obj, dict)
123
- blob_id = UUID(obj.get("blob_id"))
124
- owned_by_group_id = UUID(obj.get("owned_by_group_id"))
125
- return Onnx(blob_id, owned_by_group_id)
154
+ characters = from_str(obj.get("characters"))
155
+ value = from_str(obj.get("value"))
156
+ return OcrCharacterRestrictionPreset(characters, value)
126
157
 
127
158
  def to_dict(self) -> dict:
128
159
  result: dict = {}
129
- result["blob_id"] = str(self.blob_id)
130
- result["owned_by_group_id"] = str(self.owned_by_group_id)
160
+ result["characters"] = from_str(self.characters)
161
+ result["value"] = from_str(self.value)
162
+ return result
163
+
164
+
165
+ class OcrCharacterRestrictionElement:
166
+ allowed_characters: str
167
+ index: int
168
+ number_of_characters: int
169
+ ocr_character_restriction_preset: OcrCharacterRestrictionPreset
170
+
171
+ def __init__(self, allowed_characters: str, index: int, number_of_characters: int, ocr_character_restriction_preset: OcrCharacterRestrictionPreset) -> None:
172
+ self.allowed_characters = allowed_characters
173
+ self.index = index
174
+ self.number_of_characters = number_of_characters
175
+ self.ocr_character_restriction_preset = ocr_character_restriction_preset
176
+
177
+ @staticmethod
178
+ def from_dict(obj: Any) -> 'OcrCharacterRestrictionElement':
179
+ assert isinstance(obj, dict)
180
+ allowed_characters = from_str(obj.get("allowed_characters"))
181
+ index = from_int(obj.get("index"))
182
+ number_of_characters = from_int(obj.get("number_of_characters"))
183
+ ocr_character_restriction_preset = OcrCharacterRestrictionPreset.from_dict(obj.get("ocr_character_restriction_preset"))
184
+ return OcrCharacterRestrictionElement(allowed_characters, index, number_of_characters, ocr_character_restriction_preset)
185
+
186
+ def to_dict(self) -> dict:
187
+ result: dict = {}
188
+ result["allowed_characters"] = from_str(self.allowed_characters)
189
+ result["index"] = from_int(self.index)
190
+ result["number_of_characters"] = from_int(self.number_of_characters)
191
+ result["ocr_character_restriction_preset"] = to_class(OcrCharacterRestrictionPreset, self.ocr_character_restriction_preset)
131
192
  return result
132
193
 
133
194
 
134
- class Pytorch:
195
+ class Onnx:
135
196
  blob_id: UUID
136
197
  owned_by_group_id: UUID
137
198
 
@@ -140,11 +201,11 @@ class Pytorch:
140
201
  self.owned_by_group_id = owned_by_group_id
141
202
 
142
203
  @staticmethod
143
- def from_dict(obj: Any) -> 'Pytorch':
204
+ def from_dict(obj: Any) -> 'Onnx':
144
205
  assert isinstance(obj, dict)
145
206
  blob_id = UUID(obj.get("blob_id"))
146
207
  owned_by_group_id = UUID(obj.get("owned_by_group_id"))
147
- return Pytorch(blob_id, owned_by_group_id)
208
+ return Onnx(blob_id, owned_by_group_id)
148
209
 
149
210
  def to_dict(self) -> dict:
150
211
  result: dict = {}
@@ -155,9 +216,9 @@ class Pytorch:
155
216
 
156
217
  class Snapshot:
157
218
  onnx: Onnx
158
- pytorch: Pytorch
219
+ pytorch: Onnx
159
220
 
160
- def __init__(self, onnx: Onnx, pytorch: Pytorch) -> None:
221
+ def __init__(self, onnx: Onnx, pytorch: Onnx) -> None:
161
222
  self.onnx = onnx
162
223
  self.pytorch = pytorch
163
224
 
@@ -165,89 +226,288 @@ class Snapshot:
165
226
  def from_dict(obj: Any) -> 'Snapshot':
166
227
  assert isinstance(obj, dict)
167
228
  onnx = Onnx.from_dict(obj.get("onnx"))
168
- pytorch = Pytorch.from_dict(obj.get("pytorch"))
229
+ pytorch = Onnx.from_dict(obj.get("pytorch"))
169
230
  return Snapshot(onnx, pytorch)
170
231
 
171
232
  def to_dict(self) -> dict:
172
233
  result: dict = {}
173
234
  result["onnx"] = to_class(Onnx, self.onnx)
174
- result["pytorch"] = to_class(Pytorch, self.pytorch)
235
+ result["pytorch"] = to_class(Onnx, self.pytorch)
175
236
  return result
176
237
 
177
238
 
178
239
  class NetworkExperiment:
179
- class_labels: List[ClassLabel]
240
+ class_labels: List[ClassLabelElement]
180
241
  config: Config
181
242
  flavor: str
182
243
  network_typename: str
244
+ ocr_character_restrictions: Optional[List[OcrCharacterRestrictionElement]]
245
+ """Only present for OCR prediction requests"""
246
+
183
247
  snapshot: Snapshot
184
248
 
185
- def __init__(self, class_labels: List[ClassLabel], config: Config, flavor: str, network_typename: str, snapshot: Snapshot) -> None:
249
+ def __init__(self, class_labels: List[ClassLabelElement], config: Config, flavor: str, network_typename: str, ocr_character_restrictions: Optional[List[OcrCharacterRestrictionElement]], snapshot: Snapshot) -> None:
186
250
  self.class_labels = class_labels
187
251
  self.config = config
188
252
  self.flavor = flavor
189
253
  self.network_typename = network_typename
254
+ self.ocr_character_restrictions = ocr_character_restrictions
190
255
  self.snapshot = snapshot
191
256
 
192
257
  @staticmethod
193
258
  def from_dict(obj: Any) -> 'NetworkExperiment':
194
259
  assert isinstance(obj, dict)
195
- class_labels = from_list(ClassLabel.from_dict, obj.get("class_labels"))
260
+ class_labels = from_list(ClassLabelElement.from_dict, obj.get("class_labels"))
196
261
  config = Config.from_dict(obj.get("config"))
197
262
  flavor = from_str(obj.get("flavor"))
198
263
  network_typename = from_str(obj.get("network_typename"))
264
+ ocr_character_restrictions = from_union([lambda x: from_list(OcrCharacterRestrictionElement.from_dict, x), from_none], obj.get("ocr_character_restrictions"))
199
265
  snapshot = Snapshot.from_dict(obj.get("snapshot"))
200
- return NetworkExperiment(class_labels, config, flavor, network_typename, snapshot)
266
+ return NetworkExperiment(class_labels, config, flavor, network_typename, ocr_character_restrictions, snapshot)
201
267
 
202
268
  def to_dict(self) -> dict:
203
269
  result: dict = {}
204
- result["class_labels"] = from_list(lambda x: to_class(ClassLabel, x), self.class_labels)
270
+ result["class_labels"] = from_list(lambda x: to_class(ClassLabelElement, x), self.class_labels)
205
271
  result["config"] = to_class(Config, self.config)
206
272
  result["flavor"] = from_str(self.flavor)
207
273
  result["network_typename"] = from_str(self.network_typename)
274
+ if self.ocr_character_restrictions is not None:
275
+ result["ocr_character_restrictions"] = from_union([lambda x: from_list(lambda x: to_class(OcrCharacterRestrictionElement, x), x), from_none], self.ocr_character_restrictions)
208
276
  result["snapshot"] = to_class(Snapshot, self.snapshot)
209
277
  return result
210
278
 
211
279
 
280
+ class AnnotationType(Enum):
281
+ IGNORE = "IGNORE"
282
+ NEGATIVE = "NEGATIVE"
283
+ POSITIVE = "POSITIVE"
284
+ ROI = "ROI"
285
+
286
+
287
+ class BoundingBox:
288
+ """A bounding box with optional rotation information"""
289
+
290
+ angle: Optional[float]
291
+ """Optional rotation angle"""
292
+
293
+ bottom_right_x: float
294
+ bottom_right_y: float
295
+ full_orientation: Optional[bool]
296
+ """Optional full orientation flag"""
297
+
298
+ top_left_x: float
299
+ top_left_y: float
300
+
301
+ def __init__(self, angle: Optional[float], bottom_right_x: float, bottom_right_y: float, full_orientation: Optional[bool], top_left_x: float, top_left_y: float) -> None:
302
+ self.angle = angle
303
+ self.bottom_right_x = bottom_right_x
304
+ self.bottom_right_y = bottom_right_y
305
+ self.full_orientation = full_orientation
306
+ self.top_left_x = top_left_x
307
+ self.top_left_y = top_left_y
308
+
309
+ @staticmethod
310
+ def from_dict(obj: Any) -> 'BoundingBox':
311
+ assert isinstance(obj, dict)
312
+ angle = from_union([from_float, from_none], obj.get("angle"))
313
+ bottom_right_x = from_float(obj.get("bottom_right_x"))
314
+ bottom_right_y = from_float(obj.get("bottom_right_y"))
315
+ full_orientation = from_union([from_bool, from_none], obj.get("full_orientation"))
316
+ top_left_x = from_float(obj.get("top_left_x"))
317
+ top_left_y = from_float(obj.get("top_left_y"))
318
+ return BoundingBox(angle, bottom_right_x, bottom_right_y, full_orientation, top_left_x, top_left_y)
319
+
320
+ def to_dict(self) -> dict:
321
+ result: dict = {}
322
+ if self.angle is not None:
323
+ result["angle"] = from_union([to_float, from_none], self.angle)
324
+ result["bottom_right_x"] = to_float(self.bottom_right_x)
325
+ result["bottom_right_y"] = to_float(self.bottom_right_y)
326
+ if self.full_orientation is not None:
327
+ result["full_orientation"] = from_union([from_bool, from_none], self.full_orientation)
328
+ result["top_left_x"] = to_float(self.top_left_x)
329
+ result["top_left_y"] = to_float(self.top_left_y)
330
+ return result
331
+
332
+
333
+ class Point:
334
+ x: float
335
+ y: float
336
+
337
+ def __init__(self, x: float, y: float) -> None:
338
+ self.x = x
339
+ self.y = y
340
+
341
+ @staticmethod
342
+ def from_dict(obj: Any) -> 'Point':
343
+ assert isinstance(obj, dict)
344
+ x = from_float(obj.get("x"))
345
+ y = from_float(obj.get("y"))
346
+ return Point(x, y)
347
+
348
+ def to_dict(self) -> dict:
349
+ result: dict = {}
350
+ result["x"] = to_float(self.x)
351
+ result["y"] = to_float(self.y)
352
+ return result
353
+
354
+
355
+ class GeometrySchema:
356
+ """A single closed loop (ring) of a polygon, defining either an outer boundary or a hole."""
357
+
358
+ hierarchy: int
359
+ """Nesting level: 0=outer, 1=hole in level 0, 2=poly in level 1 hole, etc. Even levels are
360
+ filled areas, odd levels are holes.
361
+ """
362
+ points: List[Point]
363
+ """Vertices of the ring."""
364
+
365
+ def __init__(self, hierarchy: int, points: List[Point]) -> None:
366
+ self.hierarchy = hierarchy
367
+ self.points = points
368
+
369
+ @staticmethod
370
+ def from_dict(obj: Any) -> 'GeometrySchema':
371
+ assert isinstance(obj, dict)
372
+ hierarchy = from_int(obj.get("hierarchy"))
373
+ points = from_list(Point.from_dict, obj.get("points"))
374
+ return GeometrySchema(hierarchy, points)
375
+
376
+ def to_dict(self) -> dict:
377
+ result: dict = {}
378
+ result["hierarchy"] = from_int(self.hierarchy)
379
+ result["points"] = from_list(lambda x: to_class(Point, x), self.points)
380
+ return result
381
+
382
+
383
+ class Polygon:
384
+ """A polygon defined by one or more rings, allowing for holes and nested structures."""
385
+
386
+ rings: List[GeometrySchema]
387
+ """Array of polygon rings. The hierarchy field within each ring determines nesting and
388
+ fill/hole status.
389
+ """
390
+
391
+ def __init__(self, rings: List[GeometrySchema]) -> None:
392
+ self.rings = rings
393
+
394
+ @staticmethod
395
+ def from_dict(obj: Any) -> 'Polygon':
396
+ assert isinstance(obj, dict)
397
+ rings = from_list(GeometrySchema.from_dict, obj.get("rings"))
398
+ return Polygon(rings)
399
+
400
+ def to_dict(self) -> dict:
401
+ result: dict = {}
402
+ result["rings"] = from_list(lambda x: to_class(GeometrySchema, x), self.rings)
403
+ return result
404
+
405
+
406
+ class ObjectElement:
407
+ annotation_type: AnnotationType
408
+ average_width: float
409
+ bounding_box: Optional[BoundingBox]
410
+ id: UUID
411
+ label_id: UUID
412
+ polygon: Optional[Polygon]
413
+
414
+ def __init__(self, annotation_type: AnnotationType, average_width: float, bounding_box: Optional[BoundingBox], id: UUID, label_id: UUID, polygon: Optional[Polygon]) -> None:
415
+ self.annotation_type = annotation_type
416
+ self.average_width = average_width
417
+ self.bounding_box = bounding_box
418
+ self.id = id
419
+ self.label_id = label_id
420
+ self.polygon = polygon
421
+
422
+ @staticmethod
423
+ def from_dict(obj: Any) -> 'ObjectElement':
424
+ assert isinstance(obj, dict)
425
+ annotation_type = AnnotationType(obj.get("annotation_type"))
426
+ average_width = from_float(obj.get("average_width"))
427
+ bounding_box = from_union([BoundingBox.from_dict, from_none], obj.get("bounding_box"))
428
+ id = UUID(obj.get("id"))
429
+ label_id = UUID(obj.get("label_id"))
430
+ polygon = from_union([Polygon.from_dict, from_none], obj.get("polygon"))
431
+ return ObjectElement(annotation_type, average_width, bounding_box, id, label_id, polygon)
432
+
433
+ def to_dict(self) -> dict:
434
+ result: dict = {}
435
+ result["annotation_type"] = to_enum(AnnotationType, self.annotation_type)
436
+ result["average_width"] = to_float(self.average_width)
437
+ if self.bounding_box is not None:
438
+ result["bounding_box"] = from_union([lambda x: to_class(BoundingBox, x), from_none], self.bounding_box)
439
+ result["id"] = str(self.id)
440
+ result["label_id"] = str(self.label_id)
441
+ if self.polygon is not None:
442
+ result["polygon"] = from_union([lambda x: to_class(Polygon, x), from_none], self.polygon)
443
+ return result
444
+
445
+
446
+ class RequestType(Enum):
447
+ """Discriminator field to identify the type of prediction request"""
448
+
449
+ OCR = "ocr"
450
+ STANDARD = "standard"
451
+
452
+
212
453
  class PredictionRequest:
213
454
  created_by_user_id: UUID
455
+ hasura_url: str
214
456
  id: UUID
215
457
  image: Image
216
458
  network_experiment: NetworkExperiment
459
+ objects: Optional[List[ObjectElement]]
460
+ """Only present for OCR prediction requests"""
461
+
217
462
  owned_by_group_id: UUID
218
463
  prediction_priority: int
219
- request_classification_interpretation: bool
464
+ request_classification_interpretation: Optional[bool]
465
+ """Only present for standard prediction requests"""
466
+
467
+ request_type: RequestType
468
+ """Discriminator field to identify the type of prediction request"""
220
469
 
221
- def __init__(self, created_by_user_id: UUID, id: UUID, image: Image, network_experiment: NetworkExperiment, owned_by_group_id: UUID, prediction_priority: int, request_classification_interpretation: bool) -> None:
470
+ def __init__(self, created_by_user_id: UUID, hasura_url: str, id: UUID, image: Image, network_experiment: NetworkExperiment, objects: Optional[List[ObjectElement]], owned_by_group_id: UUID, prediction_priority: int, request_classification_interpretation: Optional[bool], request_type: RequestType) -> None:
222
471
  self.created_by_user_id = created_by_user_id
472
+ self.hasura_url = hasura_url
223
473
  self.id = id
224
474
  self.image = image
225
475
  self.network_experiment = network_experiment
476
+ self.objects = objects
226
477
  self.owned_by_group_id = owned_by_group_id
227
478
  self.prediction_priority = prediction_priority
228
479
  self.request_classification_interpretation = request_classification_interpretation
480
+ self.request_type = request_type
229
481
 
230
482
  @staticmethod
231
483
  def from_dict(obj: Any) -> 'PredictionRequest':
232
484
  assert isinstance(obj, dict)
233
485
  created_by_user_id = UUID(obj.get("created_by_user_id"))
486
+ hasura_url = from_str(obj.get("hasura_url"))
234
487
  id = UUID(obj.get("id"))
235
488
  image = Image.from_dict(obj.get("image"))
236
489
  network_experiment = NetworkExperiment.from_dict(obj.get("network_experiment"))
490
+ objects = from_union([lambda x: from_list(ObjectElement.from_dict, x), from_none], obj.get("objects"))
237
491
  owned_by_group_id = UUID(obj.get("owned_by_group_id"))
238
492
  prediction_priority = from_int(obj.get("prediction_priority"))
239
- request_classification_interpretation = from_bool(obj.get("request_classification_interpretation"))
240
- return PredictionRequest(created_by_user_id, id, image, network_experiment, owned_by_group_id, prediction_priority, request_classification_interpretation)
493
+ request_classification_interpretation = from_union([from_bool, from_none], obj.get("request_classification_interpretation"))
494
+ request_type = RequestType(obj.get("request_type"))
495
+ return PredictionRequest(created_by_user_id, hasura_url, id, image, network_experiment, objects, owned_by_group_id, prediction_priority, request_classification_interpretation, request_type)
241
496
 
242
497
  def to_dict(self) -> dict:
243
498
  result: dict = {}
244
499
  result["created_by_user_id"] = str(self.created_by_user_id)
500
+ result["hasura_url"] = from_str(self.hasura_url)
245
501
  result["id"] = str(self.id)
246
502
  result["image"] = to_class(Image, self.image)
247
503
  result["network_experiment"] = to_class(NetworkExperiment, self.network_experiment)
504
+ if self.objects is not None:
505
+ result["objects"] = from_union([lambda x: from_list(lambda x: to_class(ObjectElement, x), x), from_none], self.objects)
248
506
  result["owned_by_group_id"] = str(self.owned_by_group_id)
249
507
  result["prediction_priority"] = from_int(self.prediction_priority)
250
- result["request_classification_interpretation"] = from_bool(self.request_classification_interpretation)
508
+ if self.request_classification_interpretation is not None:
509
+ result["request_classification_interpretation"] = from_union([from_bool, from_none], self.request_classification_interpretation)
510
+ result["request_type"] = to_enum(RequestType, self.request_type)
251
511
  return result
252
512
 
253
513
 
@@ -281,7 +281,7 @@ class RingPoint:
281
281
  return result
282
282
 
283
283
 
284
- class SegmentationMarkupSchema:
284
+ class GeometrySchema:
285
285
  """A single closed loop (ring) of a polygon, defining either an outer boundary or a hole."""
286
286
 
287
287
  hierarchy: int
@@ -296,11 +296,11 @@ class SegmentationMarkupSchema:
296
296
  self.points = points
297
297
 
298
298
  @staticmethod
299
- def from_dict(obj: Any) -> 'SegmentationMarkupSchema':
299
+ def from_dict(obj: Any) -> 'GeometrySchema':
300
300
  assert isinstance(obj, dict)
301
301
  hierarchy = from_int(obj.get("hierarchy"))
302
302
  points = from_list(RingPoint.from_dict, obj.get("points"))
303
- return SegmentationMarkupSchema(hierarchy, points)
303
+ return GeometrySchema(hierarchy, points)
304
304
 
305
305
  def to_dict(self) -> dict:
306
306
  result: dict = {}
@@ -312,23 +312,23 @@ class SegmentationMarkupSchema:
312
312
  class PolygonAnnotation:
313
313
  """A polygon defined by one or more rings, allowing for holes and nested structures."""
314
314
 
315
- rings: List[SegmentationMarkupSchema]
315
+ rings: List[GeometrySchema]
316
316
  """Array of polygon rings. The hierarchy field within each ring determines nesting and
317
317
  fill/hole status.
318
318
  """
319
319
 
320
- def __init__(self, rings: List[SegmentationMarkupSchema]) -> None:
320
+ def __init__(self, rings: List[GeometrySchema]) -> None:
321
321
  self.rings = rings
322
322
 
323
323
  @staticmethod
324
324
  def from_dict(obj: Any) -> 'PolygonAnnotation':
325
325
  assert isinstance(obj, dict)
326
- rings = from_list(SegmentationMarkupSchema.from_dict, obj.get("rings"))
326
+ rings = from_list(GeometrySchema.from_dict, obj.get("rings"))
327
327
  return PolygonAnnotation(rings)
328
328
 
329
329
  def to_dict(self) -> dict:
330
330
  result: dict = {}
331
- result["rings"] = from_list(lambda x: to_class(SegmentationMarkupSchema, x), self.rings)
331
+ result["rings"] = from_list(lambda x: to_class(GeometrySchema, x), self.rings)
332
332
  return result
333
333
 
334
334
 
@@ -1,5 +1,5 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: denkproto
3
- Version: 1.0.92
3
+ Version: 1.0.94
4
4
  Requires-Python: >=3.10
5
5
  Requires-Dist: protobuf>=3.20.3
@@ -4,7 +4,7 @@ denkproto/DENKbuffer_pb2_grpc.py,sha256=-CPJPM4FOqwvwV8-f1iJlD18UD9juVIIHfdWUecu
4
4
  denkproto/ImageAnalysis_ProtobufMessages_pb2.py,sha256=iEY0j9ySGUThnqTdYD4uAVr9P3GiC5R02iK53zEOXUQ,21015
5
5
  denkproto/ImageAnalysis_ProtobufMessages_pb2.pyi,sha256=5LFtxrmYpJHizDDNGFTkL7-NQ_TkwqCSdq7vcv3lg-c,36243
6
6
  denkproto/ImageAnalysis_ProtobufMessages_pb2_grpc.py,sha256=l3agtDjgu4jay6P9TRnHhyhJ-7UdoII27ywhw3k84oo,911
7
- denkproto/__about__.py,sha256=LDgxmn6SiEEtSki6rD4s68kC-IpEPy_PKbB1lWh4NBQ,23
7
+ denkproto/__about__.py,sha256=XJ4McoZbsSAp6-Ys1kJXJvFJJb6hBmgr4fKsZJHt98k,23
8
8
  denkproto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  denkproto/denkcache_pb2.py,sha256=u0O26m7t4kfu4R1nx1ZcTst4n6pG32pMbhl2PGYivXE,7161
10
10
  denkproto/denkcache_pb2.pyi,sha256=8K_Ebyy4mgXrxqJenN8f8LXLvVKOiaZxhmGeYjFZVpY,6357
@@ -26,14 +26,14 @@ denkproto/validate_pb2.py,sha256=CuGAaHir9X9jniW3QsRKAESjYzoS2U6dLk_J55XmNqU,136
26
26
  denkproto/validate_pb2.pyi,sha256=fWsdVOR3NJDioCKkCKfxfl4qaEb5xqXXU_WlEbdQx6E,23077
27
27
  denkproto/validate_pb2_grpc.py,sha256=XvjuWEgJFJtH1E7HWm7SKpV10PMpOSbonKa2VPHpYy8,889
28
28
  denkproto/json/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- denkproto/json/annotation_comparer_request.py,sha256=-sWJvUj9EZ46ru78CFjllBws9KfZWSfG3zOj71Ip77A,39437
29
+ denkproto/json/annotation_comparer_request.py,sha256=tnoriGgQrth9KqgcrFe5lVql4aSiYhT4SROEYpSrsvY,40138
30
30
  denkproto/json/classification_markup.py,sha256=vTu0H7Cb3gU6UUUSg1vDTRlFUorZrjMbcp_yx6UssZA,2461
31
31
  denkproto/json/inference_graph_models_generated.py,sha256=GfsGk4bKbL8gyqOScA4x13P8sJrAmv3tEhNU36rbIDs,6313
32
32
  denkproto/json/object_detection_markup.py,sha256=T0hcFPq8F_galjDjRC9dbcRVwCSOYtu2jt9wpEeHlQs,4904
33
- denkproto/json/ocr_markup.py,sha256=KyOpth9evOekyhTJdZSnYyB9EIyoWbY33sqncb_jBgw,7069
34
- denkproto/json/ocr_prediction_request.py,sha256=t0DsoCKDxA0fSc77VGy_9bfS8H2cswa6gkWUsMR_F3A,17587
35
- denkproto/json/prediction_request.py,sha256=3_9dZq38hd-sLvOT6Jcb5s5WGa9TdEflQ6e0Mfj8mOg,8643
36
- denkproto/json/segmentation_markup.py,sha256=EvniRksF2KaQolm6zZ6UKSiGwnqc8wR2sHB1iv05RTE,19911
37
- denkproto-1.0.92.dist-info/METADATA,sha256=LgTO31cFeg3b9zbWAlzGEVi3n9THZCa7o5chRp1b-to,110
38
- denkproto-1.0.92.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
39
- denkproto-1.0.92.dist-info/RECORD,,
33
+ denkproto/json/ocr_markup.py,sha256=xZs321ZqOUPK-VzWhy3gKCdqt_EyKOs-6FbaJdSvEMQ,7824
34
+ denkproto/json/ocr_prediction_request.py,sha256=PXY_1hmPQcKpHHZyikMFG_S0HKiwbXtRv5oW5x1zHRM,17783
35
+ denkproto/json/prediction_request.py,sha256=IzpppHZzzSt1oTNTatrKApRy-tLBGenPoVArstnzkV4,18777
36
+ denkproto/json/segmentation_markup.py,sha256=ZU2qYuN1IkZDCjAjr0vEn6nRVdZv24EwRYlmrGEzeVg,19841
37
+ denkproto-1.0.94.dist-info/METADATA,sha256=OdDLtWhcIyL4i1KrDAmYq9ikpzEB5hviB_GWIV3nfFQ,110
38
+ denkproto-1.0.94.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
39
+ denkproto-1.0.94.dist-info/RECORD,,