1111from nucleus .dataset_item import DatasetItem
1212from nucleus .errors import NucleusAPIError
1313from nucleus .job import AsyncJob
14+ from nucleus .prediction import from_json as prediction_from_json
15+ from nucleus .scene import Scene
1416from nucleus .utils import (
1517 KeyErrorDict ,
1618 convert_export_payload ,
@@ -113,6 +115,7 @@ def __init__(self, slice_id: str, client):
113115 self ._dataset_id = None
114116 self ._created_at = None
115117 self ._pending_job_count = None
118+ self ._type = None
116119
117120 def __repr__ (self ):
118121 return f"Slice(slice_id='{ self .id } ', name={ self ._name } , dataset_id={ self ._dataset_id } )"
@@ -182,6 +185,13 @@ def dataset_id(self):
182185 self ._dataset_id = self .info ()["dataset_id" ]
183186 return self ._dataset_id
184187
188+ @property
189+ def type (self ):
190+ """The type of the Slice."""
191+ if self ._type is None :
192+ self ._type = self .info ()["type" ]
193+ return self ._type
194+
185195 def items_generator (self , page_size = 100000 ):
186196 """Generator yielding all dataset items in the dataset.
187197
@@ -209,28 +219,69 @@ def items_generator(self, page_size=100000):
209219 for item_json in json_generator :
210220 yield DatasetItem .from_json (item_json )
211221
222+ def dataset_items (self ):
223+ """Fetch all DatasetItems contained in the Slice.
224+
225+ We recommend using :meth:`Slice.items_generator` if the Slice has more than 200k items.
226+
227+ Returns: list of DatasetItem objects
228+
229+ """
230+ try :
231+ response = self ._client .make_request (
232+ {}, f"slice/{ self .id } " , requests_command = requests .get
233+ )
234+ except NucleusAPIError as e :
235+ if e .status_code == 503 :
236+ e .message += "/n Your request timed out while trying to get all the items in the slice. Please try slice.items_generator() instead."
237+ raise e
238+
239+ dataset_item_jsons = response .get (ITEMS_KEY , [])
240+ return [
241+ DatasetItem .from_json (dataset_item_json )
242+ for dataset_item_json in dataset_item_jsons
243+ ]
244+
212245 @property
213246 def items (self ):
214- """All DatasetItems contained in the Slice.
247+ """Fetch all items belonging to this slice, the type of items returned depends on the type of the slice.
248+ The type of the slice can be one of { dataset_item, object, scene }.
215249
216- We recommend using :meth:`Slice.items_generator` if the Slice has more than 200k items.
217250
251+ Returns: List of DatasetItems for a `dataset_item` slice,
252+ list of Annotations/Predictions for an `object` slice,
253+ or a list of Scenes for a `scene` slice.
218254 """
219255 try :
220- dataset_item_jsons = self ._client .make_request (
256+ response = self ._client .make_request (
221257 {}, f"slice/{ self .id } " , requests_command = requests .get
222- )[
223- "dataset_items"
224- ] # Unfortunately, we didn't use a standard value here, so not using a constant for the key
225- return [
226- DatasetItem .from_json (dataset_item_json )
227- for dataset_item_json in dataset_item_jsons
228- ]
258+ )
229259 except NucleusAPIError as e :
230260 if e .status_code == 503 :
231261 e .message += "/n Your request timed out while trying to get all the items in the slice. Please try slice.items_generator() instead."
232262 raise e
233263
264+ items = response .get (ITEMS_KEY , [])
265+
266+ formatted_items = []
267+ for item in items :
268+ item_id_prefix = item ["id" ].split ("_" )[0 ]
269+ if item_id_prefix == "di" :
270+ formatted_items .append (DatasetItem .from_json (item ))
271+ elif item_id_prefix == "ann" :
272+ formatted_items .append (Annotation .from_json (item ))
273+ elif item_id_prefix == "pred" :
274+ formatted_items .append (prediction_from_json (item ))
275+ elif item_id_prefix == "scn" :
276+ # here we skip validate since no frames for the scene is fetched
277+ formatted_items .append (
278+ Scene .from_json (item , skip_validate = True )
279+ )
280+ else :
281+ raise ValueError ("Unknown prefix" , item_id_prefix )
282+
283+ return formatted_items
284+
234285 def info (self ) -> dict :
235286 """Retrieves the name, slice_id, and dataset_id of the Slice.
236287
@@ -251,6 +302,11 @@ def info(self) -> dict:
251302 {}, f"slice/{ self .id } /info" , requests_command = requests .get
252303 )
253304 info .update (res )
305+ self ._name = info ["name" ]
306+ self ._dataset_id = info ["dataset_id" ]
307+ self ._created_at = info ["created_at" ]
308+ self ._pending_job_count = info ["pending_job_count" ]
309+ self ._type = info ["type" ]
254310 return info
255311
256312 def append (
@@ -552,7 +608,10 @@ def check_annotations_are_in_slice(
552608 for annotation in annotations
553609 if annotation .reference_id is not None
554610 }.difference (
555- {item_metadata ["ref_id" ] for item_metadata in slice_to_check .items }
611+ {
612+ item_metadata ["ref_id" ]
613+ for item_metadata in slice_to_check .dataset_items ()
614+ }
556615 )
557616 if reference_ids_not_found_in_slice :
558617 annotations_are_in_slice = False
0 commit comments