cognite-toolkit 0.6.83__py3-none-any.whl → 0.6.84__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.

@@ -1,6 +1,7 @@
1
1
  from typing import cast
2
2
 
3
3
  from cognite.client import CogniteClient
4
+ from rich.console import Console
4
5
 
5
6
  from .api.canvas import CanvasAPI
6
7
  from .api.charts import ChartsAPI
@@ -24,11 +25,12 @@ class ToolkitClient(CogniteClient):
24
25
  def __init__(self, config: ToolkitClientConfig | None = None, enable_set_pending_ids: bool = False) -> None:
25
26
  super().__init__(config=config)
26
27
  toolkit_config = ToolkitClientConfig.from_client_config(self.config)
28
+ self.console = Console()
27
29
  self.search = SearchAPI(self._config, self._API_VERSION, self)
28
30
  self.robotics = RoboticsAPI(self._config, self._API_VERSION, self)
29
31
  self.dml = DMLAPI(self._config, self._API_VERSION, self)
30
32
  self.verify = VerifyAPI(self._config, self._API_VERSION, self)
31
- self.lookup = LookUpGroup(self._config, self._API_VERSION, self)
33
+ self.lookup = LookUpGroup(self._config, self._API_VERSION, self, self.console)
32
34
  self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(toolkit_config, self._API_VERSION, self)
33
35
  self.data_modeling: ExtendedDataModelingAPI = ExtendedDataModelingAPI(self._config, self._API_VERSION, self)
34
36
  if enable_set_pending_ids:
@@ -17,11 +17,12 @@ from cognite.client.data_classes.capabilities import (
17
17
  )
18
18
  from cognite.client.exceptions import CogniteAPIError
19
19
  from cognite.client.utils.useful_types import SequenceNotStr
20
+ from rich.console import Console
20
21
 
21
22
  from cognite_toolkit._cdf_tk.client.api_client import ToolkitAPI
22
23
  from cognite_toolkit._cdf_tk.constants import DRY_RUN_ID
23
- from cognite_toolkit._cdf_tk.exceptions import ResourceRetrievalError
24
24
  from cognite_toolkit._cdf_tk.tk_warnings import MediumSeverityWarning
25
+ from cognite_toolkit._cdf_tk.utils import humanize_collection
25
26
 
26
27
  if TYPE_CHECKING:
27
28
  from cognite_toolkit._cdf_tk.client._toolkit_client import ToolkitClient
@@ -30,17 +31,20 @@ if TYPE_CHECKING:
30
31
  class LookUpAPI(ToolkitAPI, ABC):
31
32
  dry_run_id: int = DRY_RUN_ID
32
33
 
33
- def __init__(self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient") -> None:
34
+ def __init__(
35
+ self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
36
+ ) -> None:
34
37
  super().__init__(config, api_version, cognite_client)
35
- self._cache: dict[str, int] = {}
36
- self._reverse_cache: dict[int, str] = {}
38
+ self._console = console
39
+ self._cache: dict[str, int | None] = {}
40
+ self._reverse_cache: dict[int, str | None] = {}
37
41
 
38
42
  @property
39
43
  def resource_name(self) -> str:
40
44
  return type(self).__name__.removesuffix("LookUpAPI")
41
45
 
42
46
  @overload
43
- def id(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int: ...
47
+ def id(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int | None: ...
44
48
 
45
49
  @overload
46
50
  def id(
@@ -49,39 +53,61 @@ class LookUpAPI(ToolkitAPI, ABC):
49
53
 
50
54
  def id(
51
55
  self, external_id: str | SequenceNotStr[str], is_dry_run: bool = False, allow_empty: bool = False
52
- ) -> int | list[int]:
56
+ ) -> int | None | list[int]:
57
+ """Lookup internal IDs for given external IDs.
58
+
59
+ Args:
60
+ external_id: A string external ID or a sequence of string external IDs to look up.
61
+ is_dry_run: If True, return a predefined dry run ID for missing external IDs instead of raising an error.
62
+ allow_empty: If True, allow empty string external IDs and return 0 for them.
63
+
64
+ Returns:
65
+ The corresponding internal ID as an integer if a single external ID is provided,
66
+ or a list of internal IDs if a sequence of external IDs is provided.
67
+ """
53
68
  ids = [external_id] if isinstance(external_id, str) else external_id
54
- missing = [id for id in ids if id not in self._cache]
55
- if allow_empty and "" in missing:
69
+ need_lookup = [id for id in ids if id not in self._cache]
70
+ if allow_empty and "" in need_lookup:
56
71
  # Note we do not want to put empty string in the cache. It is a special case that
57
72
  # as of 01/02/2025 only applies to LocationFilters
58
- missing.remove("")
59
- if missing:
60
- try:
61
- lookup = self._id(missing)
62
- except CogniteAPIError as e:
63
- if 400 <= e.code < 500:
64
- missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
65
- if missing_capabilities:
66
- raise self._toolkit_client.verify.create_error(
67
- missing_capabilities,
68
- f"lookup {self.resource_name} with external_id {missing}",
69
- )
70
- # Raise the original error if it's not a 400 or the user has access to read the resource.from
71
- raise
72
- self._cache.update(lookup)
73
- self._reverse_cache.update({v: k for k, v in lookup.items()})
74
- if len(missing) != len(lookup) and not is_dry_run:
75
- raise ResourceRetrievalError(
76
- f"Failed to retrieve {self.resource_name} with external_id {missing}. Have you created it?", missing
77
- )
78
- return (
79
- self._get_id_from_cache(external_id, is_dry_run, allow_empty)
80
- if isinstance(external_id, str)
81
- else [self._get_id_from_cache(id, is_dry_run, allow_empty) for id in ids]
82
- )
73
+ need_lookup.remove("")
74
+ if need_lookup:
75
+ self._do_lookup_external_ids(need_lookup, is_dry_run)
83
76
 
84
- def _get_id_from_cache(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int:
77
+ if isinstance(external_id, str):
78
+ return self._get_id_from_cache(external_id, is_dry_run, allow_empty)
79
+ else:
80
+ internal_ids = (
81
+ self._get_id_from_cache(external_id, is_dry_run, allow_empty) for external_id in external_id
82
+ )
83
+ return [id_ for id_ in internal_ids if id_ is not None]
84
+
85
+ def _do_lookup_external_ids(self, external_ids: list[str], is_dry_run: bool) -> None:
86
+ try:
87
+ ids_by_external_id = self._id(external_ids)
88
+ except CogniteAPIError as e:
89
+ if 400 <= e.code < 500:
90
+ missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
91
+ if missing_capabilities:
92
+ raise self._toolkit_client.verify.create_error(
93
+ missing_capabilities,
94
+ f"lookup {self.resource_name} with external_id {external_ids}",
95
+ )
96
+ # Raise the original error if it's not a 400 or the user has access to read the resource.from
97
+ raise
98
+ self._cache.update(ids_by_external_id)
99
+ self._reverse_cache.update({v: k for k, v in ids_by_external_id.items()})
100
+ missing_external_ids = [ext_id for ext_id in external_ids if ext_id not in ids_by_external_id]
101
+ if missing_external_ids and not is_dry_run:
102
+ plural = "s" if len(missing_external_ids) > 1 else ""
103
+ plural2 = "They do" if len(missing_external_ids) > 1 else "It does"
104
+ MediumSeverityWarning(
105
+ f"Failed to retrieve {self.resource_name} with external_id{plural} "
106
+ f"{humanize_collection(missing_external_ids)}. {plural2} not exist in CDF"
107
+ ).print_warning(console=self._console)
108
+ self._cache.update({ext_id: None for ext_id in missing_external_ids})
109
+
110
+ def _get_id_from_cache(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int | None:
85
111
  if allow_empty and external_id == "":
86
112
  return 0
87
113
  elif is_dry_run:
@@ -96,34 +122,56 @@ class LookUpAPI(ToolkitAPI, ABC):
96
122
  def external_id(self, id: Sequence[int]) -> list[str]: ...
97
123
 
98
124
  def external_id(self, id: int | Sequence[int]) -> str | None | list[str]:
125
+ """Lookup external IDs for given internal IDs.
126
+
127
+ Args:
128
+ id: An integer ID or a sequence of integer IDs to look up. Note that an ID of 0 corresponds
129
+ to an empty string external ID.
130
+
131
+ Returns:
132
+ The corresponding external ID as a string if a single ID is provided,
133
+ or a list of external IDs if a sequence of IDs is provided.
134
+ If an ID does not exist, None is returned for that ID.
135
+
136
+ """
99
137
  ids = [id] if isinstance(id, int) else id
100
- missing = [id_ for id_ in ids if id_ not in self._reverse_cache]
101
- if 0 in missing:
102
- missing.remove(0)
103
- if missing:
104
- try:
105
- lookup = self._external_id(missing)
106
- except CogniteAPIError as e:
107
- if 400 <= e.code < 500:
108
- missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
109
- if missing_capabilities:
110
- raise self._toolkit_client.verify.create_error(
111
- missing_capabilities,
112
- f"lookup {self.resource_name} with id {missing}",
113
- )
114
- # Raise the original error if it's not a 400 or the user has access to read the resource.from
115
- raise
116
- self._reverse_cache.update(lookup)
117
- self._cache.update({v: k for k, v in lookup.items()})
118
- if len(missing) != len(lookup):
119
- MediumSeverityWarning(
120
- f"Failed to retrieve {self.resource_name} with id {missing}. It does not exist in CDF"
121
- ).print_warning()
138
+ need_lookup = [id_ for id_ in ids if id_ not in self._reverse_cache if id_ != 0]
139
+ if need_lookup:
140
+ self._do_lookup_internal_ids(need_lookup)
141
+
122
142
  if isinstance(id, int):
123
143
  return self._get_external_id_from_cache(id)
124
144
  else:
125
- external_ids = (self._get_external_id_from_cache(id) for id in ids)
126
- return [id for id in external_ids if id is not None]
145
+ external_ids = (self._get_external_id_from_cache(id_) for id_ in ids)
146
+ return [id_ for id_ in external_ids if id_ is not None]
147
+
148
+ def _do_lookup_internal_ids(self, ids: list[int]) -> None:
149
+ try:
150
+ found_by_id = self._external_id(ids)
151
+ except CogniteAPIError as e:
152
+ if 400 <= e.code < 500:
153
+ missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
154
+ if missing_capabilities:
155
+ raise self._toolkit_client.verify.create_error(
156
+ missing_capabilities,
157
+ f"lookup {self.resource_name} with id {ids}",
158
+ )
159
+ # Raise the original error if it's not a 400 or the user has access to read the resource.from
160
+ raise
161
+ self._reverse_cache.update(found_by_id)
162
+ self._cache.update({v: k for k, v in found_by_id.items()})
163
+ missing_ids = [id for id in ids if id not in found_by_id]
164
+ if not missing_ids:
165
+ return None
166
+ plural = "s" if len(missing_ids) > 1 else ""
167
+ plural2 = "They do" if len(missing_ids) > 1 else "It does"
168
+ MediumSeverityWarning(
169
+ f"Failed to retrieve {self.resource_name} with id{plural} "
170
+ f"{humanize_collection(missing_ids)}. {plural2} not exist in CDF"
171
+ ).print_warning(console=self._console)
172
+ # Cache the missing IDs with None to avoid repeated lookups
173
+ self._reverse_cache.update({missing_id: None for missing_id in missing_ids})
174
+ return None
127
175
 
128
176
  def _get_external_id_from_cache(self, id: int) -> str | None:
129
177
  if id == 0:
@@ -311,8 +359,10 @@ class FunctionLookUpAPI(LookUpAPI):
311
359
 
312
360
 
313
361
  class AllLookUpAPI(LookUpAPI, ABC):
314
- def __init__(self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient") -> None:
315
- super().__init__(config, api_version, cognite_client)
362
+ def __init__(
363
+ self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
364
+ ) -> None:
365
+ super().__init__(config, api_version, cognite_client, console)
316
366
  self._has_looked_up = False
317
367
 
318
368
  @abstractmethod
@@ -322,13 +372,15 @@ class AllLookUpAPI(LookUpAPI, ABC):
322
372
  def _id(self, external_id: SequenceNotStr[str]) -> dict[str, int]:
323
373
  if not self._has_looked_up:
324
374
  self._lookup()
325
- return {external_id: self._cache[external_id] for external_id in external_id if external_id in self._cache}
375
+ found_pairs = ((ext_id, self._cache[ext_id]) for ext_id in external_id if ext_id in self._cache)
376
+ return {k: v for k, v in found_pairs if v is not None}
326
377
 
327
378
  def _external_id(self, id: Sequence[int]) -> dict[int, str]:
328
379
  if not self._has_looked_up:
329
380
  self._lookup()
330
381
  self._has_looked_up = True
331
- return {id: self._reverse_cache[id] for id in id}
382
+ found_pairs = ((id_, self._reverse_cache[id_]) for id_ in id if id_ in self._reverse_cache)
383
+ return {k: v for k, v in found_pairs if v is not None}
332
384
 
333
385
 
334
386
  class SecurityCategoriesLookUpAPI(AllLookUpAPI):
@@ -363,18 +415,21 @@ class LocationFiltersLookUpAPI(AllLookUpAPI):
363
415
  def _id(self, external_id: SequenceNotStr[str]) -> dict[str, int]:
364
416
  if not self._has_looked_up:
365
417
  self._lookup()
366
- return {external_id: self._cache[external_id] for external_id in external_id if external_id in self._cache}
418
+ found_pairs = ((ext_id, self._cache[ext_id]) for ext_id in external_id if ext_id in self._cache)
419
+ return {k: v for k, v in found_pairs if v is not None}
367
420
 
368
421
 
369
422
  class LookUpGroup(ToolkitAPI):
370
- def __init__(self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient") -> None:
423
+ def __init__(
424
+ self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
425
+ ) -> None:
371
426
  super().__init__(config, api_version, cognite_client)
372
- self.data_sets = DataSetLookUpAPI(config, api_version, cognite_client)
373
- self.assets = AssetLookUpAPI(config, api_version, cognite_client)
374
- self.time_series = TimeSeriesLookUpAPI(config, api_version, cognite_client)
375
- self.files = FileMetadataLookUpAPI(config, api_version, cognite_client)
376
- self.events = EventLookUpAPI(config, api_version, cognite_client)
377
- self.security_categories = SecurityCategoriesLookUpAPI(config, api_version, cognite_client)
378
- self.location_filters = LocationFiltersLookUpAPI(config, api_version, cognite_client)
379
- self.extraction_pipelines = ExtractionPipelineLookUpAPI(config, api_version, cognite_client)
380
- self.functions = FunctionLookUpAPI(config, api_version, cognite_client)
427
+ self.data_sets = DataSetLookUpAPI(config, api_version, cognite_client, console)
428
+ self.assets = AssetLookUpAPI(config, api_version, cognite_client, console)
429
+ self.time_series = TimeSeriesLookUpAPI(config, api_version, cognite_client, console)
430
+ self.files = FileMetadataLookUpAPI(config, api_version, cognite_client, console)
431
+ self.events = EventLookUpAPI(config, api_version, cognite_client, console)
432
+ self.security_categories = SecurityCategoriesLookUpAPI(config, api_version, cognite_client, console)
433
+ self.location_filters = LocationFiltersLookUpAPI(config, api_version, cognite_client, console)
434
+ self.extraction_pipelines = ExtractionPipelineLookUpAPI(config, api_version, cognite_client, console)
435
+ self.functions = FunctionLookUpAPI(config, api_version, cognite_client, console)
@@ -9,6 +9,7 @@ from cognite.client._api.functions import FunctionCallsAPI, FunctionSchedulesAPI
9
9
  from cognite.client._api.raw import RawDatabasesAPI, RawRowsAPI, RawTablesAPI
10
10
  from cognite.client._api.synthetic_time_series import SyntheticDatapointsAPI
11
11
  from cognite.client.testing import CogniteClientMock
12
+ from rich.console import Console
12
13
 
13
14
  from cognite_toolkit._cdf_tk.client._toolkit_client import ToolkitClient
14
15
 
@@ -58,6 +59,7 @@ class ToolkitClientMock(CogniteClientMock):
58
59
  super().__init__(*args, **kwargs)
59
60
  return None
60
61
  super().__init__(*args, **kwargs)
62
+ self.console = Console()
61
63
  # Developer note:
62
64
  # - Please add your mocked APIs in chronological order
63
65
  # - For nested APIs:
@@ -3,7 +3,6 @@ from functools import partial
3
3
  from pathlib import Path
4
4
 
5
5
  from cognite.client.data_classes._base import T_CogniteResource
6
- from rich.console import Console
7
6
 
8
7
  from cognite_toolkit._cdf_tk.constants import DATA_MANIFEST_STEM, DATA_RESOURCE_DIR
9
8
  from cognite_toolkit._cdf_tk.exceptions import ToolkitValueError
@@ -41,7 +40,7 @@ class DownloadCommand(ToolkitCommand):
41
40
  """
42
41
  compression_cls = Compression.from_name(compression)
43
42
 
44
- console = Console()
43
+ console = io.client.console
45
44
  for selector in selectors:
46
45
  target_dir = output_dir / selector.group
47
46
  if verbose:
@@ -22,7 +22,7 @@ from cognite.client.data_classes.events import EventProperty
22
22
  from cognite_toolkit._cdf_tk.client import ToolkitClient
23
23
  from cognite_toolkit._cdf_tk.client.data_classes.apm_config_v1 import APMConfig, APMConfigList
24
24
  from cognite_toolkit._cdf_tk.cruds import NodeCRUD, ResourceCRUD, SpaceCRUD
25
- from cognite_toolkit._cdf_tk.exceptions import ToolkitRequiredValueError
25
+ from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitRequiredValueError
26
26
  from cognite_toolkit._cdf_tk.utils import humanize_collection
27
27
 
28
28
  from .data_model import CREATED_SOURCE_SYSTEM_VIEW_ID, SPACE, SPACE_SOURCE_VIEW_ID
@@ -196,9 +196,10 @@ class SourceSystemCreator(MigrationCreator[NodeApplyList]):
196
196
  @cached_property
197
197
  def _advanced_filter(self) -> filters.Filter:
198
198
  if self.data_set_external_id is not None:
199
- return filters.Equals(
200
- SourceFileProperty.data_set_id, self.client.lookup.data_sets.id(self.data_set_external_id)
201
- )
199
+ data_set_id = self.client.lookup.data_sets.id(self.data_set_external_id)
200
+ if data_set_id is None:
201
+ raise ToolkitMissingResourceError(f"Data set with external ID '{self.data_set_external_id}' not found.")
202
+ return filters.Equals(SourceFileProperty.data_set_id, data_set_id)
202
203
  if self.hierarchy is not None:
203
204
  return filters.InAssetSubtree(SourceFileProperty.asset_external_ids, [self.hierarchy])
204
205
  else:
@@ -375,6 +375,8 @@ class PurgeCommand(ToolkitCommand):
375
375
  # Validate Auth
376
376
  validator = ValidateAccess(client, "purge")
377
377
  data_set_id = client.lookup.data_sets.id(selected_data_set_external_id)
378
+ if data_set_id is None:
379
+ raise ToolkitMissingResourceError(f"DataSet {selected_data_set_external_id!r} does not exist")
378
380
  action = cast(Sequence[Literal["read", "write"]], ["read"] if dry_run else ["read", "write"])
379
381
  if include_data:
380
382
  # Check asset, events, time series, files, and sequences access, relationships, labels, 3D access.
@@ -60,7 +60,7 @@ class _ReplaceMethod:
60
60
  """This is a small helper class used in the
61
61
  lookup and replace in the ACL scoped ids"""
62
62
 
63
- lookup_method: Callable[[str, bool], int]
63
+ lookup_method: Callable[[str, bool], int | None]
64
64
  reverse_lookup_method: Callable[[int], str | None]
65
65
  id_name: str
66
66
 
@@ -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,
@@ -125,7 +126,9 @@ class MetadataAggregator(AssetCentricAggregator, ABC, Generic[T_CogniteFilter]):
125
126
  self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
126
127
  ) -> list[tuple[str, int]]:
127
128
  """Returns a list of metadata keys and their counts."""
128
- hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(hierarchy, data_sets)
129
+ hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(
130
+ hierarchy, data_sets, operation="find metadata keys"
131
+ )
129
132
  return self._used_metadata_keys(hierarchy=hierarchy_ids, data_sets=data_set_ids)
130
133
 
131
134
  @lru_cache(maxsize=1)
@@ -140,22 +143,44 @@ class MetadataAggregator(AssetCentricAggregator, ABC, Generic[T_CogniteFilter]):
140
143
  )
141
144
 
142
145
  def _lookup_hierarchy_data_set_pair(
143
- self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
146
+ self, hierarchy: str | list[str] | None, data_sets: str | list[str] | None, operation: str
144
147
  ) -> tuple[tuple[int, ...] | None, tuple[int, ...] | None]:
145
148
  """Returns a tuple of hierarchy and data sets."""
146
149
  hierarchy_ids: tuple[int, ...] | None = None
147
150
  if isinstance(hierarchy, str):
148
151
  asset_id = self.client.lookup.assets.id(external_id=hierarchy, allow_empty=False)
152
+ if asset_id is None:
153
+ raise ToolkitMissingResourceError(f"Cannot {operation}. Asset with external ID {hierarchy!r} not found")
149
154
  hierarchy_ids = (asset_id,)
150
155
  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)))
156
+ asset_ids = self.client.lookup.assets.id(external_id=hierarchy, allow_empty=False)
157
+ if len(asset_ids) != len(hierarchy):
158
+ missing = set(hierarchy) - set(
159
+ self.client.lookup.assets.external_id([id_ for id_ in asset_ids if id_ is not None])
160
+ )
161
+ raise ToolkitMissingResourceError(
162
+ f"Cannot {operation}. Assets with external IDs {sorted(missing)!r} not found"
163
+ )
164
+ hierarchy_ids = tuple(sorted(asset_ids))
152
165
 
153
166
  data_set_ids: tuple[int, ...] | None = None
154
167
  if isinstance(data_sets, str):
155
168
  data_set_id = self.client.lookup.data_sets.id(external_id=data_sets, allow_empty=False)
169
+ if data_set_id is None:
170
+ raise ToolkitMissingResourceError(
171
+ f"Cannot {operation}. Data set with external ID {data_sets!r} not found"
172
+ )
156
173
  data_set_ids = (data_set_id,)
157
174
  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)))
175
+ data_set_ids_list = self.client.lookup.data_sets.id(external_id=data_sets, allow_empty=False)
176
+ if len(data_set_ids_list) != len(data_sets):
177
+ missing = set(data_sets) - set(
178
+ self.client.lookup.data_sets.external_id([id_ for id_ in data_set_ids_list if id_ is not None])
179
+ )
180
+ raise ToolkitMissingResourceError(
181
+ f"Cannot {operation}. Data sets with external IDs {sorted(missing)!r} not found"
182
+ )
183
+ data_set_ids = tuple(sorted(data_set_ids_list))
159
184
 
160
185
  return hierarchy_ids, data_set_ids
161
186
 
@@ -201,7 +226,9 @@ class LabelAggregator(MetadataAggregator, ABC, Generic[T_CogniteFilter]):
201
226
  self, hierarchy: str | list[str] | None = None, data_sets: str | list[str] | None = None
202
227
  ) -> list[tuple[str, int]]:
203
228
  """Returns a list of labels and their counts."""
204
- hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(hierarchy, data_sets)
229
+ hierarchy_ids, data_set_ids = self._lookup_hierarchy_data_set_pair(
230
+ hierarchy, data_sets, operation="find labels"
231
+ )
205
232
  return self._used_labels(hierarchy=hierarchy_ids, data_sets=data_set_ids)
206
233
 
207
234
  @lru_cache(maxsize=1)
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.6.83
15
+ image: cognite/toolkit:0.6.84
16
16
  env:
17
17
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
18
18
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -10,7 +10,7 @@ jobs:
10
10
  environment: dev
11
11
  name: Deploy Dry Run
12
12
  container:
13
- image: cognite/toolkit:0.6.83
13
+ image: cognite/toolkit:0.6.84
14
14
  env:
15
15
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
16
16
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -4,7 +4,7 @@ default_env = "<DEFAULT_ENV_PLACEHOLDER>"
4
4
  [modules]
5
5
  # This is the version of the modules. It should not be changed manually.
6
6
  # It will be updated by the 'cdf modules upgrade' command.
7
- version = "0.6.83"
7
+ version = "0.6.84"
8
8
 
9
9
  [alpha_flags]
10
10
  external-libraries = true
@@ -1 +1 @@
1
- __version__ = "0.6.83"
1
+ __version__ = "0.6.84"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.6.83
3
+ Version: 0.6.84
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Project-URL: Homepage, https://docs.cognite.com/cdf/deploy/cdf_toolkit/
6
6
  Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
@@ -1,6 +1,6 @@
1
1
  cognite_toolkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cognite_toolkit/_cdf.py,sha256=1OSAvbOeuIrnsczEG2BtGqRP3L3sq0VMPthmugnqCUw,5821
3
- cognite_toolkit/_version.py,sha256=NoDb44OMue8eXw7UG1FCeT7NcrsMhObnFzSRH_iUix8,23
3
+ cognite_toolkit/_version.py,sha256=VnWi3C5S4335obqqoSD8NeZPSw1Kg8vPGHxnwrQk6dU,23
4
4
  cognite_toolkit/_cdf_tk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  cognite_toolkit/_cdf_tk/cdf_toml.py,sha256=DAUmHf19ByVIGH4MDPdXKHZ0G97CxdD5J-EzHTq66C8,8025
6
6
  cognite_toolkit/_cdf_tk/constants.py,sha256=e9XmGvQCqGq7zYQrNoopU5e2KnYZYBPyUC5raGShK7k,6364
@@ -35,10 +35,10 @@ cognite_toolkit/_cdf_tk/builders/_streamlit.py,sha256=8Pu_zgyKZjbAsPWywjzB2KWD7h
35
35
  cognite_toolkit/_cdf_tk/builders/_transformation.py,sha256=STB42zhzOW5M_-b8cKOQ_cegnr7FtMoMxZ87gPLXft4,4723
36
36
  cognite_toolkit/_cdf_tk/client/__init__.py,sha256=a6rQXDGfW2g7K5WwrOW5oakh1TdFlBjUVjf9wusOox8,135
37
37
  cognite_toolkit/_cdf_tk/client/_constants.py,sha256=COUGcea37mDF2sf6MGqJXWmecTY_6aCImslxXrYW1I0,73
38
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py,sha256=TNQNYKfVSTeBbaGJOKnD5fc_U5QiWdb574QrAvkZd5g,2542
38
+ cognite_toolkit/_cdf_tk/client/_toolkit_client.py,sha256=lwVpUOTfkN2dx-0rKYIVi7BNPF17lMpf-LEaEdnS4ZM,2622
39
39
  cognite_toolkit/_cdf_tk/client/api_client.py,sha256=CQdD_gfDqQkz5OYHrTnKvBvEvzHPdHDB1BkZPWRoahg,440
40
40
  cognite_toolkit/_cdf_tk/client/config.py,sha256=weMR43z-gqHMn-Jqvfmh_nJ0HbgEdyeCGtISuEf3OuY,4269
41
- cognite_toolkit/_cdf_tk/client/testing.py,sha256=77QQd6vroe7LUOY9T1s6qW261XUjkrilL9AYM8pG_YY,5989
41
+ cognite_toolkit/_cdf_tk/client/testing.py,sha256=lpcxC2l6Dj8foZr4IboqbIzVxR85NI6G_5saH2DHSfg,6055
42
42
  cognite_toolkit/_cdf_tk/client/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  cognite_toolkit/_cdf_tk/client/api/canvas.py,sha256=i2NwyhvmklTPx3e-yd4lvSxyn6JEjSpv8WXa1SxtmV8,8789
44
44
  cognite_toolkit/_cdf_tk/client/api/charts.py,sha256=t-VOrRGwpjmYUtUqGObQWYwGb5gOHVp4cHZBm8ZVGn0,4953
@@ -50,7 +50,7 @@ cognite_toolkit/_cdf_tk/client/api/extended_raw.py,sha256=9DVbM2aWmIyzbaW-lh10_p
50
50
  cognite_toolkit/_cdf_tk/client/api/extended_timeseries.py,sha256=xK7XhTfe4W9FvaueUIfR7Q64JOIDwq_svHRjORM76Q4,17774
51
51
  cognite_toolkit/_cdf_tk/client/api/fixed_transformations.py,sha256=m66cqbx4oCtjv5TBQOWLNFrz475qVTCXBu_pTxbdCD4,5589
52
52
  cognite_toolkit/_cdf_tk/client/api/location_filters.py,sha256=TIbomUbpUNDxOON_a3pwBmCBdltxL1jMQBXKcIjRx44,3759
53
- cognite_toolkit/_cdf_tk/client/api/lookup.py,sha256=QDMGuNmbvd7NUjUlfjp_v2KWoXcx0lw75WZXxgVC9iA,14974
53
+ cognite_toolkit/_cdf_tk/client/api/lookup.py,sha256=c-cvtgfGGGYyk8ROcJu44qlo1ocqbk0o1zafCql79fU,17652
54
54
  cognite_toolkit/_cdf_tk/client/api/migration.py,sha256=eIKcUAXHblL0vL9UzyZgifnL4bW2N4TUt613hTTFf1w,15156
55
55
  cognite_toolkit/_cdf_tk/client/api/project.py,sha256=Hj0uDCLyPofG-T4626EdeoRRtBaovhU-SMAQ7VWJ1M4,1063
56
56
  cognite_toolkit/_cdf_tk/client/api/search.py,sha256=L4cDPip7pJVP7bEgAiSOjqINIHg8AULNBtR29G5khEQ,612
@@ -95,9 +95,9 @@ cognite_toolkit/_cdf_tk/commands/__init__.py,sha256=OJYtHiERtUBXm3cjUTyPVaYIMVQp
95
95
  cognite_toolkit/_cdf_tk/commands/_base.py,sha256=m2hnXo_AAHhsoSayHZO_zUa4xEt5w5oMB4WCHmJr-AY,2595
96
96
  cognite_toolkit/_cdf_tk/commands/_changes.py,sha256=DIwuiRpDhWBDpsW3R3yqj0eWLAE3c_kPbmCaUkxjFuo,24852
97
97
  cognite_toolkit/_cdf_tk/commands/_cli_commands.py,sha256=TK6U_rm6VZT_V941kTyHMoulWgJzbDC8YIIQDPJ5x3w,1011
98
- cognite_toolkit/_cdf_tk/commands/_download.py,sha256=S5WuOAgbZTgU5kXyjqgTzm7e0hN9FI6IYOeQ9U-44Ow,6718
98
+ cognite_toolkit/_cdf_tk/commands/_download.py,sha256=qkbzHzd6FZydNiG83vwciBJEmQAG0t9EFfvZb0K89TA,6693
99
99
  cognite_toolkit/_cdf_tk/commands/_profile.py,sha256=_4iX3AHAI6eLmRVUlWXCSvVHx1BZW2yDr_i2i9ECg6U,43120
100
- cognite_toolkit/_cdf_tk/commands/_purge.py,sha256=aZ9c7iVrKlvgX62ZbYRKlRqx5eThNu6lheaUIFQ_FOo,41281
100
+ cognite_toolkit/_cdf_tk/commands/_purge.py,sha256=7meU96Xni0TezAZz14wB310bcf6Ps6KRHFOJOvnIlsQ,41420
101
101
  cognite_toolkit/_cdf_tk/commands/_upload.py,sha256=kXYmP1YMg-JvsuN1iYaMuZH1qZfapya2j-RABGhqGHo,11860
102
102
  cognite_toolkit/_cdf_tk/commands/_utils.py,sha256=ARlbqA_5ZWlgN3-xF-zanzSx4B0-9ULnguA5QgHmKGA,1225
103
103
  cognite_toolkit/_cdf_tk/commands/_virtual_env.py,sha256=GFAid4hplixmj9_HkcXqU5yCLj-fTXm4cloGD6U2swY,2180
@@ -119,7 +119,7 @@ cognite_toolkit/_cdf_tk/commands/_migrate/base.py,sha256=aS32Wa-gd7vFNOdCTKEIpSS
119
119
  cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py,sha256=Tv4OG9V6tDsQbSH13YW8M0n8Ury5gU16oJB-OISVR0w,6398
120
120
  cognite_toolkit/_cdf_tk/commands/_migrate/command.py,sha256=RtC5CMQC1Wy5RmOwlCM67Mc8fZEExXubJLvzDzk2IMA,14097
121
121
  cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py,sha256=Eol-0ruQ14fwS-bx2pEmbXdICodfknSJ_OsAASa6jkY,9592
122
- cognite_toolkit/_cdf_tk/commands/_migrate/creators.py,sha256=GMKwpJWH-yQmS9QUFcjKklI_9Ynxwp58R-vZlzJOBuI,9411
122
+ cognite_toolkit/_cdf_tk/commands/_migrate/creators.py,sha256=FTu7w3G8KyPY8pagG3KdPpOmpLcjehaAg2auEy6iM7A,9605
123
123
  cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py,sha256=eF3Fv-tm_A8iaRUAOVOdg1DKPN7OYVPwrLQMvawsO14,8572
124
124
  cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py,sha256=L9HJGmcTiAkC8Sftrngp8FyHBtAbkZtb9HrpLFg-ED0,6006
125
125
  cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py,sha256=i1eUsNX6Dueol9STIEwyksBnBsWUk13O8qHIjW964pM,7860
@@ -134,7 +134,7 @@ cognite_toolkit/_cdf_tk/cruds/_data_cruds.py,sha256=3FYKow5uOBWt2-6kzszRJE8YgqxJ
134
134
  cognite_toolkit/_cdf_tk/cruds/_worker.py,sha256=-jbl4JV18Ow3y8BcecYPx8XxDIP897A80yD7frwuilc,9369
135
135
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py,sha256=IE6WxGh9AthWxwHnDmj8EJDd7q6W2OGf1vMnr_lrKAY,2769
136
136
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py,sha256=2pcpwAJQ4GPvW2jM0J-Odm7d1sTlaaoBLKEXPHHz2VQ,5091
137
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py,sha256=s-oDIYu27zhsMRLKKIHJj862fQOMHwVVKoxh1I8jfIE,24964
137
+ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py,sha256=iGG2_btpEqip3o6OKpcKfrh5IljOH9NbrJcGBKX0bn4,24971
138
138
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py,sha256=JIY5qC2mg3kV5zIMZRvUuTi3z7NM7gGbd3eiTN8nI8o,25716
139
139
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py,sha256=KrL7bj8q5q18mGB2V-NDkW5U5nfseZOyorXiUbp2uLw,6100
140
140
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py,sha256=iXn9iAtwA8mhH-7j9GF-MlLomTcaw3GhEbFY28Wx0iA,9927
@@ -142,7 +142,7 @@ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py,sha256=KED-wNXTZbkrK4
142
142
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py,sha256=G27TZF1aTN3aruJ1HTfpvhI4fZyHkn-uD6NJpKgkSow,18605
143
143
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py,sha256=Gtcu-i-nejPCN0Uxn8O5_QakdX2wgDcVCJn1X7AMu-I,11638
144
144
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py,sha256=F3n2FOWAPder4z3OTYs81VB-6C6r3oUzJsHvigdhaD0,15500
145
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py,sha256=JSxkDw9yqdv_jGS_tS_BuqkpSvBSFTkirxp6CMX6TRc,28777
145
+ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py,sha256=3qWJPy5syAAILaQRnsn_EfLyL23w3E6WLLdrrvUj7KI,29158
146
146
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/group_scoped.py,sha256=WEg8-CxMP64WfE_XXIlH114zM51K0uLaYa4atd992zI,1690
147
147
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py,sha256=7y2ffuLjUAafGIXfZqqRkXopQKemmFr_IPi_lD4k-fo,15434
148
148
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py,sha256=x_hHlFZ1AURmixRKltWQ680JgrEr6CswMFyaG3N-fnk,8011
@@ -227,7 +227,7 @@ cognite_toolkit/_cdf_tk/resource_classes/robotics/location.py,sha256=dbc9HT-bc2Q
227
227
  cognite_toolkit/_cdf_tk/resource_classes/robotics/map.py,sha256=j77z7CzCMiMj8r94BdUKCum9EuZRUjaSlUAy9K9DL_Q,942
228
228
  cognite_toolkit/_cdf_tk/storageio/__init__.py,sha256=aM-skaPnKTH1B7HG0faeTUNf7u1b-sT8l7hh5JRZ1E8,2288
229
229
  cognite_toolkit/_cdf_tk/storageio/_applications.py,sha256=bhyG1d2_9duPkX-otC2brVcpChvdXSPkYhBHS5T_72g,4343
230
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py,sha256=0Q8htH7VM2mw0xx64R6lYrOLuLW8OJ4awO1kQgblh9E,23390
230
+ cognite_toolkit/_cdf_tk/storageio/_asset_centric.py,sha256=spFAdoHxGKDDEWItM4RovSddudwoPIa_uev8WCAQ9zs,27027
231
231
  cognite_toolkit/_cdf_tk/storageio/_base.py,sha256=yqAaBlZcE53V_HKcKi_q-OjpC2Nnhkw13cbSvXjx2wY,8682
232
232
  cognite_toolkit/_cdf_tk/storageio/_data_classes.py,sha256=s3TH04BJ1q7rXndRhEbVMEnoOXjxrGg4n-w9Z5uUL-o,3480
233
233
  cognite_toolkit/_cdf_tk/storageio/_instances.py,sha256=_tKOdlo7tMJoh7y-47o7sySfDMRa-G-AFVprmzjn3EQ,9311
@@ -245,7 +245,7 @@ cognite_toolkit/_cdf_tk/tk_warnings/fileread.py,sha256=d2Kx6YyLmCkyFNjK8MO6eKGce
245
245
  cognite_toolkit/_cdf_tk/tk_warnings/other.py,sha256=4T-WRqMG-KKFS0AV3w6ilea22G_MTXFcOKpbd2z6MNE,5624
246
246
  cognite_toolkit/_cdf_tk/utils/__init__.py,sha256=-X01eYNwz3l0W2jby0DZzlDIe9HEhUUj-dK8DBhYki8,1413
247
247
  cognite_toolkit/_cdf_tk/utils/_auxiliary.py,sha256=tvvgFiWwLOCVDkPg83U5XqBLfOOt_gI3697EQr7-GSE,1198
248
- cognite_toolkit/_cdf_tk/utils/aggregators.py,sha256=WU0E3YpDm2e2p7OTrIZ2eY8e9-CFaGpcL7HbAbzqj-8,15947
248
+ cognite_toolkit/_cdf_tk/utils/aggregators.py,sha256=8rgNNgrH1VhynFBzIe-bkwz1TU3DZSDJqwb6agxXzzs,17357
249
249
  cognite_toolkit/_cdf_tk/utils/auth.py,sha256=O_VuLXS8xYdjBeTATIHWht7KtemmhZIfxUrzgqCdrMQ,23106
250
250
  cognite_toolkit/_cdf_tk/utils/auxiliary.py,sha256=BLhWEBz8ErY4CVwJOaN6H9pUrkMJBT-ylYNuvDORMXQ,814
251
251
  cognite_toolkit/_cdf_tk/utils/cdf.py,sha256=hxLBhen-ad60FsGk26b1fp-dMper6Ue-qmD643A79i4,18282
@@ -284,13 +284,13 @@ cognite_toolkit/_repo_files/.gitignore,sha256=ip9kf9tcC5OguF4YF4JFEApnKYw0nG0vPi
284
284
  cognite_toolkit/_repo_files/AzureDevOps/.devops/README.md,sha256=OLA0D7yCX2tACpzvkA0IfkgQ4_swSd-OlJ1tYcTBpsA,240
285
285
  cognite_toolkit/_repo_files/AzureDevOps/.devops/deploy-pipeline.yml,sha256=brULcs8joAeBC_w_aoWjDDUHs3JheLMIR9ajPUK96nc,693
286
286
  cognite_toolkit/_repo_files/AzureDevOps/.devops/dry-run-pipeline.yml,sha256=OBFDhFWK1mlT4Dc6mDUE2Es834l8sAlYG50-5RxRtHk,723
287
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=OZbAHAwQZdUoUp4l5yVtSjif-TDdKdqrRpaYs6Cno3o,667
288
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=tDMSTeVoP8gVemK0DQpmYzWC7D-jSgY3o4BVZNC-NII,2430
289
- cognite_toolkit/_resources/cdf.toml,sha256=lp87nN7ZxGnPiocONpDzYsAeeOz3K-nec3Dd5ZR1u9Q,487
287
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=CEJyS9A4yJ3QyTKT0-bQn_gAej6TFxSyKAeh7U-x_GE,667
288
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=JETNf3gik_QNu5EC5UfGt7YSxUIpqG_g-xqb8QqReak,2430
289
+ cognite_toolkit/_resources/cdf.toml,sha256=iMFIlLuzS4GaaMM0lBi7Ve-Pt8Ce4kbYKqqvVb5GtEg,487
290
290
  cognite_toolkit/demo/__init__.py,sha256=-m1JoUiwRhNCL18eJ6t7fZOL7RPfowhCuqhYFtLgrss,72
291
291
  cognite_toolkit/demo/_base.py,sha256=6xKBUQpXZXGQ3fJ5f7nj7oT0s2n7OTAGIa17ZlKHZ5U,8052
292
- cognite_toolkit-0.6.83.dist-info/METADATA,sha256=hw2mPua88MAh5KVj90XnAU9e-QA0OnU9PGrmzZKmTSY,4501
293
- cognite_toolkit-0.6.83.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
294
- cognite_toolkit-0.6.83.dist-info/entry_points.txt,sha256=JlR7MH1_UMogC3QOyN4-1l36VbrCX9xUdQoHGkuJ6-4,83
295
- cognite_toolkit-0.6.83.dist-info/licenses/LICENSE,sha256=CW0DRcx5tL-pCxLEN7ts2S9g2sLRAsWgHVEX4SN9_Mc,752
296
- cognite_toolkit-0.6.83.dist-info/RECORD,,
292
+ cognite_toolkit-0.6.84.dist-info/METADATA,sha256=dnNPS0fE8GblOccgwHL6srQ8B7DmdquASwQSbZxsoK4,4501
293
+ cognite_toolkit-0.6.84.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
294
+ cognite_toolkit-0.6.84.dist-info/entry_points.txt,sha256=JlR7MH1_UMogC3QOyN4-1l36VbrCX9xUdQoHGkuJ6-4,83
295
+ cognite_toolkit-0.6.84.dist-info/licenses/LICENSE,sha256=CW0DRcx5tL-pCxLEN7ts2S9g2sLRAsWgHVEX4SN9_Mc,752
296
+ cognite_toolkit-0.6.84.dist-info/RECORD,,