cognite-neat 0.98.0__py3-none-any.whl → 0.99.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/_client/__init__.py +4 -0
- cognite/neat/_client/_api/data_modeling_loaders.py +585 -0
- cognite/neat/_client/_api/schema.py +111 -0
- cognite/neat/_client/_api_client.py +17 -0
- cognite/neat/_client/data_classes/__init__.py +0 -0
- cognite/neat/{_utils/cdf/data_classes.py → _client/data_classes/data_modeling.py} +8 -135
- cognite/neat/_client/data_classes/schema.py +495 -0
- cognite/neat/_constants.py +27 -4
- cognite/neat/_graph/_shared.py +14 -15
- cognite/neat/_graph/extractors/_classic_cdf/_assets.py +14 -154
- cognite/neat/_graph/extractors/_classic_cdf/_base.py +154 -7
- cognite/neat/_graph/extractors/_classic_cdf/_classic.py +25 -14
- cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +17 -92
- cognite/neat/_graph/extractors/_classic_cdf/_events.py +13 -162
- cognite/neat/_graph/extractors/_classic_cdf/_files.py +15 -179
- cognite/neat/_graph/extractors/_classic_cdf/_labels.py +32 -100
- cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +27 -178
- cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +14 -139
- cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +15 -173
- cognite/neat/_graph/extractors/_rdf_file.py +6 -7
- cognite/neat/_graph/loaders/_rdf2dms.py +2 -2
- cognite/neat/_graph/queries/_base.py +17 -1
- cognite/neat/_graph/transformers/_classic_cdf.py +74 -147
- cognite/neat/_graph/transformers/_prune_graph.py +1 -1
- cognite/neat/_graph/transformers/_rdfpath.py +1 -1
- cognite/neat/_issues/_base.py +26 -17
- cognite/neat/_issues/errors/__init__.py +4 -2
- cognite/neat/_issues/errors/_external.py +7 -0
- cognite/neat/_issues/errors/_properties.py +2 -7
- cognite/neat/_issues/errors/_resources.py +1 -1
- cognite/neat/_issues/warnings/__init__.py +8 -0
- cognite/neat/_issues/warnings/_external.py +16 -0
- cognite/neat/_issues/warnings/_properties.py +16 -0
- cognite/neat/_issues/warnings/_resources.py +26 -2
- cognite/neat/_issues/warnings/user_modeling.py +4 -4
- cognite/neat/_rules/_constants.py +8 -11
- cognite/neat/_rules/analysis/_base.py +8 -4
- cognite/neat/_rules/exporters/_base.py +3 -4
- cognite/neat/_rules/exporters/_rules2dms.py +33 -46
- cognite/neat/_rules/importers/__init__.py +1 -3
- cognite/neat/_rules/importers/_base.py +1 -1
- cognite/neat/_rules/importers/_dms2rules.py +6 -29
- cognite/neat/_rules/importers/_rdf/__init__.py +5 -0
- cognite/neat/_rules/importers/_rdf/_base.py +34 -11
- cognite/neat/_rules/importers/_rdf/_imf2rules.py +91 -0
- cognite/neat/_rules/importers/_rdf/_inference2rules.py +43 -35
- cognite/neat/_rules/importers/_rdf/_owl2rules.py +80 -0
- cognite/neat/_rules/importers/_rdf/_shared.py +138 -441
- cognite/neat/_rules/models/__init__.py +1 -1
- cognite/neat/_rules/models/_base_rules.py +22 -12
- cognite/neat/_rules/models/dms/__init__.py +4 -2
- cognite/neat/_rules/models/dms/_exporter.py +45 -48
- cognite/neat/_rules/models/dms/_rules.py +20 -17
- cognite/neat/_rules/models/dms/_rules_input.py +52 -8
- cognite/neat/_rules/models/dms/_validation.py +391 -119
- cognite/neat/_rules/models/entities/_single_value.py +32 -4
- cognite/neat/_rules/models/information/__init__.py +2 -0
- cognite/neat/_rules/models/information/_rules.py +0 -67
- cognite/neat/_rules/models/information/_validation.py +9 -9
- cognite/neat/_rules/models/mapping/__init__.py +2 -3
- cognite/neat/_rules/models/mapping/_classic2core.py +36 -146
- cognite/neat/_rules/models/mapping/_classic2core.yaml +343 -0
- cognite/neat/_rules/transformers/__init__.py +2 -2
- cognite/neat/_rules/transformers/_converters.py +110 -11
- cognite/neat/_rules/transformers/_mapping.py +105 -30
- cognite/neat/_rules/transformers/_pipelines.py +1 -1
- cognite/neat/_rules/transformers/_verification.py +31 -3
- cognite/neat/_session/_base.py +24 -8
- cognite/neat/_session/_drop.py +35 -0
- cognite/neat/_session/_inspect.py +17 -5
- cognite/neat/_session/_mapping.py +39 -0
- cognite/neat/_session/_prepare.py +219 -23
- cognite/neat/_session/_read.py +49 -12
- cognite/neat/_session/_to.py +8 -5
- cognite/neat/_session/exceptions.py +4 -0
- cognite/neat/_store/_base.py +27 -24
- cognite/neat/_utils/rdf_.py +34 -5
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +5 -88
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +3 -14
- cognite/neat/_workflows/steps/lib/current/rules_validator.py +6 -7
- {cognite_neat-0.98.0.dist-info → cognite_neat-0.99.1.dist-info}/METADATA +3 -3
- {cognite_neat-0.98.0.dist-info → cognite_neat-0.99.1.dist-info}/RECORD +87 -92
- cognite/neat/_rules/importers/_rdf/_imf2rules/__init__.py +0 -3
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2classes.py +0 -86
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2metadata.py +0 -29
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2properties.py +0 -130
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2rules.py +0 -154
- cognite/neat/_rules/importers/_rdf/_owl2rules/__init__.py +0 -3
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2classes.py +0 -58
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2metadata.py +0 -65
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2properties.py +0 -59
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -39
- cognite/neat/_rules/models/dms/_schema.py +0 -1101
- cognite/neat/_rules/models/mapping/_base.py +0 -131
- cognite/neat/_utils/cdf/loaders/__init__.py +0 -25
- cognite/neat/_utils/cdf/loaders/_base.py +0 -54
- cognite/neat/_utils/cdf/loaders/_data_modeling.py +0 -339
- cognite/neat/_utils/cdf/loaders/_ingestion.py +0 -167
- /cognite/neat/{_utils/cdf → _client/_api}/__init__.py +0 -0
- {cognite_neat-0.98.0.dist-info → cognite_neat-0.99.1.dist-info}/LICENSE +0 -0
- {cognite_neat-0.98.0.dist-info → cognite_neat-0.99.1.dist-info}/WHEEL +0 -0
- {cognite_neat-0.98.0.dist-info → cognite_neat-0.99.1.dist-info}/entry_points.txt +0 -0
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
its sub-models and validators.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
|
|
7
5
|
import math
|
|
8
6
|
import sys
|
|
9
7
|
import types
|
|
@@ -39,13 +37,16 @@ from rdflib import Namespace, URIRef
|
|
|
39
37
|
|
|
40
38
|
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
41
39
|
from cognite.neat._rules.models._types import (
|
|
42
|
-
|
|
40
|
+
ContainerEntityType,
|
|
43
41
|
DataModelExternalIdType,
|
|
44
|
-
|
|
42
|
+
DmsPropertyType,
|
|
45
43
|
SpaceType,
|
|
46
44
|
StrListType,
|
|
47
45
|
VersionType,
|
|
46
|
+
ViewEntityType,
|
|
48
47
|
)
|
|
48
|
+
from cognite.neat._rules.models.data_types import DataType
|
|
49
|
+
from cognite.neat._rules.models.entities import EdgeEntity, ReverseConnectionEntity, ViewEntity
|
|
49
50
|
|
|
50
51
|
if sys.version_info >= (3, 11):
|
|
51
52
|
from enum import StrEnum
|
|
@@ -249,7 +250,7 @@ class BaseRules(SchemaModel, ABC):
|
|
|
249
250
|
"""Returns a list of headers for the model, typically used by ExcelExporter"""
|
|
250
251
|
headers_by_sheet: dict[str, list[str]] = {}
|
|
251
252
|
for field_name, field in cls.model_fields.items():
|
|
252
|
-
if field_name
|
|
253
|
+
if field_name in ["validators_to_skip", "post_validate"]:
|
|
253
254
|
continue
|
|
254
255
|
sheet_name = (field.alias or field_name) if by_alias else field_name
|
|
255
256
|
annotation = field.annotation
|
|
@@ -379,9 +380,9 @@ class SheetList(list, MutableSequence[T_SheetRow]):
|
|
|
379
380
|
def __getitem__(self, index: SupportsIndex) -> T_SheetRow: ...
|
|
380
381
|
|
|
381
382
|
@overload
|
|
382
|
-
def __getitem__(self, index: slice) -> SheetList[T_SheetRow]: ...
|
|
383
|
+
def __getitem__(self, index: slice) -> "SheetList[T_SheetRow]": ...
|
|
383
384
|
|
|
384
|
-
def __getitem__(self, index: SupportsIndex | slice, /) -> T_SheetRow | SheetList[T_SheetRow]:
|
|
385
|
+
def __getitem__(self, index: SupportsIndex | slice, /) -> "T_SheetRow | SheetList[T_SheetRow]":
|
|
385
386
|
if isinstance(index, slice):
|
|
386
387
|
return SheetList[T_SheetRow](super().__getitem__(index))
|
|
387
388
|
return super().__getitem__(index)
|
|
@@ -399,10 +400,19 @@ ExtensionCategoryType = Annotated[
|
|
|
399
400
|
|
|
400
401
|
|
|
401
402
|
# Immutable such that this can be used as a key in a dictionary
|
|
402
|
-
class
|
|
403
|
-
|
|
404
|
-
property_:
|
|
403
|
+
class ContainerProperty(BaseModel, frozen=True):
|
|
404
|
+
container: ContainerEntityType
|
|
405
|
+
property_: DmsPropertyType
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class ContainerDestinationProperty(ContainerProperty, frozen=True):
|
|
409
|
+
value_type: DataType | ViewEntity
|
|
410
|
+
connection: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None = None
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
class ViewRef(BaseModel, frozen=True):
|
|
414
|
+
view: ViewEntityType
|
|
405
415
|
|
|
406
416
|
|
|
407
|
-
class
|
|
408
|
-
|
|
417
|
+
class ViewProperty(ViewRef, frozen=True):
|
|
418
|
+
property_: DmsPropertyType
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from cognite.neat._client.data_classes.schema import DMSSchema
|
|
2
|
+
|
|
1
3
|
from ._rules import DMSContainer, DMSEnum, DMSMetadata, DMSNode, DMSProperty, DMSRules, DMSView
|
|
2
4
|
from ._rules_input import (
|
|
3
5
|
DMSInputContainer,
|
|
@@ -8,7 +10,7 @@ from ._rules_input import (
|
|
|
8
10
|
DMSInputRules,
|
|
9
11
|
DMSInputView,
|
|
10
12
|
)
|
|
11
|
-
from .
|
|
13
|
+
from ._validation import DMSValidation
|
|
12
14
|
|
|
13
15
|
__all__ = [
|
|
14
16
|
"DMSRules",
|
|
@@ -19,7 +21,6 @@ __all__ = [
|
|
|
19
21
|
"DMSContainer",
|
|
20
22
|
"DMSNode",
|
|
21
23
|
"DMSEnum",
|
|
22
|
-
"PipelineSchema",
|
|
23
24
|
"DMSInputRules",
|
|
24
25
|
"DMSInputMetadata",
|
|
25
26
|
"DMSInputView",
|
|
@@ -27,4 +28,5 @@ __all__ = [
|
|
|
27
28
|
"DMSInputContainer",
|
|
28
29
|
"DMSInputNode",
|
|
29
30
|
"DMSInputEnum",
|
|
31
|
+
"DMSValidation",
|
|
30
32
|
]
|
|
@@ -13,6 +13,14 @@ from cognite.client.data_classes.data_modeling.views import (
|
|
|
13
13
|
ViewPropertyApply,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
+
from cognite.neat._client.data_classes.data_modeling import (
|
|
17
|
+
ContainerApplyDict,
|
|
18
|
+
NodeApplyDict,
|
|
19
|
+
SpaceApplyDict,
|
|
20
|
+
ViewApplyDict,
|
|
21
|
+
)
|
|
22
|
+
from cognite.neat._client.data_classes.schema import DMSSchema
|
|
23
|
+
from cognite.neat._constants import COGNITE_SPACES
|
|
16
24
|
from cognite.neat._issues.errors import NeatTypeError, ResourceNotFoundError
|
|
17
25
|
from cognite.neat._issues.warnings import NotSupportedWarning, PropertyNotFoundWarning
|
|
18
26
|
from cognite.neat._issues.warnings.user_modeling import (
|
|
@@ -33,10 +41,8 @@ from cognite.neat._rules.models.entities import (
|
|
|
33
41
|
UnitEntity,
|
|
34
42
|
ViewEntity,
|
|
35
43
|
)
|
|
36
|
-
from cognite.neat._utils.cdf.data_classes import ContainerApplyDict, NodeApplyDict, SpaceApplyDict, ViewApplyDict
|
|
37
44
|
|
|
38
45
|
from ._rules import DMSEnum, DMSMetadata, DMSProperty, DMSRules, DMSView
|
|
39
|
-
from ._schema import DMSSchema, PipelineSchema
|
|
40
46
|
|
|
41
47
|
|
|
42
48
|
class _DMSExporter:
|
|
@@ -49,25 +55,13 @@ class _DMSExporter:
|
|
|
49
55
|
include_pipeline (bool): If True, the pipeline will be included with the schema. Pipeline means the
|
|
50
56
|
raw tables and transformations necessary to populate the data model.
|
|
51
57
|
instance_space (str): The space to use for the instance. Defaults to None,`Rules.metadata.space` will be used
|
|
58
|
+
remove_cdf_spaces(bool): The
|
|
52
59
|
"""
|
|
53
60
|
|
|
54
|
-
def __init__(
|
|
55
|
-
self,
|
|
56
|
-
rules: DMSRules,
|
|
57
|
-
include_pipeline: bool = False,
|
|
58
|
-
instance_space: str | None = None,
|
|
59
|
-
):
|
|
60
|
-
self.include_pipeline = include_pipeline
|
|
61
|
+
def __init__(self, rules: DMSRules, instance_space: str | None = None, remove_cdf_spaces: bool = False):
|
|
61
62
|
self.instance_space = instance_space
|
|
62
63
|
self.rules = rules
|
|
63
|
-
self.
|
|
64
|
-
if self._ref_schema:
|
|
65
|
-
# We skip version as that will always be missing in the reference
|
|
66
|
-
self._ref_views_by_id = {
|
|
67
|
-
dm.ViewId(view.space, view.external_id): view for view in self._ref_schema.views.values()
|
|
68
|
-
}
|
|
69
|
-
else:
|
|
70
|
-
self._ref_views_by_id = {} # type: ignore
|
|
64
|
+
self.remove_cdf_spaces = remove_cdf_spaces
|
|
71
65
|
|
|
72
66
|
def to_schema(self) -> DMSSchema:
|
|
73
67
|
rules = self.rules
|
|
@@ -79,44 +73,39 @@ class _DMSExporter:
|
|
|
79
73
|
view_properties_by_id, rules.views
|
|
80
74
|
)
|
|
81
75
|
|
|
82
|
-
views
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
views = self._create_views(view_properties_by_id, view_properties_with_ancestors_by_id)
|
|
77
|
+
view_node_type_filters: set[dm.NodeId] = set()
|
|
78
|
+
for dms_view in rules.views:
|
|
79
|
+
if isinstance(dms_view.filter_, NodeTypeFilter):
|
|
80
|
+
view_node_type_filters.update(node.as_id() for node in dms_view.filter_.inner or [])
|
|
85
81
|
if rules.nodes:
|
|
86
82
|
node_types = NodeApplyDict(
|
|
87
83
|
[node.as_node() for node in rules.nodes]
|
|
88
84
|
+ [dm.NodeApply(node.space, node.external_id) for node in view_node_type_filters]
|
|
89
85
|
)
|
|
90
86
|
else:
|
|
91
|
-
node_types = NodeApplyDict(
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
node_types = NodeApplyDict(
|
|
88
|
+
[
|
|
89
|
+
dm.NodeApply(node.space, node.external_id)
|
|
90
|
+
for node in view_node_type_filters
|
|
91
|
+
if not (self.remove_cdf_spaces and node.space in COGNITE_SPACES)
|
|
92
|
+
]
|
|
93
|
+
)
|
|
94
94
|
|
|
95
|
-
views_not_in_model = {view.view.as_id() for view in rules.views if not view.in_model}
|
|
96
95
|
data_model = rules.metadata.as_data_model()
|
|
97
|
-
|
|
98
|
-
data_model_views = [view_id for view_id in views if view_id not in views_not_in_model]
|
|
99
|
-
|
|
100
96
|
# Sorting to ensure deterministic order
|
|
101
|
-
data_model.views = sorted(
|
|
102
|
-
|
|
97
|
+
data_model.views = sorted(
|
|
98
|
+
[dms_view.view.as_id() for dms_view in rules.views if dms_view.in_model],
|
|
99
|
+
key=lambda x: x.as_tuple(), # type: ignore[union-attr]
|
|
100
|
+
)
|
|
103
101
|
spaces = self._create_spaces(rules.metadata, containers, views, data_model)
|
|
104
|
-
|
|
105
|
-
output = DMSSchema(
|
|
102
|
+
return DMSSchema(
|
|
106
103
|
spaces=spaces,
|
|
107
104
|
data_model=data_model,
|
|
108
105
|
views=views,
|
|
109
106
|
containers=containers,
|
|
110
107
|
node_types=node_types,
|
|
111
108
|
)
|
|
112
|
-
if self.include_pipeline:
|
|
113
|
-
return PipelineSchema.from_dms(output, self.instance_space)
|
|
114
|
-
|
|
115
|
-
if self._ref_schema:
|
|
116
|
-
output.reference = self._ref_schema
|
|
117
|
-
if last_schema:
|
|
118
|
-
output.last = last_schema
|
|
119
|
-
return output
|
|
120
109
|
|
|
121
110
|
def _create_spaces(
|
|
122
111
|
self,
|
|
@@ -137,14 +126,20 @@ class _DMSExporter:
|
|
|
137
126
|
spaces[self.instance_space] = dm.SpaceApply(space=self.instance_space, name=self.instance_space)
|
|
138
127
|
return spaces
|
|
139
128
|
|
|
140
|
-
def
|
|
129
|
+
def _create_views(
|
|
141
130
|
self,
|
|
142
131
|
view_properties_by_id: dict[dm.ViewId, list[DMSProperty]],
|
|
143
132
|
view_properties_with_ancestors_by_id: dict[dm.ViewId, list[DMSProperty]],
|
|
144
|
-
) ->
|
|
133
|
+
) -> ViewApplyDict:
|
|
145
134
|
input_views = list(self.rules.views)
|
|
146
135
|
|
|
147
|
-
views = ViewApplyDict(
|
|
136
|
+
views = ViewApplyDict(
|
|
137
|
+
[
|
|
138
|
+
dms_view.as_view()
|
|
139
|
+
for dms_view in input_views
|
|
140
|
+
if not (self.remove_cdf_spaces and dms_view.view.space in COGNITE_SPACES)
|
|
141
|
+
]
|
|
142
|
+
)
|
|
148
143
|
|
|
149
144
|
for view_id, view in views.items():
|
|
150
145
|
view.properties = {}
|
|
@@ -155,11 +150,7 @@ class _DMSExporter:
|
|
|
155
150
|
if view_property is not None:
|
|
156
151
|
view.properties[prop.view_property] = view_property
|
|
157
152
|
|
|
158
|
-
|
|
159
|
-
for view in views.values():
|
|
160
|
-
unique_node_types.add(dm.NodeId(space=view.space, external_id=view.external_id))
|
|
161
|
-
|
|
162
|
-
return views, unique_node_types
|
|
153
|
+
return views
|
|
163
154
|
|
|
164
155
|
@classmethod
|
|
165
156
|
def _create_edge_type_from_prop(cls, prop: DMSProperty) -> dm.DirectRelationReference:
|
|
@@ -189,7 +180,13 @@ class _DMSExporter:
|
|
|
189
180
|
|
|
190
181
|
containers = list(self.rules.containers or [])
|
|
191
182
|
|
|
192
|
-
containers = dm.ContainerApplyList(
|
|
183
|
+
containers = dm.ContainerApplyList(
|
|
184
|
+
[
|
|
185
|
+
dms_container.as_container()
|
|
186
|
+
for dms_container in containers
|
|
187
|
+
if not (self.remove_cdf_spaces and dms_container.container.space in COGNITE_SPACES)
|
|
188
|
+
]
|
|
189
|
+
)
|
|
193
190
|
container_to_drop = set()
|
|
194
191
|
for container in containers:
|
|
195
192
|
container_id = container.as_id()
|
|
@@ -4,22 +4,26 @@ from typing import Any, ClassVar, Literal
|
|
|
4
4
|
|
|
5
5
|
import pandas as pd
|
|
6
6
|
from cognite.client import data_modeling as dm
|
|
7
|
-
from pydantic import Field, field_serializer, field_validator
|
|
7
|
+
from pydantic import Field, field_serializer, field_validator
|
|
8
8
|
from pydantic_core.core_schema import SerializationInfo, ValidationInfo
|
|
9
9
|
from rdflib import URIRef
|
|
10
10
|
|
|
11
|
+
from cognite.neat._client.data_classes.schema import DMSSchema
|
|
11
12
|
from cognite.neat._constants import COGNITE_SPACES
|
|
12
|
-
from cognite.neat._issues import
|
|
13
|
+
from cognite.neat._issues.errors import NeatValueError
|
|
13
14
|
from cognite.neat._issues.warnings import (
|
|
14
15
|
PrincipleMatchingSpaceAndVersionWarning,
|
|
15
16
|
)
|
|
16
17
|
from cognite.neat._rules.models._base_rules import (
|
|
17
18
|
BaseMetadata,
|
|
18
19
|
BaseRules,
|
|
20
|
+
ContainerProperty,
|
|
19
21
|
DataModelAspect,
|
|
20
22
|
RoleTypes,
|
|
21
23
|
SheetList,
|
|
22
24
|
SheetRow,
|
|
25
|
+
ViewProperty,
|
|
26
|
+
ViewRef,
|
|
23
27
|
)
|
|
24
28
|
from cognite.neat._rules.models._types import (
|
|
25
29
|
ClassEntityType,
|
|
@@ -44,8 +48,6 @@ from cognite.neat._rules.models.entities import (
|
|
|
44
48
|
ViewEntityList,
|
|
45
49
|
)
|
|
46
50
|
|
|
47
|
-
from ._schema import DMSSchema
|
|
48
|
-
|
|
49
51
|
_DEFAULT_VERSION = "1"
|
|
50
52
|
|
|
51
53
|
|
|
@@ -180,6 +182,14 @@ class DMSProperty(SheetRow):
|
|
|
180
182
|
return value.dump(space=metadata.space, version=metadata.version, type=default_type)
|
|
181
183
|
return str(value)
|
|
182
184
|
|
|
185
|
+
def as_container_reference(self) -> ContainerProperty:
|
|
186
|
+
if self.container is None or self.container_property is None:
|
|
187
|
+
raise NeatValueError("Accessing container reference without container and container property set")
|
|
188
|
+
return ContainerProperty(container=self.container, property_=self.container_property)
|
|
189
|
+
|
|
190
|
+
def as_view_reference(self) -> ViewProperty:
|
|
191
|
+
return ViewProperty(view=self.view, property_=self.view_property)
|
|
192
|
+
|
|
183
193
|
|
|
184
194
|
class DMSContainer(SheetRow):
|
|
185
195
|
container: ContainerEntityType = Field(alias="Container")
|
|
@@ -272,10 +282,14 @@ class DMSView(SheetRow):
|
|
|
272
282
|
version=view_id.version or _DEFAULT_VERSION,
|
|
273
283
|
name=self.name or None,
|
|
274
284
|
description=self.description,
|
|
285
|
+
filter=None if self.filter_ is None else self.filter_.as_dms_filter(),
|
|
275
286
|
implements=implements,
|
|
276
287
|
properties={},
|
|
277
288
|
)
|
|
278
289
|
|
|
290
|
+
def as_view_reference(self) -> ViewRef:
|
|
291
|
+
return ViewRef(view=self.view)
|
|
292
|
+
|
|
279
293
|
|
|
280
294
|
class DMSNode(SheetRow):
|
|
281
295
|
node: DMSNodeEntity = Field(alias="Node")
|
|
@@ -356,21 +370,10 @@ class DMSRules(BaseRules):
|
|
|
356
370
|
)
|
|
357
371
|
return value
|
|
358
372
|
|
|
359
|
-
|
|
360
|
-
def post_validation(self) -> "DMSRules":
|
|
361
|
-
from ._validation import DMSPostValidation
|
|
362
|
-
|
|
363
|
-
issue_list = DMSPostValidation(self).validate()
|
|
364
|
-
if issue_list.warnings:
|
|
365
|
-
issue_list.trigger_warnings()
|
|
366
|
-
if issue_list.has_errors:
|
|
367
|
-
raise MultiValueError(issue_list.errors)
|
|
368
|
-
return self
|
|
369
|
-
|
|
370
|
-
def as_schema(self, include_pipeline: bool = False, instance_space: str | None = None) -> DMSSchema:
|
|
373
|
+
def as_schema(self, instance_space: str | None = None, remove_cdf_spaces: bool = False) -> DMSSchema:
|
|
371
374
|
from ._exporter import _DMSExporter
|
|
372
375
|
|
|
373
|
-
return _DMSExporter(self,
|
|
376
|
+
return _DMSExporter(self, instance_space, remove_cdf_spaces=remove_cdf_spaces).to_schema()
|
|
374
377
|
|
|
375
378
|
def _repr_html_(self) -> str:
|
|
376
379
|
summary = {
|
|
@@ -5,6 +5,7 @@ from typing import Any, Literal
|
|
|
5
5
|
|
|
6
6
|
import pandas as pd
|
|
7
7
|
from cognite.client import data_modeling as dm
|
|
8
|
+
from cognite.client.data_classes.data_modeling import ContainerId, ViewId
|
|
8
9
|
from rdflib import Namespace, URIRef
|
|
9
10
|
|
|
10
11
|
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
@@ -125,6 +126,12 @@ class DMSInputProperty(InputComponent[DMSProperty]):
|
|
|
125
126
|
)
|
|
126
127
|
return output
|
|
127
128
|
|
|
129
|
+
def referenced_view(self, default_space: str, default_version: str) -> ViewEntity:
|
|
130
|
+
return ViewEntity.load(self.view, strict=True, space=default_space, version=default_version)
|
|
131
|
+
|
|
132
|
+
def referenced_container(self, default_space: str) -> ContainerEntity | None:
|
|
133
|
+
return ContainerEntity.load(self.container, strict=True, space=default_space) if self.container else None
|
|
134
|
+
|
|
128
135
|
|
|
129
136
|
@dataclass
|
|
130
137
|
class DMSInputContainer(InputComponent[DMSContainer]):
|
|
@@ -140,8 +147,7 @@ class DMSInputContainer(InputComponent[DMSContainer]):
|
|
|
140
147
|
|
|
141
148
|
def dump(self, default_space: str) -> dict[str, Any]: # type: ignore[override]
|
|
142
149
|
output = super().dump()
|
|
143
|
-
|
|
144
|
-
output["Container"] = container
|
|
150
|
+
output["Container"] = self.as_entity_id(default_space)
|
|
145
151
|
output["Constraint"] = (
|
|
146
152
|
[ContainerEntity.load(constraint.strip(), space=default_space) for constraint in self.constraint.split(",")]
|
|
147
153
|
if self.constraint
|
|
@@ -149,6 +155,9 @@ class DMSInputContainer(InputComponent[DMSContainer]):
|
|
|
149
155
|
)
|
|
150
156
|
return output
|
|
151
157
|
|
|
158
|
+
def as_entity_id(self, default_space: str) -> ContainerEntity:
|
|
159
|
+
return ContainerEntity.load(self.container, strict=True, space=default_space)
|
|
160
|
+
|
|
152
161
|
@classmethod
|
|
153
162
|
def from_container(cls, container: dm.ContainerApply) -> "DMSInputContainer":
|
|
154
163
|
constraints: list[str] = []
|
|
@@ -172,7 +181,7 @@ class DMSInputView(InputComponent[DMSView]):
|
|
|
172
181
|
name: str | None = None
|
|
173
182
|
description: str | None = None
|
|
174
183
|
implements: str | None = None
|
|
175
|
-
filter_: Literal["hasData", "nodeType", "rawFilter"] | None = None
|
|
184
|
+
filter_: Literal["hasData", "nodeType", "rawFilter"] | str | None = None
|
|
176
185
|
in_model: bool = True
|
|
177
186
|
logical: str | None = None
|
|
178
187
|
|
|
@@ -182,17 +191,25 @@ class DMSInputView(InputComponent[DMSView]):
|
|
|
182
191
|
|
|
183
192
|
def dump(self, default_space: str, default_version: str) -> dict[str, Any]: # type: ignore[override]
|
|
184
193
|
output = super().dump()
|
|
185
|
-
|
|
186
|
-
output["
|
|
187
|
-
output
|
|
194
|
+
output["View"] = self.as_entity_id(default_space, default_version)
|
|
195
|
+
output["Implements"] = self._load_implements(default_space, default_version)
|
|
196
|
+
return output
|
|
197
|
+
|
|
198
|
+
def as_entity_id(self, default_space: str, default_version: str) -> ViewEntity:
|
|
199
|
+
return ViewEntity.load(self.view, strict=True, space=default_space, version=default_version)
|
|
200
|
+
|
|
201
|
+
def _load_implements(self, default_space: str, default_version: str) -> list[ViewEntity] | None:
|
|
202
|
+
return (
|
|
188
203
|
[
|
|
189
|
-
ViewEntity.load(implement, space=default_space, version=default_version)
|
|
204
|
+
ViewEntity.load(implement, strict=True, space=default_space, version=default_version)
|
|
190
205
|
for implement in self.implements.split(",")
|
|
191
206
|
]
|
|
192
207
|
if self.implements
|
|
193
208
|
else None
|
|
194
209
|
)
|
|
195
|
-
|
|
210
|
+
|
|
211
|
+
def referenced_views(self, default_space: str, default_version: str) -> list[ViewEntity]:
|
|
212
|
+
return self._load_implements(default_space, default_version) or []
|
|
196
213
|
|
|
197
214
|
@classmethod
|
|
198
215
|
def from_view(cls, view: dm.ViewApply, in_model: bool) -> "DMSInputView":
|
|
@@ -287,3 +304,30 @@ class DMSInputRules(InputRules[DMSRules]):
|
|
|
287
304
|
return DEFAULT_NAMESPACE[
|
|
288
305
|
f"data-model/unverified/dms/{self.metadata.space}/{self.metadata.external_id}/{self.metadata.version}"
|
|
289
306
|
]
|
|
307
|
+
|
|
308
|
+
def referenced_views_and_containers(self) -> tuple[set[ViewEntity], set[ContainerEntity]]:
|
|
309
|
+
default_space = self.metadata.space
|
|
310
|
+
default_version = self.metadata.version
|
|
311
|
+
|
|
312
|
+
containers: set[ContainerEntity] = set()
|
|
313
|
+
views = {parent for view in self.views for parent in view.referenced_views(default_space, default_version)}
|
|
314
|
+
for prop in self.properties:
|
|
315
|
+
views.add(prop.referenced_view(default_space, default_version))
|
|
316
|
+
if ref_container := prop.referenced_container(default_space):
|
|
317
|
+
containers.add(ref_container)
|
|
318
|
+
|
|
319
|
+
return views, containers
|
|
320
|
+
|
|
321
|
+
def as_view_entities(self) -> list[ViewEntity]:
|
|
322
|
+
return [view.as_entity_id(self.metadata.space, self.metadata.version) for view in self.views]
|
|
323
|
+
|
|
324
|
+
def as_container_entities(self) -> list[ContainerEntity]:
|
|
325
|
+
return [container.as_entity_id(self.metadata.space) for container in self.containers or []]
|
|
326
|
+
|
|
327
|
+
def imported_views_and_containers(self) -> tuple[set[ViewEntity], set[ContainerEntity]]:
|
|
328
|
+
views, containers = self.referenced_views_and_containers()
|
|
329
|
+
return views - set(self.as_view_entities()), containers - set(self.as_container_entities())
|
|
330
|
+
|
|
331
|
+
def imported_views_and_containers_ids(self) -> tuple[set[ViewId], set[ContainerId]]:
|
|
332
|
+
views, containers = self.imported_views_and_containers()
|
|
333
|
+
return {view.as_id() for view in views}, {container.as_id() for container in containers}
|