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
@@ -133,6 +133,7 @@ class PersistentImageTTLCache(TTLCache):
133
133
  super().expire(time)
134
134
  deleted = set(existing_items.keys()).difference(self.__get_keys())
135
135
  if len(deleted) > 0:
136
+ sly.logger.debug("Deleting expired items")
136
137
  for key in deleted:
137
138
  try:
138
139
  silent_remove(existing_items[key])
@@ -239,18 +240,22 @@ class InferenceImageCache:
239
240
  self._cache.clear(False)
240
241
 
241
242
  def download_image(self, api: sly.Api, image_id: int, related: bool = False):
243
+ api.logger.debug(f"Download image #{image_id} to cache started")
242
244
  name = self._image_name(image_id)
243
245
  self._wait_if_in_queue(name, api.logger)
244
246
 
245
247
  if name not in self._cache:
248
+ api.logger.debug(f"Adding image #{image_id} to cache")
246
249
  self._load_queue.set(name, image_id)
247
- api.logger.debug(f"Add image #{image_id} to cache")
248
250
  if not related:
249
251
  img = api.image.download_np(image_id)
250
252
  else:
251
253
  img = api.pointcloud.download_related_image(image_id)
252
254
  self._add_to_cache(name, img)
255
+ api.logger.debug(f"Added image #{image_id} to cache")
253
256
  return img
257
+ else:
258
+ api.logger.debug(f"Image #{image_id} found in cache")
254
259
 
255
260
  api.logger.debug(f"Get image #{image_id} from cache")
256
261
  return self._cache.get_image(name)
@@ -771,7 +776,7 @@ class InferenceImageCache:
771
776
  def _download_many(
772
777
  self,
773
778
  indexes: List[Union[int, str]],
774
- name_cunstructor: Callable[[int], str],
779
+ name_constructor: Callable[[int], str],
775
780
  load_generator: Callable[
776
781
  [List[int]],
777
782
  Generator[Tuple[Union[int, str], np.ndarray], None, None],
@@ -785,24 +790,42 @@ class InferenceImageCache:
785
790
  all_frames = [None for _ in range(len(indexes))]
786
791
 
787
792
  def get_one_image(item):
788
- pos, index = item
793
+ pos, hash_or_id = item
789
794
  if video_id in self._cache:
790
- return pos, self.get_frame_from_cache(video_id, index)
791
- return pos, self._cache.get_image(name_cunstructor(index))
795
+ try:
796
+ frame = self.get_frame_from_cache(video_id, hash_or_id)
797
+ except Exception as e:
798
+ logger.error(
799
+ f"Error retrieving frame from cache: {repr(e)}. Frame will be re-downloaded",
800
+ exc_info=True,
801
+ )
802
+ ids_to_load.append(hash_or_id)
803
+ return pos, None
804
+ return pos, frame
805
+ try:
806
+ image = self._cache.get_image(name_constructor(hash_or_id))
807
+ except Exception as e:
808
+ logger.error(
809
+ f"Error retrieving image from cache: {repr(e)}. Image will be re-downloaded",
810
+ exc_info=True,
811
+ )
812
+ ids_to_load.append(hash_or_id)
813
+ return pos, None
814
+ return pos, image
792
815
 
793
816
  position = 0
794
817
  batch_size = 4
795
818
  for batch in batched(indexes, batch_size):
796
- indexes_to_load = []
819
+ ids_to_load = []
797
820
  items = []
798
821
  for hash_or_id in batch:
799
- name = name_cunstructor(hash_or_id)
822
+ name = name_constructor(hash_or_id)
800
823
  self._wait_if_in_queue(name, logger)
801
-
824
+ pos_by_name[name] = position
802
825
  if name not in self._cache and video_id not in self._cache:
803
826
  self._load_queue.set(name, hash_or_id)
804
- indexes_to_load.append(hash_or_id)
805
- pos_by_name[name] = position
827
+ ids_to_load.append(hash_or_id)
828
+
806
829
  elif return_images is True:
807
830
  items.append((position, hash_or_id))
808
831
  position += 1
@@ -810,14 +833,16 @@ class InferenceImageCache:
810
833
  if len(items) > 0:
811
834
  with ThreadPoolExecutor(min(64, len(items))) as executor:
812
835
  for pos, image in executor.map(get_one_image, items):
836
+ if image is None:
837
+ continue
813
838
  all_frames[pos] = image
814
839
  if progress_cb is not None:
815
840
  progress_cb()
816
841
 
817
842
  download_time = time.monotonic()
818
- if len(indexes_to_load) > 0:
819
- for id_or_hash, image in load_generator(indexes_to_load):
820
- name = name_cunstructor(id_or_hash)
843
+ if len(ids_to_load) > 0:
844
+ for id_or_hash, image in load_generator(ids_to_load):
845
+ name = name_constructor(id_or_hash)
821
846
  self._add_to_cache(name, image)
822
847
 
823
848
  if return_images:
@@ -828,13 +853,13 @@ class InferenceImageCache:
828
853
  download_time = time.monotonic() - download_time
829
854
 
830
855
  # logger.debug(f"All stored files: {sorted(os.listdir(self.tmp_path))}")
831
- if indexes_to_load:
832
- indexes_to_load = list(indexes_to_load)
856
+ if ids_to_load:
857
+ ids_to_load = list(ids_to_load)
833
858
  logger.debug(
834
- f"Images/Frames added to cache: {indexes_to_load} in {download_time:.2f} sec",
835
- extra={"indexes": indexes_to_load, "download_time": download_time},
859
+ f"Images/Frames added to cache: {ids_to_load} in {download_time:.2f} sec",
860
+ extra={"indexes": ids_to_load, "download_time": download_time},
836
861
  )
837
- found = set(batch).difference(indexes_to_load)
862
+ found = set(batch).difference(ids_to_load)
838
863
  if found:
839
864
  logger.debug(f"Images/Frames found in cache: {list(found)}")
840
865
 
@@ -23,10 +23,9 @@ from supervisely.app.widgets.experiment_selector.experiment_selector import (
23
23
  from supervisely.app.widgets.pretrained_models_selector.pretrained_models_selector import (
24
24
  PretrainedModelsSelector,
25
25
  )
26
- from supervisely.nn.experiments import get_experiment_infos
26
+ from supervisely.nn.experiments import ExperimentInfo, get_experiment_infos
27
27
  from supervisely.nn.inference.gui.serving_gui import ServingGUI
28
28
  from supervisely.nn.utils import ModelSource, RuntimeType, _get_model_name
29
- from supervisely.nn.experiments import ExperimentInfo
30
29
 
31
30
 
32
31
  class ServingGUITemplate(ServingGUI):
@@ -191,6 +190,10 @@ class ServingGUITemplate(ServingGUI):
191
190
  return model_meta.get("model_files", {})
192
191
  else:
193
192
  experiment_info = self.experiment_selector.get_selected_experiment_info()
193
+ if experiment_info is None:
194
+ raise ValueError(
195
+ "No experiment selected. Please select an experiment before serving."
196
+ )
194
197
  artifacts_dir = experiment_info.artifacts_dir
195
198
  model_files = experiment_info.model_files
196
199
  full_model_files = {