cognite-toolkit 0.6.83__py3-none-any.whl → 0.6.85__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 cognite-toolkit might be problematic. Click here for more details.

@@ -36,7 +36,6 @@ from cognite_toolkit._cdf_tk.client.data_classes.functions import FunctionSchedu
36
36
  from cognite_toolkit._cdf_tk.cruds._base_cruds import ResourceCRUD
37
37
  from cognite_toolkit._cdf_tk.exceptions import (
38
38
  ResourceCreationError,
39
- ResourceRetrievalError,
40
39
  ToolkitRequiredValueError,
41
40
  )
42
41
  from cognite_toolkit._cdf_tk.feature_flags import Flags
@@ -565,22 +564,7 @@ class FunctionScheduleCRUD(
565
564
 
566
565
  def create(self, items: FunctionScheduleWriteList) -> FunctionSchedulesList:
567
566
  created_list = FunctionSchedulesList([], cognite_client=self.client)
568
- functions_to_lookup = list({item.function_external_id for item in items if item.function_external_id})
569
- function_id_by_external_id: dict[str, int] = {}
570
- if functions_to_lookup:
571
- try:
572
- function_ids = self.client.lookup.functions.id(functions_to_lookup)
573
- except ResourceRetrievalError as e:
574
- failed_items = self.get_ids(items)
575
- missing_functions = functions_to_lookup
576
- if e.resources:
577
- missing_functions = list(e.resources)
578
- failed_items = [id_ for id_ in failed_items if id_.function_external_id in set(missing_functions)]
579
- raise ResourceCreationError(
580
- f"Failed to create function schedule(s) {humanize_collection(failed_items)}. "
581
- f"Could not find function(s) {humanize_collection(missing_functions)!r}"
582
- ) from e
583
- function_id_by_external_id = dict(zip(functions_to_lookup, function_ids))
567
+ function_id_by_external_id = self._get_function_ids_by_external_id(items)
584
568
 
585
569
  for item in items:
586
570
  id_ = self.get_id(item)
@@ -607,6 +591,28 @@ class FunctionScheduleCRUD(
607
591
  created_list.append(created)
608
592
  return created_list
609
593
 
594
+ def _get_function_ids_by_external_id(self, items: FunctionScheduleWriteList) -> dict[str, int]:
595
+ functions_to_lookup = list({item.function_external_id for item in items if item.function_external_id})
596
+ if not functions_to_lookup:
597
+ return {}
598
+ function_ids = self.client.lookup.functions.id(functions_to_lookup)
599
+
600
+ if len(function_ids) == len(functions_to_lookup):
601
+ return dict(zip(functions_to_lookup, function_ids))
602
+ # The lookup API is cached, so it is cheap to do individual lookups to find the missing ones.
603
+ lookup_pair = (
604
+ (function_external_id, self.client.lookup.functions.id(function_external_id))
605
+ for function_external_id in functions_to_lookup
606
+ )
607
+ missing_functions = {func for func, func_id in lookup_pair if func_id is None}
608
+ failed_schedules = [self.get_id(item) for item in items if item.function_external_id in missing_functions]
609
+ plural_schedules = "s" if len(failed_schedules) > 1 else ""
610
+ plural_fun = "s" if len(missing_functions) > 1 else ""
611
+ raise ResourceCreationError(
612
+ f"Failed to create function schedule{plural_schedules} {humanize_collection(failed_schedules)}. "
613
+ f"Could not find function{plural_fun} {humanize_collection(missing_functions)!r}"
614
+ )
615
+
610
616
  def delete(self, ids: SequenceNotStr[FunctionScheduleID]) -> int:
611
617
  schedules = self.retrieve(ids)
612
618
  count = 0
@@ -36,10 +36,9 @@ from cognite_toolkit._cdf_tk.cruds import (
36
36
  EventCRUD,
37
37
  FileMetadataCRUD,
38
38
  LabelCRUD,
39
- ResourceCRUD,
40
39
  TimeSeriesCRUD,
41
40
  )
42
- from cognite_toolkit._cdf_tk.exceptions import ToolkitNotImplementedError
41
+ from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitNotImplementedError
43
42
  from cognite_toolkit._cdf_tk.utils.aggregators import (
44
43
  AssetAggregator,
45
44
  AssetCentricAggregator,
@@ -85,19 +84,10 @@ class BaseAssetCentricIO(
85
84
 
86
85
  def __init__(self, client: ToolkitClient) -> None:
87
86
  super().__init__(client)
88
- self._loader = self._get_loader()
89
87
  self._aggregator = self._get_aggregator()
90
88
  self._downloaded_data_sets_by_selector: dict[AssetCentricSelector, set[int]] = defaultdict(set)
91
89
  self._downloaded_labels_by_selector: dict[AssetCentricSelector, set[str]] = defaultdict(set)
92
90
 
93
- @abstractmethod
94
- def _get_loader(
95
- self,
96
- ) -> ResourceCRUD[
97
- T_ID, T_WriteClass, T_WritableCogniteResource, T_CogniteResourceList, T_WritableCogniteResourceList
98
- ]:
99
- raise NotImplementedError()
100
-
101
91
  @abstractmethod
102
92
  def _get_aggregator(self) -> AssetCentricAggregator:
103
93
  raise NotImplementedError()
@@ -113,11 +103,6 @@ class BaseAssetCentricIO(
113
103
  return self._aggregator.count(hierarchy=selector.hierarchy)
114
104
  return None
115
105
 
116
- def data_to_json_chunk(
117
- self, data_chunk: Sequence[T_WritableCogniteResource], selector: AssetCentricSelector | None = None
118
- ) -> list[dict[str, JsonVal]]:
119
- return [self._loader.dump_resource(item) for item in data_chunk]
120
-
121
106
  def configurations(self, selector: AssetCentricSelector) -> Iterable[StorageIOConfig]:
122
107
  data_set_ids = self._downloaded_data_sets_by_selector[selector]
123
108
  if data_set_ids:
@@ -178,6 +163,22 @@ class BaseAssetCentricIO(
178
163
  def create_internal_identifier(cls, internal_id: int, project: str) -> str:
179
164
  return f"INTERNAL_ID_project_{project}_{internal_id!s}"
180
165
 
166
+ def _populate_data_set_cache(self, chunk: Sequence[Asset | FileMetadata | TimeSeries | Event]) -> None:
167
+ data_set_ids = {item.data_set_id for item in chunk if item.data_set_id is not None}
168
+ self.client.lookup.data_sets.external_id(list(data_set_ids))
169
+
170
+ def _populate_security_category_cache(self, chunk: Sequence[FileMetadata | TimeSeries]) -> None:
171
+ security_category_ids: set[int] = set()
172
+ for item in chunk:
173
+ security_category_ids.update(item.security_categories or [])
174
+ self.client.lookup.security_categories.external_id(list(security_category_ids))
175
+
176
+ def _populate_asset_cache(self, chunk: Sequence[FileMetadata | Event]) -> None:
177
+ asset_ids: set[int] = set()
178
+ for item in chunk:
179
+ asset_ids.update(item.asset_ids or [])
180
+ self.client.lookup.assets.external_id(list(asset_ids))
181
+
181
182
 
182
183
  class AssetIO(BaseAssetCentricIO[str, AssetWrite, Asset, AssetWriteList, AssetList]):
183
184
  KIND = "Assets"
@@ -187,22 +188,31 @@ class AssetIO(BaseAssetCentricIO[str, AssetWrite, Asset, AssetWriteList, AssetLi
187
188
  SUPPORTED_READ_FORMATS = frozenset({".parquet", ".csv", ".ndjson", ".yaml", ".yml"})
188
189
  UPLOAD_ENDPOINT = "/assets"
189
190
 
191
+ def __init__(self, client: ToolkitClient) -> None:
192
+ super().__init__(client)
193
+ self._crud = AssetCRUD.create_loader(self.client)
194
+
190
195
  def as_id(self, item: Asset) -> str:
191
196
  return item.external_id if item.external_id is not None else self._create_identifier(item.id)
192
197
 
193
- def _get_loader(self) -> AssetCRUD:
194
- return AssetCRUD.create_loader(self.client)
195
-
196
198
  def _get_aggregator(self) -> AssetCentricAggregator:
197
199
  return AssetAggregator(self.client)
198
200
 
199
201
  def get_schema(self, selector: AssetCentricSelector) -> list[SchemaColumn]:
200
202
  data_set_ids: list[int] = []
201
203
  if isinstance(selector, DataSetSelector):
202
- data_set_ids.append(self.client.lookup.data_sets.id(selector.data_set_external_id))
204
+ data_set_id = self.client.lookup.data_sets.id(selector.data_set_external_id)
205
+ if data_set_id is None:
206
+ raise ToolkitMissingResourceError(
207
+ f"Data set with external ID {selector.data_set_external_id} not found."
208
+ )
209
+ data_set_ids.append(data_set_id)
203
210
  hierarchy: list[int] = []
204
211
  if isinstance(selector, AssetSubtreeSelector):
205
- hierarchy.append(self.client.lookup.assets.id(selector.hierarchy))
212
+ asset_id = self.client.lookup.assets.id(selector.hierarchy)
213
+ if asset_id is None:
214
+ raise ToolkitMissingResourceError(f"Asset with external ID {selector.hierarchy} not found.")
215
+ hierarchy.append(asset_id)
206
216
 
207
217
  if hierarchy or data_set_ids:
208
218
  metadata_keys = metadata_key_counts(
@@ -238,8 +248,17 @@ class AssetIO(BaseAssetCentricIO[str, AssetWrite, Asset, AssetWriteList, AssetLi
238
248
  self._collect_dependencies(asset_list, selector)
239
249
  yield Page(worker_id="main", items=asset_list)
240
250
 
251
+ def data_to_json_chunk(
252
+ self, data_chunk: Sequence[Asset], selector: AssetCentricSelector | None = None
253
+ ) -> list[dict[str, JsonVal]]:
254
+ # Ensure data sets are looked up to populate cache.
255
+ # This is to avoid looking up each data set id individually in the .dump_resource call.
256
+ self._populate_data_set_cache(data_chunk)
257
+
258
+ return [self._crud.dump_resource(item) for item in data_chunk]
259
+
241
260
  def json_to_resource(self, item_json: dict[str, JsonVal]) -> AssetWrite:
242
- return self._loader.load_resource(item_json)
261
+ return self._crud.load_resource(item_json)
243
262
 
244
263
  def retrieve(self, ids: Sequence[int]) -> AssetList:
245
264
  return self.client.assets.retrieve_multiple(ids)
@@ -253,19 +272,25 @@ class FileMetadataIO(BaseAssetCentricIO[str, FileMetadataWrite, FileMetadata, Fi
253
272
  SUPPORTED_READ_FORMATS = frozenset({".parquet", ".csv", ".ndjson"})
254
273
  UPLOAD_ENDPOINT = "/files"
255
274
 
275
+ def __init__(self, client: ToolkitClient) -> None:
276
+ super().__init__(client)
277
+ self._crud = FileMetadataCRUD.create_loader(self.client)
278
+
256
279
  def as_id(self, item: FileMetadata) -> str:
257
280
  return item.external_id if item.external_id is not None else self._create_identifier(item.id)
258
281
 
259
- def _get_loader(self) -> FileMetadataCRUD:
260
- return FileMetadataCRUD.create_loader(self.client)
261
-
262
282
  def _get_aggregator(self) -> AssetCentricAggregator:
263
283
  return FileAggregator(self.client)
264
284
 
265
285
  def get_schema(self, selector: AssetCentricSelector) -> list[SchemaColumn]:
266
286
  data_set_ids: list[int] = []
267
287
  if isinstance(selector, DataSetSelector):
268
- data_set_ids.append(self.client.lookup.data_sets.id(selector.data_set_external_id))
288
+ data_set_id = self.client.lookup.data_sets.id(selector.data_set_external_id)
289
+ if data_set_id is None:
290
+ raise ToolkitMissingResourceError(
291
+ f"Data set with external ID {selector.data_set_external_id} not found."
292
+ )
293
+ data_set_ids.append(data_set_id)
269
294
  if isinstance(selector, AssetSubtreeSelector):
270
295
  raise ToolkitNotImplementedError(f"Selector type {type(selector)} not supported for FileIO.")
271
296
 
@@ -345,8 +370,19 @@ class FileMetadataIO(BaseAssetCentricIO[str, FileMetadataWrite, FileMetadata, Fi
345
370
  def retrieve(self, ids: Sequence[int]) -> FileMetadataList:
346
371
  return self.client.files.retrieve_multiple(ids)
347
372
 
373
+ def data_to_json_chunk(
374
+ self, data_chunk: Sequence[FileMetadata], selector: AssetCentricSelector | None = None
375
+ ) -> list[dict[str, JsonVal]]:
376
+ # Ensure data sets/assets/security-categories are looked up to populate cache.
377
+ # This is to avoid looking up each data set id individually in the .dump_resource call
378
+ self._populate_data_set_cache(data_chunk)
379
+ self._populate_asset_cache(data_chunk)
380
+ self._populate_security_category_cache(data_chunk)
381
+
382
+ return [self._crud.dump_resource(item) for item in data_chunk]
383
+
348
384
  def json_to_resource(self, item_json: dict[str, JsonVal]) -> FileMetadataWrite:
349
- return self._loader.load_resource(item_json)
385
+ return self._crud.load_resource(item_json)
350
386
 
351
387
 
352
388
  class TimeSeriesIO(BaseAssetCentricIO[str, TimeSeriesWrite, TimeSeries, TimeSeriesWriteList, TimeSeriesList]):
@@ -357,12 +393,13 @@ class TimeSeriesIO(BaseAssetCentricIO[str, TimeSeriesWrite, TimeSeries, TimeSeri
357
393
  UPLOAD_ENDPOINT = "/timeseries"
358
394
  RESOURCE_TYPE = "timeseries"
359
395
 
396
+ def __init__(self, client: ToolkitClient) -> None:
397
+ super().__init__(client)
398
+ self._crud = TimeSeriesCRUD.create_loader(self.client)
399
+
360
400
  def as_id(self, item: TimeSeries) -> str:
361
401
  return item.external_id if item.external_id is not None else self._create_identifier(item.id)
362
402
 
363
- def _get_loader(self) -> TimeSeriesCRUD:
364
- return TimeSeriesCRUD.create_loader(self.client)
365
-
366
403
  def _get_aggregator(self) -> AssetCentricAggregator:
367
404
  return TimeSeriesAggregator(self.client)
368
405
 
@@ -380,13 +417,29 @@ class TimeSeriesIO(BaseAssetCentricIO[str, TimeSeriesWrite, TimeSeries, TimeSeri
380
417
  self._collect_dependencies(ts_list, selector)
381
418
  yield Page(worker_id="main", items=ts_list)
382
419
 
420
+ def data_to_json_chunk(
421
+ self, data_chunk: Sequence[TimeSeries], selector: AssetCentricSelector | None = None
422
+ ) -> list[dict[str, JsonVal]]:
423
+ # Ensure data sets/assets/security categories are looked up to populate cache.
424
+ self._populate_data_set_cache(data_chunk)
425
+ self._populate_security_category_cache(data_chunk)
426
+ asset_ids = {item.asset_id for item in data_chunk if item.asset_id is not None}
427
+ self.client.lookup.assets.external_id(list(asset_ids))
428
+
429
+ return [self._crud.dump_resource(item) for item in data_chunk]
430
+
383
431
  def json_to_resource(self, item_json: dict[str, JsonVal]) -> TimeSeriesWrite:
384
- return self._loader.load_resource(item_json)
432
+ return self._crud.load_resource(item_json)
385
433
 
386
434
  def get_schema(self, selector: AssetCentricSelector) -> list[SchemaColumn]:
387
435
  data_set_ids: list[int] = []
388
436
  if isinstance(selector, DataSetSelector):
389
- data_set_ids.append(self.client.lookup.data_sets.id(selector.data_set_external_id))
437
+ data_set_id = self.client.lookup.data_sets.id(selector.data_set_external_id)
438
+ if data_set_id is None:
439
+ raise ToolkitMissingResourceError(
440
+ f"Data set with external ID {selector.data_set_external_id} not found."
441
+ )
442
+ data_set_ids.append(data_set_id)
390
443
  elif isinstance(selector, AssetSubtreeSelector):
391
444
  raise ToolkitNotImplementedError(f"Selector type {type(selector)} not supported for {type(self).__name__}.")
392
445
 
@@ -424,19 +477,25 @@ class EventIO(BaseAssetCentricIO[str, EventWrite, Event, EventWriteList, EventLi
424
477
  UPLOAD_ENDPOINT = "/events"
425
478
  RESOURCE_TYPE = "event"
426
479
 
480
+ def __init__(self, client: ToolkitClient) -> None:
481
+ super().__init__(client)
482
+ self._crud = EventCRUD.create_loader(self.client)
483
+
427
484
  def as_id(self, item: Event) -> str:
428
485
  return item.external_id if item.external_id is not None else self._create_identifier(item.id)
429
486
 
430
- def _get_loader(self) -> EventCRUD:
431
- return EventCRUD.create_loader(self.client)
432
-
433
487
  def _get_aggregator(self) -> AssetCentricAggregator:
434
488
  return EventAggregator(self.client)
435
489
 
436
490
  def get_schema(self, selector: AssetCentricSelector) -> list[SchemaColumn]:
437
491
  data_set_ids: list[int] = []
438
492
  if isinstance(selector, DataSetSelector):
439
- data_set_ids.append(self.client.lookup.data_sets.id(selector.data_set_external_id))
493
+ data_set_id = self.client.lookup.data_sets.id(selector.data_set_external_id)
494
+ if data_set_id is None:
495
+ raise ToolkitMissingResourceError(
496
+ f"Data set with external ID {selector.data_set_external_id} not found."
497
+ )
498
+ data_set_ids.append(data_set_id)
440
499
  hierarchy: list[int] = []
441
500
  if isinstance(selector, AssetSubtreeSelector):
442
501
  raise ToolkitNotImplementedError(f"Selector type {type(selector)} not supported for {type(self).__name__}.")
@@ -476,8 +535,17 @@ class EventIO(BaseAssetCentricIO[str, EventWrite, Event, EventWriteList, EventLi
476
535
  self._collect_dependencies(event_list, selector)
477
536
  yield Page(worker_id="main", items=event_list)
478
537
 
538
+ def data_to_json_chunk(
539
+ self, data_chunk: Sequence[Event], selector: AssetCentricSelector | None = None
540
+ ) -> list[dict[str, JsonVal]]:
541
+ # Ensure data sets/assets are looked up to populate cache.
542
+ self._populate_data_set_cache(data_chunk)
543
+ self._populate_asset_cache(data_chunk)
544
+
545
+ return [self._crud.dump_resource(item) for item in data_chunk]
546
+
479
547
  def json_to_resource(self, item_json: dict[str, JsonVal]) -> EventWrite:
480
- return self._loader.load_resource(item_json)
548
+ return self._crud.load_resource(item_json)
481
549
 
482
550
  def retrieve(self, ids: Sequence[int]) -> EventList:
483
551
  return self.client.events.retrieve_multiple(ids)
@@ -18,6 +18,7 @@ from cognite.client.data_classes.sequences import SequenceProperty
18
18
  from cognite.client.data_classes.time_series import TimeSeriesProperty
19
19
 
20
20
  from cognite_toolkit._cdf_tk.client import ToolkitClient
21
+ from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError
21
22
  from cognite_toolkit._cdf_tk.utils.cdf import (
22
23
  label_aggregate_count,
23
24
  label_count,
@@ -105,6 +106,15 @@ class AssetCentricAggregator(ABC):
105
106
  seen.add(int_id)
106
107
  return ids
107
108
 
109
+ def _to_dataset_id(self, data_set_external_id: str | list[str] | None) -> list[int] | None:
110
+ """Converts data set external IDs to data set IDs."""
111
+ dataset_id: list[int] | None = None
112
+ if data_set_external_id is not None:
113
+ if isinstance(data_set_external_id, str):
114
+ data_set_external_id = [data_set_external_id]
115
+ dataset_id = self.client.lookup.data_sets.id(data_set_external_id, allow_empty=False)
116
+ return dataset_id
117
+
108
118
 
109
119
  class MetadataAggregator(AssetCentricAggregator, ABC, Generic[T_CogniteFilter]):
110
120
  filter_cls: type[T_CogniteFilter]
@@ -125,7 +135,9 @@ class MetadataAggregator(AssetCentricAggregator, ABC, Generic[T_CogniteFilter]):
125
135
  self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
126
136
  ) -> list[tuple[str, int]]:
127
137
  """Returns a list of metadata keys and their counts."""
128
- hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(hierarchy, data_sets)
138
+ hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(
139
+ hierarchy, data_sets, operation="find metadata keys"
140
+ )
129
141
  return self._used_metadata_keys(hierarchy=hierarchy_ids, data_sets=data_set_ids)
130
142
 
131
143
  @lru_cache(maxsize=1)
@@ -140,22 +152,44 @@ class MetadataAggregator(AssetCentricAggregator, ABC, Generic[T_CogniteFilter]):
140
152
  )
141
153
 
142
154
  def _lookup_hierarchy_data_set_pair(
143
- self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
155
+ self, hierarchy: str | list[str] | None, data_sets: str | list[str] | None, operation: str
144
156
  ) -> tuple[tuple[int, ...] | None, tuple[int, ...] | None]:
145
157
  """Returns a tuple of hierarchy and data sets."""
146
158
  hierarchy_ids: tuple[int, ...] | None = None
147
159
  if isinstance(hierarchy, str):
148
160
  asset_id = self.client.lookup.assets.id(external_id=hierarchy, allow_empty=False)
161
+ if asset_id is None:
162
+ raise ToolkitMissingResourceError(f"Cannot {operation}. Asset with external ID {hierarchy!r} not found")
149
163
  hierarchy_ids = (asset_id,)
150
164
  elif isinstance(hierarchy, list) and all(isinstance(item, str) for item in hierarchy):
151
- hierarchy_ids = tuple(sorted(self.client.lookup.assets.id(external_id=hierarchy, allow_empty=False)))
165
+ asset_ids = self.client.lookup.assets.id(external_id=hierarchy, allow_empty=False)
166
+ if len(asset_ids) != len(hierarchy):
167
+ missing = set(hierarchy) - set(
168
+ self.client.lookup.assets.external_id([id_ for id_ in asset_ids if id_ is not None])
169
+ )
170
+ raise ToolkitMissingResourceError(
171
+ f"Cannot {operation}. Assets with external IDs {sorted(missing)!r} not found"
172
+ )
173
+ hierarchy_ids = tuple(sorted(asset_ids))
152
174
 
153
175
  data_set_ids: tuple[int, ...] | None = None
154
176
  if isinstance(data_sets, str):
155
177
  data_set_id = self.client.lookup.data_sets.id(external_id=data_sets, allow_empty=False)
178
+ if data_set_id is None:
179
+ raise ToolkitMissingResourceError(
180
+ f"Cannot {operation}. Data set with external ID {data_sets!r} not found"
181
+ )
156
182
  data_set_ids = (data_set_id,)
157
183
  elif isinstance(data_sets, list) and all(isinstance(item, str) for item in data_sets):
158
- data_set_ids = tuple(sorted(self.client.lookup.data_sets.id(external_id=data_sets, allow_empty=False)))
184
+ data_set_ids_list = self.client.lookup.data_sets.id(external_id=data_sets, allow_empty=False)
185
+ if len(data_set_ids_list) != len(data_sets):
186
+ missing = set(data_sets) - set(
187
+ self.client.lookup.data_sets.external_id([id_ for id_ in data_set_ids_list if id_ is not None])
188
+ )
189
+ raise ToolkitMissingResourceError(
190
+ f"Cannot {operation}. Data sets with external IDs {sorted(missing)!r} not found"
191
+ )
192
+ data_set_ids = tuple(sorted(data_set_ids_list))
159
193
 
160
194
  return hierarchy_ids, data_set_ids
161
195
 
@@ -201,7 +235,9 @@ class LabelAggregator(MetadataAggregator, ABC, Generic[T_CogniteFilter]):
201
235
  self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
202
236
  ) -> list[tuple[str, int]]:
203
237
  """Returns a list of labels and their counts."""
204
- hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(hierarchy, data_sets)
238
+ hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(
239
+ hierarchy, data_sets, operation="find labels"
240
+ )
205
241
  return self._used_labels(hierarchy=hierarchy_ids, data_sets=data_set_ids)
206
242
 
207
243
  @lru_cache(maxsize=1)
@@ -359,9 +395,10 @@ class RelationshipAggregator(AssetCentricAggregator):
359
395
  def count(
360
396
  self, hierarchy: str | list[str] | None = None, data_set_external_id: str | list[str] | None = None
361
397
  ) -> int:
362
- if hierarchy is not None or data_set_external_id is not None:
398
+ if hierarchy is not None:
363
399
  raise NotImplementedError()
364
- results = relationship_aggregate_count(self.client)
400
+ dataset_id = self._to_dataset_id(data_set_external_id)
401
+ results = relationship_aggregate_count(self.client, dataset_id)
365
402
  return sum(result.count for result in results)
366
403
 
367
404
  def used_data_sets(self, hierarchy: str | None = None) -> list[str]:
@@ -378,9 +415,10 @@ class LabelCountAggregator(AssetCentricAggregator):
378
415
  def count(
379
416
  self, hierarchy: str | list[str] | None = None, data_set_external_id: str | list[str] | None = None
380
417
  ) -> int:
381
- if hierarchy is not None or data_set_external_id is not None:
418
+ if hierarchy is not None:
382
419
  raise NotImplementedError()
383
- return label_aggregate_count(self.client)
420
+ data_set_id = self._to_dataset_id(data_set_external_id)
421
+ return label_aggregate_count(self.client, data_set_id)
384
422
 
385
423
  def used_data_sets(self, hierarchy: str | None = None) -> list[str]:
386
424
  raise NotImplementedError()