cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.39__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 (198) hide show
  1. cognite_toolkit/_cdf.py +21 -23
  2. cognite_toolkit/_cdf_tk/apps/__init__.py +4 -0
  3. cognite_toolkit/_cdf_tk/apps/_core_app.py +19 -5
  4. cognite_toolkit/_cdf_tk/apps/_data_app.py +1 -1
  5. cognite_toolkit/_cdf_tk/apps/_dev_app.py +86 -0
  6. cognite_toolkit/_cdf_tk/apps/_download_app.py +693 -25
  7. cognite_toolkit/_cdf_tk/apps/_dump_app.py +44 -102
  8. cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
  9. cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
  10. cognite_toolkit/_cdf_tk/apps/_migrate_app.py +424 -9
  11. cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
  12. cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
  13. cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
  14. cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
  15. cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
  16. cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
  17. cognite_toolkit/_cdf_tk/builders/_raw.py +1 -1
  18. cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
  19. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +32 -12
  20. cognite_toolkit/_cdf_tk/client/api/infield.py +114 -17
  21. cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
  22. cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
  23. cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
  24. cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
  25. cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +15 -18
  26. cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
  27. cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
  28. cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
  29. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
  30. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
  31. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
  32. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
  33. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
  34. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
  35. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
  36. cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
  37. cognite_toolkit/_cdf_tk/client/api/migration.py +177 -4
  38. cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
  39. cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
  40. cognite_toolkit/_cdf_tk/client/api/streams.py +88 -0
  41. cognite_toolkit/_cdf_tk/client/api/three_d.py +384 -0
  42. cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
  43. cognite_toolkit/_cdf_tk/client/data_classes/base.py +37 -33
  44. cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
  45. cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
  46. cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +18 -13
  47. cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
  48. cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +47 -4
  49. cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +3 -3
  50. cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/migration.py} +10 -2
  51. cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
  52. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +112 -0
  53. cognite_toolkit/_cdf_tk/client/testing.py +42 -18
  54. cognite_toolkit/_cdf_tk/commands/__init__.py +7 -6
  55. cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
  56. cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
  57. cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
  58. cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
  59. cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +140 -92
  60. cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
  61. cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +108 -26
  62. cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +448 -45
  63. cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
  64. cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +6 -6
  65. cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +52 -1
  66. cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +377 -11
  67. cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
  68. cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
  69. cognite_toolkit/_cdf_tk/commands/_purge.py +36 -39
  70. cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
  71. cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
  72. cognite_toolkit/_cdf_tk/commands/about.py +221 -0
  73. cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
  74. cognite_toolkit/_cdf_tk/commands/build_cmd.py +16 -62
  75. cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
  76. cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
  77. cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
  78. cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
  79. cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
  80. cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
  81. cognite_toolkit/_cdf_tk/commands/dump_resource.py +10 -8
  82. cognite_toolkit/_cdf_tk/commands/init.py +225 -3
  83. cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
  84. cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
  85. cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
  86. cognite_toolkit/_cdf_tk/commands/run.py +1 -1
  87. cognite_toolkit/_cdf_tk/constants.py +20 -1
  88. cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
  89. cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
  90. cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +10 -19
  91. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
  92. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
  93. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +5 -15
  94. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +45 -44
  95. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +5 -12
  96. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
  97. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +206 -67
  98. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +6 -18
  99. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +126 -35
  100. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +7 -28
  101. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -30
  102. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
  103. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +4 -8
  104. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +4 -16
  105. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +5 -13
  106. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +5 -11
  107. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
  108. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +16 -45
  109. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
  110. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
  111. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
  112. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +75 -32
  113. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
  114. cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
  115. cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
  116. cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
  117. cognite_toolkit/_cdf_tk/plugins.py +2 -1
  118. cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
  119. cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
  120. cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
  121. cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
  122. cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
  123. cognite_toolkit/_cdf_tk/resource_classes/search_config.py +1 -1
  124. cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
  125. cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
  126. cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
  127. cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
  128. cognite_toolkit/_cdf_tk/storageio/_applications.py +340 -28
  129. cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
  130. cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
  131. cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
  132. cognite_toolkit/_cdf_tk/storageio/_file_content.py +435 -0
  133. cognite_toolkit/_cdf_tk/storageio/_instances.py +35 -3
  134. cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
  135. cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +71 -4
  136. cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
  137. cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
  138. cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
  139. cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
  140. cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
  141. cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py +34 -0
  142. cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
  143. cognite_toolkit/_cdf_tk/tracker.py +2 -2
  144. cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
  145. cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
  146. cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
  147. cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
  148. cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
  149. cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
  150. cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
  151. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +285 -18
  152. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +56 -4
  153. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +247 -0
  154. cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
  155. cognite_toolkit/_cdf_tk/utils/interactive_select.py +60 -18
  156. cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
  157. cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
  158. cognite_toolkit/_cdf_tk/validation.py +83 -1
  159. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  160. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  161. cognite_toolkit/_resources/cdf.toml +5 -4
  162. cognite_toolkit/_version.py +1 -1
  163. cognite_toolkit/config.dev.yaml +13 -0
  164. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/METADATA +24 -24
  165. cognite_toolkit-0.7.39.dist-info/RECORD +322 -0
  166. cognite_toolkit-0.7.39.dist-info/WHEEL +4 -0
  167. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +1 -0
  168. cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
  169. cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
  170. cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
  171. cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
  172. cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
  173. cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
  174. cognite_toolkit-0.6.97.dist-info/RECORD +0 -306
  175. cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
  176. cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
  177. /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
  178. /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
  179. /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
  180. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
  181. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
  182. /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
  183. /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
  184. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
  185. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
  186. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
  187. /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
  188. /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
  189. /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
  190. /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
  191. /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
  192. /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
  193. /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
  194. /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
  195. /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
  196. /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
  197. /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
  198. /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
@@ -1,6 +1,5 @@
1
- from collections.abc import Mapping, Set
2
- from dataclasses import dataclass
3
- from typing import Any, ClassVar, overload
1
+ from collections.abc import Iterable, Mapping, Set
2
+ from typing import Any, ClassVar, cast
4
3
 
5
4
  from cognite.client.data_classes import Annotation, Asset, Event, FileMetadata, TimeSeries
6
5
  from cognite.client.data_classes.data_modeling import (
@@ -10,11 +9,17 @@ from cognite.client.data_classes.data_modeling import (
10
9
  MappedProperty,
11
10
  NodeApply,
12
11
  NodeId,
12
+ ViewId,
13
13
  )
14
14
  from cognite.client.data_classes.data_modeling.instances import EdgeApply, NodeOrEdgeData, PropertyValueWrite
15
15
  from cognite.client.data_classes.data_modeling.views import ViewProperty
16
+ from cognite.client.utils._identifier import InstanceId
16
17
 
17
- from cognite_toolkit._cdf_tk.client.data_classes.migration import AssetCentricId, ResourceViewMapping
18
+ from cognite_toolkit._cdf_tk.client import ToolkitClient
19
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.migration import (
20
+ AssetCentricId,
21
+ ResourceViewMappingApply,
22
+ )
18
23
  from cognite_toolkit._cdf_tk.utils.collection import flatten_dict_json_path
19
24
  from cognite_toolkit._cdf_tk.utils.dtype_conversion import (
20
25
  asset_centric_convert_to_primary_property,
@@ -22,124 +27,164 @@ from cognite_toolkit._cdf_tk.utils.dtype_conversion import (
22
27
  )
23
28
  from cognite_toolkit._cdf_tk.utils.useful_types import (
24
29
  AssetCentricResourceExtended,
25
- AssetCentricType,
30
+ AssetCentricTypeExtended,
26
31
  )
27
32
 
28
- from .data_model import INSTANCE_SOURCE_VIEW_ID
33
+ from .data_model import COGNITE_MIGRATION_SPACE_ID, INSTANCE_SOURCE_VIEW_ID
29
34
  from .issues import ConversionIssue, FailedConversion, InvalidPropertyDataType
30
35
 
31
36
 
32
- @dataclass
33
37
  class DirectRelationCache:
34
38
  """Cache for direct relation references to look up target of direct relations.
35
39
 
36
- This is used when creating direct relations from asset-centric resources to CogniteAsset and CogniteSourceSystem.
37
-
38
- Attributes:
39
- asset: Mapping[int, DirectRelationReference]
40
- A mapping from asset IDs to their corresponding DirectRelationReference in the data model.
41
- source: Mapping[str, DirectRelationReference]
42
- A mapping from source strings to their corresponding DirectRelationReference in the data model.
43
-
44
- Methods:
45
- get(resource_type: AssetCentric, property_id: str) -> Mapping[str | int, DirectRelationReference]:
46
- Get the appropriate mapping based on the resource type and property ID.
47
-
48
- Note:
49
- The ASSET_REFERENCE_PROPERTIES and SOURCE_REFERENCE_PROPERTIES class variables define which properties
50
- in asset-centric resources reference assets and sources, respectively.
51
-
40
+ This is used when creating direct relations from asset-centric resources to assets, files, and source systems.
52
41
  """
53
42
 
54
- ASSET_REFERENCE_PROPERTIES: ClassVar[Set[tuple[AssetCentricType, str]]] = {
43
+ class TableName:
44
+ ASSET_ID = "assetId"
45
+ SOURCE_NAME = "source"
46
+ FILE_ID = "fileId"
47
+ ASSET_EXTERNAL_ID = "assetExternalId"
48
+ FILE_EXTERNAL_ID = "fileExternalId"
49
+
50
+ ASSET_ID_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {
55
51
  ("timeseries", "assetId"),
56
52
  ("file", "assetIds"),
57
53
  ("event", "assetIds"),
58
54
  ("sequence", "assetId"),
55
+ ("annotation", "data.assetRef.id"),
59
56
  ("asset", "parentId"),
60
- ("fileAnnotation", "data.assetRef.id"),
61
57
  }
62
- SOURCE_REFERENCE_PROPERTIES: ClassVar[Set[tuple[AssetCentricType, str]]] = {
58
+ SOURCE_NAME_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {
63
59
  ("asset", "source"),
64
60
  ("event", "source"),
65
61
  ("file", "source"),
66
62
  }
67
- FILE_REFERENCE_PROPERTIES: ClassVar[Set[tuple[AssetCentricType, str]]] = {
68
- ("fileAnnotation", "data.fileRef.id"),
69
- ("fileAnnotation", "annotatedResourceId"),
63
+ FILE_ID_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {
64
+ ("annotation", "data.fileRef.id"),
65
+ ("annotation", "annotatedResourceId"),
70
66
  }
67
+ ASSET_EXTERNAL_ID_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {("annotation", "data.assetRef.externalId")}
68
+ FILE_EXTERNAL_ID_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {("annotation", "data.fileRef.externalId")}
69
+
70
+ def __init__(self, client: ToolkitClient) -> None:
71
+ self._client = client
72
+ self._cache_map: dict[
73
+ tuple[str, str] | str, dict[str, DirectRelationReference] | dict[int, DirectRelationReference]
74
+ ] = {}
75
+ # Constructing the cache map to be accessed by both table name and property id
76
+ for table_name, properties in [
77
+ (self.TableName.ASSET_ID, self.ASSET_ID_PROPERTIES),
78
+ (self.TableName.SOURCE_NAME, self.SOURCE_NAME_PROPERTIES),
79
+ (self.TableName.FILE_ID, self.FILE_ID_PROPERTIES),
80
+ (self.TableName.ASSET_EXTERNAL_ID, self.ASSET_EXTERNAL_ID_PROPERTIES),
81
+ (self.TableName.FILE_EXTERNAL_ID, self.FILE_EXTERNAL_ID_PROPERTIES),
82
+ ]:
83
+ cache: dict[str, DirectRelationReference] | dict[int, DirectRelationReference] = {}
84
+ self._cache_map[table_name] = cache
85
+ for key in properties:
86
+ self._cache_map[key] = cache
87
+
88
+ def update(self, resources: Iterable[AssetCentricResourceExtended]) -> None:
89
+ """Update the cache with direct relation references for the given asset-centric resources.
90
+
91
+ This is used to bulk update the cache for a chunk of resources before converting them to data model instances.
92
+ """
93
+ asset_ids: set[int] = set()
94
+ source_ids: set[str] = set()
95
+ file_ids: set[int] = set()
96
+ asset_external_ids: set[str] = set()
97
+ file_external_ids: set[str] = set()
98
+ for resource in resources:
99
+ if isinstance(resource, Annotation):
100
+ if resource.annotated_resource_type == "file" and resource.annotated_resource_id:
101
+ file_ids.add(resource.annotated_resource_id)
102
+ if "assetRef" in resource.data:
103
+ asset_ref = resource.data["assetRef"]
104
+ if isinstance(asset_id := asset_ref.get("id"), int):
105
+ asset_ids.add(asset_id)
106
+ if isinstance(asset_external_id := asset_ref.get("externalId"), str):
107
+ asset_external_ids.add(asset_external_id)
108
+ if "fileRef" in resource.data:
109
+ file_ref = resource.data["fileRef"]
110
+ if isinstance(file_id := file_ref.get("id"), int):
111
+ file_ids.add(file_id)
112
+ if isinstance(file_external_id := file_ref.get("externalId"), str):
113
+ file_external_ids.add(file_external_id)
114
+ elif isinstance(resource, Asset):
115
+ if resource.source:
116
+ source_ids.add(resource.source)
117
+ if resource.parent_id is not None:
118
+ asset_ids.add(resource.parent_id)
119
+ elif isinstance(resource, FileMetadata):
120
+ if resource.source:
121
+ source_ids.add(resource.source)
122
+ if resource.asset_ids:
123
+ asset_ids.update(resource.asset_ids)
124
+ elif isinstance(resource, Event):
125
+ if resource.source:
126
+ source_ids.add(resource.source)
127
+ if resource.asset_ids:
128
+ asset_ids.update(resource.asset_ids)
129
+ elif isinstance(resource, TimeSeries):
130
+ if resource.asset_id is not None:
131
+ asset_ids.add(resource.asset_id)
132
+ if asset_ids:
133
+ self._update_cache(self._client.migration.lookup.assets(id=list(asset_ids)), self.TableName.ASSET_ID)
134
+ if source_ids:
135
+ # SourceSystems are not cached in the client, so we have to handle the caching ourselves.
136
+ cache = cast(dict[str, DirectRelationReference], self._cache_map[self.TableName.SOURCE_NAME])
137
+ missing = set(source_ids) - set(cache.keys())
138
+ if missing:
139
+ source_systems = self._client.migration.created_source_system.retrieve(list(missing))
140
+ for source_system in source_systems:
141
+ cache[source_system.source] = source_system.as_direct_relation_reference()
142
+ if file_ids:
143
+ self._update_cache(self._client.migration.lookup.files(id=list(file_ids)), self.TableName.FILE_ID)
144
+ if asset_external_ids:
145
+ self._update_cache(
146
+ self._client.migration.lookup.assets(external_id=list(asset_external_ids)),
147
+ self.TableName.ASSET_EXTERNAL_ID,
148
+ )
149
+ if file_external_ids:
150
+ self._update_cache(
151
+ self._client.migration.lookup.files(external_id=list(file_external_ids)),
152
+ self.TableName.FILE_EXTERNAL_ID,
153
+ )
71
154
 
72
- asset: Mapping[int, DirectRelationReference]
73
- source: Mapping[str, DirectRelationReference]
74
- file: Mapping[int, DirectRelationReference]
75
-
76
- def get(self, resource_type: AssetCentricType, property_id: str) -> Mapping[str | int, DirectRelationReference]:
77
- key = resource_type, property_id
78
- if key in self.ASSET_REFERENCE_PROPERTIES:
79
- return self.asset # type: ignore[return-value]
80
- if key in self.SOURCE_REFERENCE_PROPERTIES:
81
- return self.source # type: ignore[return-value]
82
- if key in self.FILE_REFERENCE_PROPERTIES:
83
- return self.file # type: ignore[return-value]
84
- return {}
85
-
86
-
87
- @overload
88
- def asset_centric_to_dm(
89
- resource: AssetCentricResourceExtended,
90
- instance_id: NodeId,
91
- view_source: ResourceViewMapping,
92
- view_properties: dict[str, ViewProperty],
93
- asset_instance_id_by_id: Mapping[int, DirectRelationReference],
94
- source_instance_id_by_external_id: Mapping[str, DirectRelationReference],
95
- file_instance_id_by_id: Mapping[int, DirectRelationReference],
96
- ) -> tuple[NodeApply | None, ConversionIssue]: ...
97
-
155
+ def _update_cache(self, instance_id_by_id: dict[int, NodeId] | dict[str, NodeId], table_name: str) -> None:
156
+ cache = self._cache_map[table_name]
157
+ for identifier, instance_id in instance_id_by_id.items():
158
+ cache[identifier] = DirectRelationReference(space=instance_id.space, external_id=instance_id.external_id) # type: ignore[index]
98
159
 
99
- @overload
100
- def asset_centric_to_dm(
101
- resource: AssetCentricResourceExtended,
102
- instance_id: EdgeId,
103
- view_source: ResourceViewMapping,
104
- view_properties: dict[str, ViewProperty],
105
- asset_instance_id_by_id: Mapping[int, DirectRelationReference],
106
- source_instance_id_by_external_id: Mapping[str, DirectRelationReference],
107
- file_instance_id_by_id: Mapping[int, DirectRelationReference],
108
- ) -> tuple[EdgeApply | None, ConversionIssue]: ...
160
+ def get_cache(
161
+ self, resource_type: AssetCentricTypeExtended, property_id: str
162
+ ) -> Mapping[str | int, DirectRelationReference] | None:
163
+ """Get the cache for the given resource type and property ID."""
164
+ return self._cache_map.get((resource_type, property_id)) # type: ignore[return-value]
109
165
 
110
166
 
111
167
  def asset_centric_to_dm(
112
168
  resource: AssetCentricResourceExtended,
113
- instance_id: NodeId | EdgeId,
114
- view_source: ResourceViewMapping,
169
+ instance_id: InstanceId,
170
+ view_source: ResourceViewMappingApply,
115
171
  view_properties: dict[str, ViewProperty],
116
- asset_instance_id_by_id: Mapping[int, DirectRelationReference],
117
- source_instance_id_by_external_id: Mapping[str, DirectRelationReference],
118
- file_instance_id_by_id: Mapping[int, DirectRelationReference],
172
+ direct_relation_cache: DirectRelationCache,
173
+ preferred_consumer_view: ViewId | None = None,
119
174
  ) -> tuple[NodeApply | EdgeApply | None, ConversionIssue]:
120
175
  """Convert an asset-centric resource to a data model instance.
121
176
 
122
177
  Args:
123
178
  resource (CogniteResource): The asset-centric resource to convert.
124
179
  instance_id (NodeId | EdgeApply): The ID of the instance to create or update.
125
- view_source (ResourceViewMapping): The view source defining how to map the resource to the data model.
180
+ view_source (ResourceViewMappingApply): The view source defining how to map the resource to the data model.
126
181
  view_properties (dict[str, ViewProperty]): The defined properties referenced in the view source mapping.
127
- asset_instance_id_by_id (dict[int, DirectRelationReference]): A mapping from asset IDs to their corresponding
128
- DirectRelationReference in the data model. This is used to create direct relations for resources that
129
- reference assets.
130
- source_instance_id_by_external_id (dict[str, DirectRelationReference]): A mapping from source strings to their
131
- corresponding DirectRelationReference in the data model. This is used to create direct relations for resources
132
- that reference sources.
133
- file_instance_id_by_id (dict[int, DirectRelationReference]): A mapping from file IDs to their corresponding
134
- DirectRelationReference in the data model. This is used to create direct relations for resources that
135
- reference files.
182
+ direct_relation_cache (DirectRelationCache): Cache for direct relation references.
183
+ preferred_consumer_view (ViewId | None): The preferred consumer view for the instance.
136
184
 
137
185
  Returns:
138
186
  tuple[NodeApply | EdgeApply, ConversionIssue]: A tuple containing the converted NodeApply and any ConversionIssue encountered.
139
187
  """
140
- cache = DirectRelationCache(
141
- asset=asset_instance_id_by_id, source=source_instance_id_by_external_id, file=file_instance_id_by_id
142
- )
143
188
  resource_type = _lookup_resource_type(resource)
144
189
  dumped = resource.dump()
145
190
  try:
@@ -159,25 +204,28 @@ def asset_centric_to_dm(
159
204
  view_source.property_mapping,
160
205
  resource_type,
161
206
  issue=issue,
162
- direct_relation_cache=cache,
207
+ direct_relation_cache=direct_relation_cache,
163
208
  )
164
209
  sources: list[NodeOrEdgeData] = []
165
210
  if properties:
166
211
  sources.append(NodeOrEdgeData(source=view_source.view_id, properties=properties))
167
212
 
168
- if resource_type != "fileAnnotation":
213
+ if resource_type != "annotation":
169
214
  instance_source_properties = {
170
215
  "resourceType": resource_type,
171
216
  "id": id_,
172
217
  "dataSetId": data_set_id,
173
218
  "classicExternalId": external_id,
219
+ "resourceViewMapping": {"space": COGNITE_MIGRATION_SPACE_ID, "externalId": view_source.external_id},
174
220
  }
221
+ if preferred_consumer_view:
222
+ instance_source_properties["preferredConsumerViewId"] = preferred_consumer_view.dump()
175
223
  sources.append(NodeOrEdgeData(source=INSTANCE_SOURCE_VIEW_ID, properties=instance_source_properties))
176
224
 
177
225
  instance: NodeApply | EdgeApply
178
226
  if isinstance(instance_id, EdgeId):
179
227
  edge_properties = create_edge_properties(
180
- dumped, view_source.property_mapping, resource_type, issue, cache, instance_id.space
228
+ dumped, view_source.property_mapping, resource_type, issue, direct_relation_cache, instance_id.space
181
229
  )
182
230
  if any(key not in edge_properties for key in ("start_node", "end_node", "type")):
183
231
  # Failed conversion of edge properties
@@ -196,7 +244,7 @@ def asset_centric_to_dm(
196
244
  return instance, issue
197
245
 
198
246
 
199
- def _lookup_resource_type(resource_type: AssetCentricResourceExtended) -> AssetCentricType:
247
+ def _lookup_resource_type(resource_type: AssetCentricResourceExtended) -> AssetCentricTypeExtended:
200
248
  if isinstance(resource_type, Asset):
201
249
  return "asset"
202
250
  elif isinstance(resource_type, FileMetadata):
@@ -210,7 +258,7 @@ def _lookup_resource_type(resource_type: AssetCentricResourceExtended) -> AssetC
210
258
  "diagrams.AssetLink",
211
259
  "diagrams.FileLink",
212
260
  ):
213
- return "fileAnnotation"
261
+ return "annotation"
214
262
  raise ValueError(f"Unsupported resource type: {resource_type}")
215
263
 
216
264
 
@@ -218,7 +266,7 @@ def create_properties(
218
266
  dumped: dict[str, Any],
219
267
  view_properties: dict[str, ViewProperty],
220
268
  property_mapping: dict[str, str],
221
- resource_type: AssetCentricType,
269
+ resource_type: AssetCentricTypeExtended,
222
270
  issue: ConversionIssue,
223
271
  direct_relation_cache: DirectRelationCache,
224
272
  ) -> dict[str, PropertyValueWrite]:
@@ -261,7 +309,7 @@ def create_properties(
261
309
  dm_prop.nullable,
262
310
  destination_container_property=(dm_prop.container, dm_prop.container_property_identifier),
263
311
  source_property=(resource_type, prop_json_path),
264
- direct_relation_lookup=direct_relation_cache.get(resource_type, prop_json_path),
312
+ direct_relation_lookup=direct_relation_cache.get_cache(resource_type, prop_json_path),
265
313
  )
266
314
  except (ValueError, TypeError, NotImplementedError) as e:
267
315
  issue.failed_conversions.append(
@@ -289,7 +337,7 @@ def create_properties(
289
337
  def create_edge_properties(
290
338
  dumped: dict[str, Any],
291
339
  property_mapping: dict[str, str],
292
- resource_type: AssetCentricType,
340
+ resource_type: AssetCentricTypeExtended,
293
341
  issue: ConversionIssue,
294
342
  direct_relation_cache: DirectRelationCache,
295
343
  default_instance_space: str,
@@ -309,7 +357,7 @@ def create_edge_properties(
309
357
  flatten_dump[prop_json_path],
310
358
  DirectRelation(),
311
359
  False,
312
- direct_relation_lookup=direct_relation_cache.get(resource_type, prop_json_path),
360
+ direct_relation_lookup=direct_relation_cache.get_cache(resource_type, prop_json_path),
313
361
  )
314
362
  except (ValueError, TypeError, NotImplementedError) as e:
315
363
  issue.failed_conversions.append(
@@ -20,7 +20,7 @@ from cognite.client.data_classes.documents import SourceFileProperty
20
20
  from cognite.client.data_classes.events import EventProperty
21
21
 
22
22
  from cognite_toolkit._cdf_tk.client import ToolkitClient
23
- from cognite_toolkit._cdf_tk.client.data_classes.apm_config_v1 import APMConfig, APMConfigList
23
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.apm_config_v1 import APMConfig, APMConfigList
24
24
  from cognite_toolkit._cdf_tk.cruds import NodeCRUD, ResourceCRUD, SpaceCRUD
25
25
  from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitRequiredValueError
26
26
  from cognite_toolkit._cdf_tk.utils import humanize_collection
@@ -1,26 +1,32 @@
1
1
  from dataclasses import dataclass
2
2
  from pathlib import Path
3
- from typing import Any, Generic, Literal
3
+ from typing import Annotated, Any, Generic, Literal
4
4
 
5
5
  from cognite.client.data_classes._base import (
6
6
  WriteableCogniteResource,
7
7
  WriteableCogniteResourceList,
8
8
  )
9
- from cognite.client.data_classes.data_modeling import InstanceApply, NodeId, ViewId
9
+ from cognite.client.data_classes.data_modeling import EdgeId, InstanceApply, NodeId, ViewId
10
+ from cognite.client.utils._identifier import InstanceId
10
11
  from cognite.client.utils._text import to_camel_case
11
- from pydantic import BaseModel, field_validator, model_validator
12
-
13
- from cognite_toolkit._cdf_tk.client.data_classes.instances import InstanceApplyList
14
- from cognite_toolkit._cdf_tk.client.data_classes.migration import AssetCentricId
15
- from cognite_toolkit._cdf_tk.client.data_classes.pending_instances_ids import PendingInstanceId
16
- from cognite_toolkit._cdf_tk.commands._migrate.default_mappings import create_default_mappings
12
+ from pydantic import BaseModel, BeforeValidator, Field, field_validator, model_validator
13
+
14
+ from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestResource
15
+ from cognite_toolkit._cdf_tk.client.data_classes.instance_api import InstanceIdentifier
16
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.instances import InstanceApplyList
17
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.migration import AssetCentricId
18
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.pending_instances_ids import PendingInstanceId
19
+ from cognite_toolkit._cdf_tk.commands._migrate.default_mappings import (
20
+ ASSET_ANNOTATIONS_ID,
21
+ FILE_ANNOTATIONS_ID,
22
+ create_default_mappings,
23
+ )
17
24
  from cognite_toolkit._cdf_tk.exceptions import ToolkitValueError
18
25
  from cognite_toolkit._cdf_tk.storageio._data_classes import ModelList
19
26
  from cognite_toolkit._cdf_tk.utils.useful_types import (
20
- AssetCentricKind,
21
- AssetCentricType,
27
+ AssetCentricKindExtended,
22
28
  JsonVal,
23
- T_AssetCentricResource,
29
+ T_AssetCentricResourceExtended,
24
30
  )
25
31
 
26
32
 
@@ -37,8 +43,8 @@ class MigrationMapping(BaseModel, alias_generator=to_camel_case, extra="ignore",
37
43
  for example, the Canvas migration to determine which view to use for the resource.
38
44
  """
39
45
 
40
- resource_type: AssetCentricType
41
- instance_id: NodeId
46
+ resource_type: str
47
+ instance_id: InstanceId
42
48
  id: int
43
49
  data_set_id: int | None = None
44
50
  ingestion_view: str | None = None
@@ -56,7 +62,8 @@ class MigrationMapping(BaseModel, alias_generator=to_camel_case, extra="ignore",
56
62
  raise ToolkitValueError(f"No default ingestion view specified for resource type '{self.resource_type}'")
57
63
 
58
64
  def as_asset_centric_id(self) -> AssetCentricId:
59
- return AssetCentricId(resource_type=self.resource_type, id_=self.id)
65
+ # MyPy fails to understand that resource_type is AssetCentricKindExtended in subclasses
66
+ return AssetCentricId(resource_type=self.resource_type, id_=self.id) # type: ignore[arg-type]
60
67
 
61
68
  @model_validator(mode="before")
62
69
  def _handle_flat_dict(cls, values: Any) -> Any:
@@ -87,12 +94,6 @@ class MigrationMapping(BaseModel, alias_generator=to_camel_case, extra="ignore",
87
94
  return ViewId.load(v)
88
95
  return v
89
96
 
90
- @field_validator("instance_id", mode="before")
91
- def _validate_instance_id(cls, v: Any) -> Any:
92
- if isinstance(v, dict):
93
- return NodeId.load(v)
94
- return v
95
-
96
97
 
97
98
  class MigrationMappingList(ModelList[MigrationMapping]):
98
99
  @classmethod
@@ -113,14 +114,22 @@ class MigrationMappingList(ModelList[MigrationMapping]):
113
114
 
114
115
  def as_node_ids(self) -> list[NodeId]:
115
116
  """Return a list of NodeIds from the migration mappings."""
116
- return [mapping.instance_id for mapping in self]
117
+ return [mapping.instance_id for mapping in self if isinstance(mapping.instance_id, NodeId)]
118
+
119
+ def as_edge_ids(self) -> list[EdgeId]:
120
+ """Return a list of EdgeIds from the migration mappings."""
121
+ return [mapping.instance_id for mapping in self if isinstance(mapping.instance_id, EdgeId)]
117
122
 
118
123
  def spaces(self) -> set[str]:
119
124
  """Return a set of spaces from the migration mappings."""
120
125
  return {mapping.instance_id.space for mapping in self}
121
126
 
122
127
  def as_pending_ids(self) -> list[PendingInstanceId]:
123
- return [PendingInstanceId(pending_instance_id=mapping.instance_id, id=mapping.id) for mapping in self]
128
+ return [
129
+ PendingInstanceId(pending_instance_id=mapping.instance_id, id=mapping.id)
130
+ for mapping in self
131
+ if isinstance(mapping.instance_id, NodeId)
132
+ ]
124
133
 
125
134
  def get_data_set_ids(self) -> set[int]:
126
135
  """Return a list of data set IDs from the migration mappings."""
@@ -131,7 +140,9 @@ class MigrationMappingList(ModelList[MigrationMapping]):
131
140
  return {mapping.id: mapping for mapping in self}
132
141
 
133
142
  @classmethod
134
- def read_csv_file(cls, filepath: Path, resource_type: AssetCentricKind | None = None) -> "MigrationMappingList":
143
+ def read_csv_file(
144
+ cls, filepath: Path, resource_type: AssetCentricKindExtended | None = None
145
+ ) -> "MigrationMappingList":
135
146
  if cls is not MigrationMappingList or resource_type is None:
136
147
  return super().read_csv_file(filepath)
137
148
  cls_by_resource_type: dict[str, type[MigrationMappingList]] = {
@@ -139,6 +150,7 @@ class MigrationMappingList(ModelList[MigrationMapping]):
139
150
  "TimeSeries": TimeSeriesMigrationMappingList,
140
151
  "FileMetadata": FileMigrationMappingList,
141
152
  "Events": EventMigrationMappingList,
153
+ "Annotations": AnnotationMigrationMappingList,
142
154
  }
143
155
  if resource_type not in cls_by_resource_type:
144
156
  raise ToolkitValueError(
@@ -147,20 +159,53 @@ class MigrationMappingList(ModelList[MigrationMapping]):
147
159
  return cls_by_resource_type[resource_type].read_csv_file(filepath, resource_type=None)
148
160
 
149
161
 
162
+ def _validate_node_id(value: Any) -> Any:
163
+ if isinstance(value, dict):
164
+ return NodeId.load(value)
165
+ return value
166
+
167
+
150
168
  class AssetMapping(MigrationMapping):
151
169
  resource_type: Literal["asset"] = "asset"
170
+ instance_id: Annotated[NodeId, BeforeValidator(_validate_node_id)]
152
171
 
153
172
 
154
173
  class EventMapping(MigrationMapping):
155
174
  resource_type: Literal["event"] = "event"
175
+ instance_id: Annotated[NodeId, BeforeValidator(_validate_node_id)]
156
176
 
157
177
 
158
178
  class TimeSeriesMapping(MigrationMapping):
159
179
  resource_type: Literal["timeseries"] = "timeseries"
180
+ instance_id: Annotated[NodeId, BeforeValidator(_validate_node_id)]
160
181
 
161
182
 
162
183
  class FileMapping(MigrationMapping):
163
184
  resource_type: Literal["file"] = "file"
185
+ instance_id: Annotated[NodeId, BeforeValidator(_validate_node_id)]
186
+
187
+
188
+ class AnnotationMapping(MigrationMapping):
189
+ resource_type: Literal["annotation"] = "annotation"
190
+ instance_id: EdgeId
191
+ annotation_type: Literal["diagrams.AssetLink", "diagrams.FileLink"] | None = None
192
+
193
+ def get_ingestion_view(self) -> str:
194
+ """Get the ingestion view for the mapping. If not specified, return the default ingestion view."""
195
+ if self.ingestion_view:
196
+ return self.ingestion_view
197
+ elif self.annotation_type == "diagrams.AssetLink":
198
+ return ASSET_ANNOTATIONS_ID
199
+ elif self.annotation_type == "diagrams.FileLink":
200
+ return FILE_ANNOTATIONS_ID
201
+ else:
202
+ raise ToolkitValueError("Cannot determine default ingestion view for annotation without annotation_type")
203
+
204
+ @field_validator("instance_id", mode="before")
205
+ def _validate_instance_id(cls, v: Any) -> Any:
206
+ if isinstance(v, dict):
207
+ return EdgeId.load(v)
208
+ return v
164
209
 
165
210
 
166
211
  class AssetMigrationMappingList(MigrationMappingList):
@@ -187,10 +232,16 @@ class TimeSeriesMigrationMappingList(MigrationMappingList):
187
232
  return TimeSeriesMapping
188
233
 
189
234
 
235
+ class AnnotationMigrationMappingList(MigrationMappingList):
236
+ @classmethod
237
+ def _get_base_model_cls(cls) -> type[AnnotationMapping]:
238
+ return AnnotationMapping
239
+
240
+
190
241
  @dataclass
191
- class AssetCentricMapping(Generic[T_AssetCentricResource], WriteableCogniteResource[InstanceApply]):
242
+ class AssetCentricMapping(Generic[T_AssetCentricResourceExtended], WriteableCogniteResource[InstanceApply]):
192
243
  mapping: MigrationMapping
193
- resource: T_AssetCentricResource
244
+ resource: T_AssetCentricResourceExtended
194
245
 
195
246
  def as_write(self) -> InstanceApply:
196
247
  raise NotImplementedError()
@@ -205,8 +256,39 @@ class AssetCentricMapping(Generic[T_AssetCentricResource], WriteableCogniteResou
205
256
  }
206
257
 
207
258
 
208
- class AssetCentricMappingList(WriteableCogniteResourceList[InstanceApply, AssetCentricMapping[T_AssetCentricResource]]):
259
+ class AssetCentricMappingList(
260
+ WriteableCogniteResourceList[InstanceApply, AssetCentricMapping[T_AssetCentricResourceExtended]]
261
+ ):
209
262
  _RESOURCE: type = AssetCentricMapping
210
263
 
211
264
  def as_write(self) -> InstanceApplyList:
212
265
  return InstanceApplyList([item.as_write() for item in self])
266
+
267
+
268
+ class Model(BaseModelObject):
269
+ instance_id: InstanceIdentifier
270
+
271
+
272
+ class Thumbnail(BaseModelObject):
273
+ instance_id: InstanceIdentifier
274
+
275
+
276
+ class ThreeDRevisionMigrationRequest(RequestResource):
277
+ space: str
278
+ type: Literal["CAD", "PointCloud", "Image360"]
279
+ revision_id: int
280
+ model: Model
281
+
282
+ def as_id(self) -> int:
283
+ return self.revision_id
284
+
285
+
286
+ class ThreeDMigrationRequest(RequestResource):
287
+ model_id: int
288
+ type: Literal["CAD", "PointCloud", "Image360"]
289
+ space: str
290
+ thumbnail: Thumbnail | None = None
291
+ revision: ThreeDRevisionMigrationRequest = Field(exclude=True)
292
+
293
+ def as_id(self) -> int:
294
+ return self.model_id