supervisely 6.73.374__py3-none-any.whl → 6.73.376__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 (31) hide show
  1. supervisely/api/nn/neural_network_api.py +1 -1
  2. supervisely/app/widgets/__init__.py +1 -0
  3. supervisely/app/widgets/agent_selector/agent_selector.py +6 -0
  4. supervisely/app/widgets/agent_selector/template.html +2 -0
  5. supervisely/app/widgets/button/button.py +28 -1
  6. supervisely/app/widgets/button/template.html +1 -1
  7. supervisely/app/widgets/card/card.py +4 -0
  8. supervisely/app/widgets/card/template.html +1 -1
  9. supervisely/app/widgets/classes_table/classes_table.py +3 -1
  10. supervisely/app/widgets/fast_table/fast_table.py +16 -0
  11. supervisely/app/widgets/fast_table/script.js +6 -2
  12. supervisely/app/widgets/fast_table/template.html +1 -0
  13. supervisely/app/widgets/random_splits_table/random_splits_table.py +2 -0
  14. supervisely/app/widgets/select_collection/__init__.py +0 -0
  15. supervisely/app/widgets/select_collection/select_collection.py +693 -0
  16. supervisely/app/widgets/select_collection/template.html +3 -0
  17. supervisely/app/widgets/train_val_splits/train_val_splits.py +111 -13
  18. supervisely/nn/training/gui/gui.py +28 -1
  19. supervisely/nn/training/gui/train_val_splits_selector.py +133 -30
  20. supervisely/nn/training/train_app.py +44 -16
  21. supervisely/project/pointcloud_episode_project.py +16 -0
  22. supervisely/project/pointcloud_project.py +16 -0
  23. supervisely/project/project.py +57 -0
  24. supervisely/project/video_project.py +16 -0
  25. supervisely/project/volume_project.py +16 -0
  26. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/METADATA +1 -1
  27. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/RECORD +31 -28
  28. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/LICENSE +0 -0
  29. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/WHEEL +0 -0
  30. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/entry_points.txt +0 -0
  31. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- """deploy and connect to to running inference apps"""
2
+ """deploy and connect to running serving apps"""
3
3
 
4
4
  from __future__ import annotations
5
5
 
@@ -150,3 +150,4 @@ from supervisely.app.widgets.report_thumbnail.report_thumbnail import ReportThum
150
150
  from supervisely.app.widgets.experiment_selector.experiment_selector import ExperimentSelector
151
151
  from supervisely.app.widgets.bokeh.bokeh import Bokeh
152
152
  from supervisely.app.widgets.run_app_button.run_app_button import RunAppButton
153
+ from supervisely.app.widgets.select_collection.select_collection import SelectCollection
@@ -49,6 +49,12 @@ class AgentSelector(Widget):
49
49
 
50
50
  def get_value(self) -> int:
51
51
  return StateJson()[self.widget_id]["agentId"]
52
+
53
+ def set_value(self, agent_id: int) -> None:
54
+ if not isinstance(agent_id, int):
55
+ raise TypeError("Agent ID must be an integer.")
56
+ StateJson()[self.widget_id]["agentId"] = agent_id
57
+ StateJson().send_changes()
52
58
 
53
59
  def value_changed(self, func):
54
60
  route_path = self.get_route_path(AgentSelector.Routes.VALUE_CHANGED)
@@ -7,6 +7,8 @@
7
7
  :is-community="data.{{{ widget.widget_id }}}.isCommunity"
8
8
  {% if widget._changes_handled == true %}
9
9
  @input="state.{{{ widget.widget_id }}}.agentId = $event; post('/{{{ widget.widget_id }}}/value_changed')"
10
+ {% else %}
11
+ @input="state.{{{ widget.widget_id }}}.agentId = $event"
10
12
  {% endif %}
11
13
  ></sly-select-agent>
12
14
 
@@ -40,6 +40,8 @@ class Button(Widget):
40
40
  :type style: Optional[str]
41
41
  :param call_on_click: Function to be called on button click.
42
42
  :type call_on_click: Optional[str]
43
+ :param icon_color: Color of the icon.
44
+ :type icon_color: Optional[str]
43
45
 
44
46
  :Usage example:
45
47
  .. code-block:: python
@@ -68,6 +70,7 @@ class Button(Widget):
68
70
  style: Optional[str] = None,
69
71
  call_on_click: Optional[str] = None,
70
72
  visible_by_vue_field: Optional[str] = "",
73
+ icon_color: Optional[str] = None,
71
74
  ):
72
75
  self._widget_routes = {}
73
76
 
@@ -80,7 +83,10 @@ class Button(Widget):
80
83
  if icon is None:
81
84
  self._icon = ""
82
85
  else:
83
- self._icon = f'<i class="{icon}" style="margin-right: {icon_gap}px"></i>'
86
+ icon_style = f"margin-right: {icon_gap}px"
87
+ if icon_color is not None:
88
+ icon_style += f"; color: {icon_color}"
89
+ self._icon = f'<i class="{icon}" style="{icon_style}"></i>'
84
90
 
85
91
  self._loading = False
86
92
  self._disabled = False
@@ -115,6 +121,7 @@ class Button(Widget):
115
121
  "disabled": self._disabled,
116
122
  "icon": self._icon,
117
123
  "link": self._link,
124
+ "style": self._style,
118
125
  }
119
126
 
120
127
  def get_json_state(self) -> None:
@@ -263,6 +270,26 @@ class Button(Widget):
263
270
  :rtype: bool
264
271
  """
265
272
  return self._disabled
273
+
274
+ @property
275
+ def style(self) -> Optional[str]:
276
+ """Returns the CSS style applied to the button.
277
+
278
+ :return: CSS style applied to the button.
279
+ :rtype: Optional[str]
280
+ """
281
+ return self._style
282
+
283
+ @style.setter
284
+ def style(self, value: Optional[str]) -> None:
285
+ """Sets the CSS style to be applied to the button.
286
+
287
+ :param value: CSS style to be applied to the button.
288
+ :type value: Optional[str]
289
+ """
290
+ self._style = value
291
+ DataJson()[self.widget_id]["style"] = self._style
292
+ DataJson().send_changes()
266
293
 
267
294
  @disabled.setter
268
295
  def disabled(self, value: bool) -> None:
@@ -20,7 +20,7 @@ endif
20
20
  @click="{{{widget._get_on_click()}}}"
21
21
  {% endif %}
22
22
  {% if widget._style %}
23
- style="{{{widget._style}}}"
23
+ :style="data.{{{widget.widget_id}}}.style"
24
24
  {% endif %}
25
25
  >
26
26
  <span v-html="data.{{{widget.widget_id}}}.icon"></span>
@@ -28,6 +28,8 @@ class Card(Widget):
28
28
  :type remove_padding: Optional[bool]
29
29
  :param overflow: Overflow property of the card. Can be "auto", "unset" or "scroll".
30
30
  :type overflow: Optional[Literal["auto", "unset", "scroll"]]
31
+ :param style: CSS styles string of the card.
32
+ :type style: Optional[str]
31
33
  :param widget_id: Unique widget identifier.
32
34
  :type widget_id: str
33
35
 
@@ -51,6 +53,7 @@ class Card(Widget):
51
53
  widget_id: Optional[str] = None,
52
54
  remove_padding: Optional[bool] = False,
53
55
  overflow: Optional[Literal["auto", "unset", "scroll"]] = "auto",
56
+ style: Optional[str] = "",
54
57
  ):
55
58
  self._title = title
56
59
  self._description = description
@@ -63,6 +66,7 @@ class Card(Widget):
63
66
  if self._slot_content is not None:
64
67
  self._show_slot = True
65
68
  self._overflow = overflow
69
+ self._style = style
66
70
  self._options = {
67
71
  "collapsable": self._collapsable,
68
72
  "marginBottom": "0px",
@@ -14,7 +14,7 @@
14
14
  :options="data.{{{widget.widget_id}}}.options"
15
15
  :disabled="state.{{{widget.widget_id}}}.disabled"
16
16
  :collapsed="state.{{{widget.widget_id}}}.collapsed"
17
- style="width: 100%"
17
+ style="width: 100%; {{{widget._style}}}"
18
18
  >
19
19
  <div>{{{widget._content}}}</div>
20
20
  <div v-if="data.{{{widget.widget_id}}}.show_slot" slot="header">
@@ -412,10 +412,12 @@ class ClassesTable(Widget):
412
412
  :rtype: List[str]
413
413
  """
414
414
  classes = []
415
+ checkboxes = StateJson()[self.widget_id]["checkboxes"]
415
416
  for i, line in enumerate(self._table_data):
416
- checkboxes = StateJson()[self.widget_id]["checkboxes"]
417
417
  if len(checkboxes) == 0:
418
418
  checkboxes = [False] * len(self._table_data)
419
+ if i >= len(checkboxes):
420
+ continue
419
421
  if checkboxes[i]:
420
422
  for col in line:
421
423
  if col["name"] == "CLASS":
@@ -112,6 +112,7 @@ class FastTable(Widget):
112
112
  sort_order: Optional[Literal["asc", "desc"]] = None,
113
113
  width: Optional[str] = "auto",
114
114
  widget_id: Optional[str] = None,
115
+ show_header: bool = True,
115
116
  ):
116
117
  self._supported_types = tuple([pd.DataFrame, list, type(None)])
117
118
  self._row_click_handled = False
@@ -127,6 +128,7 @@ class FastTable(Widget):
127
128
  self._clickable_rows = False
128
129
  self._clickable_cells = False
129
130
  self._search_str = ""
131
+ self._show_header = show_header
130
132
  self._project_meta = self._unpack_project_meta(project_meta)
131
133
 
132
134
  # table_options
@@ -212,6 +214,7 @@ class FastTable(Widget):
212
214
  "fixColumns": self._fix_columns,
213
215
  },
214
216
  "pageSize": self._page_size,
217
+ "showHeader": self._show_header,
215
218
  }
216
219
 
217
220
  def get_json_state(self) -> Dict[str, Any]:
@@ -469,6 +472,17 @@ class FastTable(Widget):
469
472
  DataJson().send_changes()
470
473
  return popped_row
471
474
 
475
+ def clear(self) -> None:
476
+ """Clears the table data."""
477
+ self._source_data = pd.DataFrame(columns=self._columns_first_idx)
478
+ self._parsed_source_data = {"data": [], "columns": []}
479
+ self._sliced_data = pd.DataFrame(columns=self._columns_first_idx)
480
+ self._parsed_active_data = {"data": [], "columns": []}
481
+ self._rows_total = 0
482
+ DataJson()[self.widget_id]["data"] = []
483
+ DataJson()[self.widget_id]["total"] = 0
484
+ DataJson().send_changes()
485
+
472
486
  def row_click(self, func: Callable[[ClickedRow], Any]) -> Callable[[], None]:
473
487
  """Decorator for function that handles row click event.
474
488
 
@@ -802,6 +816,8 @@ class FastTable(Widget):
802
816
  failed_column_idxs = []
803
817
  failed_column_idx = 0
804
818
  for column, value in zip(self._source_data.columns, row):
819
+ if len(self._source_data[column].values) == 0:
820
+ continue
805
821
  col_type = type(self._source_data[column].values[0])
806
822
  if col_type == str and not isinstance(value, str):
807
823
  failed_column_idxs.append(
@@ -40,6 +40,10 @@ Vue.component('fast-table', {
40
40
  type: String,
41
41
  default: '',
42
42
  },
43
+ showHeader: {
44
+ type: Boolean,
45
+ default: true,
46
+ },
43
47
  },
44
48
  data() {
45
49
  return {
@@ -116,7 +120,7 @@ Vue.component('fast-table', {
116
120
  template: `
117
121
  <div class="tailwind fast-table">
118
122
  <div class="rounded-lg border border-slate-200 shadow bg-white" ref="wrapper">
119
- <div class="py-2 px-2 md:px-5 md:py-4 flex flex-col md:flex-row gap-2 justify-between items-center">
123
+ <div v-if ="showHeader === true" class="py-2 px-2 md:px-5 md:py-4 flex flex-col md:flex-row gap-2 justify-between items-center">
120
124
  <div class="relative w-full md:max-w-[18rem]">
121
125
  <i class="zmdi zmdi-search h-4 absolute top-2 left-2.5 opacity-50"></i>
122
126
  <!--<img alt="Search" src="~assets/icons/search.png" class="h-4 absolute top-2 left-2.5 opacity-50" />
@@ -194,4 +198,4 @@ Vue.component('fast-table', {
194
198
  </div>
195
199
  </div>
196
200
  `,
197
- });
201
+ });
@@ -12,6 +12,7 @@
12
12
  :sort.sync="state.{{{widget.widget_id}}}.sort"
13
13
  :search.sync="state.{{{widget.widget_id}}}.search"
14
14
  :data="data.{{{widget.widget_id}}}.data"
15
+ :show-header="data.{{{widget.widget_id}}}.showHeader"
15
16
  {%
16
17
  if
17
18
  widget._row_click_handled
@@ -22,6 +22,8 @@ class RandomSplitsTable(Widget):
22
22
  {"name": "val", "type": "primary"},
23
23
  {"name": "total", "type": "gray"},
24
24
  ]
25
+ if items_count is None:
26
+ items_count = 0
25
27
  self._items_count = items_count
26
28
  train_count = int(items_count / 100 * start_train_percent)
27
29
  self._count = {"total": items_count, "train": train_count, "val": items_count - train_count}
File without changes