@@ -127,6 +127,8 @@ def create_item(
127127 item_type : str = "samples" ,
128128 item_data : dict [str , Any ] | None = None ,
129129 collection_id : str | None = None ,
130+ collection_ids : str | Iterable [str ] | None = None , # alias for collection_id
131+ group_ids : str | Iterable [str ] | None = None ,
130132 ) -> dict [str , Any ]:
131133 """Create an item with a given ID and item data.
132134
@@ -135,7 +137,9 @@ def create_item(
135137 item_type: The type of item to create, e.g., 'samples', 'cells'.
136138 item_data: The data for the item.
137139 collection_id: The ID of the collection to add the item to (optional).
138- If such a collection does not exist, one will be made.
140+ If such a collection does not exist, one will be made. Deprecated in favor of `collection_ids`.
141+ collection_ids: The ID or IDs of the collection(s) to add the item to (optional).
142+ group_ids: The ID or IDs of the group(s) to share the item with (optional).
139143
140144 """
141145 new_item = {}
@@ -147,13 +151,34 @@ def create_item(
147151 new_item .pop ("item_id" )
148152
149153 if collection_id is not None :
150- try :
151- collection_immutable_id = self .get_collection (collection_id )[0 ]["immutable_id" ]
152- except (RuntimeError , DatalabAPIError ):
153- self .create_collection (collection_id )
154- collection_immutable_id = self .get_collection (collection_id )[0 ]["immutable_id" ]
154+ warnings .warn (
155+ DeprecationWarning (
156+ "`collection_id` is deprecated, please use `collection_ids` instead."
157+ )
158+ )
159+ if collection_ids is None :
160+ collection_ids = [collection_id ]
161+
162+ if collection_ids :
155163 new_item ["collections" ] = new_item .get ("collections" , [])
156- new_item ["collections" ].append ({"immutable_id" : collection_immutable_id })
164+ for collection_id in collection_ids :
165+ try :
166+ collection_immutable_id = self .get_collection (collection_id )[0 ]["immutable_id" ]
167+ except (RuntimeError , DatalabAPIError ):
168+ self .create_collection (collection_id )
169+ collection_immutable_id = self .get_collection (collection_id )[0 ]["immutable_id" ]
170+ new_item ["collections" ].append ({"immutable_id" : collection_immutable_id })
171+
172+ if group_ids :
173+ # For now, we have to use the search groups endpoint
174+ # until we add a get group by id endpoint that is locked down per user
175+ new_item ["groups" ] = new_item .get ("groups" , [])
176+ for group_id in group_ids :
177+ try :
178+ group_immutable_id = self .get_group (group_id )["immutable_id" ]
179+ new_item ["groups" ].append ({"immutable_id" : group_immutable_id })
180+ except (RuntimeError , DatalabAPIError ):
181+ pass
157182
158183 create_item_url = f"{ self .datalab_api_url } /new-sample/"
159184 created_item = self ._post (
@@ -435,6 +460,32 @@ def get_collection(self, collection_id: str) -> tuple[dict[str, Any], list[dict[
435460 collection = self ._get (collection_url )
436461 return collection ["data" ], collection ["child_items" ]
437462
463+ def get_group (self , group_id : str ) -> dict [str , Any ]:
464+ """Get a group with a given ID.
465+
466+ Uses the search groups endpoint under the hood,
467+ so will only find groups that the user has access
468+ to and that match the query.
469+
470+ Parameters:
471+ group_id: The human-readable ID of the group to search for.
472+
473+ Returns:
474+ A dictionary of group data for the group with the given ID.
475+
476+ Raises:
477+ DatalabAPIError: If no group with the given ID is found.
478+
479+ """
480+ group_url = f"{ self .datalab_api_url } /search/groups?query={ group_id } "
481+ group_resp = self ._get (group_url )
482+ matching_groups = group_resp ["data" ]
483+ if matching_groups :
484+ matching_groups = [g for g in matching_groups if g .get ("group_id" ) == group_id ]
485+ return matching_groups [0 ]
486+
487+ raise DatalabAPIError (f"No group found with ID { group_id !r} " )
488+
438489 def create_collection (
439490 self , collection_id : str , collection_data : dict | None = None
440491 ) -> dict [str , Any ]:
0 commit comments