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,8 +1,14 @@
1
- from typing import Any, ClassVar, Literal, TypeAlias
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, ClassVar, Literal, TypeAlias, TypeVar
2
3
 
3
- from pydantic import ConfigDict, JsonValue, model_serializer
4
+ from pydantic import model_validator
4
5
 
5
- from cognite_toolkit._cdf_tk.client._resource_base import BaseModelObject, Identifier, RequestResource
6
+ from cognite_toolkit._cdf_tk.client._resource_base import (
7
+ BaseModelObject,
8
+ Identifier,
9
+ RequestResource,
10
+ ResponseResource,
11
+ )
6
12
 
7
13
  InstanceType: TypeAlias = Literal["node", "edge"]
8
14
 
@@ -39,6 +45,9 @@ class TypedEdgeIdentifier(TypedInstanceIdentifier):
39
45
  return f"Edge({self.space}, {self.external_id})"
40
46
 
41
47
 
48
+ T_TypedInstanceIdentifier = TypeVar("T_TypedInstanceIdentifier", bound=TypedInstanceIdentifier)
49
+
50
+
42
51
  class InstanceIdentifier(Identifier):
43
52
  space: str
44
53
  external_id: str
@@ -64,7 +73,7 @@ class InstanceResult(BaseModelObject):
64
73
  )
65
74
 
66
75
 
67
- class ViewReference(Identifier):
76
+ class TypedViewReference(Identifier):
68
77
  type: Literal["view"] = "view"
69
78
  space: str
70
79
  external_id: str
@@ -88,108 +97,139 @@ class ViewReference(Identifier):
88
97
  #######################################################
89
98
 
90
99
 
91
- class InstanceRequestResource(RequestResource):
92
- """This is a base class for resources that are Instances."""
100
+ class WrappedInstanceRequest(RequestResource, ABC):
101
+ """This is a base class for resources that are Instances.
102
+ It is used to define resources that are
103
+ """
93
104
 
94
- VIEW_ID: ClassVar[ViewReference]
105
+ VIEW_ID: ClassVar[TypedViewReference]
95
106
  instance_type: InstanceType
96
107
  space: str
97
108
  external_id: str
109
+ existing_version: int | None = None
98
110
 
99
- def as_id(self) -> TypedInstanceIdentifier:
100
- return TypedInstanceIdentifier(
101
- instance_type=self.instance_type,
102
- space=self.space,
103
- external_id=self.external_id,
104
- )
105
-
106
- def as_request_item(self) -> "InstanceRequestItem":
107
- return InstanceRequestItem(
108
- instance_type=self.instance_type,
109
- space=self.space,
110
- external_id=self.external_id,
111
- sources=[InstanceSource(source=self.VIEW_ID, resource=self)],
112
- )
113
-
114
-
115
- class InstanceSource(BaseModelObject):
116
- source: ViewReference
117
- resource: InstanceRequestResource
111
+ def dump(
112
+ self, camel_case: bool = True, exclude_extra: bool = False, context: Literal["api", "toolkit"] = "api"
113
+ ) -> dict[str, Any]:
114
+ """Dump the resource to a dictionary.
118
115
 
119
- @model_serializer(mode="plain")
120
- def serialize_resource(self) -> dict[str, Any]:
121
- properties: dict[str, JsonValue] = {}
122
- for field_id, field in type(self.resource).model_fields.items():
123
- if field_id in InstanceRequestResource.model_fields:
124
- # Skip space, external_id, instance_type
125
- continue
126
- key = field.alias or field_id
127
- properties[key] = self._serialize_property(getattr(self.resource, field_id))
116
+ Args:
117
+ camel_case (bool): Whether to use camelCase for the keys. Default is True.
118
+ exclude_extra (bool): Whether to exclude extra fields not defined in the model. Default is False.
119
+ context (Literal["api", "toolkit"]): The context in which the dump is used. Default is "api".
128
120
 
121
+ """
122
+ exclude: set[str] = set()
123
+ if exclude_extra:
124
+ exclude |= set(self.__pydantic_extra__) if self.__pydantic_extra__ else set()
125
+ if context == "api":
126
+ exclude.update({"existing_version", "instance_type", "space", "external_id"})
127
+ dumped = self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True, exclude=exclude)
128
+ if context == "toolkit":
129
+ return dumped
129
130
  return {
130
- "source": self.source.model_dump(by_alias=True),
131
- "properties": properties,
131
+ "instanceType": self.instance_type,
132
+ "space": self.space,
133
+ "externalId": self.external_id,
134
+ "sources": [
135
+ {
136
+ "source": self.VIEW_ID.dump(camel_case=camel_case, include_type=True),
137
+ "properties": dumped,
138
+ }
139
+ ],
132
140
  }
133
141
 
134
- @classmethod
135
- def _serialize_property(cls, value: Any) -> JsonValue:
136
- """Handles serialization of direct relations."""
137
- if isinstance(value, InstanceRequestResource):
138
- return {"space": value.space, "externalId": value.external_id}
139
- elif isinstance(value, list):
140
- return [cls._serialize_property(v) for v in value]
141
- return value
142
142
 
143
+ T_WrappedInstanceRequest = TypeVar("T_WrappedInstanceRequest", bound=WrappedInstanceRequest)
143
144
 
144
- class InstanceRequestItem(RequestResource):
145
- model_config = ConfigDict(populate_by_name=True)
146
- instance_type: InstanceType
147
- space: str
148
- external_id: str
149
- existing_version: int | None = None
150
- sources: list[InstanceSource] | None = None
151
-
152
- def as_id(self) -> TypedInstanceIdentifier:
153
- return TypedInstanceIdentifier(
154
- instance_type=self.instance_type,
155
- space=self.space,
156
- external_id=self.external_id,
157
- )
158
145
 
159
-
160
- class InstanceResponseItem(BaseModelObject):
146
+ class WrappedInstanceResponse(ResponseResource[T_WrappedInstanceRequest], ABC):
147
+ VIEW_ID: ClassVar[TypedViewReference]
161
148
  instance_type: InstanceType
162
149
  space: str
163
150
  external_id: str
151
+
164
152
  version: int
165
- type: TypedInstanceIdentifier | None = None
166
153
  created_time: int
167
154
  last_updated_time: int
168
155
  deleted_time: int | None = None
169
- properties: dict[str, dict[str, dict[str, JsonValue]]] | None = None
170
156
 
171
- def get_properties_for_source(
172
- self, source: ViewReference, include_identifier: bool = False
173
- ) -> dict[str, JsonValue]:
174
- output: dict[str, JsonValue] = (
175
- {"space": self.space, "externalId": self.external_id} if include_identifier else {}
176
- )
177
- if not self.properties:
178
- return output
179
- if source.space not in self.properties:
180
- return output
181
- space_properties = self.properties[source.space]
182
- view_version = f"{source.external_id}/{source.version}"
183
- output.update(space_properties.get(view_version, {}))
184
- return output
157
+ @model_validator(mode="before")
158
+ def move_properties(cls, values: dict[str, Any]) -> dict[str, Any]:
159
+ """Move properties from sources to the top level."""
160
+ return move_properties(values, cls.VIEW_ID)
185
161
 
186
- def as_id(self) -> TypedInstanceIdentifier:
187
- return TypedInstanceIdentifier(
162
+
163
+ def move_properties(values: dict[str, Any], view_id: TypedViewReference) -> dict[str, Any]:
164
+ """Help function to move properties from properties.space.externalId/version to the top level.
165
+
166
+ It is used in WrappedInstanceResponse to move properties from the response to the top level.
167
+ """
168
+ if "properties" not in values:
169
+ return values
170
+ values_copy = dict(values)
171
+ properties = values_copy.pop("properties")
172
+ if not isinstance(properties, dict) or view_id.space not in properties:
173
+ return values
174
+ view_properties = properties.pop(view_id.space)
175
+ identifier = f"{view_id.external_id}/{view_id.version}"
176
+ if not isinstance(view_properties, dict) or identifier not in view_properties:
177
+ return values
178
+ source_properties = view_properties.pop(identifier)
179
+ values_copy.update(source_properties)
180
+ return values_copy
181
+
182
+
183
+ T_WrappedInstanceResponse = TypeVar("T_WrappedInstanceResponse", bound=WrappedInstanceResponse)
184
+
185
+
186
+ class WrappedInstanceListRequest(RequestResource, ABC):
187
+ VIEW_ID: ClassVar[TypedViewReference]
188
+ instance_type: Literal["node"] = "node"
189
+ space: str
190
+ external_id: str
191
+
192
+ @abstractmethod
193
+ def dump_instances(self) -> list[dict[str, Any]]:
194
+ """Dumps the object to a list of instance request dictionaries."""
195
+ raise NotImplementedError()
196
+
197
+ def as_id(self) -> TypedNodeIdentifier:
198
+ return TypedNodeIdentifier(
188
199
  instance_type=self.instance_type,
189
200
  space=self.space,
190
201
  external_id=self.external_id,
191
202
  )
192
203
 
204
+ @abstractmethod
205
+ def as_ids(self) -> list[TypedInstanceIdentifier]:
206
+ """Convert the response to a list of typed instance identifiers."""
207
+ raise NotImplementedError()
208
+
209
+
210
+ T_InstancesListRequest = TypeVar("T_InstancesListRequest", bound=WrappedInstanceListRequest)
211
+
212
+
213
+ class WrappedInstanceListResponse(ResponseResource[T_InstancesListRequest], ABC):
214
+ VIEW_ID: ClassVar[TypedViewReference]
215
+ instance_type: Literal["node"] = "node"
216
+ space: str
217
+ external_id: str
218
+
219
+ @model_validator(mode="before")
220
+ @classmethod
221
+ def move_properties(cls, values: dict[str, Any]) -> dict[str, Any]:
222
+ """Move properties from sources to the top level."""
223
+ return move_properties(values, cls.VIEW_ID)
224
+
225
+ @abstractmethod
226
+ def as_ids(self) -> list[TypedInstanceIdentifier]:
227
+ """Convert the response to a list of typed instance identifiers."""
228
+ raise NotImplementedError()
229
+
230
+
231
+ T_InstancesListResponse = TypeVar("T_InstancesListResponse", bound=WrappedInstanceListResponse)
232
+
193
233
 
194
234
  class NodeReference(BaseModelObject):
195
235
  space: str
@@ -23,15 +23,14 @@ from cognite_toolkit._cdf_tk.client.api.legacy.extended_functions import Extende
23
23
  from cognite_toolkit._cdf_tk.client.api.legacy.extended_raw import ExtendedRawAPI
24
24
  from cognite_toolkit._cdf_tk.client.api.legacy.extended_timeseries import ExtendedTimeSeriesAPI
25
25
  from cognite_toolkit._cdf_tk.client.api.legacy.location_filters import LocationFiltersAPI
26
- from cognite_toolkit._cdf_tk.client.api.legacy.robotics import (
27
- CapabilitiesAPI,
28
- DataPostProcessingAPI,
29
- FramesAPI,
30
- MapsAPI,
31
- RoboticsAPI,
32
- )
33
- from cognite_toolkit._cdf_tk.client.api.legacy.robotics import LocationsAPI as RoboticsLocationsAPI
34
26
  from cognite_toolkit._cdf_tk.client.api.legacy.search_config import SearchConfigurationsAPI
27
+ from cognite_toolkit._cdf_tk.client.api.robotics import RoboticsAPI
28
+ from cognite_toolkit._cdf_tk.client.api.robotics_capabilities import CapabilitiesAPI
29
+ from cognite_toolkit._cdf_tk.client.api.robotics_data_postprocessing import DataPostProcessingAPI
30
+ from cognite_toolkit._cdf_tk.client.api.robotics_frames import FramesAPI
31
+ from cognite_toolkit._cdf_tk.client.api.robotics_locations import LocationsAPI
32
+ from cognite_toolkit._cdf_tk.client.api.robotics_maps import MapsAPI
33
+ from cognite_toolkit._cdf_tk.client.api.robotics_robots import RobotsAPI
35
34
 
36
35
  from ._toolkit_client import ToolAPI
37
36
  from .api.assets import AssetsAPI
@@ -139,14 +138,6 @@ class ToolkitClientMock(CogniteClientMock):
139
138
  self.raw.rows = MagicMock(spec_set=RawRowsAPI)
140
139
  self.raw.tables = MagicMock(spec_set=RawTablesAPI)
141
140
 
142
- self.robotics = MagicMock()
143
- self.robotics.robots = MagicMock(spec=RoboticsAPI)
144
- self.robotics.data_postprocessing = MagicMock(spec_set=DataPostProcessingAPI)
145
- self.robotics.locations = MagicMock(spec_set=RoboticsLocationsAPI)
146
- self.robotics.frames = MagicMock(spec_set=FramesAPI)
147
- self.robotics.maps = MagicMock(spec_set=MapsAPI)
148
- self.robotics.capabilities = MagicMock(spec_set=CapabilitiesAPI)
149
-
150
141
  self.data_modeling.instances = MagicMock(spec_set=ExtendedInstancesAPI)
151
142
 
152
143
  self.time_series = MagicMock(spec=ExtendedTimeSeriesAPI)
@@ -171,6 +162,13 @@ class ToolkitClientMock(CogniteClientMock):
171
162
  self.tool.hosted_extractors.destinations = MagicMock(spec_set=HostedExtractorDestinationsAPI)
172
163
  self.tool.hosted_extractors.mappings = MagicMock(spec_set=HostedExtractorMappingsAPI)
173
164
  self.tool.labels = MagicMock(spec_set=LabelsAPI)
165
+ self.tool.robotics = MagicMock(spec=RoboticsAPI)
166
+ self.tool.robotics.capabilities = MagicMock(spec_set=CapabilitiesAPI)
167
+ self.tool.robotics.data_postprocessing = MagicMock(spec_set=DataPostProcessingAPI)
168
+ self.tool.robotics.frames = MagicMock(spec_set=FramesAPI)
169
+ self.tool.robotics.locations = MagicMock(spec_set=LocationsAPI)
170
+ self.tool.robotics.maps = MagicMock(spec_set=MapsAPI)
171
+ self.tool.robotics.robots = MagicMock(spec_set=RobotsAPI)
174
172
  self.tool.security_categories = MagicMock(spec_set=SecurityCategoriesAPI)
175
173
  self.tool.sequences = MagicMock(spec_set=SequencesAPI)
176
174
  self.tool.transformations = MagicMock(spec_set=TransformationsAPI)
@@ -8,13 +8,15 @@ from cognite.client.data_classes.data_modeling import NodeApplyResultList, NodeI
8
8
  from cognite.client.exceptions import CogniteAPIError
9
9
  from cognite.client.utils.useful_types import SequenceNotStr
10
10
 
11
+ from cognite_toolkit._cdf_tk.client.resource_classes.data_modeling._instance import InstanceSlimDefinition
11
12
  from cognite_toolkit._cdf_tk.client.resource_classes.identifiers import ExternalId
12
13
  from cognite_toolkit._cdf_tk.client.resource_classes.infield import (
13
- InFieldCDMLocationConfig,
14
- InfieldLocationConfig,
15
- InfieldLocationConfigList,
14
+ InFieldCDMLocationConfigRequest,
15
+ InFieldCDMLocationConfigResponse,
16
+ InFieldLocationConfigRequest,
17
+ InFieldLocationConfigResponse,
16
18
  )
17
- from cognite_toolkit._cdf_tk.client.resource_classes.instance_api import InstanceResult, TypedNodeIdentifier
19
+ from cognite_toolkit._cdf_tk.client.resource_classes.instance_api import TypedNodeIdentifier
18
20
  from cognite_toolkit._cdf_tk.client.resource_classes.legacy.apm_config_v1 import (
19
21
  APMConfig,
20
22
  APMConfigList,
@@ -34,7 +36,7 @@ from cognite_toolkit._cdf_tk.utils.diff_list import diff_list_hashable, diff_lis
34
36
  from .auth import GroupAllScopedCRUD
35
37
  from .classic import AssetCRUD
36
38
  from .data_organization import DataSetsCRUD
37
- from .datamodel import SpaceCRUD
39
+ from .datamodel import SpaceCRUD, ViewCRUD
38
40
  from .group_scoped import GroupResourceScopedCRUD
39
41
 
40
42
 
@@ -247,10 +249,12 @@ class InfieldV1CRUD(ResourceCRUD[str, APMConfigWrite, APMConfig]):
247
249
 
248
250
 
249
251
  @final
250
- class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocationConfig, InfieldLocationConfig]):
252
+ class InFieldLocationConfigCRUD(
253
+ ResourceCRUD[TypedNodeIdentifier, InFieldLocationConfigRequest, InFieldLocationConfigResponse]
254
+ ):
251
255
  folder_name = "cdf_applications"
252
- resource_cls = InfieldLocationConfig
253
- resource_write_cls = InfieldLocationConfig
256
+ resource_cls = InFieldLocationConfigResponse
257
+ resource_write_cls = InFieldLocationConfigRequest
254
258
  kind = "InFieldLocationConfig"
255
259
  yaml_cls = InfieldLocationConfigYAML
256
260
  dependencies = frozenset({SpaceCRUD, GroupAllScopedCRUD, GroupResourceScopedCRUD})
@@ -261,7 +265,7 @@ class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocatio
261
265
  return "infield location configs"
262
266
 
263
267
  @classmethod
264
- def get_id(cls, item: InfieldLocationConfig | dict) -> TypedNodeIdentifier:
268
+ def get_id(cls, item: InFieldLocationConfigRequest | InFieldLocationConfigResponse | dict) -> TypedNodeIdentifier:
265
269
  if isinstance(item, dict):
266
270
  return TypedNodeIdentifier(space=item["space"], external_id=item["externalId"])
267
271
  return TypedNodeIdentifier(space=item.space, external_id=item.external_id)
@@ -275,7 +279,7 @@ class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocatio
275
279
 
276
280
  @classmethod
277
281
  def get_required_capability(
278
- cls, items: Sequence[InfieldLocationConfig] | None, read_only: bool
282
+ cls, items: Sequence[InFieldLocationConfigRequest] | None, read_only: bool
279
283
  ) -> Capability | list[Capability]:
280
284
  if not items or items is None:
281
285
  return []
@@ -289,8 +293,10 @@ class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocatio
289
293
 
290
294
  return DataModelInstancesAcl(actions, DataModelInstancesAcl.Scope.SpaceID(instance_spaces))
291
295
 
292
- def dump_resource(self, resource: InfieldLocationConfig, local: dict[str, Any] | None = None) -> dict[str, Any]:
293
- dumped = resource.dump()
296
+ def dump_resource(
297
+ self, resource: InFieldLocationConfigResponse, local: dict[str, Any] | None = None
298
+ ) -> dict[str, Any]:
299
+ dumped = resource.as_request_resource().dump()
294
300
  local = local or {}
295
301
  dumped.pop("instanceType", None)
296
302
  if isinstance(cdf_dec := dumped.get("dataExplorationConfig"), dict):
@@ -305,33 +311,24 @@ class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocatio
305
311
 
306
312
  return dumped
307
313
 
308
- def create(self, items: Sequence[InfieldLocationConfig]) -> list[InstanceResult]:
309
- created = self.client.infield.config.apply(items)
310
- config_ids = {config.as_id() for config in items}
311
- # We filter out all the data exploration configs that were created along with the infield location configs
312
- # as we only want to count the infield location configs here.
313
- return [res for res in created if res.as_id() in config_ids]
314
+ def create(self, items: Sequence[InFieldLocationConfigRequest]) -> list[InstanceSlimDefinition]:
315
+ return self.client.infield.config.create(items)
314
316
 
315
- def retrieve(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> InfieldLocationConfigList:
316
- return InfieldLocationConfigList(self.client.infield.config.retrieve(list(ids)))
317
+ def retrieve(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> list[InFieldLocationConfigResponse]:
318
+ return self.client.infield.config.retrieve(list(ids))
317
319
 
318
- def update(self, items: Sequence[InfieldLocationConfig]) -> Sized:
319
- return self.create(items)
320
+ def update(self, items: Sequence[InFieldLocationConfigRequest]) -> Sized:
321
+ return self.client.infield.config.update(items)
320
322
 
321
323
  def delete(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> int:
322
- # We must retrieve the full resource to get hte DataExplorationConfig linked resource deleted as well.
323
- retrieved = self.retrieve(list(ids))
324
- # Then, we pass the entire resource to the delete method, which will delete both the InfieldLocationConfig
325
- # and the linked DataExplorationConfig.
326
- _ = self.client.infield.config.delete(retrieved)
327
- return len(retrieved)
324
+ return len(self.client.infield.config.delete(list(ids)))
328
325
 
329
326
  def _iterate(
330
327
  self,
331
328
  data_set_external_id: str | None = None,
332
329
  space: str | None = None,
333
330
  parent_ids: list[Hashable] | None = None,
334
- ) -> Iterable[InfieldLocationConfig]:
331
+ ) -> Iterable[InFieldLocationConfigResponse]:
335
332
  raise NotImplementedError(f"Iteration over {self.display_name} is not supported.")
336
333
 
337
334
  def diff_list(
@@ -350,14 +347,14 @@ class InFieldLocationConfigCRUD(ResourceCRUD[TypedNodeIdentifier, InfieldLocatio
350
347
 
351
348
  @final
352
349
  class InFieldCDMLocationConfigCRUD(
353
- ResourceCRUD[TypedNodeIdentifier, InFieldCDMLocationConfig, InFieldCDMLocationConfig]
350
+ ResourceCRUD[TypedNodeIdentifier, InFieldCDMLocationConfigRequest, InFieldCDMLocationConfigResponse]
354
351
  ):
355
352
  folder_name = "cdf_applications"
356
- resource_cls = InFieldCDMLocationConfig
357
- resource_write_cls = InFieldCDMLocationConfig
353
+ resource_cls = InFieldCDMLocationConfigResponse
354
+ resource_write_cls = InFieldCDMLocationConfigRequest
358
355
  kind = "InFieldCDMLocationConfig"
359
356
  yaml_cls = InFieldCDMLocationConfigYAML
360
- dependencies = frozenset({SpaceCRUD, GroupAllScopedCRUD, GroupResourceScopedCRUD})
357
+ dependencies = frozenset({SpaceCRUD, GroupAllScopedCRUD, GroupResourceScopedCRUD, ViewCRUD})
361
358
  _doc_url = "Instances/operation/applyNodeAndEdges"
362
359
 
363
360
  @property
@@ -365,7 +362,9 @@ class InFieldCDMLocationConfigCRUD(
365
362
  return "infield CDM location configs"
366
363
 
367
364
  @classmethod
368
- def get_id(cls, item: InFieldCDMLocationConfig | dict) -> TypedNodeIdentifier:
365
+ def get_id(
366
+ cls, item: InFieldCDMLocationConfigRequest | InFieldCDMLocationConfigResponse | dict
367
+ ) -> TypedNodeIdentifier:
369
368
  if isinstance(item, dict):
370
369
  return TypedNodeIdentifier(space=item["space"], external_id=item["externalId"])
371
370
  return TypedNodeIdentifier(space=item.space, external_id=item.external_id)
@@ -379,7 +378,7 @@ class InFieldCDMLocationConfigCRUD(
379
378
 
380
379
  @classmethod
381
380
  def get_required_capability(
382
- cls, items: Sequence[InFieldCDMLocationConfig] | None, read_only: bool
381
+ cls, items: Sequence[InFieldCDMLocationConfigRequest] | None, read_only: bool
383
382
  ) -> Capability | list[Capability]:
384
383
  if not items or items is None:
385
384
  return []
@@ -393,8 +392,10 @@ class InFieldCDMLocationConfigCRUD(
393
392
 
394
393
  return DataModelInstancesAcl(actions, DataModelInstancesAcl.Scope.SpaceID(instance_spaces))
395
394
 
396
- def dump_resource(self, resource: InFieldCDMLocationConfig, local: dict[str, Any] | None = None) -> dict[str, Any]:
397
- dumped = resource.as_write().dump()
395
+ def dump_resource(
396
+ self, resource: InFieldCDMLocationConfigResponse, local: dict[str, Any] | None = None
397
+ ) -> dict[str, Any]:
398
+ dumped = resource.as_request_resource().dump(context="toolkit")
398
399
  local = local or {}
399
400
  if "existingVersion" not in local:
400
401
  # Existing version is typically not set when creating nodes, but we get it back
@@ -403,27 +404,25 @@ class InFieldCDMLocationConfigCRUD(
403
404
  dumped.pop("instanceType", None)
404
405
  return dumped
405
406
 
406
- def create(self, items: Sequence[InFieldCDMLocationConfig]) -> list[InstanceResult]:
407
- return self.client.infield.cdm_config.apply(items)
407
+ def create(self, items: Sequence[InFieldCDMLocationConfigRequest]) -> list[InstanceSlimDefinition]:
408
+ return self.client.infield.cdm_config.create(items)
408
409
 
409
- def retrieve(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> list[InFieldCDMLocationConfig]:
410
+ def retrieve(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> list[InFieldCDMLocationConfigResponse]:
410
411
  return self.client.infield.cdm_config.retrieve(list(ids))
411
412
 
412
- def update(self, items: Sequence[InFieldCDMLocationConfig]) -> Sized:
413
+ def update(self, items: Sequence[InFieldCDMLocationConfigRequest]) -> Sized:
413
414
  return self.create(items)
414
415
 
415
416
  def delete(self, ids: SequenceNotStr[TypedNodeIdentifier]) -> int:
416
- # We must retrieve the full resource to delete it.
417
- retrieved = self.retrieve(list(ids))
418
- _ = self.client.infield.cdm_config.delete(retrieved)
419
- return len(retrieved)
417
+ deleted = self.client.infield.cdm_config.delete(list(ids))
418
+ return len(deleted)
420
419
 
421
420
  def _iterate(
422
421
  self,
423
422
  data_set_external_id: str | None = None,
424
423
  space: str | None = None,
425
424
  parent_ids: list[Hashable] | None = None,
426
- ) -> Iterable[InFieldCDMLocationConfig]:
425
+ ) -> Iterable[InFieldCDMLocationConfigResponse]:
427
426
  raise NotImplementedError(f"Iteration over {self.display_name} is not supported.")
428
427
 
429
428
  def diff_list(