supervisely 6.73.456__py3-none-any.whl → 6.73.458__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 (41) hide show
  1. supervisely/__init__.py +24 -1
  2. supervisely/api/image_api.py +4 -0
  3. supervisely/api/video/video_annotation_api.py +4 -2
  4. supervisely/api/video/video_api.py +41 -1
  5. supervisely/app/v1/app_service.py +18 -2
  6. supervisely/app/v1/constants.py +7 -1
  7. supervisely/app/widgets/card/card.py +20 -0
  8. supervisely/app/widgets/deploy_model/deploy_model.py +56 -35
  9. supervisely/app/widgets/experiment_selector/experiment_selector.py +8 -0
  10. supervisely/app/widgets/fast_table/fast_table.py +45 -11
  11. supervisely/app/widgets/fast_table/template.html +1 -1
  12. supervisely/app/widgets/radio_tabs/radio_tabs.py +18 -2
  13. supervisely/app/widgets/radio_tabs/template.html +1 -0
  14. supervisely/app/widgets/select_dataset_tree/select_dataset_tree.py +63 -7
  15. supervisely/app/widgets/tree_select/tree_select.py +2 -0
  16. supervisely/nn/inference/cache.py +2 -2
  17. supervisely/nn/inference/inference.py +364 -73
  18. supervisely/nn/inference/inference_request.py +3 -2
  19. supervisely/nn/inference/predict_app/gui/classes_selector.py +81 -12
  20. supervisely/nn/inference/predict_app/gui/gui.py +676 -488
  21. supervisely/nn/inference/predict_app/gui/input_selector.py +178 -25
  22. supervisely/nn/inference/predict_app/gui/model_selector.py +2 -4
  23. supervisely/nn/inference/predict_app/gui/output_selector.py +46 -6
  24. supervisely/nn/inference/predict_app/gui/settings_selector.py +756 -59
  25. supervisely/nn/inference/predict_app/gui/tags_selector.py +1 -1
  26. supervisely/nn/inference/predict_app/gui/utils.py +236 -119
  27. supervisely/nn/inference/predict_app/predict_app.py +2 -2
  28. supervisely/nn/model/model_api.py +9 -0
  29. supervisely/nn/tracker/base_tracker.py +11 -1
  30. supervisely/nn/tracker/botsort/botsort_config.yaml +0 -1
  31. supervisely/nn/tracker/botsort_tracker.py +14 -7
  32. supervisely/nn/tracker/visualize.py +70 -72
  33. supervisely/video/video.py +15 -1
  34. supervisely/worker_api/agent_rpc.py +24 -1
  35. supervisely/worker_api/rpc_servicer.py +31 -7
  36. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/METADATA +3 -2
  37. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/RECORD +41 -41
  38. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/LICENSE +0 -0
  39. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/WHEEL +0 -0
  40. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/entry_points.txt +0 -0
  41. {supervisely-6.73.456.dist-info → supervisely-6.73.458.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,9 @@ from supervisely.api.api import Api
5
5
  from supervisely.app.widgets import Widget
6
6
  from supervisely.app.widgets.checkbox.checkbox import Checkbox
7
7
  from supervisely.app.widgets.container.container import Container
8
+ from supervisely.app.widgets.field.field import Field
8
9
  from supervisely.app.widgets.select.select import Select
10
+ from supervisely.app.widgets.select_project.select_project import SelectProject
9
11
  from supervisely.app.widgets.tree_select.tree_select import TreeSelect
10
12
  from supervisely.project.project_type import ProjectType
11
13
 
@@ -97,6 +99,7 @@ class SelectDatasetTree(Widget):
97
99
  widget_id: Union[str, None] = None,
98
100
  show_select_all_datasets_checkbox: bool = True,
99
101
  width: int = 193,
102
+ show_selectors_labels: bool = False,
100
103
  ):
101
104
  self._api = Api.from_env()
102
105
 
@@ -114,11 +117,23 @@ class SelectDatasetTree(Widget):
114
117
  # Using environment variables to set the default values if they are not provided.
115
118
  self._project_id = project_id or env.project_id(raise_not_found=False)
116
119
  self._dataset_id = default_id or env.dataset_id(raise_not_found=False)
120
+ if self._project_id:
121
+ project_info = self._api.project.get_info_by_id(self._project_id)
122
+ if (
123
+ project_info.type not in [pt.value for pt in allowed_project_types]
124
+ and allowed_project_types is not None
125
+ ):
126
+ self._project_id = None
117
127
 
118
128
  self._multiselect = multiselect
119
129
  self._compact = compact
120
130
  self._append_to_body = append_to_body
121
131
 
132
+ # User-defined callbacks
133
+ self._team_changed_callbacks = []
134
+ self._workspace_changed_callbacks = []
135
+ self._project_changed_callbacks = []
136
+
122
137
  # Extract values from Enum to match the .type property of the ProjectInfo object.
123
138
  self._project_types = None
124
139
  if allowed_project_types is not None:
@@ -160,6 +175,7 @@ class SelectDatasetTree(Widget):
160
175
  if show_select_all_datasets_checkbox:
161
176
  self._create_select_all_datasets_checkbox(select_all_datasets)
162
177
 
178
+ self._show_selectors_labels = show_selectors_labels
163
179
  # Group the selectors and the dataset selector into a container.
164
180
  self._content = Container(self._widgets)
165
181
  super().__init__(widget_id=widget_id, file_path=__file__)
@@ -310,6 +326,31 @@ class SelectDatasetTree(Widget):
310
326
  raise ValueError("This method can only be called when multiselect is enabled.")
311
327
  self._select_dataset.set_selected_by_id(dataset_ids)
312
328
 
329
+
330
+ def team_changed(self, func: Callable) -> Callable:
331
+ """Decorator to set the callback function for the team changed event.
332
+ """
333
+ if self._compact:
334
+ raise ValueError("callback 'team_changed' is not available in compact mode.")
335
+ self._team_changed_callbacks.append(func)
336
+ return func
337
+
338
+ def workspace_changed(self, func: Callable) -> Callable:
339
+ """Decorator to set the callback function for the workspace changed event.
340
+ """
341
+ if self._compact:
342
+ raise ValueError("callback 'workspace_changed' is not available in compact mode.")
343
+ self._workspace_changed_callbacks.append(func)
344
+ return func
345
+
346
+ def project_changed(self, func: Callable) -> Callable:
347
+ """Decorator to set the callback function for the project changed event.
348
+ """
349
+ if self._compact:
350
+ raise ValueError("callback 'project_changed' is not available in compact mode.")
351
+ self._project_changed_callbacks.append(func)
352
+ return func
353
+
313
354
  def value_changed(self, func: Callable) -> Callable:
314
355
  """Decorator to set the callback function for the value changed event.
315
356
 
@@ -353,13 +394,13 @@ class SelectDatasetTree(Widget):
353
394
 
354
395
  if checked:
355
396
  self._select_dataset.select_all()
356
- self._select_dataset.hide()
397
+ self._select_dataset_field.hide()
357
398
  else:
358
399
  self._select_dataset.clear_selected()
359
- self._select_dataset.show()
400
+ self._select_dataset_field.show()
360
401
 
361
402
  if select_all_datasets:
362
- self._select_dataset.hide()
403
+ self._select_dataset_field.hide()
363
404
  select_all_datasets_checkbox.check()
364
405
 
365
406
  self._widgets.append(select_all_datasets_checkbox)
@@ -390,9 +431,10 @@ class SelectDatasetTree(Widget):
390
431
  self._select_dataset.set_selected_by_id(self._dataset_id)
391
432
  if select_all_datasets:
392
433
  self._select_dataset.select_all()
434
+ self._select_dataset_field = Field(self._select_dataset, title="Dataset")
393
435
 
394
436
  # Adding the dataset selector to the list of widgets to be added to the container.
395
- self._widgets.append(self._select_dataset)
437
+ self._widgets.append(self._select_dataset_field)
396
438
 
397
439
  def _create_selectors(self, team_is_selectable: bool, workspace_is_selectable: bool):
398
440
  """Create the team, workspace, and project selectors.
@@ -412,6 +454,9 @@ class SelectDatasetTree(Widget):
412
454
  self._select_workspace.set(items=self._get_select_items(team_id=team_id))
413
455
  self._team_id = team_id
414
456
 
457
+ for callback in self._team_changed_callbacks:
458
+ callback(team_id)
459
+
415
460
  def workspace_selector_handler(workspace_id: int):
416
461
  """Handler function for the event when the workspace selector value changes.
417
462
 
@@ -421,6 +466,9 @@ class SelectDatasetTree(Widget):
421
466
  self._select_project.set(items=self._get_select_items(workspace_id=workspace_id))
422
467
  self._workspace_id = workspace_id
423
468
 
469
+ for callback in self._workspace_changed_callbacks:
470
+ callback(workspace_id)
471
+
424
472
  def project_selector_handler(project_id: int):
425
473
  """Handler function for the event when the project selector value changes.
426
474
 
@@ -435,7 +483,10 @@ class SelectDatasetTree(Widget):
435
483
  and self._select_all_datasets_checkbox.is_checked()
436
484
  ):
437
485
  self._select_dataset.select_all()
438
- self._select_dataset.hide()
486
+ self._select_dataset_field.hide()
487
+
488
+ for callback in self._project_changed_callbacks:
489
+ callback(project_id)
439
490
 
440
491
  self._select_team = Select(
441
492
  items=self._get_select_items(),
@@ -446,6 +497,7 @@ class SelectDatasetTree(Widget):
446
497
  self._select_team.set_value(self._team_id)
447
498
  if not team_is_selectable:
448
499
  self._select_team.disable()
500
+ self._select_team_field = Field(self._select_team, title="Team")
449
501
 
450
502
  self._select_workspace = Select(
451
503
  items=self._get_select_items(team_id=self._team_id),
@@ -456,6 +508,7 @@ class SelectDatasetTree(Widget):
456
508
  self._select_workspace.set_value(self._workspace_id)
457
509
  if not workspace_is_selectable:
458
510
  self._select_workspace.disable()
511
+ self._select_workspace_field = Field(self._select_workspace, title="Workspace")
459
512
 
460
513
  self._select_project = Select(
461
514
  items=self._get_select_items(workspace_id=self._workspace_id),
@@ -464,14 +517,17 @@ class SelectDatasetTree(Widget):
464
517
  width_px=self._width,
465
518
  )
466
519
  self._select_project.set_value(self._project_id)
520
+ self._select_project_field = Field(self._select_project, title="Project")
467
521
 
468
- # Register the event handlers.
522
+ # Register the event handlers._select_project
469
523
  self._select_team.value_changed(team_selector_handler)
470
524
  self._select_workspace.value_changed(workspace_selector_handler)
471
525
  self._select_project.value_changed(project_selector_handler)
472
526
 
473
527
  # Adding widgets to the list, so they can be added to the container.
474
- self._widgets.extend([self._select_team, self._select_workspace, self._select_project])
528
+ self._widgets.extend(
529
+ [self._select_team_field, self._select_workspace_field, self._select_project_field]
530
+ )
475
531
 
476
532
  def _get_select_items(self, **kwargs) -> List[Select.Item]:
477
533
  """Get the list of items for the team, workspace, and project selectors.
@@ -264,6 +264,8 @@ class TreeSelect(Widget):
264
264
 
265
265
  def _get_all_items(items: List[TreeSelect.Item]) -> List[TreeSelect.Item]:
266
266
  res = []
267
+ if not items:
268
+ return res
267
269
  for item in items:
268
270
  res.append(item)
269
271
  res.extend(_get_all_items(item.children))
@@ -810,11 +810,11 @@ class InferenceImageCache:
810
810
  for hash_or_id in batch:
811
811
  name = name_constructor(hash_or_id)
812
812
  self._wait_if_in_queue(name, logger)
813
-
813
+ pos_by_name[name] = position
814
814
  if name not in self._cache and video_id not in self._cache:
815
815
  self._load_queue.set(name, hash_or_id)
816
816
  ids_to_load.append(hash_or_id)
817
- pos_by_name[name] = position
817
+
818
818
  elif return_images is True:
819
819
  items.append((position, hash_or_id))
820
820
  position += 1