supervisely 6.73.435__py3-none-any.whl → 6.73.437__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.
@@ -70,6 +70,7 @@ from supervisely.api.module_api import (
70
70
  _get_single_item,
71
71
  )
72
72
  from supervisely.imaging import image as sly_image
73
+ from supervisely.io.env import app_categories, increment_upload_count, add_uploaded_ids_to_env
73
74
  from supervisely.io.fs import (
74
75
  OFFSETS_PKL_BATCH_SIZE,
75
76
  OFFSETS_PKL_SUFFIX,
@@ -2613,6 +2614,16 @@ class ImageApi(RemoveableBulkModuleApi):
2613
2614
  info_json_copy[ApiField.EXT] = info_json[ApiField.MIME].split("/")[1]
2614
2615
  # results.append(self.InfoType(*[info_json_copy[field_name] for field_name in self.info_sequence()]))
2615
2616
  results.append(self._convert_json_info(info_json_copy))
2617
+
2618
+ try:
2619
+ if "import" in app_categories():
2620
+ ids = [info.id for info in results[-len(batch_names) :]]
2621
+ if len(ids) > 0:
2622
+ increment_upload_count(dataset_id, len(ids))
2623
+ add_uploaded_ids_to_env(dataset_id, ids)
2624
+ except:
2625
+ pass
2626
+
2616
2627
  break
2617
2628
  except HTTPError as e:
2618
2629
  error_details = e.response.json().get("details", {})
@@ -47,6 +47,7 @@ from supervisely.api.module_api import (
47
47
  RemoveableModuleApi,
48
48
  UpdateableModule,
49
49
  )
50
+ from supervisely.io.env import upload_count, uploaded_ids
50
51
  from supervisely.io.json import dump_json_file, load_json_file
51
52
  from supervisely.project.project_meta import ProjectMeta
52
53
  from supervisely.project.project_meta import ProjectMetaJsonFields as MetaJsonF
@@ -2658,5 +2659,77 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2658
2659
  ):
2659
2660
  infos.append((src_info, dst_info))
2660
2661
 
2662
+ return infos
2661
2663
 
2662
- return infos
2664
+ def add_import_history(self, id: int, task_id: int) -> None:
2665
+ """
2666
+ Adds import history to project info. Gets task info and adds it to project custom data.
2667
+
2668
+ :param id: Project ID
2669
+ :type id: int
2670
+ :param task_id: Task ID
2671
+ :type task_id: int
2672
+ :return: None
2673
+ :rtype: :class:`NoneType`
2674
+ :Usage example:
2675
+ .. code-block:: python
2676
+ import os
2677
+ from dotenv import load_dotenv
2678
+
2679
+ import supervisely as sly
2680
+
2681
+ # Load secrets and create API object from .env file (recommended)
2682
+ # Learn more here: https://developer.supervisely.com/getting-started/basics-of-authentication
2683
+ load_dotenv(os.path.expanduser("~/supervisely.env"))
2684
+ api = sly.Api.from_env()
2685
+
2686
+ project_id = 123
2687
+ task_id = 456
2688
+ api.project.add_import_history(project_id, task_id)
2689
+ """
2690
+
2691
+ task_info = self._api.task.get_info_by_id(task_id)
2692
+ module_id = task_info.get("meta", {}).get("app", {}).get("moduleId")
2693
+ slug = None
2694
+ if module_id is not None:
2695
+ module_info = self._api.app.get_ecosystem_module_info(module_id)
2696
+ slug = module_info.slug
2697
+
2698
+ items_count = upload_count()
2699
+ items_count = {int(k): v for k, v in items_count.items()}
2700
+ uploaded_images = uploaded_ids()
2701
+ uploaded_images = {int(k): v for k, v in uploaded_images.items()}
2702
+ total_items = sum(items_count.values()) if len(items_count) > 0 else 0
2703
+ app = task_info.get("meta", {}).get("app")
2704
+ app_name = app.get("name") if app else None
2705
+ app_version = app.get("version") if app else None
2706
+ data = {
2707
+ "task_id": task_id,
2708
+ "app": {"name": app_name, "version": app_version},
2709
+ "slug": slug,
2710
+ "status": task_info.get(ApiField.STATUS),
2711
+ "user_id": task_info.get(ApiField.USER_ID),
2712
+ "team_id": task_info.get(ApiField.TEAM_ID),
2713
+ "timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
2714
+ "source_state": task_info.get("settings", {}).get("message", {}).get("state"),
2715
+ "items_count": total_items,
2716
+ "datasets": [
2717
+ {
2718
+ "id": ds,
2719
+ "items_count": items_count[ds],
2720
+ "uploaded_images": uploaded_images.get(ds, []),
2721
+ }
2722
+ for ds in items_count.keys()
2723
+ ],
2724
+ }
2725
+
2726
+ project_info = self.get_info_by_id(id)
2727
+
2728
+ custom_data = project_info.custom_data or {}
2729
+ if "import_history" not in custom_data:
2730
+ custom_data["import_history"] = {"tasks": []}
2731
+ if "tasks" not in custom_data["import_history"]:
2732
+ custom_data["import_history"]["tasks"] = []
2733
+ custom_data["import_history"]["tasks"].append(data)
2734
+
2735
+ self.edit_info(id, custom_data=custom_data)
@@ -24,6 +24,7 @@ from supervisely.api.module_api import (
24
24
  WaitingTimeExceeded,
25
25
  )
26
26
  from supervisely.collection.str_enum import StrEnum
27
+ from supervisely.io.env import app_categories
27
28
  from supervisely.io.fs import (
28
29
  ensure_base_path,
29
30
  get_file_hash,
@@ -652,6 +653,8 @@ class TaskApi(ModuleApiBase, ModuleWithStatus):
652
653
  project_preview: Optional[str] = None,
653
654
  ) -> Dict:
654
655
  """set_output_project"""
656
+ if "import" in app_categories():
657
+ self._api.project.add_import_history(project_id, task_id)
655
658
  if project_name is None:
656
659
  project = self._api.project.get_info_by_id(project_id, raise_error=True)
657
660
  project_name = project.name
supervisely/io/env.py CHANGED
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ import json
2
3
  import os
3
4
  from typing import Callable, List, Literal, Optional, Union
4
5
 
@@ -686,3 +687,87 @@ def configure_minimum_instance_version() -> None:
686
687
  latest_version = get_latest_instance_version_from_json()
687
688
  if latest_version:
688
689
  os.environ["MINIMUM_INSTANCE_VERSION_FOR_SDK"] = latest_version
690
+
691
+ def app_categories(raise_not_found: Optional[bool] = False) -> list:
692
+ """Returns a list of app categories from environment variable using following keys:
693
+ - APP_CATEGORIES
694
+ :param raise_not_found: if True, raises KeyError if app category is not found in environment variables
695
+ :type raise_not_found: Optional[bool]
696
+ :return: app categories
697
+ :rtype: list
698
+ """
699
+ return _parse_from_env(
700
+ name="app_category",
701
+ keys=["APP_CATEGORIES"],
702
+ postprocess_fn=lambda x: json.loads(x),
703
+ default=[],
704
+ raise_not_found=raise_not_found,
705
+ )
706
+
707
+
708
+ def upload_count(raise_not_found: Optional[bool] = False) -> dict:
709
+ """Returns a dictionary of upload counts from environment variable using following
710
+ - UPLOAD_COUNT
711
+ :param raise_not_found: if True, raises KeyError if upload count is not found in environment variables
712
+ :type raise_not_found: Optional[bool]
713
+ :return: upload count
714
+ :rtype: dict
715
+ """
716
+ return _parse_from_env(
717
+ name="upload_count",
718
+ keys=["UPLOAD_COUNT"],
719
+ postprocess_fn=lambda x: json.loads(x),
720
+ default={},
721
+ raise_not_found=raise_not_found,
722
+ )
723
+
724
+
725
+ def uploaded_ids(raise_not_found: Optional[bool] = False) -> dict:
726
+ """Returns a dictionary with dataset IDs as keys and lists of uploaded IDs as values from environment variable using following
727
+ - UPLOADED_IDS
728
+ :param raise_not_found: if True, raises KeyError if uploaded IDs is not found in environment variables
729
+ :type raise_not_found: Optional[bool]
730
+ :return: uploaded IDs
731
+ :rtype: dict
732
+ """
733
+ return _parse_from_env(
734
+ name="uploaded_ids",
735
+ keys=["UPLOADED_IDS"],
736
+ postprocess_fn=lambda x: json.loads(x),
737
+ default={},
738
+ raise_not_found=raise_not_found,
739
+ )
740
+
741
+
742
+ def increment_upload_count(dataset_id: int, count: int = 1) -> None:
743
+ """Increments the upload count for the given dataset id by the specified count.
744
+
745
+ :param dataset_id: The dataset id to increment the upload count for.
746
+ :type dataset_id: int
747
+ :param count: The amount to increment the upload count by. Defaults to 1.
748
+ :type count: int
749
+ """
750
+ upload_info = upload_count()
751
+ upload_info[str(dataset_id)] = upload_info.get(str(dataset_id), 0) + count
752
+ os.environ["UPLOAD_COUNT"] = json.dumps(upload_info)
753
+
754
+
755
+ def add_uploaded_ids_to_env(dataset_id: int, ids: List[int]) -> None:
756
+ """Adds the list of uploaded IDs to the environment variable for the given dataset ID.
757
+
758
+ :param dataset_id: The dataset ID to associate the uploaded IDs with.
759
+ :type dataset_id: int
760
+ :param ids: The list of uploaded IDs to add.
761
+ :type ids: List[int]
762
+ """
763
+ uploaded = uploaded_ids()
764
+ if str(dataset_id) not in uploaded:
765
+ uploaded[str(dataset_id)] = []
766
+ existing_ids = set(uploaded[str(dataset_id)])
767
+ if set(ids).intersection(existing_ids):
768
+ for _id in ids:
769
+ if _id not in existing_ids:
770
+ uploaded[str(dataset_id)].append(_id)
771
+ else:
772
+ uploaded[str(dataset_id)].extend(ids)
773
+ os.environ["UPLOADED_IDS"] = json.dumps(uploaded)
@@ -548,13 +548,21 @@ class PredictAppGui:
548
548
 
549
549
  # Input
550
550
  # Input would be newely created project
551
+ input_args = {}
551
552
  input_parameters = run_parameters["input"]
552
553
  input_project_id = input_parameters.get("project_id", None)
553
554
  if input_project_id is None:
554
555
  raise ValueError("Input project ID is required for prediction.")
555
556
  input_dataset_ids = input_parameters.get("dataset_ids", [])
556
- if not input_dataset_ids:
557
+ input_image_ids = input_parameters.get("image_ids", [])
558
+ if not (input_dataset_ids or input_image_ids):
557
559
  raise ValueError("At least one dataset must be selected for prediction.")
560
+ if input_image_ids:
561
+ input_args["image_ids"] = input_image_ids
562
+ elif input_dataset_ids:
563
+ input_args["dataset_ids"] = input_dataset_ids
564
+ else:
565
+ input_args["project_id"] = input_project_id
558
566
 
559
567
  # Settings
560
568
  settings = run_parameters["settings"]
@@ -582,23 +590,32 @@ class PredictAppGui:
582
590
  # Always create new project
583
591
  # But the actual inference will happen inplace
584
592
  output_parameters = run_parameters["output"]
585
- project_name = output_parameters["project_name"]
586
- if not project_name:
587
- input_project_info = self.api.project.get_info_by_id(input_project_id)
588
- project_name = input_project_info.name + " [Predictions]"
589
- logger.warning("Project name is empty, using auto-generated name: " + project_name)
590
-
591
- # Copy project
592
- self.set_validator_text("Copying project...", "info")
593
- created_project = copy_project(
594
- self.api,
595
- project_name,
596
- self.workspace_id,
597
- input_project_id,
598
- input_dataset_ids,
599
- with_annotations,
600
- self.output_selector.progress,
601
- )
593
+ project_name = output_parameters.get("project_name", "")
594
+ upload_to_source_project = output_parameters.get("upload_to_source_project", False)
595
+ if upload_to_source_project:
596
+ output_project_id = input_project_id
597
+ else:
598
+ if not project_name:
599
+ input_project_info = self.api.project.get_info_by_id(input_project_id)
600
+ project_name = input_project_info.name + " [Predictions]"
601
+ logger.warning("Project name is empty, using auto-generated name: " + project_name)
602
+
603
+ # Copy project
604
+ self.set_validator_text("Copying project...", "info")
605
+ created_project = copy_project(
606
+ self.api,
607
+ project_name,
608
+ self.workspace_id,
609
+ input_project_id,
610
+ input_dataset_ids,
611
+ with_annotations,
612
+ self.output_selector.progress,
613
+ )
614
+ output_project_id = created_project.id
615
+ input_args = {
616
+ "project_id": output_project_id,
617
+ }
618
+
602
619
  # ------------------------ #
603
620
 
604
621
  # Run prediction
@@ -607,7 +624,7 @@ class PredictAppGui:
607
624
  self._is_running = True
608
625
  try:
609
626
  with model_api.predict_detached(
610
- project_id=created_project.id,
627
+ **input_args,
611
628
  tqdm=self.output_selector.progress(),
612
629
  **kwargs,
613
630
  ) as session:
@@ -635,7 +652,7 @@ class PredictAppGui:
635
652
 
636
653
  # Set result thumbnail
637
654
  self.set_validator_text("Project successfully processed", "success")
638
- self.output_selector.set_result_thumbnail(created_project.id)
655
+ self.output_selector.set_result_thumbnail(output_project_id)
639
656
  # ------------------------ #
640
657
  return predictions
641
658
 
@@ -3,13 +3,13 @@ from typing import Dict, List, Optional
3
3
 
4
4
  from fastapi import BackgroundTasks, Request
5
5
 
6
+ import supervisely.io.fs as sly_fs
6
7
  from supervisely._utils import logger
7
8
  from supervisely.api.api import Api
8
9
  from supervisely.app.fastapi.subapp import Application
9
10
  from supervisely.nn.inference.predict_app.gui.gui import PredictAppGui
10
- from supervisely.nn.model.prediction import Prediction
11
11
  from supervisely.nn.inference.predict_app.gui.utils import disable_enable
12
- import supervisely.io.fs as sly_fs
12
+ from supervisely.nn.model.prediction import Prediction
13
13
 
14
14
 
15
15
  class PredictApp:
@@ -91,14 +91,16 @@ class PredictApp:
91
91
  # "mode": "custom",
92
92
  # "train_task_id": 123
93
93
  },
94
- "items": {
94
+ "input": {
95
95
  "project_id": 123,
96
96
  # "dataset_ids": [...],
97
97
  # "video_id": 123
98
98
  },
99
- "inference_settings": {
100
- "confidence_threshold": 0.5
101
- },
99
+ "settings": {
100
+ "inference_settings": {
101
+ "confidence_threshold": 0.5
102
+ },
103
+ }
102
104
  "output": {
103
105
  "mode": "create",
104
106
  "project_name": "Predictions",
@@ -153,7 +155,7 @@ class PredictApp:
153
155
  "inference_settings": {
154
156
  "conf": 0.6,
155
157
  },
156
- "item": {
158
+ "input": {
157
159
  # "project_id": ...,
158
160
  # "dataset_ids": [...],
159
161
  "image_ids": [1148679, 1148675],
@@ -162,17 +164,7 @@ class PredictApp:
162
164
  }
163
165
  """
164
166
  state = request.state.state
165
- run_parameters = {
166
- "item": state["item"],
167
- }
168
- if "inference_settings" in state:
169
- run_parameters["inference_settings"] = state["inference_settings"]
170
- if "output" in state:
171
- run_parameters["output"] = state["output"]
172
- else:
173
- run_parameters["output"] = {"mode": None}
174
-
175
- predictions = self.run(run_parameters)
167
+ predictions = self.run(state)
176
168
  return [prediction.to_json() for prediction in predictions]
177
169
 
178
170
  @server.post("/run")
@@ -254,6 +254,7 @@ class TrainGUI:
254
254
  self.app_options = app_options
255
255
  self.collapsable = self.app_options.get("collapsable", False)
256
256
  self.need_convert_shapes = False
257
+ self._start_training = False
257
258
 
258
259
  self.team_id = sly_env.team_id(raise_not_found=False)
259
260
  self.workspace_id = sly_env.workspace_id(raise_not_found=False)
@@ -844,6 +845,7 @@ class TrainGUI:
844
845
  },
845
846
  },
846
847
  "experiment_name": "My Experiment",
848
+ "start_training": False,
847
849
  }
848
850
  """
849
851
  if isinstance(app_state, str):
@@ -888,6 +890,8 @@ class TrainGUI:
888
890
 
889
891
  if validate_steps:
890
892
  logger.info(f"All steps have been validated successfully")
893
+
894
+ self._start_training = app_state.get("start_training", False)
891
895
  # ------------------------------------------------------------------ #
892
896
 
893
897
  def _init_input(
@@ -305,6 +305,12 @@ class TrainApp:
305
305
 
306
306
  # Properties
307
307
  # General
308
+ @property
309
+ def auto_start(self) -> bool:
310
+ """
311
+ If True, the training will start automatically after the GUI is loaded and train server is started.
312
+ """
313
+ return self.gui._start_training
308
314
  # ----------------------------------------- #
309
315
 
310
316
  # Input Data
@@ -2047,13 +2053,16 @@ class TrainApp:
2047
2053
  try:
2048
2054
  output_file_info = self._generate_experiment_report(experiment_info, model_meta)
2049
2055
  experiment_info["has_report"] = True
2056
+ experiment_info["experiment_report_id"] = output_file_info.id
2050
2057
  except Exception as e:
2051
2058
  logger.error(f"Error generating experiment report: {e}")
2052
2059
  output_file_info = session_link_file_info
2053
2060
  experiment_info["has_report"] = False
2061
+ experiment_info["experiment_report_id"] = None
2054
2062
  else: # link to artifacts directory
2055
2063
  output_file_info = session_link_file_info
2056
2064
  experiment_info["has_report"] = False
2065
+ experiment_info["experiment_report_id"] = None
2057
2066
  return output_file_info, experiment_info
2058
2067
 
2059
2068
  def _get_train_val_splits_for_app_state(self) -> Dict:
@@ -2789,6 +2798,12 @@ class TrainApp:
2789
2798
  train_logger.add_on_step_finished_callback(step_callback)
2790
2799
 
2791
2800
  # ----------------------------------------- #
2801
+ def start_in_thread(self):
2802
+ def auto_train():
2803
+ import threading
2804
+ threading.Thread(target=self._wrapped_start_training, daemon=True).start()
2805
+ self._server.add_event_handler("startup", auto_train)
2806
+
2792
2807
  def _wrapped_start_training(self):
2793
2808
  """
2794
2809
  Wrapper function to wrap the training process.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.435
3
+ Version: 6.73.437
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -31,7 +31,7 @@ supervisely/api/entities_collection_api.py,sha256=Be13HsfMFLmq9XpiOfQog0Y569kbUn
31
31
  supervisely/api/file_api.py,sha256=gNXNsikocSYRojoZrVmXIqXycqXm0e320piAwaLN6JI,92978
32
32
  supervisely/api/github_api.py,sha256=NIexNjEer9H5rf5sw2LEZd7C1WR-tK4t6IZzsgeAAwQ,623
33
33
  supervisely/api/image_annotation_tool_api.py,sha256=YcUo78jRDBJYvIjrd-Y6FJAasLta54nnxhyaGyanovA,5237
34
- supervisely/api/image_api.py,sha256=kDx5VO-1IXrN6HDTta9CYjlPGHGiXOh2zv1wO5rON0s,232422
34
+ supervisely/api/image_api.py,sha256=5GBlY_7hYI7RXkBrwjkxGe3YkJktoytA1o9wdeHdIA4,232938
35
35
  supervisely/api/import_storage_api.py,sha256=BDCgmR0Hv6OoiRHLCVPKt3iDxSVlQp1WrnKhAK_Zl84,460
36
36
  supervisely/api/issues_api.py,sha256=BqDJXmNoTzwc3xe6_-mA7FDFC5QQ-ahGbXk_HmpkSeQ,17925
37
37
  supervisely/api/labeling_job_api.py,sha256=G2_BV_WtA2lAhfw_nAQmWmv1P-pwimD0ba9GVKoGjiA,55537
@@ -39,13 +39,13 @@ supervisely/api/labeling_queue_api.py,sha256=ilNjAL1d9NSa9yabQn6E-W26YdtooT3ZGXI
39
39
  supervisely/api/module_api.py,sha256=8Asdr3llhC8XQ98xGdR03hpe2GYznJONzNfgN-mQYv8,46458
40
40
  supervisely/api/object_class_api.py,sha256=7-npNFMYjWNtSXYZg6syc6bX56_oCzDU2kFRPGQWCwA,10399
41
41
  supervisely/api/plugin_api.py,sha256=SFm0IlTTOjuHBLUMgG4d4k6U3cWJocE-SVb-f08fwMQ,5286
42
- supervisely/api/project_api.py,sha256=R4KjWUiO1pLQhsd6hDTgRWjaSdEiSE_bFI8UZ9Lo3pQ,101688
42
+ supervisely/api/project_api.py,sha256=rZfPGwswx25-QXEgXwKIaCr5IEQJDA78s_2S92nAroY,104652
43
43
  supervisely/api/project_class_api.py,sha256=5cyjdGPPb2tpttu5WmYoOxUNiDxqiojschkhZumF0KM,1426
44
44
  supervisely/api/remote_storage_api.py,sha256=1O4rTIwW8s9gxC00yvFuKbEMGNsa7YSRlZ8j494ARwY,17793
45
45
  supervisely/api/report_api.py,sha256=Om7CGulUbQ4BuJ16eDtz7luLe0JQNqab-LoLpUXu7YE,7123
46
46
  supervisely/api/role_api.py,sha256=c1XAU_wZg6zL4wG2R7iuS9EJOoaHHNGchxa1nYVL7yo,3047
47
47
  supervisely/api/storage_api.py,sha256=VxiflQt-SfyB1OuEOB66JsMkxCosUr4n0WHQ5if3Ltg,13039
48
- supervisely/api/task_api.py,sha256=i6Rnf7IqIIKA0N3BHYydGD5zjBmnrcw1bkm8qNg9P5Y,38797
48
+ supervisely/api/task_api.py,sha256=zfnug7I6UKUoCcUNKNqxMDr-z0abl4zkA7FpnKi6cVE,38954
49
49
  supervisely/api/team_api.py,sha256=uPsBpDP_Ig9HDQ9Zm6Y-VboLbSYKIV9S_a1S7e4vqvo,19470
50
50
  supervisely/api/user_api.py,sha256=m29GP9tvem8P2fJZgg7DAZ9yhFdBX26ZBcWxCKdnhn4,24943
51
51
  supervisely/api/video_annotation_tool_api.py,sha256=3A9-U8WJzrTShP_n9T8U01M9FzGYdeS51CCBTzUnooo,6686
@@ -734,7 +734,7 @@ supervisely/imaging/font.py,sha256=0XcmWhlw7y2PAhrWgcsfInyRWj0WnlFpMSEXXilR8UA,2
734
734
  supervisely/imaging/image.py,sha256=1KNc4qRbP9OlI4Yta07Kc2ohAgSBJ_9alF9Jag74w30,41873
735
735
  supervisely/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
736
736
  supervisely/io/docker_utils.py,sha256=hb_HXGM8IYB0PF-nD7NxMwaHgzaxIFxofsUzQ_RCUZI,7935
737
- supervisely/io/env.py,sha256=fK-v4rW_tWiS6qjZtv91WM7uNtem27E_F1zDvaYfjN4,21766
737
+ supervisely/io/env.py,sha256=wf15PXGd_xzY6c4g8ywPGcZ25A8a9Jv_BXg9-x61cgg,24884
738
738
  supervisely/io/exception_handlers.py,sha256=22LPlLgyq59DnrhpaFrbGBYJE7uxO64VTZjsPJC0PLE,36757
739
739
  supervisely/io/fs.py,sha256=pzNAK5fbT3G-7PKRY5oYcOPjgXeZ9x5Dyry7fzzZsr8,63604
740
740
  supervisely/io/fs_cache.py,sha256=985gvBGzveLcDudgz10E4EWVjP9jxdU1Pa0GFfCBoCA,6520
@@ -931,10 +931,10 @@ supervisely/nn/inference/object_detection_3d/object_detection_3d.py,sha256=GmBz7
931
931
  supervisely/nn/inference/pose_estimation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
932
932
  supervisely/nn/inference/pose_estimation/pose_estimation.py,sha256=oI-zWO7zY0-tHwGhSFmno3eSwE5I0BDKRDrZBoU9jPY,6452
933
933
  supervisely/nn/inference/predict_app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
934
- supervisely/nn/inference/predict_app/predict_app.py,sha256=AIEKqAzU0g2Nksw7r7_bwcbOXOwh1V2Xp7rLLntYNSY,6621
934
+ supervisely/nn/inference/predict_app/predict_app.py,sha256=iI_uxCzRpxY-XSXRUzwn261PQEIoQvCZFyRq0jtOv5w,6298
935
935
  supervisely/nn/inference/predict_app/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
936
936
  supervisely/nn/inference/predict_app/gui/classes_selector.py,sha256=V6fmsEnn8-FwoS7c9Bpms1jR_hqWDnGNIBU6s2a-XnQ,2916
937
- supervisely/nn/inference/predict_app/gui/gui.py,sha256=RquvLtlWQ9OWB0fOJx6DAoiHCRdmPLMKUld3-VkOoh4,28096
937
+ supervisely/nn/inference/predict_app/gui/gui.py,sha256=lLdRQA1iyZApbOPxL6lgFBiwcgm80OkMA-Etu2FoFSk,28831
938
938
  supervisely/nn/inference/predict_app/gui/input_selector.py,sha256=Jh-eSU-cnqHtbcBfSjBCfZrq5nfQlPi7bOAzqqo26xc,6187
939
939
  supervisely/nn/inference/predict_app/gui/model_selector.py,sha256=sGKzxaPwbTzP7_463sWeJe7qEfxntZHK6hYQPm6smFU,2453
940
940
  supervisely/nn/inference/predict_app/gui/output_selector.py,sha256=lDX6q8Liw8wsbOae9DphOIEH1yKj5u2EwMqf0yO1mgY,4885
@@ -1012,10 +1012,10 @@ supervisely/nn/tracker/botsort/tracker/kalman_filter.py,sha256=waTArMcbmpHAzb57a
1012
1012
  supervisely/nn/tracker/botsort/tracker/matching.py,sha256=bgnheHwWD3XZSI3OJVfdrU5bYJ44rxPHzzSElfg6LZM,6600
1013
1013
  supervisely/nn/tracker/botsort/tracker/mc_bot_sort.py,sha256=dFjWmubyJLrUP4i-CJaOhPEkQD-WD144deW7Ua5a7Rc,17775
1014
1014
  supervisely/nn/training/__init__.py,sha256=gY4PCykJ-42MWKsqb9kl-skemKa8yB6t_fb5kzqR66U,111
1015
- supervisely/nn/training/train_app.py,sha256=DW9J6qZEebRFdq59sexvEZTWyExisbz7Z2lHXwEkPjY,131937
1015
+ supervisely/nn/training/train_app.py,sha256=yHr8s8xQsk1zs3wxOxSlJ_qMecO4g112SXvFUL6n99M,132593
1016
1016
  supervisely/nn/training/gui/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
1017
1017
  supervisely/nn/training/gui/classes_selector.py,sha256=tqmVwUfC2u5K53mZmvDvNOhu9Mw5mddjpB2kxRXXUO8,12453
1018
- supervisely/nn/training/gui/gui.py,sha256=Yjavju7HbgYZMZvhI_kdrz65Uf87Qc4-KR7SVkfUXTc,51600
1018
+ supervisely/nn/training/gui/gui.py,sha256=_CtpzlwP6WLFgOTBDB_4RPcaqrQPK92DwSCDvO-dIKM,51749
1019
1019
  supervisely/nn/training/gui/hyperparameters_selector.py,sha256=tEyppV5ay7nECi6qBQ9seKgfidPa_FxxtGmqsfQapa4,7768
1020
1020
  supervisely/nn/training/gui/input_selector.py,sha256=rmirJzpdxuYONI6y5_cvMdGWBJ--T20YTsISghATHu4,2510
1021
1021
  supervisely/nn/training/gui/model_selector.py,sha256=YKBAk6MheulFEl9TF9_mVtE3-Hsc0B3LmeOzMiV6AlQ,7487
@@ -1127,9 +1127,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1127
1127
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1128
1128
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1129
1129
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1130
- supervisely-6.73.435.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1131
- supervisely-6.73.435.dist-info/METADATA,sha256=WRRLB8yK8nHMzOoIyjbjpxlbeC8s_7om9dJIrN5SozA,35433
1132
- supervisely-6.73.435.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1133
- supervisely-6.73.435.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1134
- supervisely-6.73.435.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1135
- supervisely-6.73.435.dist-info/RECORD,,
1130
+ supervisely-6.73.437.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1131
+ supervisely-6.73.437.dist-info/METADATA,sha256=XBgqkLz3078y1s0fpxtmLbxX8MUVdFj_zR6fvjs-FsA,35433
1132
+ supervisely-6.73.437.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1133
+ supervisely-6.73.437.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1134
+ supervisely-6.73.437.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1135
+ supervisely-6.73.437.dist-info/RECORD,,