cognite-toolkit 0.7.70__py3-none-any.whl → 0.7.72__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.
Files changed (35) hide show
  1. cognite_toolkit/_cdf_tk/client/_resource_base.py +0 -22
  2. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +0 -2
  3. cognite_toolkit/_cdf_tk/client/api/infield.py +56 -204
  4. cognite_toolkit/_cdf_tk/client/api/instances.py +239 -16
  5. cognite_toolkit/_cdf_tk/client/api/robotics_capabilities.py +9 -3
  6. cognite_toolkit/_cdf_tk/client/api/robotics_data_postprocessing.py +12 -3
  7. cognite_toolkit/_cdf_tk/client/api/robotics_frames.py +10 -3
  8. cognite_toolkit/_cdf_tk/client/api/robotics_locations.py +10 -3
  9. cognite_toolkit/_cdf_tk/client/api/robotics_maps.py +10 -3
  10. cognite_toolkit/_cdf_tk/client/api/robotics_robots.py +10 -3
  11. cognite_toolkit/_cdf_tk/client/cdf_client/responses.py +3 -3
  12. cognite_toolkit/_cdf_tk/client/http_client/_client.py +1 -1
  13. cognite_toolkit/_cdf_tk/client/resource_classes/infield.py +133 -72
  14. cognite_toolkit/_cdf_tk/client/resource_classes/instance_api.py +119 -79
  15. cognite_toolkit/_cdf_tk/client/testing.py +14 -16
  16. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +45 -46
  17. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +154 -160
  18. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  19. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  20. cognite_toolkit/_resources/cdf.toml +1 -1
  21. cognite_toolkit/_version.py +1 -1
  22. {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.72.dist-info}/METADATA +1 -1
  23. {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.72.dist-info}/RECORD +25 -35
  24. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +0 -8
  25. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/api.py +0 -20
  26. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/capabilities.py +0 -142
  27. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/data_postprocessing.py +0 -144
  28. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/frames.py +0 -136
  29. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/locations.py +0 -136
  30. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/maps.py +0 -136
  31. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/robots.py +0 -132
  32. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/utlis.py +0 -13
  33. cognite_toolkit/_cdf_tk/client/resource_classes/legacy/robotics.py +0 -970
  34. {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.72.dist-info}/WHEEL +0 -0
  35. {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.72.dist-info}/entry_points.txt +0 -0
@@ -1,30 +1,23 @@
1
1
  import json
2
- from collections.abc import Callable, Hashable, Iterable, Sequence
3
- from contextlib import suppress
2
+ from collections.abc import Hashable, Iterable, Sequence
4
3
  from typing import Any
5
4
 
6
5
  from cognite.client.data_classes import capabilities
7
- from cognite.client.data_classes._base import T_CogniteResourceList
8
6
  from cognite.client.data_classes.capabilities import Capability
9
- from cognite.client.exceptions import CogniteAPIError
10
7
  from cognite.client.utils.useful_types import SequenceNotStr
11
8
 
12
- from cognite_toolkit._cdf_tk.client.resource_classes.legacy.robotics import (
13
- DataPostProcessing,
14
- DataPostProcessingList,
15
- DataPostProcessingWrite,
16
- Frame,
17
- FrameList,
18
- FrameWrite,
19
- Location,
20
- LocationList,
21
- LocationWrite,
22
- Map,
23
- MapList,
24
- MapWrite,
25
- RobotCapability,
26
- RobotCapabilityList,
27
- RobotCapabilityWrite,
9
+ from cognite_toolkit._cdf_tk.client.resource_classes.identifiers import ExternalId
10
+ from cognite_toolkit._cdf_tk.client.resource_classes.robotics import (
11
+ RobotCapabilityRequest,
12
+ RobotCapabilityResponse,
13
+ RobotDataPostProcessingRequest,
14
+ RobotDataPostProcessingResponse,
15
+ RobotFrameRequest,
16
+ RobotFrameResponse,
17
+ RobotLocationRequest,
18
+ RobotLocationResponse,
19
+ RobotMapRequest,
20
+ RobotMapResponse,
28
21
  )
29
22
  from cognite_toolkit._cdf_tk.cruds._base_cruds import ResourceCRUD
30
23
  from cognite_toolkit._cdf_tk.resource_classes import (
@@ -37,10 +30,10 @@ from cognite_toolkit._cdf_tk.resource_classes import (
37
30
  from cognite_toolkit._cdf_tk.utils.diff_list import diff_list_hashable
38
31
 
39
32
 
40
- class RoboticFrameCRUD(ResourceCRUD[str, FrameWrite, Frame]):
33
+ class RoboticFrameCRUD(ResourceCRUD[ExternalId, RobotFrameRequest, RobotFrameResponse]):
41
34
  folder_name = "robotics"
42
- resource_cls = Frame
43
- resource_write_cls = FrameWrite
35
+ resource_cls = RobotFrameResponse
36
+ resource_write_cls = RobotFrameRequest
44
37
  kind = "Frame"
45
38
  yaml_cls = RobotFrameYAML
46
39
  _doc_url = "Frames/operation/createFrames"
@@ -50,20 +43,18 @@ class RoboticFrameCRUD(ResourceCRUD[str, FrameWrite, Frame]):
50
43
  return "robotics frames"
51
44
 
52
45
  @classmethod
53
- def get_id(cls, item: Frame | FrameWrite | dict) -> str:
46
+ def get_id(cls, item: RobotFrameRequest | RobotFrameResponse | dict) -> ExternalId:
54
47
  if isinstance(item, dict):
55
- return item["externalId"]
56
- if not item.external_id:
57
- raise KeyError("Frame must have external_id")
58
- return item.external_id
48
+ return ExternalId(external_id=item["externalId"])
49
+ return item.as_id()
59
50
 
60
51
  @classmethod
61
- def dump_id(cls, id: str) -> dict[str, Any]:
62
- return {"externalId": id}
52
+ def dump_id(cls, id: ExternalId) -> dict[str, Any]:
53
+ return id.dump()
63
54
 
64
55
  @classmethod
65
56
  def get_required_capability(
66
- cls, items: Sequence[FrameWrite] | None, read_only: bool
57
+ cls, items: Sequence[RobotFrameRequest] | None, read_only: bool
67
58
  ) -> Capability | list[Capability]:
68
59
  if not items and items is not None:
69
60
  return []
@@ -77,20 +68,27 @@ class RoboticFrameCRUD(ResourceCRUD[str, FrameWrite, Frame]):
77
68
  capabilities.RoboticsAcl.Scope.All(),
78
69
  )
79
70
 
80
- def create(self, items: Sequence[FrameWrite]) -> FrameList:
81
- return self.client.robotics.frames.create(items)
71
+ def dump_resource(self, resource: RobotFrameResponse, local: dict[str, Any] | None = None) -> dict[str, Any]:
72
+ dumped = resource.as_request_resource().dump()
73
+ local = local or {}
74
+ if dumped.get("transform") is None and "transform" not in (local or {}):
75
+ # Default value set on the server side.
76
+ dumped.pop("transform", None)
77
+ return dumped
78
+
79
+ def create(self, items: Sequence[RobotFrameRequest]) -> list[RobotFrameResponse]:
80
+ return self.client.tool.robotics.frames.create(items)
82
81
 
83
- def retrieve(self, ids: SequenceNotStr[str]) -> FrameList:
84
- return _fallback_to_one_by_one(self.client.robotics.frames.retrieve, ids, FrameList)
82
+ def retrieve(self, ids: SequenceNotStr[ExternalId]) -> list[RobotFrameResponse]:
83
+ return self.client.tool.robotics.frames.retrieve(list(ids), ignore_unknown_ids=True)
85
84
 
86
- def update(self, items: Sequence[FrameWrite]) -> FrameList:
87
- return self.client.robotics.frames.update(items)
85
+ def update(self, items: Sequence[RobotFrameRequest]) -> list[RobotFrameResponse]:
86
+ return self.client.tool.robotics.frames.update(items, mode="replace")
88
87
 
89
- def delete(self, ids: SequenceNotStr[str]) -> int:
90
- try:
91
- self.client.robotics.frames.delete(ids)
92
- except CogniteAPIError as e:
93
- return len(e.successful)
88
+ def delete(self, ids: SequenceNotStr[ExternalId]) -> int:
89
+ if not ids:
90
+ return 0
91
+ self.client.tool.robotics.frames.delete(list(ids), ignore_unknown_ids=True)
94
92
  return len(ids)
95
93
 
96
94
  def _iterate(
@@ -98,14 +96,15 @@ class RoboticFrameCRUD(ResourceCRUD[str, FrameWrite, Frame]):
98
96
  data_set_external_id: str | None = None,
99
97
  space: str | None = None,
100
98
  parent_ids: list[Hashable] | None = None,
101
- ) -> Iterable[Frame]:
102
- return iter(self.client.robotics.frames)
99
+ ) -> Iterable[RobotFrameResponse]:
100
+ for frames in self.client.tool.robotics.frames.iterate(limit=None):
101
+ yield from frames
103
102
 
104
103
 
105
- class RoboticLocationCRUD(ResourceCRUD[str, LocationWrite, Location]):
104
+ class RoboticLocationCRUD(ResourceCRUD[ExternalId, RobotLocationRequest, RobotLocationResponse]):
106
105
  folder_name = "robotics"
107
- resource_cls = Location
108
- resource_write_cls = LocationWrite
106
+ resource_cls = RobotLocationResponse
107
+ resource_write_cls = RobotLocationRequest
109
108
  kind = "Location"
110
109
  yaml_cls = RobotLocationYAML
111
110
  _doc_url = "Locations/operation/createLocations"
@@ -115,20 +114,18 @@ class RoboticLocationCRUD(ResourceCRUD[str, LocationWrite, Location]):
115
114
  return "robotics locations"
116
115
 
117
116
  @classmethod
118
- def get_id(cls, item: Location | LocationWrite | dict) -> str:
117
+ def get_id(cls, item: RobotLocationRequest | RobotLocationResponse | dict) -> ExternalId:
119
118
  if isinstance(item, dict):
120
- return item["externalId"]
121
- if not item.external_id:
122
- raise KeyError("Location must have external_id")
123
- return item.external_id
119
+ return ExternalId(external_id=item["externalId"])
120
+ return item.as_id()
124
121
 
125
122
  @classmethod
126
- def dump_id(cls, id: str) -> dict[str, Any]:
127
- return {"externalId": id}
123
+ def dump_id(cls, id: ExternalId) -> dict[str, Any]:
124
+ return id.dump()
128
125
 
129
126
  @classmethod
130
127
  def get_required_capability(
131
- cls, items: Sequence[LocationWrite] | None, read_only: bool
128
+ cls, items: Sequence[RobotLocationRequest] | None, read_only: bool
132
129
  ) -> Capability | list[Capability]:
133
130
  if not items and items is not None:
134
131
  return []
@@ -147,20 +144,19 @@ class RoboticLocationCRUD(ResourceCRUD[str, LocationWrite, Location]):
147
144
 
148
145
  return capabilities.RoboticsAcl(actions, capabilities.RoboticsAcl.Scope.All())
149
146
 
150
- def create(self, items: Sequence[LocationWrite]) -> LocationList:
151
- return self.client.robotics.locations.create(items)
147
+ def create(self, items: Sequence[RobotLocationRequest]) -> list[RobotLocationResponse]:
148
+ return self.client.tool.robotics.locations.create(items)
152
149
 
153
- def retrieve(self, ids: SequenceNotStr[str]) -> LocationList:
154
- return _fallback_to_one_by_one(self.client.robotics.locations.retrieve, ids, LocationList)
150
+ def retrieve(self, ids: SequenceNotStr[ExternalId]) -> list[RobotLocationResponse]:
151
+ return self.client.tool.robotics.locations.retrieve(list(ids), ignore_unknown_ids=True)
155
152
 
156
- def update(self, items: Sequence[LocationWrite]) -> LocationList:
157
- return self.client.robotics.locations.update(items)
153
+ def update(self, items: Sequence[RobotLocationRequest]) -> list[RobotLocationResponse]:
154
+ return self.client.tool.robotics.locations.update(items, mode="replace")
158
155
 
159
- def delete(self, ids: SequenceNotStr[str]) -> int:
160
- try:
161
- self.client.robotics.locations.delete(ids)
162
- except CogniteAPIError as e:
163
- return len(e.successful)
156
+ def delete(self, ids: SequenceNotStr[ExternalId]) -> int:
157
+ if not ids:
158
+ return 0
159
+ self.client.tool.robotics.locations.delete(list(ids), ignore_unknown_ids=True)
164
160
  return len(ids)
165
161
 
166
162
  def _iterate(
@@ -168,14 +164,23 @@ class RoboticLocationCRUD(ResourceCRUD[str, LocationWrite, Location]):
168
164
  data_set_external_id: str | None = None,
169
165
  space: str | None = None,
170
166
  parent_ids: list[Hashable] | None = None,
171
- ) -> Iterable[Location]:
172
- return iter(self.client.robotics.locations)
167
+ ) -> Iterable[RobotLocationResponse]:
168
+ for locations in self.client.tool.robotics.locations.iterate(limit=None):
169
+ yield from locations
173
170
 
171
+ def dump_resource(self, resource: RobotLocationResponse, local: dict[str, Any] | None = None) -> dict[str, Any]:
172
+ return resource.as_request_resource().dump()
174
173
 
175
- class RoboticsDataPostProcessingCRUD(ResourceCRUD[str, DataPostProcessingWrite, DataPostProcessing]):
174
+ def load_resource(self, resource: dict[str, Any], is_dry_run: bool = False) -> RobotLocationRequest:
175
+ return RobotLocationRequest.model_validate(resource)
176
+
177
+
178
+ class RoboticsDataPostProcessingCRUD(
179
+ ResourceCRUD[ExternalId, RobotDataPostProcessingRequest, RobotDataPostProcessingResponse]
180
+ ):
176
181
  folder_name = "robotics"
177
- resource_cls = DataPostProcessing
178
- resource_write_cls = DataPostProcessingWrite
182
+ resource_cls = RobotDataPostProcessingResponse
183
+ resource_write_cls = RobotDataPostProcessingRequest
179
184
  kind = "DataPostProcessing"
180
185
  yaml_cls = RobotDataPostProcessingYAML
181
186
  _doc_url = "DataPostProcessing/operation/createDataPostProcessing"
@@ -185,20 +190,18 @@ class RoboticsDataPostProcessingCRUD(ResourceCRUD[str, DataPostProcessingWrite,
185
190
  return "robotics data postprocessing"
186
191
 
187
192
  @classmethod
188
- def get_id(cls, item: DataPostProcessing | DataPostProcessingWrite | dict) -> str:
193
+ def get_id(cls, item: RobotDataPostProcessingRequest | RobotDataPostProcessingResponse | dict) -> ExternalId:
189
194
  if isinstance(item, dict):
190
- return item["externalId"]
191
- if not item.external_id:
192
- raise KeyError("DataPostProcessing must have external_id")
193
- return item.external_id
195
+ return ExternalId(external_id=item["externalId"])
196
+ return item.as_id()
194
197
 
195
198
  @classmethod
196
- def dump_id(cls, id: str) -> dict[str, Any]:
197
- return {"externalId": id}
199
+ def dump_id(cls, id: ExternalId) -> dict[str, Any]:
200
+ return id.dump()
198
201
 
199
202
  @classmethod
200
203
  def get_required_capability(
201
- cls, items: Sequence[DataPostProcessingWrite] | None, read_only: bool
204
+ cls, items: Sequence[RobotDataPostProcessingRequest] | None, read_only: bool
202
205
  ) -> Capability | list[Capability]:
203
206
  if not items and items is not None:
204
207
  return []
@@ -217,32 +220,31 @@ class RoboticsDataPostProcessingCRUD(ResourceCRUD[str, DataPostProcessingWrite,
217
220
 
218
221
  return capabilities.RoboticsAcl(actions, capabilities.RoboticsAcl.Scope.All())
219
222
 
220
- def create(self, items: Sequence[DataPostProcessingWrite]) -> DataPostProcessingList:
221
- return self.client.robotics.data_postprocessing.create(items)
223
+ def create(self, items: Sequence[RobotDataPostProcessingRequest]) -> list[RobotDataPostProcessingResponse]:
224
+ return self.client.tool.robotics.data_postprocessing.create(items)
222
225
 
223
- def retrieve(self, ids: SequenceNotStr[str]) -> DataPostProcessingList:
224
- return _fallback_to_one_by_one(self.client.robotics.data_postprocessing.retrieve, ids, DataPostProcessingList)
226
+ def retrieve(self, ids: SequenceNotStr[ExternalId]) -> list[RobotDataPostProcessingResponse]:
227
+ return self.client.tool.robotics.data_postprocessing.retrieve(list(ids), ignore_unknown_ids=True)
225
228
 
226
- def update(self, items: Sequence[DataPostProcessingWrite]) -> DataPostProcessingList:
229
+ def update(self, items: Sequence[RobotDataPostProcessingRequest]) -> list[RobotDataPostProcessingResponse]:
227
230
  # There is a bug in the /update endpoint that requires the input_schema to be a string
228
231
  # and not an object. This is a workaround until the bug is fixed.
229
232
  # We do the serialization to avoid modifying the original object.
230
233
  to_update = []
231
234
  for item in items:
232
235
  if isinstance(item.input_schema, dict):
233
- update = DataPostProcessingWrite.load(item.dump())
236
+ update = RobotDataPostProcessingRequest.model_validate(item.dump())
234
237
  update.input_schema = json.dumps(item.input_schema) # type: ignore[assignment]
235
238
  to_update.append(update)
236
239
  else:
237
240
  to_update.append(item)
238
241
 
239
- return self.client.robotics.data_postprocessing.update(to_update)
242
+ return self.client.tool.robotics.data_postprocessing.update(to_update, mode="replace")
240
243
 
241
- def delete(self, ids: SequenceNotStr[str]) -> int:
242
- try:
243
- self.client.robotics.data_postprocessing.delete(ids)
244
- except CogniteAPIError as e:
245
- return len(e.successful)
244
+ def delete(self, ids: SequenceNotStr[ExternalId]) -> int:
245
+ if not ids:
246
+ return 0
247
+ self.client.tool.robotics.data_postprocessing.delete(list(ids), ignore_unknown_ids=True)
246
248
  return len(ids)
247
249
 
248
250
  def _iterate(
@@ -250,8 +252,9 @@ class RoboticsDataPostProcessingCRUD(ResourceCRUD[str, DataPostProcessingWrite,
250
252
  data_set_external_id: str | None = None,
251
253
  space: str | None = None,
252
254
  parent_ids: list[Hashable] | None = None,
253
- ) -> Iterable[DataPostProcessing]:
254
- return iter(self.client.robotics.data_postprocessing)
255
+ ) -> Iterable[RobotDataPostProcessingResponse]:
256
+ for items in self.client.tool.robotics.data_postprocessing.iterate(limit=None):
257
+ yield from items
255
258
 
256
259
  def diff_list(
257
260
  self, local: list[Any], cdf: list[Any], json_path: tuple[str | int, ...]
@@ -261,10 +264,10 @@ class RoboticsDataPostProcessingCRUD(ResourceCRUD[str, DataPostProcessingWrite,
261
264
  return super().diff_list(local, cdf, json_path)
262
265
 
263
266
 
264
- class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapability]):
267
+ class RobotCapabilityCRUD(ResourceCRUD[ExternalId, RobotCapabilityRequest, RobotCapabilityResponse]):
265
268
  folder_name = "robotics"
266
- resource_cls = RobotCapability
267
- resource_write_cls = RobotCapabilityWrite
269
+ resource_cls = RobotCapabilityResponse
270
+ resource_write_cls = RobotCapabilityRequest
268
271
  kind = "RobotCapability"
269
272
  yaml_cls = RobotCapabilityYAML
270
273
  _doc_url = "RobotCapabilities/operation/createRobotCapabilities"
@@ -274,20 +277,18 @@ class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapabilit
274
277
  return "robotics robot capabilities"
275
278
 
276
279
  @classmethod
277
- def get_id(cls, item: RobotCapability | RobotCapabilityWrite | dict) -> str:
280
+ def get_id(cls, item: RobotCapabilityRequest | RobotCapabilityResponse | dict) -> ExternalId:
278
281
  if isinstance(item, dict):
279
- return item["externalId"]
280
- if not item.external_id:
281
- raise KeyError("RobotCapability must have external_id")
282
- return item.external_id
282
+ return ExternalId(external_id=item["externalId"])
283
+ return item.as_id()
283
284
 
284
285
  @classmethod
285
- def dump_id(cls, id: str) -> dict[str, Any]:
286
- return {"externalId": id}
286
+ def dump_id(cls, id: ExternalId) -> dict[str, Any]:
287
+ return id.dump()
287
288
 
288
289
  @classmethod
289
290
  def get_required_capability(
290
- cls, items: Sequence[RobotCapabilityWrite] | None, read_only: bool
291
+ cls, items: Sequence[RobotCapabilityRequest] | None, read_only: bool
291
292
  ) -> Capability | list[Capability]:
292
293
  if not items and items is not None:
293
294
  return []
@@ -306,20 +307,20 @@ class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapabilit
306
307
 
307
308
  return capabilities.RoboticsAcl(actions, capabilities.RoboticsAcl.Scope.All())
308
309
 
309
- def create(self, items: Sequence[RobotCapabilityWrite]) -> RobotCapabilityList:
310
- return self.client.robotics.capabilities.create(items)
310
+ def create(self, items: Sequence[RobotCapabilityRequest]) -> list[RobotCapabilityResponse]:
311
+ return self.client.tool.robotics.capabilities.create(items)
311
312
 
312
- def retrieve(self, ids: SequenceNotStr[str]) -> RobotCapabilityList:
313
- return _fallback_to_one_by_one(self.client.robotics.capabilities.retrieve, ids, RobotCapabilityList)
313
+ def retrieve(self, ids: SequenceNotStr[ExternalId]) -> list[RobotCapabilityResponse]:
314
+ return self.client.tool.robotics.capabilities.retrieve(list(ids), ignore_unknown_ids=True)
314
315
 
315
- def update(self, items: Sequence[RobotCapabilityWrite]) -> RobotCapabilityList:
316
+ def update(self, items: Sequence[RobotCapabilityRequest]) -> list[RobotCapabilityResponse]:
316
317
  # There is a bug in the /update endpoint that requires the input_schema to be a string
317
318
  # and not an object. This is a workaround until the bug is fixed.
318
319
  # We do the serialization to avoid modifying the original object.
319
320
  to_update = []
320
321
  for item in items:
321
322
  if isinstance(item.input_schema, dict) or isinstance(item.data_handling_schema, dict):
322
- update = RobotCapabilityWrite.load(item.dump())
323
+ update = RobotCapabilityRequest.model_validate(item.dump())
323
324
  if isinstance(item.data_handling_schema, dict):
324
325
  update.data_handling_schema = json.dumps(item.data_handling_schema) # type: ignore[assignment]
325
326
  if isinstance(item.input_schema, dict):
@@ -328,13 +329,12 @@ class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapabilit
328
329
  else:
329
330
  to_update.append(item)
330
331
 
331
- return self.client.robotics.capabilities.update(to_update)
332
+ return self.client.tool.robotics.capabilities.update(to_update, mode="replace")
332
333
 
333
- def delete(self, ids: SequenceNotStr[str]) -> int:
334
- try:
335
- self.client.robotics.capabilities.delete(ids)
336
- except CogniteAPIError as e:
337
- return len(e.successful)
334
+ def delete(self, ids: SequenceNotStr[ExternalId]) -> int:
335
+ if not ids:
336
+ return 0
337
+ self.client.tool.robotics.capabilities.delete(list(ids), ignore_unknown_ids=True)
338
338
  return len(ids)
339
339
 
340
340
  def _iterate(
@@ -342,8 +342,9 @@ class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapabilit
342
342
  data_set_external_id: str | None = None,
343
343
  space: str | None = None,
344
344
  parent_ids: list[Hashable] | None = None,
345
- ) -> Iterable[RobotCapability]:
346
- return iter(self.client.robotics.capabilities)
345
+ ) -> Iterable[RobotCapabilityResponse]:
346
+ for items in self.client.tool.robotics.capabilities.iterate(limit=None):
347
+ yield from items
347
348
 
348
349
  def diff_list(
349
350
  self, local: list[Any], cdf: list[Any], json_path: tuple[str | int, ...]
@@ -353,10 +354,10 @@ class RobotCapabilityCRUD(ResourceCRUD[str, RobotCapabilityWrite, RobotCapabilit
353
354
  return super().diff_list(local, cdf, json_path)
354
355
 
355
356
 
356
- class RoboticMapCRUD(ResourceCRUD[str, MapWrite, Map]):
357
+ class RoboticMapCRUD(ResourceCRUD[ExternalId, RobotMapRequest, RobotMapResponse]):
357
358
  folder_name = "robotics"
358
- resource_cls = Map
359
- resource_write_cls = MapWrite
359
+ resource_cls = RobotMapResponse
360
+ resource_write_cls = RobotMapRequest
360
361
  kind = "Map"
361
362
  dependencies = frozenset({RoboticFrameCRUD, RoboticLocationCRUD})
362
363
  yaml_cls = RobotMapYAML
@@ -367,20 +368,18 @@ class RoboticMapCRUD(ResourceCRUD[str, MapWrite, Map]):
367
368
  return "robotics maps"
368
369
 
369
370
  @classmethod
370
- def get_id(cls, item: Map | MapWrite | dict) -> str:
371
+ def get_id(cls, item: RobotMapRequest | RobotMapResponse | dict) -> ExternalId:
371
372
  if isinstance(item, dict):
372
- return item["externalId"]
373
- if not item.external_id:
374
- raise KeyError("Map must have external_id")
375
- return item.external_id
373
+ return ExternalId(external_id=item["externalId"])
374
+ return item.as_id()
376
375
 
377
376
  @classmethod
378
- def dump_id(cls, id: str) -> dict[str, Any]:
379
- return {"externalId": id}
377
+ def dump_id(cls, id: ExternalId) -> dict[str, Any]:
378
+ return id.dump()
380
379
 
381
380
  @classmethod
382
381
  def get_required_capability(
383
- cls, items: Sequence[MapWrite] | None, read_only: bool
382
+ cls, items: Sequence[RobotMapRequest] | None, read_only: bool
384
383
  ) -> Capability | list[Capability]:
385
384
  if not items and items is not None:
386
385
  return []
@@ -400,28 +399,38 @@ class RoboticMapCRUD(ResourceCRUD[str, MapWrite, Map]):
400
399
 
401
400
  return capabilities.RoboticsAcl(actions, capabilities.RoboticsAcl.Scope.All())
402
401
 
403
- def dump_resource(self, resource: Map, local: dict[str, Any] | None = None) -> dict[str, Any]:
404
- dump = resource.as_write().dump()
402
+ def dump_resource(self, resource: RobotMapResponse, local: dict[str, Any] | None = None) -> dict[str, Any]:
403
+ dump = resource.as_request_resource().dump()
405
404
  local = local or {}
406
405
  if dump.get("scale") == 1.0 and "scale" not in local:
407
406
  # Default value set on the server side.
408
407
  del dump["scale"]
408
+ for key in [
409
+ "data",
410
+ "frameExternalId",
411
+ "locationExternalId",
412
+ ]:
413
+ if dump.get(key) is None and key not in (local or {}):
414
+ # Key set to null on the server side.
415
+ dump.pop(key, None)
409
416
  return dump
410
417
 
411
- def create(self, items: Sequence[MapWrite]) -> MapList:
412
- return self.client.robotics.maps.create(items)
418
+ def load_resource(self, resource: dict[str, Any], is_dry_run: bool = False) -> RobotMapRequest:
419
+ return RobotMapRequest.model_validate(resource)
420
+
421
+ def create(self, items: Sequence[RobotMapRequest]) -> list[RobotMapResponse]:
422
+ return self.client.tool.robotics.maps.create(items)
413
423
 
414
- def retrieve(self, ids: SequenceNotStr[str]) -> MapList:
415
- return _fallback_to_one_by_one(self.client.robotics.maps.retrieve, ids, MapList)
424
+ def retrieve(self, ids: SequenceNotStr[ExternalId]) -> list[RobotMapResponse]:
425
+ return self.client.tool.robotics.maps.retrieve(list(ids), ignore_unknown_ids=True)
416
426
 
417
- def update(self, items: Sequence[MapWrite]) -> MapList:
418
- return self.client.robotics.maps.update(items)
427
+ def update(self, items: Sequence[RobotMapRequest]) -> list[RobotMapResponse]:
428
+ return self.client.tool.robotics.maps.update(items, mode="replace")
419
429
 
420
- def delete(self, ids: SequenceNotStr[str]) -> int:
421
- try:
422
- self.client.robotics.maps.delete(ids)
423
- except CogniteAPIError as e:
424
- return len(e.successful)
430
+ def delete(self, ids: SequenceNotStr[ExternalId]) -> int:
431
+ if not ids:
432
+ return 0
433
+ self.client.tool.robotics.maps.delete(list(ids), ignore_unknown_ids=True)
425
434
  return len(ids)
426
435
 
427
436
  def _iterate(
@@ -429,21 +438,6 @@ class RoboticMapCRUD(ResourceCRUD[str, MapWrite, Map]):
429
438
  data_set_external_id: str | None = None,
430
439
  space: str | None = None,
431
440
  parent_ids: list[Hashable] | None = None,
432
- ) -> Iterable[Map]:
433
- return iter(self.client.robotics.maps)
434
-
435
-
436
- def _fallback_to_one_by_one(
437
- api_call: Callable, items: Sequence | SequenceNotStr, return_cls: type[T_CogniteResourceList]
438
- ) -> T_CogniteResourceList:
439
- try:
440
- return api_call(items)
441
- except CogniteAPIError:
442
- return_items = return_cls([])
443
- if len(items) > 1:
444
- # The API does not give any information about which items were not found/failed.
445
- # so we need to apply them one by one to find out which ones failed.
446
- for item in items:
447
- with suppress(CogniteAPIError):
448
- return_items.append(api_call(item))
449
- return return_items
441
+ ) -> Iterable[RobotMapResponse]:
442
+ for maps in self.client.tool.robotics.maps.iterate(limit=None):
443
+ yield from maps
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.7.70
15
+ image: cognite/toolkit:0.7.72
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.7.70
13
+ image: cognite/toolkit:0.7.72
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.7.70"
7
+ version = "0.7.72"
8
8
 
9
9
 
10
10
  [plugins]
@@ -1 +1 @@
1
- __version__ = "0.7.70"
1
+ __version__ = "0.7.72"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.7.70
3
+ Version: 0.7.72
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Author: Cognite AS
6
6
  Author-email: Cognite AS <support@cognite.com>