supervisely 6.73.344__py3-none-any.whl → 6.73.345__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.
@@ -1,21 +1,23 @@
1
1
  import os
2
+ from pathlib import Path
2
3
 
4
+ import supervisely.convert.image.sly.sly_image_helper as helper
3
5
  from supervisely import (
4
6
  Annotation,
5
7
  Api,
6
- ProjectMeta,
7
8
  Label,
9
+ Project,
10
+ ProjectMeta,
8
11
  Rectangle,
9
12
  batched,
10
13
  is_development,
11
14
  logger,
12
15
  )
13
- from supervisely.convert.image.sly.sly_image_converter import SLYImageConverter
14
- import supervisely.convert.image.sly.sly_image_helper as helper
15
16
  from supervisely.convert.image.image_converter import ImageConverter
16
- from supervisely.io.fs import get_file_ext
17
- from supervisely.io.json import load_json_file
18
17
  from supervisely.convert.image.image_helper import validate_image_bounds
18
+ from supervisely.convert.image.sly.sly_image_converter import SLYImageConverter
19
+ from supervisely.io.fs import dir_empty, dir_exists, get_file_ext
20
+ from supervisely.io.json import load_json_file
19
21
 
20
22
 
21
23
  class FastSlyImageConverter(SLYImageConverter, ImageConverter):
@@ -29,7 +31,11 @@ class FastSlyImageConverter(SLYImageConverter, ImageConverter):
29
31
  detected_ann_cnt = 0
30
32
  self._items = []
31
33
  meta = ProjectMeta()
34
+
32
35
  for root, _, files in os.walk(self._input_data):
36
+ if Path(root).name == Project.blob_dir_name:
37
+ logger.debug("FastSlyImageConverter: Detected blob directory. Skipping...")
38
+ return False
33
39
  for file in files:
34
40
  full_path = os.path.join(root, file)
35
41
  ext = get_file_ext(full_path)
@@ -291,8 +291,19 @@ class SLYImageConverter(ImageConverter):
291
291
  self.upload_project(api, dataset_id, batch_size, log_progress)
292
292
  elif self.blob_project:
293
293
  dataset_info = api.dataset.get_info_by_id(dataset_id, raise_error=True)
294
+ project_dirs = [d for d in find_project_dirs(self._input_data)]
295
+ if len(project_dirs) == 0:
296
+ raise RuntimeError(
297
+ "Failed to find Supervisely project with blobs in the input data"
298
+ )
299
+ project_dir = project_dirs[0]
300
+ if len(project_dirs) > 1:
301
+ logger.info(
302
+ "Found multiple possible Supervisely projects with blobs in the input data. "
303
+ f"Only the first one will be uploaded: {project_dir}"
304
+ )
294
305
  upload_project_fs(
295
- dir=self._input_data,
306
+ dir=project_dir,
296
307
  api=api,
297
308
  workspace_id=dataset_info.workspace_id,
298
309
  log_progress=log_progress,
@@ -17,7 +17,9 @@ from supervisely.io.fs import remove_dir, silent_remove
17
17
 
18
18
 
19
19
  class VersionInfo(NamedTuple):
20
- """ """
20
+ """
21
+ Object with image parameters from Supervisely that describes the version of the project.
22
+ """
21
23
 
22
24
  id: int
23
25
  project_id: int
@@ -34,6 +36,10 @@ class VersionInfo(NamedTuple):
34
36
 
35
37
 
36
38
  class DataVersion(ModuleApiBase):
39
+ """
40
+ Class for managing project versions.
41
+ This class provides methods for creating, restoring, and managing project versions.
42
+ """
37
43
 
38
44
  def __init__(self, api):
39
45
  """
@@ -579,21 +579,24 @@ class Dataset(KeyObject):
579
579
  Consistency checks. Every item must have an annotation, and the correspondence must be one to one.
580
580
  If not - it generate exception error.
581
581
  """
582
- if not dir_exists(self.item_dir):
582
+ blob_offset_paths = list_files(
583
+ self.directory, filter_fn=lambda x: x.endswith(OFFSETS_PKL_SUFFIX)
584
+ )
585
+ has_blob_offsets = len(blob_offset_paths) > 0
586
+
587
+ if not dir_exists(self.item_dir) and not has_blob_offsets:
583
588
  raise FileNotFoundError("Item directory not found: {!r}".format(self.item_dir))
584
589
  if not dir_exists(self.ann_dir):
585
590
  raise FileNotFoundError("Annotation directory not found: {!r}".format(self.ann_dir))
586
591
 
587
592
  raw_ann_paths = list_files(self.ann_dir, [ANN_EXT])
588
- img_paths = list_files(self.item_dir, filter_fn=self._has_valid_ext)
589
-
590
593
  raw_ann_names = set(os.path.basename(path) for path in raw_ann_paths)
591
- img_names = [os.path.basename(path) for path in img_paths]
592
594
 
593
- blob_offset_paths = list_files(
594
- self.directory, filter_fn=lambda x: x.endswith(OFFSETS_PKL_SUFFIX)
595
- )
596
- has_blob_offsets = len(blob_offset_paths) > 0
595
+ if dir_exists(self.item_dir):
596
+ img_paths = list_files(self.item_dir, filter_fn=self._has_valid_ext)
597
+ img_names = [os.path.basename(path) for path in img_paths]
598
+ else:
599
+ img_names = []
597
600
 
598
601
  # If we have blob offset files, add the image names from those
599
602
  if has_blob_offsets:
@@ -2061,6 +2064,84 @@ class Dataset(KeyObject):
2061
2064
  progress_cb=progress_cb,
2062
2065
  )
2063
2066
 
2067
+ def get_blob_img_bytes(self, image_name: str) -> bytes:
2068
+ """
2069
+ Get image bytes from blob file.
2070
+
2071
+ :param image_name: Image name with extension.
2072
+ :type image_name: :class:`str`
2073
+ :return: Bytes of the image.
2074
+ :rtype: :class:`bytes`
2075
+
2076
+ :Usage example:
2077
+
2078
+ .. code-block:: python
2079
+
2080
+ import supervisely as sly
2081
+ dataset_path = "/path/to/project/lemons_annotated/ds1"
2082
+ dataset = sly.Dataset(dataset_path, sly.OpenMode.READ)
2083
+ image_name = "IMG_0748.jpeg"
2084
+
2085
+ img_bytes = dataset.get_blob_img_bytes(image_name)
2086
+ """
2087
+
2088
+ if self.project_dir is None:
2089
+ raise RuntimeError("Project directory is not set. Cannot get blob image bytes.")
2090
+
2091
+ blob_image_info = None
2092
+
2093
+ for offset in self.blob_offsets:
2094
+ for batch in BlobImageInfo.load_from_pickle_generator(offset):
2095
+ for file in batch:
2096
+ if file.name == image_name:
2097
+ blob_image_info = file
2098
+ blob_file_name = removesuffix(Path(offset).name, OFFSETS_PKL_SUFFIX)
2099
+ break
2100
+ if blob_image_info is None:
2101
+ logger.debug(
2102
+ f"Image '{image_name}' not found in blob offsets. "
2103
+ f"Make sure that the image is stored in the blob file."
2104
+ )
2105
+ return None
2106
+
2107
+ blob_file_path = os.path.join(self.project_dir, self.blob_dir_name, blob_file_name + ".tar")
2108
+ if file_exists(blob_file_path):
2109
+ with open(blob_file_path, "rb") as f:
2110
+ f.seek(blob_image_info.offset_start)
2111
+ img_bytes = f.read(blob_image_info.offset_end - blob_image_info.offset_start)
2112
+ else:
2113
+ logger.debug(
2114
+ f"Blob file '{blob_file_path}' not found. "
2115
+ f"Make sure that the blob file exists in the specified directory."
2116
+ )
2117
+ img_bytes = None
2118
+ return img_bytes
2119
+
2120
+ def get_blob_img_np(self, image_name: str) -> np.ndarray:
2121
+ """
2122
+ Get image as numpy array from blob file.
2123
+
2124
+ :param image_name: Image name with extension.
2125
+ :type image_name: :class:`str`
2126
+ :return: Numpy array of the image.
2127
+ :rtype: :class:`numpy.ndarray`
2128
+
2129
+ :Usage example:
2130
+
2131
+ .. code-block:: python
2132
+
2133
+ import supervisely as sly
2134
+ dataset_path = "/path/to/project/lemons_annotated/ds1"
2135
+ dataset = sly.Dataset(dataset_path, sly.OpenMode.READ)
2136
+ image_name = "IMG_0748.jpeg"
2137
+
2138
+ img_np = dataset.get_blob_img_np(image_name)
2139
+ """
2140
+ img_bytes = self.get_blob_img_bytes(image_name)
2141
+ if img_bytes is None:
2142
+ return None
2143
+ return sly_image.read_bytes(img_bytes)
2144
+
2064
2145
 
2065
2146
  class Project:
2066
2147
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.344
3
+ Version: 6.73.345
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -606,8 +606,8 @@ supervisely/convert/image/pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
606
606
  supervisely/convert/image/pdf/pdf_converter.py,sha256=LKvVng9jPp0cSIjYEjKLOb48wtdOdB7LXS2gjmOdZhE,2442
607
607
  supervisely/convert/image/pdf/pdf_helper.py,sha256=IDwLEvsVy8lu-KC1lXvSRkZZ9BCC6ylebnNEtLQU5L4,1288
608
608
  supervisely/convert/image/sly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
609
- supervisely/convert/image/sly/fast_sly_image_converter.py,sha256=pZmQzhx9FrHwgVnJgqp-37Cn3zAnPww6MLa1grL6aWM,5429
610
- supervisely/convert/image/sly/sly_image_converter.py,sha256=wsdQt53w_QDxdcLCmPs7-lRt9rEvsIX97NpSVi-5MUE,13821
609
+ supervisely/convert/image/sly/fast_sly_image_converter.py,sha256=wtiM-Dl4xivT60-79pj8XMdHQc2kPMi7DqGcEngiWRg,5669
610
+ supervisely/convert/image/sly/sly_image_converter.py,sha256=_sTiPTeNwZ1qWdtecmusanzvApHN7TskB7slgI3mibs,14370
611
611
  supervisely/convert/image/sly/sly_image_helper.py,sha256=5Ri8fKb5dzh5b3v8AJ5u8xVFOQfAtoWqZ7HktPsCjTI,7373
612
612
  supervisely/convert/image/yolo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
613
613
  supervisely/convert/image/yolo/yolo_converter.py,sha256=Wn5dR05y4SEPONcaxWr9ofnbvbf-SbRZN0fkksk5Dps,11391
@@ -1016,11 +1016,11 @@ supervisely/pointcloud_annotation/pointcloud_tag_collection.py,sha256=j_TAN23GkT
1016
1016
  supervisely/pointcloud_episodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1017
1017
  supervisely/pointcloud_episodes/pointcloud_episodes.py,sha256=cRXdtw7bMsbsdVQjxfWxFSESrO-LGiqqsZyyExl2Mbg,3430
1018
1018
  supervisely/project/__init__.py,sha256=hlzdj9Pgy53Q3qdP8LMtGTChvZHQuuShdtui2eRUQeE,2601
1019
- supervisely/project/data_version.py,sha256=6vOz5ovBeCIiMAKUG7lGQ5IXvQnU1GbcnrWxdOvaVlo,19311
1019
+ supervisely/project/data_version.py,sha256=P5Lui6i64pYeJWmAdGJDv8GRXxjfpSSZ8zT_MxIrynE,19553
1020
1020
  supervisely/project/download.py,sha256=4QOEQZnolmOpEO6Wl6DIc73BwIYr9m-6anbarrU6VwQ,24902
1021
1021
  supervisely/project/pointcloud_episode_project.py,sha256=yiWdNBQiI6f1O9sr1pg8JHW6O-w3XUB1rikJNn3Oung,41866
1022
1022
  supervisely/project/pointcloud_project.py,sha256=Kx1Vaes-krwG3BiRRtHRLQxb9G5m5bTHPN9IzRqmNWo,49399
1023
- supervisely/project/project.py,sha256=UFElUMvFxknLwSTly-9tF85NAYneavolpOGIGZtpSmo,230359
1023
+ supervisely/project/project.py,sha256=OunVB11sVQSOvkqkjsEEkX1nq9OUXOXpHTdcLDjOFe0,233256
1024
1024
  supervisely/project/project_meta.py,sha256=26s8IiHC5Pg8B1AQi6_CrsWteioJP2in00cRNe8QlW0,51423
1025
1025
  supervisely/project/project_settings.py,sha256=NLThzU_DCynOK6hkHhVdFyezwprn9UqlnrLDe_3qhkY,9347
1026
1026
  supervisely/project/project_type.py,sha256=7mQ7zg6r7Bm2oFn5aR8n_PeLqMmOaPZd6ph7Z8ZISTw,608
@@ -1082,9 +1082,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1082
1082
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1083
1083
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1084
1084
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1085
- supervisely-6.73.344.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1086
- supervisely-6.73.344.dist-info/METADATA,sha256=jYLJlhCcUufKznUrKoqqqzibJr920dezFFVBpx308LA,33596
1087
- supervisely-6.73.344.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1088
- supervisely-6.73.344.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1089
- supervisely-6.73.344.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1090
- supervisely-6.73.344.dist-info/RECORD,,
1085
+ supervisely-6.73.345.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1086
+ supervisely-6.73.345.dist-info/METADATA,sha256=a_-hgFBcPCUpfVuBt4CFWG3BZqou1JjGWi8G-Q6SwpE,33596
1087
+ supervisely-6.73.345.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1088
+ supervisely-6.73.345.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1089
+ supervisely-6.73.345.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1090
+ supervisely-6.73.345.dist-info/RECORD,,