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.
- cognite_toolkit/_cdf.py +21 -23
- cognite_toolkit/_cdf_tk/apps/__init__.py +4 -0
- cognite_toolkit/_cdf_tk/apps/_core_app.py +19 -5
- cognite_toolkit/_cdf_tk/apps/_data_app.py +1 -1
- cognite_toolkit/_cdf_tk/apps/_dev_app.py +86 -0
- cognite_toolkit/_cdf_tk/apps/_download_app.py +693 -25
- cognite_toolkit/_cdf_tk/apps/_dump_app.py +44 -102
- cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
- cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
- cognite_toolkit/_cdf_tk/apps/_migrate_app.py +424 -9
- cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
- cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
- cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
- cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
- cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
- cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
- cognite_toolkit/_cdf_tk/builders/_raw.py +1 -1
- cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py +32 -12
- cognite_toolkit/_cdf_tk/client/api/infield.py +114 -17
- cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
- cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
- cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +15 -18
- cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
- cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
- cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
- cognite_toolkit/_cdf_tk/client/api/migration.py +177 -4
- cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
- cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
- cognite_toolkit/_cdf_tk/client/api/streams.py +88 -0
- cognite_toolkit/_cdf_tk/client/api/three_d.py +384 -0
- cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +37 -33
- cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
- cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
- cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +18 -13
- cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
- cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +47 -4
- cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +3 -3
- cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/migration.py} +10 -2
- cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
- cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +112 -0
- cognite_toolkit/_cdf_tk/client/testing.py +42 -18
- cognite_toolkit/_cdf_tk/commands/__init__.py +7 -6
- cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
- cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
- cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
- cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +140 -92
- cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +108 -26
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +448 -45
- cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
- cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +6 -6
- cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +52 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +377 -11
- cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
- cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
- cognite_toolkit/_cdf_tk/commands/_purge.py +36 -39
- cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
- cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
- cognite_toolkit/_cdf_tk/commands/about.py +221 -0
- cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
- cognite_toolkit/_cdf_tk/commands/build_cmd.py +16 -62
- cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
- cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
- cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
- cognite_toolkit/_cdf_tk/commands/dump_resource.py +10 -8
- cognite_toolkit/_cdf_tk/commands/init.py +225 -3
- cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
- cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
- cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
- cognite_toolkit/_cdf_tk/commands/run.py +1 -1
- cognite_toolkit/_cdf_tk/constants.py +20 -1
- cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
- cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
- cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +10 -19
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +5 -15
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +45 -44
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +5 -12
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +206 -67
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +6 -18
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +126 -35
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +7 -28
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -30
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +4 -8
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +4 -16
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +5 -13
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +5 -11
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +16 -45
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +75 -32
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
- cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
- cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
- cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
- cognite_toolkit/_cdf_tk/plugins.py +2 -1
- cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
- cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
- cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
- cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
- cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
- cognite_toolkit/_cdf_tk/resource_classes/search_config.py +1 -1
- cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
- cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
- cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
- cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
- cognite_toolkit/_cdf_tk/storageio/_applications.py +340 -28
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
- cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
- cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
- cognite_toolkit/_cdf_tk/storageio/_file_content.py +435 -0
- cognite_toolkit/_cdf_tk/storageio/_instances.py +35 -3
- cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +71 -4
- cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
- cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
- cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py +34 -0
- cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
- cognite_toolkit/_cdf_tk/tracker.py +2 -2
- cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
- cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
- cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
- cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
- cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
- cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
- cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
- cognite_toolkit/_cdf_tk/utils/http_client/_client.py +285 -18
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +56 -4
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +247 -0
- cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
- cognite_toolkit/_cdf_tk/utils/interactive_select.py +60 -18
- cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
- cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
- cognite_toolkit/_cdf_tk/validation.py +83 -1
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
- cognite_toolkit/_resources/cdf.toml +5 -4
- cognite_toolkit/_version.py +1 -1
- cognite_toolkit/config.dev.yaml +13 -0
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/METADATA +24 -24
- cognite_toolkit-0.7.39.dist-info/RECORD +322 -0
- cognite_toolkit-0.7.39.dist-info/WHEEL +4 -0
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +1 -0
- cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
- cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
- cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
- cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
- cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
- cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
- cognite_toolkit-0.6.97.dist-info/RECORD +0 -306
- cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
- cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
- /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
- /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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
58
|
+
SOURCE_NAME_PROPERTIES: ClassVar[Set[tuple[str, str]]] = {
|
|
63
59
|
("asset", "source"),
|
|
64
60
|
("event", "source"),
|
|
65
61
|
("file", "source"),
|
|
66
62
|
}
|
|
67
|
-
|
|
68
|
-
("
|
|
69
|
-
("
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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:
|
|
114
|
-
view_source:
|
|
169
|
+
instance_id: InstanceId,
|
|
170
|
+
view_source: ResourceViewMappingApply,
|
|
115
171
|
view_properties: dict[str, ViewProperty],
|
|
116
|
-
|
|
117
|
-
|
|
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 (
|
|
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
|
-
|
|
128
|
-
|
|
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=
|
|
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 != "
|
|
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,
|
|
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) ->
|
|
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 "
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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.
|
|
14
|
-
from cognite_toolkit._cdf_tk.client.data_classes.
|
|
15
|
-
from cognite_toolkit._cdf_tk.client.data_classes.
|
|
16
|
-
from cognite_toolkit._cdf_tk.
|
|
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
|
-
|
|
21
|
-
AssetCentricType,
|
|
27
|
+
AssetCentricKindExtended,
|
|
22
28
|
JsonVal,
|
|
23
|
-
|
|
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:
|
|
41
|
-
instance_id:
|
|
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
|
-
|
|
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 [
|
|
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(
|
|
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[
|
|
242
|
+
class AssetCentricMapping(Generic[T_AssetCentricResourceExtended], WriteableCogniteResource[InstanceApply]):
|
|
192
243
|
mapping: MigrationMapping
|
|
193
|
-
resource:
|
|
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(
|
|
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
|