supervisely 6.73.287__py3-none-any.whl → 6.73.288__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.

Potentially problematic release.


This version of supervisely might be problematic. Click here for more details.

@@ -543,7 +543,7 @@ class Annotation:
543
543
  image_id=take_with_default(image_id, self.image_id),
544
544
  )
545
545
 
546
- def _add_labels_impl(self, dest, labels):
546
+ def _add_labels_impl(self, dest: List, labels: List[Label]):
547
547
  """
548
548
  The function _add_labels_impl extend list of the labels of the current Annotation object
549
549
  :param dest: destination list of the Label class objects
@@ -554,7 +554,15 @@ class Annotation:
554
554
  if self.img_size.count(None) == 0:
555
555
  # image has resolution in DB
556
556
  canvas_rect = Rectangle.from_size(self.img_size)
557
- dest.extend(label.crop(canvas_rect))
557
+ try:
558
+ dest.extend(label.crop(canvas_rect))
559
+ except Exception:
560
+ logger.error(
561
+ f"Cannot crop label of '{label.obj_class.name}' class "
562
+ "when extend list of the labels of the current Annotation object",
563
+ exc_info=True,
564
+ )
565
+ raise
558
566
  else:
559
567
  # image was uploaded by link and does not have resolution in DB
560
568
  # add label without normalization and validation
@@ -1403,37 +1403,33 @@ class AnnotationApi(ModuleApi):
1403
1403
  progress_cb(len(response.content))
1404
1404
 
1405
1405
  result = response.json()
1406
- # Convert annotation to pixel coordinate system
1407
- result[ApiField.ANNOTATION] = Annotation._to_pixel_coordinate_system_json(
1408
- result[ApiField.ANNOTATION]
1406
+ # Convert annotation to pixel coordinate system
1407
+ result[ApiField.ANNOTATION] = Annotation._to_pixel_coordinate_system_json(
1408
+ result[ApiField.ANNOTATION]
1409
+ )
1410
+ # check if there are any AlphaMask geometries in the batch
1411
+ additonal_geometries = defaultdict(int)
1412
+ labels = result[ApiField.ANNOTATION][AnnotationJsonFields.LABELS]
1413
+ for idx, label in enumerate(labels):
1414
+ if label[LabelJsonFields.GEOMETRY_TYPE] == AlphaMask.geometry_name():
1415
+ figure_id = label[LabelJsonFields.ID]
1416
+ additonal_geometries[figure_id] = idx
1417
+
1418
+ # if so, download them separately and update the annotation
1419
+ if len(additonal_geometries) > 0:
1420
+ figure_ids = list(additonal_geometries.keys())
1421
+ figures = await self._api.image.figure.download_geometries_batch_async(
1422
+ figure_ids,
1423
+ (progress_cb if progress_cb is not None and progress_cb_type == "size" else None),
1424
+ semaphore=semaphore,
1409
1425
  )
1410
- # check if there are any AlphaMask geometries in the batch
1411
- additonal_geometries = defaultdict(int)
1412
- labels = result[ApiField.ANNOTATION][AnnotationJsonFields.LABELS]
1413
- for idx, label in enumerate(labels):
1414
- if label[LabelJsonFields.GEOMETRY_TYPE] == AlphaMask.geometry_name():
1415
- figure_id = label[LabelJsonFields.ID]
1416
- additonal_geometries[figure_id] = idx
1417
-
1418
- # if so, download them separately and update the annotation
1419
- if len(additonal_geometries) > 0:
1420
- figure_ids = list(additonal_geometries.keys())
1421
- figures = await self._api.image.figure.download_geometries_batch_async(
1422
- figure_ids,
1423
- (
1424
- progress_cb
1425
- if progress_cb is not None and progress_cb_type == "size"
1426
- else None
1427
- ),
1428
- semaphore=semaphore,
1429
- )
1430
- for figure_id, geometry in zip(figure_ids, figures):
1431
- label_idx = additonal_geometries[figure_id]
1432
- labels[label_idx].update({BITMAP: geometry})
1433
- ann_info = self._convert_json_info(result)
1434
- if progress_cb is not None and progress_cb_type == "number":
1435
- progress_cb(1)
1436
- return ann_info
1426
+ for figure_id, geometry in zip(figure_ids, figures):
1427
+ label_idx = additonal_geometries[figure_id]
1428
+ labels[label_idx].update({BITMAP: geometry})
1429
+ ann_info = self._convert_json_info(result)
1430
+ if progress_cb is not None and progress_cb_type == "number":
1431
+ progress_cb(1)
1432
+ return ann_info
1437
1433
 
1438
1434
  async def download_batch_async(
1439
1435
  self,
supervisely/api/api.py CHANGED
@@ -66,10 +66,10 @@ import supervisely.io.env as sly_env
66
66
  from supervisely._utils import camel_to_snake, is_community, is_development
67
67
  from supervisely.api.module_api import ApiField
68
68
  from supervisely.io.network_exceptions import (
69
+ RetryableRequestException,
69
70
  process_requests_exception,
70
71
  process_requests_exception_async,
71
72
  process_unhandled_request,
72
- RetryableRequestException,
73
73
  )
74
74
  from supervisely.project.project_meta import ProjectMeta
75
75
  from supervisely.sly_logger import logger
@@ -380,6 +380,7 @@ class Api:
380
380
  self.async_httpx_client: httpx.AsyncClient = None
381
381
  self.httpx_client: httpx.Client = None
382
382
  self._semaphore = None
383
+ self._instance_version = None
383
384
 
384
385
  @classmethod
385
386
  def normalize_server_address(cls, server_address: str) -> str:
@@ -515,11 +516,14 @@ class Api:
515
516
  # '6.9.13'
516
517
  """
517
518
  try:
518
- version = self.post("instance.version", {}).json().get(ApiField.VERSION)
519
+ if self._instance_version is None:
520
+ self._instance_version = (
521
+ self.post("instance.version", {}).json().get(ApiField.VERSION)
522
+ )
519
523
  except Exception as e:
520
524
  logger.warning(f"Failed to get instance version from server: {e}")
521
- version = "unknown"
522
- return version
525
+ self._instance_version = "unknown"
526
+ return self._instance_version
523
527
 
524
528
  def is_version_supported(self, version: Optional[str] = None) -> Union[bool, None]:
525
529
  """Check if the given version is lower or equal to the current Supervisely instance version.
@@ -642,13 +642,13 @@ class FigureApi(RemoveableBulkModuleApi):
642
642
  response = await self._api.post_async(
643
643
  "figures.bulk.download.geometry", {ApiField.IDS: batch_ids}
644
644
  )
645
- decoder = MultipartDecoder.from_response(response)
646
- for part in decoder.parts:
647
- content_utf8 = part.headers[b"Content-Disposition"].decode("utf-8")
648
- # Find name="1245" preceded by a whitespace, semicolon or beginning of line.
649
- # The regex has 2 capture group: one for the prefix and one for the actual name value.
650
- figure_id = int(re.findall(r'(^|[\s;])name="(\d*)"', content_utf8)[0][1])
651
- yield figure_id, part.content
645
+ decoder = MultipartDecoder.from_response(response)
646
+ for part in decoder.parts:
647
+ content_utf8 = part.headers[b"Content-Disposition"].decode("utf-8")
648
+ # Find name="1245" preceded by a whitespace, semicolon or beginning of line.
649
+ # The regex has 2 capture group: one for the prefix and one for the actual name value.
650
+ figure_id = int(re.findall(r'(^|[\s;])name="(\d*)"', content_utf8)[0][1])
651
+ yield figure_id, part.content
652
652
 
653
653
  async def download_geometries_batch_async(
654
654
  self,
@@ -4456,26 +4456,26 @@ class ImageApi(RemoveableBulkModuleApi):
4456
4456
  json=json_body,
4457
4457
  headers=headers,
4458
4458
  )
4459
- decoder = MultipartDecoder.from_response(response)
4460
- for part in decoder.parts:
4461
- content_utf8 = part.headers[b"Content-Disposition"].decode("utf-8")
4462
- # Find name="1245" preceded by a whitespace, semicolon or beginning of line.
4463
- # The regex has 2 capture group: one for the prefix and one for the actual name value.
4464
- img_id = int(re.findall(r'(^|[\s;])name="(\d*)"', content_utf8)[0][1])
4465
- if check_hash:
4466
- hhash = part.headers.get("x-content-checksum-sha256", None)
4467
- if hhash is not None:
4468
- downloaded_bytes_hash = get_bytes_hash(part)
4469
- if hhash != downloaded_bytes_hash:
4470
- raise RuntimeError(
4471
- f"Downloaded hash of image with ID:{img_id} does not match the expected hash: {downloaded_bytes_hash} != {hhash}"
4472
- )
4473
- if progress_cb is not None and progress_cb_type == "number":
4474
- progress_cb(1)
4475
- elif progress_cb is not None and progress_cb_type == "size":
4476
- progress_cb(len(part.content))
4459
+ decoder = MultipartDecoder.from_response(response)
4460
+ for part in decoder.parts:
4461
+ content_utf8 = part.headers[b"Content-Disposition"].decode("utf-8")
4462
+ # Find name="1245" preceded by a whitespace, semicolon or beginning of line.
4463
+ # The regex has 2 capture group: one for the prefix and one for the actual name value.
4464
+ img_id = int(re.findall(r'(^|[\s;])name="(\d*)"', content_utf8)[0][1])
4465
+ if check_hash:
4466
+ hhash = part.headers.get("x-content-checksum-sha256", None)
4467
+ if hhash is not None:
4468
+ downloaded_bytes_hash = get_bytes_hash(part)
4469
+ if hhash != downloaded_bytes_hash:
4470
+ raise RuntimeError(
4471
+ f"Downloaded hash of image with ID:{img_id} does not match the expected hash: {downloaded_bytes_hash} != {hhash}"
4472
+ )
4473
+ if progress_cb is not None and progress_cb_type == "number":
4474
+ progress_cb(1)
4475
+ elif progress_cb is not None and progress_cb_type == "size":
4476
+ progress_cb(len(part.content))
4477
4477
 
4478
- yield img_id, part.content
4478
+ yield img_id, part.content
4479
4479
 
4480
4480
  async def get_list_generator_async(
4481
4481
  self,
@@ -9,6 +9,7 @@ from typing import Dict, List, Optional, Tuple, Union
9
9
  import cv2
10
10
  import numpy as np
11
11
 
12
+ from supervisely import logger
12
13
  from supervisely.geometry.constants import (
13
14
  CLASS_ID,
14
15
  CREATED_AT,
@@ -215,6 +216,8 @@ class GraphNodes(Geometry):
215
216
  updated_at=updated_at,
216
217
  created_at=created_at,
217
218
  )
219
+ if len(nodes) == 0:
220
+ raise ValueError("Empty list of nodes is not allowed for GraphNodes")
218
221
  self._nodes = nodes
219
222
  if isinstance(nodes, (list, tuple)):
220
223
  self._nodes = {}
@@ -593,6 +596,10 @@ class GraphNodes(Geometry):
593
596
 
594
597
  rectangle = figure.to_bbox()
595
598
  """
599
+ if self._nodes is None or len(self._nodes) == 0:
600
+ logger.warning(
601
+ f"Cannot create a bounding box from {self.name()} with empty nodes. Geometry ID: {self.sly_id} "
602
+ )
596
603
  return Rectangle.from_geometries_list(
597
604
  [Point.from_point_location(node.location) for node in self._nodes.values()]
598
605
  )
@@ -476,7 +476,7 @@ class Rectangle(Geometry):
476
476
  return cls(0, 0, size[0] - 1, size[1] - 1)
477
477
 
478
478
  @classmethod
479
- def from_geometries_list(cls, geometries: List[sly.geometry.geometry]) -> Rectangle:
479
+ def from_geometries_list(cls, geometries: List[Geometry]) -> Rectangle:
480
480
  """
481
481
  Create Rectangle from given geometry objects.
482
482
 
@@ -494,6 +494,8 @@ class Rectangle(Geometry):
494
494
  geom_objs = [sly.Point(100, 200), sly.Polyline([sly.PointLocation(730, 2104), sly.PointLocation(2479, 402)])]
495
495
  figure_from_geom_objs = sly.Rectangle.from_geometries_list(geom_objs)
496
496
  """
497
+ if geometries is None or len(geometries) == 0:
498
+ raise ValueError("No geometries provided to create a Rectangle.")
497
499
  bboxes = [g.to_bbox() for g in geometries]
498
500
  top = min(bbox.top for bbox in bboxes)
499
501
  left = min(bbox.left for bbox in bboxes)
@@ -4780,26 +4780,6 @@ async def _download_project_async(
4780
4780
  if semaphore is None:
4781
4781
  semaphore = api.get_default_semaphore()
4782
4782
 
4783
- # number of workers
4784
- num_workers = min(kwargs.get("num_workers", semaphore._value), 10)
4785
-
4786
- async def worker(queue: asyncio.Queue, stop_event: asyncio.Event):
4787
- while not stop_event.is_set():
4788
- task = await queue.get()
4789
- if task is None:
4790
- break
4791
- try:
4792
- await task
4793
- except Exception as e:
4794
- logger.error(f"Error in _download_project_async worker: {e}")
4795
- stop_event.set()
4796
- finally:
4797
- queue.task_done()
4798
-
4799
- queue = asyncio.Queue()
4800
- stop_event = asyncio.Event()
4801
- workers = [asyncio.create_task(worker(queue, stop_event)) for _ in range(num_workers)]
4802
-
4803
4783
  dataset_ids = set(dataset_ids) if (dataset_ids is not None) else None
4804
4784
  project_fs = None
4805
4785
  meta = ProjectMeta.from_json(api.project.get_meta(project_id, with_settings=True))
@@ -4883,11 +4863,25 @@ async def _download_project_async(
4883
4863
  ds_progress(1)
4884
4864
  return to_download
4885
4865
 
4866
+ async def run_tasks_with_delay(tasks, delay=0.1):
4867
+ created_tasks = []
4868
+ for task in tasks:
4869
+ created_task = asyncio.create_task(task)
4870
+ created_tasks.append(created_task)
4871
+ await asyncio.sleep(delay)
4872
+ logger.debug(
4873
+ f"{len(created_tasks)} tasks have been created for dataset ID: {dataset.id}, Name: {dataset.name}"
4874
+ )
4875
+ return created_tasks
4876
+
4877
+ tasks = []
4886
4878
  small_images = await check_items(small_images)
4887
4879
  large_images = await check_items(large_images)
4880
+
4888
4881
  if len(small_images) == 1:
4889
4882
  large_images.append(small_images.pop())
4890
4883
  for images_batch in batched(small_images, batch_size=batch_size):
4884
+
4891
4885
  task = _download_project_items_batch_async(
4892
4886
  api=api,
4893
4887
  dataset_id=dataset_id,
@@ -4901,7 +4895,7 @@ async def _download_project_async(
4901
4895
  only_image_tags=only_image_tags,
4902
4896
  progress_cb=ds_progress,
4903
4897
  )
4904
- await queue.put(task)
4898
+ tasks.append(task)
4905
4899
  for image in large_images:
4906
4900
  task = _download_project_item_async(
4907
4901
  api=api,
@@ -4915,9 +4909,10 @@ async def _download_project_async(
4915
4909
  only_image_tags=only_image_tags,
4916
4910
  progress_cb=ds_progress,
4917
4911
  )
4918
- await queue.put(task)
4912
+ tasks.append(task)
4919
4913
 
4920
- await queue.join()
4914
+ created_tasks = await run_tasks_with_delay(tasks)
4915
+ await asyncio.gather(*created_tasks)
4921
4916
 
4922
4917
  if save_image_meta:
4923
4918
  meta_dir = dataset_fs.meta_dir
@@ -4934,13 +4929,6 @@ async def _download_project_async(
4934
4929
  if item_name not in items_names_set:
4935
4930
  dataset_fs.delete_item(item_name)
4936
4931
 
4937
- for _ in range(num_workers):
4938
- await queue.put(None)
4939
- await asyncio.gather(*workers)
4940
-
4941
- if stop_event.is_set():
4942
- raise RuntimeError("Download process was stopped due to an error in one of the workers.")
4943
-
4944
4932
  try:
4945
4933
  create_readme(dest_dir, project_id, api)
4946
4934
  except Exception as e:
@@ -4964,7 +4952,7 @@ async def _download_project_item_async(
4964
4952
  """
4965
4953
  if save_images:
4966
4954
  logger.debug(
4967
- f"Downloading 1 image in single mode: {img_info.name} with _download_project_item_async"
4955
+ f"Downloading 1 image in single mode with _download_project_item_async. ID: {img_info.id}, Name: {img_info.name}"
4968
4956
  )
4969
4957
  img_bytes = await api.image.download_bytes_single_async(
4970
4958
  img_info.id, semaphore=semaphore, check_hash=True
@@ -4982,7 +4970,11 @@ async def _download_project_item_async(
4982
4970
  force_metadata_for_links=not save_images,
4983
4971
  )
4984
4972
  ann_json = ann_info.annotation
4985
- tmp_ann = Annotation.from_json(ann_json, meta)
4973
+ try:
4974
+ tmp_ann = Annotation.from_json(ann_json, meta)
4975
+ except Exception:
4976
+ logger.error(f"Error while deserializing annotation for image with ID: {img_info.id}")
4977
+ raise
4986
4978
  if None in tmp_ann.img_size:
4987
4979
  tmp_ann = tmp_ann.clone(img_size=(img_info.height, img_info.width))
4988
4980
  ann_json = tmp_ann.to_json()
@@ -5004,6 +4996,7 @@ async def _download_project_item_async(
5004
4996
  )
5005
4997
  if progress_cb is not None:
5006
4998
  progress_cb(1)
4999
+ logger.debug(f"Single project item has been downloaded. Semaphore state: {semaphore._value}")
5007
5000
 
5008
5001
 
5009
5002
  async def _download_project_items_batch_async(
@@ -5056,12 +5049,18 @@ async def _download_project_items_batch_async(
5056
5049
  semaphore=semaphore,
5057
5050
  force_metadata_for_links=not save_images,
5058
5051
  )
5059
- tmps_anns = [Annotation.from_json(ann_info.annotation, meta) for ann_info in ann_infos]
5060
5052
  ann_jsons = []
5061
- for tmp_ann in tmps_anns:
5062
- if None in tmp_ann.img_size:
5063
- tmp_ann = tmp_ann.clone(img_size=(img_info.height, img_info.width))
5064
- ann_jsons.append(tmp_ann.to_json())
5053
+ for img_info, ann_info in zip(img_infos, ann_infos):
5054
+ try:
5055
+ tmp_ann = Annotation.from_json(ann_info.annotation, meta)
5056
+ if None in tmp_ann.img_size:
5057
+ tmp_ann = tmp_ann.clone(img_size=(img_info.height, img_info.width))
5058
+ ann_jsons.append(tmp_ann.to_json())
5059
+ except Exception:
5060
+ logger.error(
5061
+ f"Error while deserializing annotation for image with ID: {img_info.id}"
5062
+ )
5063
+ raise
5065
5064
  else:
5066
5065
  ann_jsons = []
5067
5066
  for img_info in img_infos:
@@ -5083,5 +5082,7 @@ async def _download_project_items_batch_async(
5083
5082
  if progress_cb is not None:
5084
5083
  progress_cb(1)
5085
5084
 
5085
+ logger.debug(f"Batch of project items has been downloaded. Semaphore state: {semaphore._value}")
5086
+
5086
5087
 
5087
5088
  DatasetDict = Project.DatasetDict
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.287
3
+ Version: 6.73.288
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -5,7 +5,7 @@ supervisely/function_wrapper.py,sha256=R5YajTQ0GnRp2vtjwfC9hINkzQc0JiyGsu8TER373
5
5
  supervisely/sly_logger.py,sha256=LG1wTyyctyEKuCuKM2IKf_SMPH7BzkTsFdO-0tnorzg,6225
6
6
  supervisely/tiny_timer.py,sha256=hkpe_7FE6bsKL79blSs7WBaktuPavEVu67IpEPrfmjE,183
7
7
  supervisely/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- supervisely/annotation/annotation.py,sha256=Kdn3HRpx7ie6vkDaQFXrg597nOidZ6FMN-oXpDk4nyI,114289
8
+ supervisely/annotation/annotation.py,sha256=5AG1AhebkmiYy2r7nKbz6TjdmCF4tuf9FtqUjLLs7aU,114659
9
9
  supervisely/annotation/annotation_transforms.py,sha256=TlVy_gUbM-XH6GbLpZPrAi6pMIGTr7Ow02iSKOSTa-I,9582
10
10
  supervisely/annotation/json_geometries_map.py,sha256=nL6AmMhFy02fw9ryBm75plKyOkDh61QdOToSuLAcz_Q,1659
11
11
  supervisely/annotation/label.py,sha256=NpHZ5o2H6dI4KiII22o2HpiLXG1yekh-bEy8WvI2Ljg,37498
@@ -21,14 +21,14 @@ supervisely/annotation/tag_meta_mapper.py,sha256=RWeTrxJ64syodyhXIRSH007bX6Hr3B4
21
21
  supervisely/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  supervisely/api/advanced_api.py,sha256=Nd5cCnHFWc3PSUrCtENxTGtDjS37_lCHXsgXvUI3Ti8,2054
23
23
  supervisely/api/agent_api.py,sha256=ShWAIlXcWXcyI9fqVuP5GZVCigCMJmjnvdGUfLspD6Y,8890
24
- supervisely/api/annotation_api.py,sha256=kB9l0NhQEkunGDC9fWjNzf5DdhqRF1tv-RRnIbkV2k0,64941
25
- supervisely/api/api.py,sha256=0dgPx_eizoCEFzfT8YH9uh1kq-OJwjrV5fBGD7uZ7E4,65840
24
+ supervisely/api/annotation_api.py,sha256=fVQJOg5SLcD_mRUmPaVsJIOVTGFhsabRXqve0LyUgrc,64743
25
+ supervisely/api/api.py,sha256=YBE6yi682H5dy3BBQtESmfC9hKZcbHyYRPNGLRldgSU,66014
26
26
  supervisely/api/app_api.py,sha256=RsbVej8WxWVn9cNo5s3Fqd1symsCdsfOaKVBKEUapRY,71927
27
27
  supervisely/api/dataset_api.py,sha256=GH7prDRJKyJlTv_7_Y-RkTwJN7ED4EkXNqqmi3iIdI4,41352
28
28
  supervisely/api/file_api.py,sha256=v2FsD3oljwNPqcDgEJRe8Bu5k0PYKzVhqmRb5QFaHAQ,83422
29
29
  supervisely/api/github_api.py,sha256=NIexNjEer9H5rf5sw2LEZd7C1WR-tK4t6IZzsgeAAwQ,623
30
30
  supervisely/api/image_annotation_tool_api.py,sha256=YcUo78jRDBJYvIjrd-Y6FJAasLta54nnxhyaGyanovA,5237
31
- supervisely/api/image_api.py,sha256=qZwTjeCo6bkEuXDuB8RhhP0g6PzlRuCXJkUfN9rsUZ4,190985
31
+ supervisely/api/image_api.py,sha256=bSal6vB2c7Ct2qDarXTaTmXy7x0X1VlV8oTuT6YpY2o,191061
32
32
  supervisely/api/import_storage_api.py,sha256=BDCgmR0Hv6OoiRHLCVPKt3iDxSVlQp1WrnKhAK_Zl84,460
33
33
  supervisely/api/issues_api.py,sha256=BqDJXmNoTzwc3xe6_-mA7FDFC5QQ-ahGbXk_HmpkSeQ,17925
34
34
  supervisely/api/labeling_job_api.py,sha256=odnzZjp29yM16Gq-FYkv-OA4WFMNJCLFo4qSikW2A7c,56280
@@ -49,7 +49,7 @@ supervisely/api/video_annotation_tool_api.py,sha256=3A9-U8WJzrTShP_n9T8U01M9FzGY
49
49
  supervisely/api/workspace_api.py,sha256=5KAxpI9DKBmgF_pyQaXHpGT30HZ9wRtR6DP3FoYFZtY,9228
50
50
  supervisely/api/entity_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  supervisely/api/entity_annotation/entity_annotation_api.py,sha256=K79KdDyepQv4FiNQHBj9V4-zLIemxK9WG1ig1bfBKb8,3083
52
- supervisely/api/entity_annotation/figure_api.py,sha256=deYCZNG7JeDhxlYew51FyGvqY3dc7fkERtwmBPJmHcw,24503
52
+ supervisely/api/entity_annotation/figure_api.py,sha256=jNObHAjy2JdXvKLP5IeBWISDjrZn_Budxp9J3Odyhxo,24531
53
53
  supervisely/api/entity_annotation/object_api.py,sha256=gbcNvN_KY6G80Me8fHKQgryc2Co7VU_kfFd1GYILZ4E,8875
54
54
  supervisely/api/entity_annotation/tag_api.py,sha256=M-28m9h8R4k9Eqo6P1S0UH8_D5kqCwAvQLYY6_Yz4oM,11161
55
55
  supervisely/api/pointcloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -677,7 +677,7 @@ supervisely/geometry/cuboid.py,sha256=oxsRoTKuwTNxH4Vp6khyvw1TCrBagSWNV5HmQKJZHt
677
677
  supervisely/geometry/cuboid_2d.py,sha256=-oXeKiUS2gguQ4GyIZYp1cNPPhOLsGOFZl7uI71BfZM,13438
678
678
  supervisely/geometry/cuboid_3d.py,sha256=x472ZPHTZDIY5Dj8tKbLQG3BCukFPgSvPJlxfHdKi1w,4168
679
679
  supervisely/geometry/geometry.py,sha256=dbXnct8hrr7Wour6yCrtAef22KSJ2uYRm1F5GE10_MM,15287
680
- supervisely/geometry/graph.py,sha256=1_tX7FGmYkXuAx3P_w4zA4p8mRYnCN4iZ--2pMyxseI,24121
680
+ supervisely/geometry/graph.py,sha256=RDdZtN_P7TKAg4s_QXluCGzdmhD-IeonvK4Pix924kk,24474
681
681
  supervisely/geometry/helpers.py,sha256=2gdYMFWTAr836gVXcp-lkDQs9tdaV0ou33kj3mzJBQA,5132
682
682
  supervisely/geometry/image_rotator.py,sha256=wrU8cXEUfuNcmPms2myUV4BpZqz_2oDArsEUFeiTpxs,6888
683
683
  supervisely/geometry/main_tests.py,sha256=K3Olsz9igHDW2IfIA5JOpjoE8bZ3ex2PXvVR2ZCDrHU,27199
@@ -689,7 +689,7 @@ supervisely/geometry/point_location.py,sha256=vLu5pWdtAi-WVQUKgFO7skigTaR-mtWR0t
689
689
  supervisely/geometry/pointcloud.py,sha256=cc4P_UNLGx5dWah3caRJytW7_mAi8UnYsJOa20mUy8s,1472
690
690
  supervisely/geometry/polygon.py,sha256=cAgCR8ccdGtieJTnmDnupPALMEwerHIqMWx7k3OCzVQ,11594
691
691
  supervisely/geometry/polyline.py,sha256=LjjD-YGVDw1TQ84_IOHqnq43JFuSnsGdGMx404olYDs,8258
692
- supervisely/geometry/rectangle.py,sha256=f-Y6AnVYbMXXaAOLREyjqVJeb-l_tevQQHy9kiMKHhI,33749
692
+ supervisely/geometry/rectangle.py,sha256=QaBcSPeH87rcwsSft1TavEdCe4NpvfHZztZMEmzIxGk,33869
693
693
  supervisely/geometry/sliding_windows.py,sha256=VWtE3DS9AaIlS0ch0PY6wwtWU89J82icDRZ-F0LFrjM,1700
694
694
  supervisely/geometry/sliding_windows_fuzzy.py,sha256=InvJlH6MEW55DM1IdoMHP2MLFLieTDZfHrZZEINLQOc,3626
695
695
  supervisely/geometry/validation.py,sha256=G5vjtiXTCaTQvWegPIBiNw8pN_GiY86OUSRSsccdyLU,2139
@@ -1009,7 +1009,7 @@ supervisely/project/data_version.py,sha256=nknaWJSUCwoDyNG9_d1KA-GjzidhV9zd9Cn8c
1009
1009
  supervisely/project/download.py,sha256=zb8sb4XZ6Qi3CP7fmtLRUAYzaxs_W0WnOfe2x3ZVRMs,24639
1010
1010
  supervisely/project/pointcloud_episode_project.py,sha256=yiWdNBQiI6f1O9sr1pg8JHW6O-w3XUB1rikJNn3Oung,41866
1011
1011
  supervisely/project/pointcloud_project.py,sha256=Kx1Vaes-krwG3BiRRtHRLQxb9G5m5bTHPN9IzRqmNWo,49399
1012
- supervisely/project/project.py,sha256=tvNPGyIZVs4p3iMz2eDU1tmtsPZWZOhQ9vBJCqCMxbs,202003
1012
+ supervisely/project/project.py,sha256=34fAbYV4VdfVSqMs0a5ggAIwELd8nPb-uGoaC1F7h4I,202299
1013
1013
  supervisely/project/project_meta.py,sha256=26s8IiHC5Pg8B1AQi6_CrsWteioJP2in00cRNe8QlW0,51423
1014
1014
  supervisely/project/project_settings.py,sha256=NLThzU_DCynOK6hkHhVdFyezwprn9UqlnrLDe_3qhkY,9347
1015
1015
  supervisely/project/project_type.py,sha256=_3RqW2CnDBKFOvSIrQT1RJQaiHirs34_jiQS8CkwCpo,530
@@ -1071,9 +1071,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1071
1071
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1072
1072
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1073
1073
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1074
- supervisely-6.73.287.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1075
- supervisely-6.73.287.dist-info/METADATA,sha256=9oifX7yDdPoCm5GaVVjDyURQrPfVIjGIT27n3C10lf8,33573
1076
- supervisely-6.73.287.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1077
- supervisely-6.73.287.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1078
- supervisely-6.73.287.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1079
- supervisely-6.73.287.dist-info/RECORD,,
1074
+ supervisely-6.73.288.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1075
+ supervisely-6.73.288.dist-info/METADATA,sha256=bY0YA_vkWd0RNep6zrPSU0itBr5BQBWR8J6aHKBkzQw,33573
1076
+ supervisely-6.73.288.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1077
+ supervisely-6.73.288.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1078
+ supervisely-6.73.288.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1079
+ supervisely-6.73.288.dist-info/RECORD,,