supervisely 6.73.409__py3-none-any.whl → 6.73.410__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.
supervisely/__init__.py CHANGED
@@ -312,7 +312,9 @@ try:
312
312
  except Exception as e:
313
313
  logger.warn(f"Failed to setup certificates. Reason: {repr(e)}", exc_info=True)
314
314
 
315
- # If new changes in Supervisely Python SDK require upgrade of the Supervisely instance
316
- # set a new value for the environment variable MINIMUM_INSTANCE_VERSION_FOR_SDK, otherwise
317
- # users can face compatibility issues, if the instance version is lower than the SDK version.
318
- os.environ["MINIMUM_INSTANCE_VERSION_FOR_SDK"] = "6.14.00"
315
+ # Configure minimum instance version automatically from versions.json
316
+ # if new changes in Supervisely Python SDK require upgrade of the Supervisely instance.
317
+ # If the instance version is lower than the SDK version, users can face compatibility issues.
318
+ from supervisely.io.env import configure_minimum_instance_version
319
+
320
+ configure_minimum_instance_version()
supervisely/_utils.py CHANGED
@@ -597,3 +597,42 @@ def remove_non_printable(text: str) -> str:
597
597
  :rtype: str
598
598
  """
599
599
  return "".join(char for char in text if char.isprintable()).strip()
600
+
601
+
602
+ def get_latest_instance_version_from_json() -> Optional[str]:
603
+ """
604
+ Get the latest (last) instance version from versions.json file.
605
+
606
+ The versions.json file should contain a mapping of SDK versions to instance versions.
607
+ This function returns the instance version from the last entry in the file.
608
+
609
+ :return: Latest instance version or None if not found
610
+ :rtype: Optional[str]
611
+ """
612
+ import json
613
+
614
+ try:
615
+ # Get the path to versions.json relative to this file
616
+ current_dir = os.path.dirname(os.path.abspath(__file__))
617
+ versions_file = os.path.join(current_dir, "versions.json")
618
+
619
+ if not os.path.exists(versions_file):
620
+ logger.debug(f"versions.json file not found at {versions_file}")
621
+ return None
622
+
623
+ with open(versions_file, "r", encoding="utf-8") as f:
624
+ versions_mapping = json.load(f)
625
+
626
+ if not versions_mapping:
627
+ return None
628
+
629
+ # Get the last (latest) entry from the versions mapping
630
+ # Since JSON preserves order in Python 3.7+, the last item is the latest
631
+ latest_instance_version = list(versions_mapping.keys())[-1]
632
+ logger.debug(f"Latest instance version found: {latest_instance_version}")
633
+ return latest_instance_version
634
+
635
+ except Exception:
636
+ # Silently fail - don't break the import if versions.json is missing or malformed
637
+ logger.debug("Failed to get latest instance version from versions.json")
638
+ return None
@@ -695,6 +695,14 @@ class ApiField:
695
695
  """"""
696
696
  REMOTE_ENTITIES_COUNT = "remoteEntitiesCount"
697
697
  """"""
698
+ RESTRICTED_IMAGE_IDS = "restrictedImageIds"
699
+ """"""
700
+ NUMBER_OF_CLUSTERS = "numberOfClusters"
701
+ """"""
702
+ CLUSTERING_METHOD = "clusteringMethod"
703
+ """"""
704
+ ERROR_MESSAGE = "errorMessage"
705
+ """"""
698
706
 
699
707
 
700
708
  def _get_single_item(items):
@@ -215,6 +215,39 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
215
215
  ApiField.REMOTE_ENTITIES_COUNT,
216
216
  ]
217
217
 
218
+ @staticmethod
219
+ def info_sequence_for_listing():
220
+ """
221
+ NamedTuple ProjectInfo fields available for listing operations.
222
+
223
+ This subset includes only fields that are available in the `projects.list` API endpoint.
224
+ For complete project information, use `get_info_by_id()`.
225
+
226
+ :return: List of API field names available for listing
227
+ :rtype: List[str]
228
+ """
229
+ return [
230
+ ApiField.ID,
231
+ ApiField.NAME,
232
+ ApiField.DESCRIPTION,
233
+ ApiField.SIZE,
234
+ ApiField.README,
235
+ ApiField.WORKSPACE_ID,
236
+ ApiField.IMAGES_COUNT, # for compatibility with existing code
237
+ ApiField.DATASETS_COUNT,
238
+ ApiField.CREATED_AT,
239
+ ApiField.UPDATED_AT,
240
+ ApiField.TYPE,
241
+ ApiField.REFERENCE_IMAGE_URL,
242
+ ApiField.CUSTOM_DATA,
243
+ ApiField.BACKUP_ARCHIVE,
244
+ ApiField.TEAM_ID,
245
+ ApiField.IMPORT_SETTINGS,
246
+ ApiField.EMBEDDINGS_ENABLED,
247
+ ApiField.EMBEDDINGS_UPDATED_AT,
248
+ ApiField.EMBEDDINGS_IN_PROGRESS,
249
+ ]
250
+
218
251
  @staticmethod
219
252
  def info_tuple_name():
220
253
  """
@@ -347,7 +380,7 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
347
380
  id: int,
348
381
  expected_type: Optional[str] = None,
349
382
  raise_error: bool = False,
350
- extra_fields: Optional[List[str]] = None
383
+ extra_fields: Optional[List[str]] = None,
351
384
  ) -> ProjectInfo:
352
385
  """
353
386
  Get Project information by ID.
@@ -457,21 +490,24 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
457
490
  # import_settings={}
458
491
  # )
459
492
  """
460
-
461
- fields = [
462
- x
463
- for x in self.info_sequence()
464
- if x
465
- not in (
466
- ApiField.ITEMS_COUNT,
467
- ApiField.SETTINGS,
468
- ApiField.CREATED_BY_ID,
469
- ApiField.LOCAL_ENTITIES_COUNT,
470
- ApiField.REMOTE_ENTITIES_COUNT,
493
+ try:
494
+ fields = self.info_sequence_for_listing()
495
+ info = super().get_info_by_name(parent_id, name, fields)
496
+ except Exception as e:
497
+ logger.trace(
498
+ f"Failed to get info by name with all available fields for 'projects.list' endpoint: {e} "
499
+ "Falling back to minimal fields (id) and get_info_by_id()."
471
500
  )
472
- ]
473
-
474
- info = super().get_info_by_name(parent_id, name, fields)
501
+ fields = [ApiField.ID]
502
+ info = super().get_info_by_name(parent_id, name, fields)
503
+ if info is None:
504
+ if raise_error:
505
+ raise ProjectNotFound(
506
+ f"Project with name {name!r} not found in workspace {parent_id!r}."
507
+ )
508
+ else:
509
+ return None
510
+ info = self.get_info_by_id(info.id)
475
511
  self._check_project_info(
476
512
  info, name=name, expected_type=expected_type, raise_error=raise_error
477
513
  )
@@ -2213,7 +2249,21 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2213
2249
  {ApiField.ID: id, ApiField.EMBEDDINGS_ENABLED: False, ApiField.SILENT: silent},
2214
2250
  )
2215
2251
 
2216
- def set_embeddings_in_progress(self, id: int, in_progress: bool) -> None:
2252
+ def is_embeddings_enabled(self, id: int) -> bool:
2253
+ """
2254
+ Check if embeddings are enabled for the project.
2255
+
2256
+ :param id: Project ID
2257
+ :type id: int
2258
+ :return: True if embeddings are enabled, False otherwise.
2259
+ :rtype: bool
2260
+ """
2261
+ info = self.get_info_by_id(id, extra_fields=[ApiField.EMBEDDINGS_ENABLED])
2262
+ return info.embeddings_enabled
2263
+
2264
+ def set_embeddings_in_progress(
2265
+ self, id: int, in_progress: bool, error_message: Optional[str] = None
2266
+ ) -> None:
2217
2267
  """
2218
2268
  Set embeddings in progress status for the project.
2219
2269
  This method is used to indicate whether embeddings are currently being created for the project.
@@ -2222,13 +2272,34 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2222
2272
  :type id: int
2223
2273
  :param in_progress: Status to set. If True, embeddings are in progress right now.
2224
2274
  :type in_progress: bool
2275
+ :param error_message: Optional error message to provide additional context.
2276
+ :type error_message: Optional[str]
2225
2277
  :return: None
2226
2278
  :rtype: :class:`NoneType`
2227
2279
  """
2228
- self._api.post(
2229
- "projects.embeddings-in-progress.update",
2230
- {ApiField.ID: id, ApiField.EMBEDDINGS_IN_PROGRESS: in_progress},
2231
- )
2280
+ data = {ApiField.ID: id, ApiField.EMBEDDINGS_IN_PROGRESS: in_progress}
2281
+ if error_message is not None:
2282
+ data[ApiField.ERROR_MESSAGE] = error_message
2283
+ self._api.post("projects.embeddings-in-progress.update", data)
2284
+
2285
+ def get_embeddings_in_progress(self, id: int) -> bool:
2286
+ """
2287
+ Get the embeddings in progress status for the project.
2288
+ This method checks whether embeddings are currently being created for the project.
2289
+
2290
+ :param id: Project ID
2291
+ :type id: int
2292
+ :return: True if embeddings are in progress, False otherwise.
2293
+ :rtype: bool
2294
+ """
2295
+ info = self.get_info_by_id(id, extra_fields=[ApiField.EMBEDDINGS_IN_PROGRESS])
2296
+ if info is None:
2297
+ raise RuntimeError(f"Project with ID {id} not found.")
2298
+ if not hasattr(info, "embeddings_in_progress"):
2299
+ raise RuntimeError(
2300
+ f"Project with ID {id} does not have 'embeddings_in_progress' field in its info."
2301
+ )
2302
+ return info.embeddings_in_progress
2232
2303
 
2233
2304
  def set_embeddings_updated_at(
2234
2305
  self, id: int, timestamp: Optional[str] = None, silent: bool = True
@@ -2267,14 +2338,46 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2267
2338
  {ApiField.ID: id, ApiField.EMBEDDINGS_UPDATED_AT: timestamp, ApiField.SILENT: silent},
2268
2339
  )
2269
2340
 
2341
+ def get_embeddings_updated_at(self, id: int) -> Optional[str]:
2342
+ """
2343
+ Get the timestamp when embeddings were last updated for the project.
2344
+
2345
+ :param id: Project ID
2346
+ :type id: int
2347
+ :return: ISO format timestamp (YYYY-MM-DDTHH:MM:SS.fffZ) or None if not set.
2348
+ :rtype: Optional[str]
2349
+ :Usage example:
2350
+
2351
+ .. code-block:: python
2352
+
2353
+ api = sly.Api.from_env()
2354
+ project_id = 123
2355
+
2356
+ # Get embeddings updated timestamp
2357
+ updated_at = api.project.get_embeddings_updated_at(project_id)
2358
+ print(updated_at) # Output: "2025-06-01T10:30:45.123Z" or None
2359
+ """
2360
+ info = self.get_info_by_id(id, extra_fields=[ApiField.EMBEDDINGS_UPDATED_AT])
2361
+ if info is None:
2362
+ raise RuntimeError(f"Project with ID {id} not found.")
2363
+ if not hasattr(info, "embeddings_updated_at"):
2364
+ raise RuntimeError(
2365
+ f"Project with ID {id} does not have 'embeddings_updated_at' field in its info."
2366
+ )
2367
+ return info.embeddings_updated_at
2368
+
2270
2369
  def perform_ai_search(
2271
2370
  self,
2272
2371
  project_id: int,
2273
2372
  dataset_id: Optional[int] = None,
2274
- image_id: Optional[int] = None,
2373
+ image_id: Optional[Union[int, List[int]]] = None,
2275
2374
  prompt: Optional[str] = None,
2276
2375
  method: Optional[Literal["centroids", "random"]] = None,
2277
2376
  limit: int = 100,
2377
+ clustering_method: Optional[Literal["kmeans", "dbscan"]] = None,
2378
+ num_clusters: Optional[int] = None,
2379
+ image_id_scope: Optional[List[int]] = None,
2380
+ threshold: Optional[float] = None,
2278
2381
  ) -> Optional[int]:
2279
2382
  """
2280
2383
  Send AI search request to initiate search process.
@@ -2285,14 +2388,22 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2285
2388
  :type project_id: int
2286
2389
  :param dataset_id: ID of the Dataset. If not None - search will be limited to this dataset.
2287
2390
  :type dataset_id: Optional[int]
2288
- :param image_id: ID of the Image. Searches for images similar to the specified image.
2289
- :type image_id: Optional[int]
2391
+ :param image_id: ID(s) of the Image(s). Searches for images similar to the specified image(s).
2392
+ :type image_id: Optional[Union[int, List[int]]]
2290
2393
  :param prompt: Text prompt for search request. Searches for similar images based on a text description.
2291
2394
  :type prompt: Optional[str]
2292
2395
  :param method: Activates diverse search using one of the following methods: "centroids", "random".
2293
2396
  :type method: Optional[Literal["centroids", "random"]]
2294
2397
  :param limit: Limit for search request
2295
2398
  :type limit: int
2399
+ :param clustering_method: Method for clustering results. Can be "kmeans" or "dbscan". If None, no clustering is applied.
2400
+ :type clustering_method: Optional[Literal["kmeans", "dbscan"]]
2401
+ :param num_clusters: Number of clusters to create if clustering_method is specified. Required for "kmeans" method.
2402
+ :type num_clusters: Optional[int]
2403
+ :param image_id_scope: List of image IDs to limit the search scope. If None, the search will be performed across all images in the project if other filters are not set.
2404
+ :type image_id_scope: Optional[List[int]]
2405
+ :param threshold: Threshold for similarity. If provided, only images with similarity above this threshold will be returned.
2406
+ :type threshold: Optional[float]
2296
2407
  :return: Entitites Collection ID of the search results, or None if no collection was created.
2297
2408
  :rtype: Optional[int]
2298
2409
  :raises ValueError: only one of `prompt`, `image_id` or `method`must be provided, and `method` must be one of the allowed values.
@@ -2349,15 +2460,45 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2349
2460
  if dataset_id is not None:
2350
2461
  request_body[ApiField.DATASET_ID] = dataset_id
2351
2462
 
2352
- if image_id is not None:
2353
- request_body[ApiField.IMAGE_ID] = image_id
2354
-
2355
2463
  if prompt is not None:
2356
2464
  request_body[ApiField.PROMPT] = prompt
2357
2465
 
2466
+ if image_id is not None:
2467
+ if prompt is not None or method is not None:
2468
+ raise ValueError("If 'image_id' is provided, 'prompt' and 'method' must be None.")
2469
+ if isinstance(image_id, int):
2470
+ image_id = [image_id]
2471
+ if not isinstance(image_id, list):
2472
+ raise ValueError("image_id must be a list of image IDs.")
2473
+ request_body[ApiField.IMAGE_IDS] = image_id
2474
+
2358
2475
  if method is not None:
2476
+ if image_id is not None or prompt is not None:
2477
+ raise ValueError("If 'method' is provided, 'image_id' and 'prompt' must be None.")
2359
2478
  request_body[ApiField.METHOD] = method
2360
2479
 
2480
+ if clustering_method is not None:
2481
+ if clustering_method not in ["kmeans", "dbscan"]:
2482
+ raise ValueError("Clustering method must be either 'kmeans' or 'dbscan'.")
2483
+ request_body[ApiField.CLUSTERING_METHOD] = clustering_method
2484
+
2485
+ if num_clusters is not None:
2486
+ if clustering_method != "kmeans":
2487
+ raise ValueError(
2488
+ "Number of clusters is only applicable for 'kmeans' clustering method."
2489
+ )
2490
+ request_body[ApiField.NUMBER_OF_CLUSTERS] = num_clusters
2491
+
2492
+ if image_id_scope is not None:
2493
+ if not isinstance(image_id_scope, list):
2494
+ raise ValueError("image_id_scope must be a list of image IDs.")
2495
+ request_body[ApiField.RESTRICTED_IMAGE_IDS] = image_id_scope
2496
+
2497
+ if threshold is not None:
2498
+ if not isinstance(threshold, (int, float)):
2499
+ raise ValueError("Threshold must be a number.")
2500
+ request_body[ApiField.THRESHOLD] = threshold
2501
+
2361
2502
  response = self._api.post("embeddings.send-ai-search", request_body)
2362
2503
  return response.json().get(ApiField.COLLECTION_ID, None)
2363
2504
 
@@ -2366,6 +2507,8 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2366
2507
  Calculate embeddings for the project.
2367
2508
  This method is used to calculate embeddings for all images in the project.
2368
2509
 
2510
+ To check status of embeddings calculation, use :meth:`get_embeddings_in_progress`
2511
+
2369
2512
  :param id: Project ID
2370
2513
  :type id: int
2371
2514
  :return: None
supervisely/io/env.py CHANGED
@@ -671,3 +671,18 @@ def supervisely_skip_https_user_helper_check() -> bool:
671
671
  default=False,
672
672
  raise_not_found=False,
673
673
  )
674
+
675
+
676
+ def configure_minimum_instance_version() -> None:
677
+ """
678
+ Configure MINIMUM_INSTANCE_VERSION_FOR_SDK environment variable
679
+ from the latest entry in versions.json file.
680
+
681
+ This function should be called during SDK initialization to automatically
682
+ set the minimum required instance version based on the versions.json file.
683
+ """
684
+ from supervisely._utils import get_latest_instance_version_from_json
685
+
686
+ latest_version = get_latest_instance_version_from_json()
687
+ if latest_version:
688
+ os.environ["MINIMUM_INSTANCE_VERSION_FOR_SDK"] = latest_version
@@ -6,6 +6,7 @@ from typing import Dict, Optional, Tuple, Union
6
6
  from supervisely._utils import take_with_default
7
7
  from supervisely.annotation.tag_meta import TagMeta
8
8
  from supervisely.annotation.tag_meta_collection import TagMetaCollection
9
+ from supervisely.api.module_api import ApiField
9
10
  from supervisely.video_annotation.key_id_map import KeyIdMap
10
11
  from supervisely.video_annotation.video_tag import VideoTag
11
12
 
@@ -30,6 +31,10 @@ class PointcloudEpisodeTag(VideoTag):
30
31
  :type updated_at: str, optional
31
32
  :param created_at: Date and Time when PointcloudEpisodeTag was created. Date Format is the same as in "updated_at" parameter.
32
33
  :type created_at: str, optional
34
+ :param is_finished: Pointcloud Episode Tag is finished or not (applicable for range tags).
35
+ :type is_finished: bool, optional
36
+ :param non_final_value: Pointcloud Episode Tag value is final or not. Can be useful to create tag without value.
37
+ :type non_final_value: bool, optional
33
38
  :Usage example:
34
39
 
35
40
  .. code-block:: python
@@ -37,7 +42,7 @@ class PointcloudEpisodeTag(VideoTag):
37
42
  import supervisely as sly
38
43
 
39
44
  meta_car = sly.TagMeta('car', sly.TagValueType.NONE)
40
- # Now we can create a VideoTag using our TagMeta
45
+ # Now we can create a PointcloudEpisodeTag using our TagMeta
41
46
  tag_car = sly.PointcloudEpisodeTag(meta_car)
42
47
  # When you are creating a new Tag
43
48
  # Tag.value is automatically cross-checked against your TagMeta value type to make sure the value is valid.
@@ -60,7 +65,7 @@ class PointcloudEpisodeTag(VideoTag):
60
65
  # Output: ValueError: Tag car color can not have value yellow
61
66
  """
62
67
 
63
- _SUPPORT_UNFINISHED_TAGS = False
68
+ _SUPPORT_UNFINISHED_TAGS = True
64
69
 
65
70
  def __init__(
66
71
  self,
@@ -72,6 +77,8 @@ class PointcloudEpisodeTag(VideoTag):
72
77
  labeler_login=None,
73
78
  updated_at=None,
74
79
  created_at=None,
80
+ is_finished=None,
81
+ non_final_value=None,
75
82
  ):
76
83
  super().__init__(
77
84
  meta,
@@ -82,6 +89,8 @@ class PointcloudEpisodeTag(VideoTag):
82
89
  labeler_login,
83
90
  updated_at,
84
91
  created_at,
92
+ is_finished=is_finished,
93
+ non_final_value=non_final_value,
85
94
  )
86
95
 
87
96
  @classmethod
@@ -121,7 +130,8 @@ class PointcloudEpisodeTag(VideoTag):
121
130
 
122
131
  tag_car_color = sly.PointcloudEpisodeTag.from_json(tag_car_color_json, meta_car_collection)
123
132
  """
124
-
133
+ is_finished = data.get(ApiField.IS_FINISHED, True)
134
+ non_final_value = data.get(ApiField.NON_FINAL_VALUE, False)
125
135
  temp = super(PointcloudEpisodeTag, cls).from_json(data, tag_meta_collection, key_id_map)
126
136
 
127
137
  return cls(
@@ -133,6 +143,8 @@ class PointcloudEpisodeTag(VideoTag):
133
143
  labeler_login=temp.labeler_login,
134
144
  updated_at=temp.updated_at,
135
145
  created_at=temp.created_at,
146
+ is_finished=is_finished,
147
+ non_final_value=non_final_value,
136
148
  )
137
149
 
138
150
  def __eq__(self, other: PointcloudEpisodeTag) -> bool:
@@ -148,6 +160,8 @@ class PointcloudEpisodeTag(VideoTag):
148
160
  labeler_login: Optional[str] = None,
149
161
  updated_at: Optional[str] = None,
150
162
  created_at: Optional[str] = None,
163
+ is_finished: Optional[bool] = None,
164
+ non_final_value: Optional[bool] = None,
151
165
  ) -> PointcloudEpisodeTag:
152
166
  """
153
167
  Makes a copy of PointcloudEpisodeTag with new fields, if fields are given, otherwise it will use fields of the original PointcloudEpisodeTag.
@@ -168,6 +182,10 @@ class PointcloudEpisodeTag(VideoTag):
168
182
  :type updated_at: str, optional
169
183
  :param created_at: Date and Time when PointcloudEpisodeTag was created. Date Format is the same as in "updated_at" parameter.
170
184
  :type created_at: str, optional
185
+ :param is_finished: Pointcloud Episode Tag is finished or not (applicable for range tags).
186
+ :type is_finished: bool, optional
187
+ :param non_final_value: Pointcloud Episode Tag value is final or not. Can be useful to create tag without value.
188
+ :type non_final_value: bool, optional
171
189
  :Usage example:
172
190
 
173
191
  .. code-block:: python
@@ -201,4 +219,6 @@ class PointcloudEpisodeTag(VideoTag):
201
219
  labeler_login=take_with_default(labeler_login, self.labeler_login),
202
220
  updated_at=take_with_default(updated_at, self.updated_at),
203
221
  created_at=take_with_default(created_at, self.created_at),
222
+ is_finished=take_with_default(is_finished, self.is_finished),
223
+ non_final_value=take_with_default(non_final_value, self.non_final_value),
204
224
  )
@@ -0,0 +1,26 @@
1
+ {
2
+ "6.9.11": "6.72.70",
3
+ "6.9.13": "6.73.76",
4
+ "6.9.18": "6.73.81",
5
+ "6.9.22": "6.73.90",
6
+ "6.9.31": "6.73.123",
7
+ "6.10.0": "6.73.126",
8
+ "6.11.8": "6.73.159",
9
+ "6.11.10": "6.73.166",
10
+ "6.11.16": "6.73.184",
11
+ "6.11.19": "6.73.199",
12
+ "6.12.2": "6.73.222",
13
+ "6.12.5": "6.73.226",
14
+ "6.12.12": "6.73.241",
15
+ "6.12.17": "6.73.263",
16
+ "6.12.23": "6.73.281",
17
+ "6.12.28": "6.73.292",
18
+ "6.12.30": "6.73.312",
19
+ "6.12.34": "6.73.324",
20
+ "6.12.44": "6.73.344",
21
+ "6.12.46": "6.73.375",
22
+ "6.13.1": "6.73.379",
23
+ "6.13.8": "6.73.394",
24
+ "6.14.0": "6.73.400",
25
+ "6.14.4": "6.73.410"
26
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.409
3
+ Version: 6.73.410
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -1,9 +1,10 @@
1
1
  supervisely/README.md,sha256=XM-DiMC6To3I9RjQZ0c61905EFRR_jnCUx2q3uNR-X8,3331
2
- supervisely/__init__.py,sha256=lr0ZXE_WCeOpNo-zsynBKIhG3RaeKyXl549b6vk1nfU,11010
3
- supervisely/_utils.py,sha256=Wrnck4645QXRZdmMpqIRQ_t6QynEAkYaFfcialxQBIE,19157
2
+ supervisely/__init__.py,sha256=ojclMFGrJk0YVXxFU5wcUOQINaeFQ_eiZ1-GzModiYs,11035
3
+ supervisely/_utils.py,sha256=59vOeNOnmVHODnlAvULT8jdwvHHVTs2FOtAFw8mvaqE,20643
4
4
  supervisely/function_wrapper.py,sha256=R5YajTQ0GnRp2vtjwfC9hINkzQc0JiyGsu8TER373xY,1912
5
5
  supervisely/sly_logger.py,sha256=z92Vu5hmC0GgTIJO1n6kPDayRW9__8ix8hL6poDZj-Y,6274
6
6
  supervisely/tiny_timer.py,sha256=hkpe_7FE6bsKL79blSs7WBaktuPavEVu67IpEPrfmjE,183
7
+ supervisely/versions.json,sha256=xfHoZZTqcNGMK-BumXLEQnTmSyvCjdATci45G6a_MJk,562
7
8
  supervisely/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
9
  supervisely/annotation/annotation.py,sha256=th4gsIU-LNGcMRohHrtupmjxDwdzx1g4_0xIAa6NyJU,114717
9
10
  supervisely/annotation/annotation_transforms.py,sha256=TlVy_gUbM-XH6GbLpZPrAi6pMIGTr7Ow02iSKOSTa-I,9582
@@ -35,10 +36,10 @@ supervisely/api/import_storage_api.py,sha256=BDCgmR0Hv6OoiRHLCVPKt3iDxSVlQp1WrnK
35
36
  supervisely/api/issues_api.py,sha256=BqDJXmNoTzwc3xe6_-mA7FDFC5QQ-ahGbXk_HmpkSeQ,17925
36
37
  supervisely/api/labeling_job_api.py,sha256=G2_BV_WtA2lAhfw_nAQmWmv1P-pwimD0ba9GVKoGjiA,55537
37
38
  supervisely/api/labeling_queue_api.py,sha256=ilNjAL1d9NSa9yabQn6E-W26YdtooT3ZGXIFZtGnAvY,30158
38
- supervisely/api/module_api.py,sha256=FF8fTRxdR7QbzxyntPDhmTTbnFobCq-Lcujs9DWWK98,46126
39
+ supervisely/api/module_api.py,sha256=vqojLHCC-uCNVnqB2FUMCJdXAElg5FON3BZTr8AkiiE,46340
39
40
  supervisely/api/object_class_api.py,sha256=7-npNFMYjWNtSXYZg6syc6bX56_oCzDU2kFRPGQWCwA,10399
40
41
  supervisely/api/plugin_api.py,sha256=SFm0IlTTOjuHBLUMgG4d4k6U3cWJocE-SVb-f08fwMQ,5286
41
- supervisely/api/project_api.py,sha256=UR9IQ2fMm7te50DtpFrCad1WSS6WQ_GUdXB7NA6NZ34,89642
42
+ supervisely/api/project_api.py,sha256=ZTmPEqWUQgYv5s5nEvnb2qobaiYxHFxibYZrtsJ-QAs,96362
42
43
  supervisely/api/project_class_api.py,sha256=5cyjdGPPb2tpttu5WmYoOxUNiDxqiojschkhZumF0KM,1426
43
44
  supervisely/api/remote_storage_api.py,sha256=1O4rTIwW8s9gxC00yvFuKbEMGNsa7YSRlZ8j494ARwY,17793
44
45
  supervisely/api/report_api.py,sha256=Om7CGulUbQ4BuJ16eDtz7luLe0JQNqab-LoLpUXu7YE,7123
@@ -723,7 +724,7 @@ supervisely/imaging/font.py,sha256=0XcmWhlw7y2PAhrWgcsfInyRWj0WnlFpMSEXXilR8UA,2
723
724
  supervisely/imaging/image.py,sha256=1KNc4qRbP9OlI4Yta07Kc2ohAgSBJ_9alF9Jag74w30,41873
724
725
  supervisely/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
725
726
  supervisely/io/docker_utils.py,sha256=hb_HXGM8IYB0PF-nD7NxMwaHgzaxIFxofsUzQ_RCUZI,7935
726
- supervisely/io/env.py,sha256=l-Xkil6FVxMP8FmnjF4H4p3RJQ3AoBd0OUjZHA2QVTc,21193
727
+ supervisely/io/env.py,sha256=fK-v4rW_tWiS6qjZtv91WM7uNtem27E_F1zDvaYfjN4,21766
727
728
  supervisely/io/exception_handlers.py,sha256=22LPlLgyq59DnrhpaFrbGBYJE7uxO64VTZjsPJC0PLE,36757
728
729
  supervisely/io/fs.py,sha256=pzNAK5fbT3G-7PKRY5oYcOPjgXeZ9x5Dyry7fzzZsr8,63604
729
730
  supervisely/io/fs_cache.py,sha256=985gvBGzveLcDudgz10E4EWVjP9jxdU1Pa0GFfCBoCA,6520
@@ -1026,7 +1027,7 @@ supervisely/pointcloud_annotation/pointcloud_episode_frame.py,sha256=XI1tZVs7vPN
1026
1027
  supervisely/pointcloud_annotation/pointcloud_episode_frame_collection.py,sha256=_nyvoN8dQ9mMdNKlPqGAiXnoWJl7TlmcODZNI-Cx29M,16113
1027
1028
  supervisely/pointcloud_annotation/pointcloud_episode_object.py,sha256=kkjLwxm6clLTFMmXXyM8n-k58Jyzmf3buJsEWyRK2Pg,2221
1028
1029
  supervisely/pointcloud_annotation/pointcloud_episode_object_collection.py,sha256=emP5RuejfwuUhyA5MmgGPXMinowNBkFREHe7qEKUdfE,2707
1029
- supervisely/pointcloud_annotation/pointcloud_episode_tag.py,sha256=wen4fDZnPgNCCi6jFbblvpWMiMpOORUYgzgDRDaNclI,9000
1030
+ supervisely/pointcloud_annotation/pointcloud_episode_tag.py,sha256=msFhL7MkWO_beE6PJ_PvSU2nPMLhUV6J6iBwOlqkJEY,10257
1030
1031
  supervisely/pointcloud_annotation/pointcloud_episode_tag_collection.py,sha256=B4b9Ob26kAdpLWzBlHSeZNn7OPw8E7nHdHpnFrEbF-E,10358
1031
1032
  supervisely/pointcloud_annotation/pointcloud_figure.py,sha256=URhVTChvF2WCLTYhT2UFzYE1pU5JWr_TGz-TAsfW3u0,11194
1032
1033
  supervisely/pointcloud_annotation/pointcloud_object.py,sha256=7SB_t-kLxY_dwxbVbjfGqB-n_vLKhkhGJV9Epgq-fa4,5652
@@ -1114,9 +1115,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1114
1115
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1115
1116
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1116
1117
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1117
- supervisely-6.73.409.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1118
- supervisely-6.73.409.dist-info/METADATA,sha256=oVG-Ilf2UfnueczjSJvq8bF1HhG3GcVQPVczU9N_mfQ,35254
1119
- supervisely-6.73.409.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1120
- supervisely-6.73.409.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1121
- supervisely-6.73.409.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1122
- supervisely-6.73.409.dist-info/RECORD,,
1118
+ supervisely-6.73.410.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1119
+ supervisely-6.73.410.dist-info/METADATA,sha256=CNGxrr7PWqWR6ZPxhf6ujqvjgoEq4TxkKeUbTRLoiEw,35254
1120
+ supervisely-6.73.410.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1121
+ supervisely-6.73.410.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1122
+ supervisely-6.73.410.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1123
+ supervisely-6.73.410.dist-info/RECORD,,