supervisely 6.73.432__py3-none-any.whl → 6.73.434__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.
@@ -185,6 +185,7 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
185
185
  filters: Optional[List[Dict[str, str]]] = None,
186
186
  recursive: Optional[bool] = False,
187
187
  parent_id: Optional[int] = None,
188
+ include_custom_data: Optional[bool] = False,
188
189
  ) -> List[DatasetInfo]:
189
190
  """
190
191
  Returns list of dataset in the given project, or list of nested datasets
@@ -200,6 +201,9 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
200
201
  :type recursive: bool, optional
201
202
  :param parent_id: Parent Dataset ID. If set to None, the search will be performed at the top level of the Project,
202
203
  otherwise the search will be performed in the specified Dataset.
204
+ :type parent_id: Union[int, None], optional
205
+ :param include_custom_data: If True, the response will include the `custom_data` field for each Dataset.
206
+ :type include_custom_data: bool, optional
203
207
  :return: List of all Datasets with information for the given Project. See :class:`info_sequence<info_sequence>`
204
208
  :rtype: :class:`List[DatasetInfo]`
205
209
  :Usage example:
@@ -246,14 +250,16 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
246
250
  filters.append({"field": ApiField.PARENT_ID, "operator": "=", "value": parent_id})
247
251
  recursive = True
248
252
 
249
- return self.get_list_all_pages(
250
- "datasets.list",
251
- {
252
- ApiField.PROJECT_ID: project_id,
253
- ApiField.FILTER: filters,
254
- ApiField.RECURSIVE: recursive,
255
- },
256
- )
253
+ method = "datasets.list"
254
+ data = {
255
+ ApiField.PROJECT_ID: project_id,
256
+ ApiField.FILTER: filters,
257
+ ApiField.RECURSIVE: recursive,
258
+ }
259
+ if include_custom_data:
260
+ data[ApiField.EXTRA_FIELDS] = [ApiField.CUSTOM_DATA]
261
+
262
+ return self.get_list_all_pages(method, data)
257
263
 
258
264
  def get_info_by_id(self, id: int, raise_error: Optional[bool] = False) -> DatasetInfo:
259
265
  """
@@ -304,6 +310,7 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
304
310
  description: Optional[str] = "",
305
311
  change_name_if_conflict: Optional[bool] = False,
306
312
  parent_id: Optional[int] = None,
313
+ custom_data: Optional[Dict[Any, Any]] = None,
307
314
  ) -> DatasetInfo:
308
315
  """
309
316
  Create Dataset with given name in the given Project.
@@ -318,6 +325,9 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
318
325
  :type change_name_if_conflict: bool, optional
319
326
  :param parent_id: Parent Dataset ID. If set to None, then the Dataset will be created at
320
327
  the top level of the Project, otherwise the Dataset will be created in a specified Dataset.
328
+ :type parent_id: Union[int, None]
329
+ :param custom_data: Custom data to store in the Dataset.
330
+ :type custom_data: Dict[Any, Any], optional
321
331
  :return: Information about Dataset. See :class:`info_sequence<info_sequence>`
322
332
  :rtype: :class:`DatasetInfo`
323
333
  :Usage example:
@@ -345,15 +355,16 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
345
355
  change_name_if_conflict=change_name_if_conflict,
346
356
  parent_id=parent_id,
347
357
  )
348
- response = self._api.post(
349
- "datasets.add",
350
- {
351
- ApiField.PROJECT_ID: project_id,
352
- ApiField.NAME: effective_name,
353
- ApiField.DESCRIPTION: description,
354
- ApiField.PARENT_ID: parent_id,
355
- },
356
- )
358
+ method = "datasets.add"
359
+ payload = {
360
+ ApiField.PROJECT_ID: project_id,
361
+ ApiField.NAME: effective_name,
362
+ ApiField.DESCRIPTION: description,
363
+ ApiField.PARENT_ID: parent_id,
364
+ }
365
+ if custom_data is not None:
366
+ payload[ApiField.CUSTOM_DATA] = custom_data
367
+ response = self._api.post(method, payload)
357
368
  return self._convert_json_info(response.json())
358
369
 
359
370
  def get_or_create(
@@ -564,6 +575,7 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
564
575
  new_dataset_name,
565
576
  dataset.description,
566
577
  change_name_if_conflict=change_name_if_conflict,
578
+ custom_data=dataset.custom_data,
567
579
  )
568
580
  items_api.copy_batch(
569
581
  new_dataset.id, src_item_ids, change_name_if_conflict, with_annotations
@@ -797,6 +809,7 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
797
809
  sort_order: Optional[str] = None,
798
810
  per_page: Optional[int] = None,
799
811
  page: Union[int, Literal["all"]] = "all",
812
+ include_custom_data: Optional[bool] = False,
800
813
  ) -> dict:
801
814
  """
802
815
  List all available datasets from all available teams for the user that match the specified filtering criteria.
@@ -807,22 +820,20 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
807
820
  - 'operator': Takes values '=', 'eq', '!=', 'not', 'in', '!in', '>', 'gt', '>=', 'gte', '<', 'lt', '<=', 'lte'
808
821
  - 'value': Takes on values according to the meaning of 'field' or null
809
822
  :type filters: List[Dict[str, str]], optional
810
-
811
823
  :param sort: Specifies by which parameter to sort the project list.
812
824
  Takes values 'id', 'name', 'size', 'createdAt', 'updatedAt'
813
825
  :type sort: str, optional
814
-
815
826
  :param sort_order: Determines which value to list from.
816
827
  :type sort_order: str, optional
817
-
818
828
  :param per_page: Number of first items found to be returned.
819
829
  'None' will return the first page with a default size of 20000 datasets.
820
830
  :type per_page: int, optional
821
-
822
831
  :param page: Page number, used to retrieve the following items if the number of them found is more than per_page.
823
832
  The default value is 'all', which retrieves all available datasets.
824
833
  'None' will return the first page with datasets, the amount of which is set in param 'per_page'.
825
834
  :type page: Union[int, Literal["all"]], optional
835
+ :param include_custom_data: If True, the response will include the `custom_data` field for each Dataset.
836
+ :type include_custom_data: bool, optional
826
837
 
827
838
  :return: Search response information and 'DatasetInfo' of all datasets that are searched by a given criterion.
828
839
  :rtype: dict
@@ -899,6 +910,8 @@ class DatasetApi(UpdateableModule, RemoveableModuleApi):
899
910
  request_body[ApiField.PER_PAGE] = per_page
900
911
  if page is not None and page != "all":
901
912
  request_body[ApiField.PAGE] = page
913
+ if include_custom_data:
914
+ request_body[ApiField.EXTRA_FIELDS] = [ApiField.CUSTOM_DATA]
902
915
 
903
916
  first_response = self._api.post(method, request_body).json()
904
917
 
@@ -12,10 +12,12 @@ from typing import (
12
12
  Any,
13
13
  Callable,
14
14
  Dict,
15
+ Generator,
15
16
  List,
16
17
  Literal,
17
18
  NamedTuple,
18
19
  Optional,
20
+ Tuple,
19
21
  Union,
20
22
  )
21
23
 
@@ -38,6 +40,7 @@ from supervisely.annotation.annotation import TagCollection
38
40
  from supervisely.annotation.obj_class import ObjClass
39
41
  from supervisely.annotation.obj_class_collection import ObjClassCollection
40
42
  from supervisely.annotation.tag_meta import TagMeta, TagValueType
43
+ from supervisely.api.dataset_api import DatasetInfo
41
44
  from supervisely.api.module_api import (
42
45
  ApiField,
43
46
  CloneableModuleApi,
@@ -2556,3 +2559,104 @@ class ProjectApi(CloneableModuleApi, UpdateableModule, RemoveableModuleApi):
2556
2559
  api.project.calculate_embeddings(project_id)
2557
2560
  """
2558
2561
  self._api.post("embeddings.calculate-project-embeddings", {ApiField.PROJECT_ID: id})
2562
+
2563
+ def recreate_structure_generator(
2564
+ self,
2565
+ src_project_id: int,
2566
+ dst_project_id: Optional[int] = None,
2567
+ dst_project_name: Optional[str] = None,
2568
+ ) -> Generator[Tuple[DatasetInfo, DatasetInfo], None, None]:
2569
+ """This method can be used to recreate a project with hierarchial datasets (without the data itself) and
2570
+ yields the tuple of source and destination DatasetInfo objects.
2571
+
2572
+ :param src_project_id: Source project ID
2573
+ :type src_project_id: int
2574
+ :param dst_project_id: Destination project ID
2575
+ :type dst_project_id: int, optional
2576
+ :param dst_project_name: Name of the destination project. If `dst_project_id` is None, a new project will be created with this name. If `dst_project_id` is provided, this parameter will be ignored.
2577
+ :type dst_project_name: str, optional
2578
+
2579
+ :return: Generator of tuples of source and destination DatasetInfo objects
2580
+ :rtype: Generator[Tuple[DatasetInfo, DatasetInfo], None, None]
2581
+
2582
+ :Usage example:
2583
+
2584
+ .. code-block:: python
2585
+
2586
+ import supervisely as sly
2587
+
2588
+ api = sly.Api.from_env()
2589
+
2590
+ src_project_id = 123
2591
+ dst_project_id = api.project.create("new_project", "images").id
2592
+
2593
+ for src_ds, dst_ds in api.project.recreate_structure_generator(src_project_id, dst_project_id):
2594
+ print(f"Recreated dataset {src_ds.id} -> {dst_ds.id}")
2595
+ # Implement your logic here to process the datasets.
2596
+ """
2597
+ if dst_project_id is None:
2598
+ src_project_info = self._api.project.get_info_by_id(src_project_id)
2599
+ dst_project_info = self._api.project.create(
2600
+ src_project_info.workspace_id,
2601
+ dst_project_name or f"Recreation of {src_project_info.name}",
2602
+ src_project_info.type,
2603
+ src_project_info.description,
2604
+ change_name_if_conflict=True,
2605
+ )
2606
+ dst_project_id = dst_project_info.id
2607
+
2608
+ datasets = self._api.dataset.get_list(src_project_id, recursive=True, include_custom_data=True)
2609
+ src_to_dst_ids = {}
2610
+
2611
+ for src_dataset_info in datasets:
2612
+ dst_dataset_info = self._api.dataset.create(
2613
+ dst_project_id,
2614
+ src_dataset_info.name,
2615
+ description=src_dataset_info.description,
2616
+ parent_id=src_to_dst_ids.get(src_dataset_info.parent_id),
2617
+ custom_data=src_dataset_info.custom_data,
2618
+ )
2619
+ src_to_dst_ids[src_dataset_info.id] = dst_dataset_info.id
2620
+
2621
+ yield src_dataset_info, dst_dataset_info
2622
+
2623
+ def recreate_structure(
2624
+ self,
2625
+ src_project_id: int,
2626
+ dst_project_id: Optional[int] = None,
2627
+ dst_project_name: Optional[str] = None,
2628
+ ) -> Tuple[List[DatasetInfo], List[DatasetInfo]]:
2629
+ """This method can be used to recreate a project with hierarchial datasets (without the data itself).
2630
+
2631
+ :param src_project_id: Source project ID
2632
+ :type src_project_id: int
2633
+ :param dst_project_id: Destination project ID
2634
+ :type dst_project_id: int, optional
2635
+ :param dst_project_name: Name of the destination project. If `dst_project_id` is None, a new project will be created with this name. If `dst_project_id` is provided, this parameter will be ignored.
2636
+ :type dst_project_name: str, optional
2637
+
2638
+ :return: Destination project ID
2639
+ :rtype: int
2640
+
2641
+ :Usage example:
2642
+
2643
+ .. code-block:: python
2644
+
2645
+ import supervisely as sly
2646
+
2647
+ api = sly.Api.from_env()
2648
+
2649
+ src_project_id = 123
2650
+ dst_project_name = "New Project"
2651
+
2652
+ dst_project_id = api.project.recreate_structure(src_project_id, dst_project_name=dst_project_name)
2653
+ print(f"Recreated project {src_project_id} -> {dst_project_id}")
2654
+ """
2655
+ infos = []
2656
+ for src_info, dst_info in self.recreate_structure_generator(
2657
+ src_project_id, dst_project_id, dst_project_name
2658
+ ):
2659
+ infos.append((src_info, dst_info))
2660
+
2661
+
2662
+ return infos
supervisely/versions.json CHANGED
@@ -23,5 +23,6 @@
23
23
  "6.13.8": "6.73.394",
24
24
  "6.14.0": "6.73.400",
25
25
  "6.14.4": "6.73.410",
26
- "6.15.0": "6.73.431"
26
+ "6.15.0": "6.73.431",
27
+ "6.15.2": "6.73.433"
27
28
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.432
3
+ Version: 6.73.434
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -32,7 +32,7 @@ Requires-Dist: requests-toolbelt>=0.9.1
32
32
  Requires-Dist: Shapely<=2.0.2,>=1.7.1
33
33
  Requires-Dist: bidict<1.0.0,>=0.21.2
34
34
  Requires-Dist: varname<1.0.0,>=0.8.1
35
- Requires-Dist: python-dotenv<=1.0.0,>=0.19.2
35
+ Requires-Dist: python-dotenv<=1.0.1,>=0.19.2
36
36
  Requires-Dist: pynrrd<1.0.0,>=0.4.2
37
37
  Requires-Dist: SimpleITK<=2.4.1.0,>=2.1.1.2
38
38
  Requires-Dist: pydicom<3.0.0,>=2.3.0
@@ -4,7 +4,7 @@ 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=Cppk4ndoCkIEclgQwVKzJjFQjahjOPpVuoo4LrM9eTE,585
7
+ supervisely/versions.json,sha256=J7V7XPpDno0fvmNaAXXcxNksXqpRFaYRrG4POC0UDKQ,608
8
8
  supervisely/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  supervisely/annotation/annotation.py,sha256=th4gsIU-LNGcMRohHrtupmjxDwdzx1g4_0xIAa6NyJU,114717
10
10
  supervisely/annotation/annotation_transforms.py,sha256=TlVy_gUbM-XH6GbLpZPrAi6pMIGTr7Ow02iSKOSTa-I,9582
@@ -26,7 +26,7 @@ supervisely/api/annotation_api.py,sha256=JdcCKuy_7PvtNcHsRhi4ANhn3aynLY44rtbqau2
26
26
  supervisely/api/api.py,sha256=gRItQzO6Xj7k_pJIpVUS2dV1vkTTHV25_1Uia6xxZSc,67930
27
27
  supervisely/api/app_api.py,sha256=Q6XxLxp3D_Vc3PIVyBmP7wJtTLbgYCPNOLND5UvJhMw,79010
28
28
  supervisely/api/constants.py,sha256=WfqIcEpRnU4Mcfb6q0njeRs2VVSoTAJaIyrqBkBjP8I,253
29
- supervisely/api/dataset_api.py,sha256=7idBMFL8jumWNw-wlBAbQWC09RskG-3GlidfPDukq3Q,47930
29
+ supervisely/api/dataset_api.py,sha256=BD6kG2lj826ajWjHxmiKEsyWb2Ov6CyTQlItzAxADbo,48955
30
30
  supervisely/api/entities_collection_api.py,sha256=Be13HsfMFLmq9XpiOfQog0Y569kbUn52hXv6x5vX3Vg,22624
31
31
  supervisely/api/file_api.py,sha256=gNXNsikocSYRojoZrVmXIqXycqXm0e320piAwaLN6JI,92978
32
32
  supervisely/api/github_api.py,sha256=NIexNjEer9H5rf5sw2LEZd7C1WR-tK4t6IZzsgeAAwQ,623
@@ -39,7 +39,7 @@ 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=2Y8h1R--aIuvZlMSNhRoBMmSqL2U0Zz19sLzePbgiLU,97499
42
+ supervisely/api/project_api.py,sha256=R4KjWUiO1pLQhsd6hDTgRWjaSdEiSE_bFI8UZ9Lo3pQ,101688
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
@@ -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.432.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1131
- supervisely-6.73.432.dist-info/METADATA,sha256=mJQpgFJG362uNb35ChhLMbHqErpjRc-bx5KHRkaut_c,35433
1132
- supervisely-6.73.432.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1133
- supervisely-6.73.432.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1134
- supervisely-6.73.432.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1135
- supervisely-6.73.432.dist-info/RECORD,,
1130
+ supervisely-6.73.434.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1131
+ supervisely-6.73.434.dist-info/METADATA,sha256=5-WsymH6I1mRUh66ihKvonvbfz2342msC9_mzwnBhVM,35433
1132
+ supervisely-6.73.434.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1133
+ supervisely-6.73.434.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1134
+ supervisely-6.73.434.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1135
+ supervisely-6.73.434.dist-info/RECORD,,