datamint 2.4.0__py3-none-any.whl → 2.4.1__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 datamint might be problematic. Click here for more details.

@@ -25,6 +25,7 @@ import nest_asyncio # For running asyncio in jupyter notebooks
25
25
  from PIL import Image
26
26
  import io
27
27
  from datamint.types import ImagingData
28
+ from collections import defaultdict
28
29
 
29
30
 
30
31
  _LOGGER = logging.getLogger(__name__)
@@ -279,7 +280,6 @@ class ResourcesApi(CreatableEntityApi[Resource], DeletableEntityApi[Resource]):
279
280
  _LOGGER.warning(msg)
280
281
  _USER_LOGGER.warning(msg)
281
282
 
282
-
283
283
  mimetype = standardize_mimetype(mimetype)
284
284
 
285
285
  if is_a_dicom_file == True or is_dicom(file_path):
@@ -440,12 +440,12 @@ class ResourcesApi(CreatableEntityApi[Resource], DeletableEntityApi[Resource]):
440
440
 
441
441
  try:
442
442
  tasks = [__upload_single_resource(f, segfiles, metadata_file)
443
- for f, segfiles, metadata_file in zip(files_path, segmentation_files, metadata_files)]
443
+ for f, segfiles, metadata_file in zip(files_path, segmentation_files, metadata_files)]
444
444
  except ValueError:
445
445
  msg = f"Error preparing upload tasks. Try `assemble_dicom=False`."
446
446
  _LOGGER.error(msg)
447
447
  _USER_LOGGER.error(msg)
448
- raise
448
+ raise
449
449
  return await asyncio.gather(*tasks, return_exceptions=on_error == 'skip')
450
450
 
451
451
  def upload_resources(self,
@@ -996,22 +996,28 @@ class ResourcesApi(CreatableEntityApi[Resource], DeletableEntityApi[Resource]):
996
996
  raise
997
997
 
998
998
  def set_tags(self,
999
- resource: str | Resource,
999
+ resource: str | Resource | Sequence[str | Resource],
1000
1000
  tags: Sequence[str],
1001
1001
  ):
1002
1002
  """
1003
1003
  Set tags for a resource, IMPORTANT: This replaces all existing tags.
1004
1004
  Args:
1005
- resource: The resource unique id or Resource object.
1005
+ resource: The resource object or a list of resources.
1006
1006
  tags: The tags to set.
1007
1007
  """
1008
1008
  data = {'tags': tags}
1009
- resource_id = self._entid(resource)
1010
-
1011
- response = self._make_entity_request('PUT',
1012
- resource_id,
1013
- add_path='tags',
1014
- json=data)
1009
+ if isinstance(resource, Sequence):
1010
+ resource_ids = [self._entid(res) for res in resource]
1011
+ response = self._make_request('PUT',
1012
+ f'{self.endpoint_base}/tags',
1013
+ json={'resource_ids': resource_ids,
1014
+ 'tags': tags})
1015
+ else:
1016
+ resource_id = self._entid(resource)
1017
+ response = self._make_entity_request('PUT',
1018
+ resource_id,
1019
+ add_path='tags',
1020
+ json=data)
1015
1021
  return response
1016
1022
 
1017
1023
  # def get_projects(self, resource: Resource) -> Sequence[Project]:
@@ -1029,7 +1035,7 @@ class ResourcesApi(CreatableEntityApi[Resource], DeletableEntityApi[Resource]):
1029
1035
  # return [proj for proj in self.projects_api.get_all() if proj.id in proj_ids]
1030
1036
 
1031
1037
  def add_tags(self,
1032
- resource: str | Resource,
1038
+ resource: str | Resource | Sequence[str | Resource],
1033
1039
  tags: Sequence[str],
1034
1040
  ):
1035
1041
  """
@@ -1040,8 +1046,26 @@ class ResourcesApi(CreatableEntityApi[Resource], DeletableEntityApi[Resource]):
1040
1046
  """
1041
1047
  if isinstance(resource, str):
1042
1048
  resource = self.get_by_id(resource)
1049
+ elif isinstance(resource, Sequence):
1050
+ # Transform every str to Resource first.
1051
+ resources = [self.get_by_id(res) if isinstance(res, str) else res for res in resource]
1052
+
1053
+ # group resource having the exact same tags to minimize requests
1054
+ tag_map: dict[tuple, list[Resource]] = defaultdict(list)
1055
+ for res in resources:
1056
+ old_tags = res.tags if res.tags is not None else []
1057
+ # key = tuple(sorted(old_tags))
1058
+ key = tuple(old_tags) # keep order, assuming order matters for tags
1059
+ tag_map[key].append(res)
1060
+
1061
+ # finally, set tags for each group
1062
+ for old_tags_tuple, res_group in tag_map.items():
1063
+ old_tags = list(old_tags_tuple)
1064
+ self.set_tags(res_group, old_tags + list(tags))
1065
+ return
1066
+
1043
1067
  old_tags = resource.tags if resource.tags is not None else []
1044
- return self.set_tags(resource, old_tags + list(tags))
1068
+ self.set_tags(resource, old_tags + list(tags))
1045
1069
 
1046
1070
  def bulk_delete(self, entities: Sequence[str | Resource]) -> None:
1047
1071
  """Delete multiple entities. Faster than deleting them one by one.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamint
3
- Version: 2.4.0
3
+ Version: 2.4.1
4
4
  Summary: A library for interacting with the Datamint API, designed for efficient data management, processing and Deep Learning workflows.
5
5
  Requires-Python: >=3.10
6
6
  Classifier: Programming Language :: Python :: 3
@@ -10,7 +10,7 @@ datamint/api/endpoints/channels_api.py,sha256=oQqxSw9DJzAqtVQI7-tc1llTdnsm-URx8j
10
10
  datamint/api/endpoints/datasetsinfo_api.py,sha256=WdzrUzK63w9gvAP6U--P65FbD-3X-jm9TPCcYnRNjas,597
11
11
  datamint/api/endpoints/models_api.py,sha256=tbVuajc-mCsIp5AKSCoq3uQRDWgKnJaIA6tf_ck8-XY,1502
12
12
  datamint/api/endpoints/projects_api.py,sha256=Pfr3fEiMw_aRzoGtcVXHJQ68leVoPAghw23L4ZIglno,8237
13
- datamint/api/endpoints/resources_api.py,sha256=ZsGy4xTdLHLkM2z8VyRRLEjB0Rv3kTZFQceYkFYpk7A,50601
13
+ datamint/api/endpoints/resources_api.py,sha256=TwePvZJp0yBXYoWLzBe4BXucPWAQWjiokzWyQDsD29E,51950
14
14
  datamint/api/endpoints/users_api.py,sha256=pnkuTZ1B9Y0FtwwvXO8J64e02RSkRxnBmTl9UGSuC5I,1186
15
15
  datamint/api/entity_base_api.py,sha256=-8SIt4M8P9G2b8SQznuWpFuFE8zEQjQxkRkw0s_w0Y4,11692
16
16
  datamint/apihandler/annotation_api_handler.py,sha256=W3vV4z3BqX1OQe1r7zr8dI-IVu4zUDxED4QttdiWV-E,57098
@@ -61,7 +61,7 @@ datamint/types.py,sha256=2OaY5QJvQIJKxyMNJYzxBksKCa9ZS2gb_ayJrByvu2Y,410
61
61
  datamint/utils/logging_utils.py,sha256=9pRoaPrWu2jOdDCiAoUsjEdP5ZwaealWL3hjUqFvx9g,4022
62
62
  datamint/utils/torchmetrics.py,sha256=lwU0nOtsSWfebyp7dvjlAggaqXtj5ohSEUXOg3L0hJE,2837
63
63
  datamint/utils/visualization.py,sha256=yaUVAOHar59VrGUjpAWv5eVvQSfztFG0eP9p5Vt3l-M,4470
64
- datamint-2.4.0.dist-info/METADATA,sha256=g4WkKWDq3mBETvQibcoISGXTtQCRdebfrw4leyurg3E,8974
65
- datamint-2.4.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
66
- datamint-2.4.0.dist-info/entry_points.txt,sha256=wTr9DXteCfAFqLUstN1Qx_SqC_rFLrAUIcDx9q1eXZw,845
67
- datamint-2.4.0.dist-info/RECORD,,
64
+ datamint-2.4.1.dist-info/METADATA,sha256=aViMZ43PB9dY38iwu36keNIcnp__cIpV16NRNOKcT7g,8974
65
+ datamint-2.4.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
66
+ datamint-2.4.1.dist-info/entry_points.txt,sha256=wTr9DXteCfAFqLUstN1Qx_SqC_rFLrAUIcDx9q1eXZw,845
67
+ datamint-2.4.1.dist-info/RECORD,,