supervisely 6.73.452__py3-none-any.whl → 6.73.513__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.
Files changed (189) hide show
  1. supervisely/__init__.py +25 -1
  2. supervisely/annotation/annotation.py +8 -2
  3. supervisely/annotation/json_geometries_map.py +13 -12
  4. supervisely/api/annotation_api.py +6 -3
  5. supervisely/api/api.py +2 -0
  6. supervisely/api/app_api.py +10 -1
  7. supervisely/api/dataset_api.py +74 -12
  8. supervisely/api/entities_collection_api.py +10 -0
  9. supervisely/api/entity_annotation/figure_api.py +28 -0
  10. supervisely/api/entity_annotation/object_api.py +3 -3
  11. supervisely/api/entity_annotation/tag_api.py +63 -12
  12. supervisely/api/guides_api.py +210 -0
  13. supervisely/api/image_api.py +4 -0
  14. supervisely/api/labeling_job_api.py +83 -1
  15. supervisely/api/labeling_queue_api.py +33 -7
  16. supervisely/api/module_api.py +5 -0
  17. supervisely/api/project_api.py +71 -26
  18. supervisely/api/storage_api.py +3 -1
  19. supervisely/api/task_api.py +13 -2
  20. supervisely/api/team_api.py +4 -3
  21. supervisely/api/video/video_annotation_api.py +119 -3
  22. supervisely/api/video/video_api.py +65 -14
  23. supervisely/app/__init__.py +1 -1
  24. supervisely/app/content.py +23 -7
  25. supervisely/app/development/development.py +18 -2
  26. supervisely/app/fastapi/__init__.py +1 -0
  27. supervisely/app/fastapi/custom_static_files.py +1 -1
  28. supervisely/app/fastapi/multi_user.py +105 -0
  29. supervisely/app/fastapi/subapp.py +88 -42
  30. supervisely/app/fastapi/websocket.py +77 -9
  31. supervisely/app/singleton.py +21 -0
  32. supervisely/app/v1/app_service.py +18 -2
  33. supervisely/app/v1/constants.py +7 -1
  34. supervisely/app/widgets/__init__.py +6 -0
  35. supervisely/app/widgets/activity_feed/__init__.py +0 -0
  36. supervisely/app/widgets/activity_feed/activity_feed.py +239 -0
  37. supervisely/app/widgets/activity_feed/style.css +78 -0
  38. supervisely/app/widgets/activity_feed/template.html +22 -0
  39. supervisely/app/widgets/card/card.py +20 -0
  40. supervisely/app/widgets/classes_list_selector/classes_list_selector.py +121 -9
  41. supervisely/app/widgets/classes_list_selector/template.html +60 -93
  42. supervisely/app/widgets/classes_mapping/classes_mapping.py +13 -12
  43. supervisely/app/widgets/classes_table/classes_table.py +1 -0
  44. supervisely/app/widgets/deploy_model/deploy_model.py +56 -35
  45. supervisely/app/widgets/ecosystem_model_selector/ecosystem_model_selector.py +1 -1
  46. supervisely/app/widgets/experiment_selector/experiment_selector.py +8 -0
  47. supervisely/app/widgets/fast_table/fast_table.py +184 -60
  48. supervisely/app/widgets/fast_table/template.html +1 -1
  49. supervisely/app/widgets/heatmap/__init__.py +0 -0
  50. supervisely/app/widgets/heatmap/heatmap.py +564 -0
  51. supervisely/app/widgets/heatmap/script.js +533 -0
  52. supervisely/app/widgets/heatmap/style.css +233 -0
  53. supervisely/app/widgets/heatmap/template.html +21 -0
  54. supervisely/app/widgets/modal/__init__.py +0 -0
  55. supervisely/app/widgets/modal/modal.py +198 -0
  56. supervisely/app/widgets/modal/template.html +10 -0
  57. supervisely/app/widgets/object_class_view/object_class_view.py +3 -0
  58. supervisely/app/widgets/radio_tabs/radio_tabs.py +18 -2
  59. supervisely/app/widgets/radio_tabs/template.html +1 -0
  60. supervisely/app/widgets/select/select.py +6 -3
  61. supervisely/app/widgets/select_class/__init__.py +0 -0
  62. supervisely/app/widgets/select_class/select_class.py +363 -0
  63. supervisely/app/widgets/select_class/template.html +50 -0
  64. supervisely/app/widgets/select_cuda/select_cuda.py +22 -0
  65. supervisely/app/widgets/select_dataset_tree/select_dataset_tree.py +65 -7
  66. supervisely/app/widgets/select_tag/__init__.py +0 -0
  67. supervisely/app/widgets/select_tag/select_tag.py +352 -0
  68. supervisely/app/widgets/select_tag/template.html +64 -0
  69. supervisely/app/widgets/select_team/select_team.py +37 -4
  70. supervisely/app/widgets/select_team/template.html +4 -5
  71. supervisely/app/widgets/select_user/__init__.py +0 -0
  72. supervisely/app/widgets/select_user/select_user.py +270 -0
  73. supervisely/app/widgets/select_user/template.html +13 -0
  74. supervisely/app/widgets/select_workspace/select_workspace.py +59 -10
  75. supervisely/app/widgets/select_workspace/template.html +9 -12
  76. supervisely/app/widgets/table/table.py +68 -13
  77. supervisely/app/widgets/tree_select/tree_select.py +2 -0
  78. supervisely/aug/aug.py +6 -2
  79. supervisely/convert/base_converter.py +1 -0
  80. supervisely/convert/converter.py +2 -2
  81. supervisely/convert/image/image_converter.py +3 -1
  82. supervisely/convert/image/image_helper.py +48 -4
  83. supervisely/convert/image/label_studio/label_studio_converter.py +2 -0
  84. supervisely/convert/image/medical2d/medical2d_helper.py +2 -24
  85. supervisely/convert/image/multispectral/multispectral_converter.py +6 -0
  86. supervisely/convert/image/pascal_voc/pascal_voc_converter.py +8 -5
  87. supervisely/convert/image/pascal_voc/pascal_voc_helper.py +7 -0
  88. supervisely/convert/pointcloud/kitti_3d/kitti_3d_converter.py +33 -3
  89. supervisely/convert/pointcloud/kitti_3d/kitti_3d_helper.py +12 -5
  90. supervisely/convert/pointcloud/las/las_converter.py +13 -1
  91. supervisely/convert/pointcloud/las/las_helper.py +110 -11
  92. supervisely/convert/pointcloud/nuscenes_conv/nuscenes_converter.py +27 -16
  93. supervisely/convert/pointcloud/pointcloud_converter.py +91 -3
  94. supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_converter.py +58 -22
  95. supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py +21 -47
  96. supervisely/convert/video/__init__.py +1 -0
  97. supervisely/convert/video/multi_view/__init__.py +0 -0
  98. supervisely/convert/video/multi_view/multi_view.py +543 -0
  99. supervisely/convert/video/sly/sly_video_converter.py +359 -3
  100. supervisely/convert/video/video_converter.py +22 -2
  101. supervisely/convert/volume/dicom/dicom_converter.py +13 -5
  102. supervisely/convert/volume/dicom/dicom_helper.py +30 -18
  103. supervisely/geometry/constants.py +1 -0
  104. supervisely/geometry/geometry.py +4 -0
  105. supervisely/geometry/helpers.py +5 -1
  106. supervisely/geometry/oriented_bbox.py +676 -0
  107. supervisely/geometry/rectangle.py +2 -1
  108. supervisely/io/env.py +76 -1
  109. supervisely/io/fs.py +21 -0
  110. supervisely/nn/benchmark/base_evaluator.py +104 -11
  111. supervisely/nn/benchmark/instance_segmentation/evaluator.py +1 -8
  112. supervisely/nn/benchmark/object_detection/evaluator.py +20 -4
  113. supervisely/nn/benchmark/object_detection/vis_metrics/pr_curve.py +10 -5
  114. supervisely/nn/benchmark/semantic_segmentation/evaluator.py +34 -16
  115. supervisely/nn/benchmark/semantic_segmentation/vis_metrics/confusion_matrix.py +1 -1
  116. supervisely/nn/benchmark/semantic_segmentation/vis_metrics/frequently_confused.py +1 -1
  117. supervisely/nn/benchmark/semantic_segmentation/vis_metrics/overview.py +1 -1
  118. supervisely/nn/benchmark/visualization/evaluation_result.py +66 -4
  119. supervisely/nn/inference/cache.py +43 -18
  120. supervisely/nn/inference/gui/serving_gui_template.py +5 -2
  121. supervisely/nn/inference/inference.py +795 -199
  122. supervisely/nn/inference/inference_request.py +42 -9
  123. supervisely/nn/inference/predict_app/gui/classes_selector.py +83 -12
  124. supervisely/nn/inference/predict_app/gui/gui.py +676 -488
  125. supervisely/nn/inference/predict_app/gui/input_selector.py +205 -26
  126. supervisely/nn/inference/predict_app/gui/model_selector.py +2 -4
  127. supervisely/nn/inference/predict_app/gui/output_selector.py +46 -6
  128. supervisely/nn/inference/predict_app/gui/settings_selector.py +756 -59
  129. supervisely/nn/inference/predict_app/gui/tags_selector.py +1 -1
  130. supervisely/nn/inference/predict_app/gui/utils.py +236 -119
  131. supervisely/nn/inference/predict_app/predict_app.py +2 -2
  132. supervisely/nn/inference/session.py +43 -35
  133. supervisely/nn/inference/tracking/bbox_tracking.py +113 -34
  134. supervisely/nn/inference/tracking/tracker_interface.py +7 -2
  135. supervisely/nn/inference/uploader.py +139 -12
  136. supervisely/nn/live_training/__init__.py +7 -0
  137. supervisely/nn/live_training/api_server.py +111 -0
  138. supervisely/nn/live_training/artifacts_utils.py +243 -0
  139. supervisely/nn/live_training/checkpoint_utils.py +229 -0
  140. supervisely/nn/live_training/dynamic_sampler.py +44 -0
  141. supervisely/nn/live_training/helpers.py +14 -0
  142. supervisely/nn/live_training/incremental_dataset.py +146 -0
  143. supervisely/nn/live_training/live_training.py +497 -0
  144. supervisely/nn/live_training/loss_plateau_detector.py +111 -0
  145. supervisely/nn/live_training/request_queue.py +52 -0
  146. supervisely/nn/model/model_api.py +9 -0
  147. supervisely/nn/prediction_dto.py +12 -1
  148. supervisely/nn/tracker/base_tracker.py +11 -1
  149. supervisely/nn/tracker/botsort/botsort_config.yaml +0 -1
  150. supervisely/nn/tracker/botsort/tracker/mc_bot_sort.py +7 -4
  151. supervisely/nn/tracker/botsort_tracker.py +94 -65
  152. supervisely/nn/tracker/visualize.py +87 -90
  153. supervisely/nn/training/gui/classes_selector.py +16 -1
  154. supervisely/nn/training/train_app.py +28 -29
  155. supervisely/project/data_version.py +115 -51
  156. supervisely/project/download.py +1 -1
  157. supervisely/project/pointcloud_episode_project.py +37 -8
  158. supervisely/project/pointcloud_project.py +30 -2
  159. supervisely/project/project.py +14 -2
  160. supervisely/project/project_meta.py +27 -1
  161. supervisely/project/project_settings.py +32 -18
  162. supervisely/project/versioning/__init__.py +1 -0
  163. supervisely/project/versioning/common.py +20 -0
  164. supervisely/project/versioning/schema_fields.py +35 -0
  165. supervisely/project/versioning/video_schema.py +221 -0
  166. supervisely/project/versioning/volume_schema.py +87 -0
  167. supervisely/project/video_project.py +717 -15
  168. supervisely/project/volume_project.py +623 -5
  169. supervisely/template/experiment/experiment.html.jinja +4 -4
  170. supervisely/template/experiment/experiment_generator.py +14 -21
  171. supervisely/template/live_training/__init__.py +0 -0
  172. supervisely/template/live_training/header.html.jinja +96 -0
  173. supervisely/template/live_training/live_training.html.jinja +51 -0
  174. supervisely/template/live_training/live_training_generator.py +464 -0
  175. supervisely/template/live_training/sly-style.css +402 -0
  176. supervisely/template/live_training/template.html.jinja +18 -0
  177. supervisely/versions.json +28 -26
  178. supervisely/video/sampling.py +39 -20
  179. supervisely/video/video.py +40 -11
  180. supervisely/video_annotation/video_object.py +29 -4
  181. supervisely/volume/stl_converter.py +2 -0
  182. supervisely/worker_api/agent_rpc.py +24 -1
  183. supervisely/worker_api/rpc_servicer.py +31 -7
  184. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info}/METADATA +56 -39
  185. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info}/RECORD +189 -142
  186. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info}/WHEEL +1 -1
  187. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info}/entry_points.txt +0 -0
  188. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info/licenses}/LICENSE +0 -0
  189. {supervisely-6.73.452.dist-info → supervisely-6.73.513.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,221 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from typing import Any, Dict, List, Optional
6
+
7
+ from supervisely.project.versioning.schema_fields import VersionSchemaField
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class VideoSnapshotSchema:
12
+ schema_version: str
13
+
14
+ def datasets_schema(self, pa_module):
15
+ return pa_module.schema(
16
+ [
17
+ (VersionSchemaField.SRC_DATASET_ID, pa_module.int64()),
18
+ (VersionSchemaField.PARENT_SRC_DATASET_ID, pa_module.int64()),
19
+ (VersionSchemaField.NAME, pa_module.utf8()),
20
+ (VersionSchemaField.FULL_PATH, pa_module.utf8()),
21
+ (VersionSchemaField.DESCRIPTION, pa_module.utf8()),
22
+ (VersionSchemaField.CUSTOM_DATA, pa_module.utf8()),
23
+ ]
24
+ )
25
+
26
+ def videos_schema(self, pa_module):
27
+ return pa_module.schema(
28
+ [
29
+ (VersionSchemaField.SRC_VIDEO_ID, pa_module.int64()),
30
+ (VersionSchemaField.SRC_DATASET_ID, pa_module.int64()),
31
+ (VersionSchemaField.NAME, pa_module.utf8()),
32
+ (VersionSchemaField.HASH, pa_module.utf8()),
33
+ (VersionSchemaField.LINK, pa_module.utf8()),
34
+ (VersionSchemaField.FRAMES_COUNT, pa_module.int32()),
35
+ (VersionSchemaField.FRAME_WIDTH, pa_module.int32()),
36
+ (VersionSchemaField.FRAME_HEIGHT, pa_module.int32()),
37
+ (VersionSchemaField.FRAMES_TO_TIMECODES, pa_module.utf8()),
38
+ (VersionSchemaField.META, pa_module.utf8()),
39
+ (VersionSchemaField.CUSTOM_DATA, pa_module.utf8()),
40
+ (VersionSchemaField.CREATED_AT, pa_module.utf8()),
41
+ (VersionSchemaField.UPDATED_AT, pa_module.utf8()),
42
+ (VersionSchemaField.ANN_JSON, pa_module.utf8()),
43
+ ]
44
+ )
45
+
46
+ def objects_schema(self, pa_module):
47
+ return pa_module.schema(
48
+ [
49
+ (VersionSchemaField.SRC_OBJECT_ID, pa_module.int64()),
50
+ (VersionSchemaField.SRC_VIDEO_ID, pa_module.int64()),
51
+ (VersionSchemaField.CLASS_NAME, pa_module.utf8()),
52
+ (VersionSchemaField.KEY, pa_module.utf8()),
53
+ (VersionSchemaField.TAGS_JSON, pa_module.utf8()),
54
+ ]
55
+ )
56
+
57
+ def figures_schema(self, pa_module):
58
+ return pa_module.schema(
59
+ [
60
+ (VersionSchemaField.SRC_FIGURE_ID, pa_module.int64()),
61
+ (VersionSchemaField.SRC_OBJECT_ID, pa_module.int64()),
62
+ (VersionSchemaField.SRC_VIDEO_ID, pa_module.int64()),
63
+ (VersionSchemaField.FRAME_INDEX, pa_module.int32()),
64
+ (VersionSchemaField.GEOMETRY_TYPE, pa_module.utf8()),
65
+ (VersionSchemaField.GEOMETRY_JSON, pa_module.utf8()),
66
+ ]
67
+ )
68
+
69
+ def dataset_row(
70
+ self,
71
+ *,
72
+ src_dataset_id: int,
73
+ parent_src_dataset_id: Optional[int],
74
+ name: str,
75
+ full_path: str,
76
+ description: Optional[str],
77
+ custom_data: Optional[dict],
78
+ ) -> Dict[str, Any]:
79
+ return {
80
+ VersionSchemaField.SRC_DATASET_ID: src_dataset_id,
81
+ VersionSchemaField.PARENT_SRC_DATASET_ID: parent_src_dataset_id,
82
+ VersionSchemaField.NAME: name,
83
+ VersionSchemaField.FULL_PATH: full_path,
84
+ VersionSchemaField.DESCRIPTION: description,
85
+ VersionSchemaField.CUSTOM_DATA: (
86
+ json.dumps(custom_data) if isinstance(custom_data, dict) and len(custom_data) > 0 else None
87
+ ),
88
+ }
89
+
90
+ def video_row(
91
+ self,
92
+ *,
93
+ src_video_id: int,
94
+ src_dataset_id: int,
95
+ name: str,
96
+ hash: Optional[str],
97
+ link: Optional[str],
98
+ frames_count: Optional[int],
99
+ frame_width: Optional[int],
100
+ frame_height: Optional[int],
101
+ frames_to_timecodes: Optional[list],
102
+ meta: Optional[dict],
103
+ custom_data: Optional[dict],
104
+ created_at: Optional[str],
105
+ updated_at: Optional[str],
106
+ ann_json: dict,
107
+ ) -> Dict[str, Any]:
108
+ return {
109
+ VersionSchemaField.SRC_VIDEO_ID: src_video_id,
110
+ VersionSchemaField.SRC_DATASET_ID: src_dataset_id,
111
+ VersionSchemaField.NAME: name,
112
+ VersionSchemaField.HASH: hash,
113
+ VersionSchemaField.LINK: link,
114
+ VersionSchemaField.FRAMES_COUNT: frames_count,
115
+ VersionSchemaField.FRAME_WIDTH: frame_width,
116
+ VersionSchemaField.FRAME_HEIGHT: frame_height,
117
+ VersionSchemaField.FRAMES_TO_TIMECODES: (
118
+ json.dumps(frames_to_timecodes) if frames_to_timecodes else None
119
+ ),
120
+ VersionSchemaField.META: json.dumps(meta) if meta else None,
121
+ VersionSchemaField.CUSTOM_DATA: json.dumps(custom_data) if custom_data else None,
122
+ VersionSchemaField.CREATED_AT: created_at,
123
+ VersionSchemaField.UPDATED_AT: updated_at,
124
+ VersionSchemaField.ANN_JSON: json.dumps(ann_json),
125
+ }
126
+
127
+ def object_row(
128
+ self,
129
+ *,
130
+ src_object_id: int,
131
+ src_video_id: int,
132
+ class_name: str,
133
+ key_hex: str,
134
+ tags_json: Optional[List[Dict[str, Any]]],
135
+ ) -> Dict[str, Any]:
136
+ return {
137
+ VersionSchemaField.SRC_OBJECT_ID: src_object_id,
138
+ VersionSchemaField.SRC_VIDEO_ID: src_video_id,
139
+ VersionSchemaField.CLASS_NAME: class_name,
140
+ VersionSchemaField.KEY: key_hex,
141
+ VersionSchemaField.TAGS_JSON: json.dumps(tags_json) if tags_json is not None else None,
142
+ }
143
+
144
+ def figure_row(
145
+ self,
146
+ *,
147
+ src_figure_id: int,
148
+ src_object_id: int,
149
+ src_video_id: int,
150
+ frame_index: int,
151
+ geometry_type: str,
152
+ geometry_json: dict,
153
+ ) -> Dict[str, Any]:
154
+ return {
155
+ VersionSchemaField.SRC_FIGURE_ID: src_figure_id,
156
+ VersionSchemaField.SRC_OBJECT_ID: src_object_id,
157
+ VersionSchemaField.SRC_VIDEO_ID: src_video_id,
158
+ VersionSchemaField.FRAME_INDEX: frame_index,
159
+ VersionSchemaField.GEOMETRY_TYPE: geometry_type,
160
+ VersionSchemaField.GEOMETRY_JSON: json.dumps(geometry_json),
161
+ }
162
+
163
+ def dataset_row_from_ds_info(self, ds_info, *, full_path: str, custom_data: Optional[dict]):
164
+ return self.dataset_row(
165
+ src_dataset_id=ds_info.id,
166
+ parent_src_dataset_id=ds_info.parent_id,
167
+ name=ds_info.name,
168
+ full_path=full_path,
169
+ description=getattr(ds_info, "description", None),
170
+ custom_data=custom_data,
171
+ )
172
+
173
+ def video_row_from_video_info(self, video_info, *, src_dataset_id: int, ann_json: dict):
174
+ return self.video_row(
175
+ src_video_id=video_info.id,
176
+ src_dataset_id=src_dataset_id,
177
+ name=video_info.name,
178
+ hash=getattr(video_info, "hash", None),
179
+ link=getattr(video_info, "link", None),
180
+ frames_count=getattr(video_info, "frames_count", None),
181
+ frame_width=getattr(video_info, "frame_width", None),
182
+ frame_height=getattr(video_info, "frame_height", None),
183
+ frames_to_timecodes=getattr(video_info, "frames_to_timecodes", None),
184
+ meta=getattr(video_info, "meta", None),
185
+ custom_data=getattr(video_info, "custom_data", None),
186
+ created_at=getattr(video_info, "created_at", None),
187
+ updated_at=getattr(video_info, "updated_at", None),
188
+ ann_json=ann_json,
189
+ )
190
+
191
+ def object_row_from_object(self, obj, *, src_object_id: int, src_video_id: int) -> Dict[str, Any]:
192
+ return self.object_row(
193
+ src_object_id=src_object_id,
194
+ src_video_id=src_video_id,
195
+ class_name=obj.obj_class.name,
196
+ key_hex=obj.key().hex,
197
+ tags_json=obj.tags.to_json() if getattr(obj, "tags", None) is not None else None,
198
+ )
199
+
200
+ def figure_row_from_figure(
201
+ self,
202
+ fig,
203
+ *,
204
+ figure_row_idx: int,
205
+ src_object_id: int,
206
+ src_video_id: int,
207
+ frame_index: int,
208
+ ) -> Dict[str, Any]:
209
+ return self.figure_row(
210
+ src_figure_id=figure_row_idx + 1,
211
+ src_object_id=src_object_id,
212
+ src_video_id=src_video_id,
213
+ frame_index=frame_index,
214
+ geometry_type=fig.geometry.geometry_name(),
215
+ geometry_json=fig.geometry.to_json(),
216
+ )
217
+
218
+ _VIDEO_SCHEMAS: Dict[str, VideoSnapshotSchema] = {
219
+ "v2.0.0": VideoSnapshotSchema(schema_version="v2.0.0"),
220
+ }
221
+
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from typing import Any, Dict
6
+
7
+ from supervisely.api.api import Api
8
+ from supervisely.api.module_api import ApiField
9
+ from supervisely.geometry.mask_3d import Mask3D
10
+ from supervisely.project.data_version import VersionSchemaField
11
+ from supervisely.project.project_meta import ProjectMeta
12
+ from supervisely.project.versioning.schema_fields import VersionSchemaField
13
+ from supervisely.video_annotation.key_id_map import KeyIdMap
14
+ from supervisely.volume_annotation.volume_annotation import VolumeAnnotation
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class VolumeSnapshotSchema:
19
+ schema_version: str
20
+
21
+ def datasets_table_schema(self, pa_module):
22
+ return pa_module.schema(
23
+ [
24
+ (VersionSchemaField.SRC_DATASET_ID, pa_module.int64()),
25
+ (VersionSchemaField.JSON, pa_module.large_string()),
26
+ ]
27
+ )
28
+
29
+ def volumes_table_schema(self, pa_module):
30
+ return pa_module.schema(
31
+ [
32
+ (VersionSchemaField.SRC_VOLUME_ID, pa_module.int64()),
33
+ (VersionSchemaField.SRC_DATASET_ID, pa_module.int64()),
34
+ (VersionSchemaField.JSON, pa_module.large_string()),
35
+ ]
36
+ )
37
+
38
+ def annotations_table_schema(self, pa_module):
39
+ return pa_module.schema(
40
+ [
41
+ (VersionSchemaField.SRC_VOLUME_ID, pa_module.int64()),
42
+ (VersionSchemaField.ANNOTATION, pa_module.large_string()),
43
+ ]
44
+ )
45
+
46
+ def dataset_row_from_record(self, dataset_record: dict) -> Dict[str, Any]:
47
+ return {
48
+ VersionSchemaField.SRC_DATASET_ID: dataset_record.get(ApiField.ID),
49
+ VersionSchemaField.JSON: json.dumps(dataset_record, ensure_ascii=False),
50
+ }
51
+
52
+ def volume_row_from_record(self, volume_record: dict) -> Dict[str, Any]:
53
+ return {
54
+ VersionSchemaField.SRC_VOLUME_ID: volume_record.get(ApiField.ID),
55
+ VersionSchemaField.SRC_DATASET_ID: volume_record.get(ApiField.DATASET_ID),
56
+ VersionSchemaField.JSON: json.dumps(volume_record, ensure_ascii=False),
57
+ }
58
+
59
+ def annotation_row_from_dict(self, *, src_volume_id: int, annotation: dict) -> Dict[str, Any]:
60
+ return {
61
+ VersionSchemaField.SRC_VOLUME_ID: src_volume_id,
62
+ VersionSchemaField.ANNOTATION: json.dumps(annotation, ensure_ascii=False),
63
+ }
64
+
65
+ def annotation_dict_from_raw(
66
+ self,
67
+ *,
68
+ api: Api,
69
+ raw_ann_json: dict,
70
+ project_meta_obj: ProjectMeta,
71
+ key_id_map: KeyIdMap,
72
+ ) -> dict:
73
+ ann = VolumeAnnotation.from_json(raw_ann_json, project_meta_obj, key_id_map)
74
+ self._load_mask_geometries(api, ann, key_id_map)
75
+ return ann.to_json()
76
+
77
+ @staticmethod
78
+ def _load_mask_geometries(api: Api, ann: VolumeAnnotation, key_id_map: KeyIdMap) -> None:
79
+ for sf in ann.spatial_figures:
80
+ if sf.geometry.name() != Mask3D.name():
81
+ continue
82
+ api.volume.figure.load_sf_geometry(sf, key_id_map)
83
+
84
+
85
+ _VOLUME_SCHEMAS: Dict[str, VolumeSnapshotSchema] = {
86
+ "v2.0.0": VolumeSnapshotSchema(schema_version="v2.0.0"),
87
+ }