cognite-neat 0.87.4__py3-none-any.whl → 0.87.6__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/_version.py +1 -1
- cognite/neat/app/api/routers/rules.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_assets.py +8 -2
- cognite/neat/graph/extractors/_mock_graph_generator.py +2 -2
- cognite/neat/graph/loaders/_base.py +17 -12
- cognite/neat/graph/loaders/_rdf2asset.py +223 -58
- cognite/neat/graph/loaders/_rdf2dms.py +1 -1
- cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +2 -2
- cognite/neat/legacy/rules/models/rules.py +1 -1
- cognite/neat/rules/analysis/_asset.py +31 -1
- cognite/neat/rules/models/information/_rules.py +1 -1
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.87.6.dist-info}/METADATA +1 -1
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.87.6.dist-info}/RECORD +16 -16
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.87.6.dist-info}/LICENSE +0 -0
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.87.6.dist-info}/WHEEL +0 -0
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.87.6.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.87.
|
|
1
|
+
__version__ = "0.87.6"
|
|
@@ -166,7 +166,7 @@ def get_original_rules_from_workflow(workflow_name: str):
|
|
|
166
166
|
return {"error": f"Workflow {workflow_name} is not found"}
|
|
167
167
|
context = workflow.get_context()
|
|
168
168
|
rules_data = context["RulesData"]
|
|
169
|
-
if type(rules_data)
|
|
169
|
+
if type(rules_data) is not RulesData:
|
|
170
170
|
return {"error": "RulesData is not found in workflow context"}
|
|
171
171
|
|
|
172
172
|
return Response(content=rules_data.rules.model_dump_json(), media_type="application/json")
|
|
@@ -30,6 +30,8 @@ class AssetsExtractor(BaseExtractor):
|
|
|
30
30
|
limit the extraction to 1000 assets to test the setup.
|
|
31
31
|
unpack_metadata (bool, optional): Whether to unpack metadata. Defaults to False, which yields the metadata as
|
|
32
32
|
a JSON string.
|
|
33
|
+
skip_metadata_values (set[str] | frozenset[str] | None, optional): A set of values to skip when unpacking
|
|
34
|
+
metadata. Defaults to frozenset({"nan", "null", "none", ""}).
|
|
33
35
|
"""
|
|
34
36
|
|
|
35
37
|
_SPACE_PATTERN = re.compile(r"\s+")
|
|
@@ -42,6 +44,7 @@ class AssetsExtractor(BaseExtractor):
|
|
|
42
44
|
total: int | None = None,
|
|
43
45
|
limit: int | None = None,
|
|
44
46
|
unpack_metadata: bool = True,
|
|
47
|
+
skip_metadata_values: set[str] | frozenset[str] | None = frozenset({"nan", "null", "none", ""}),
|
|
45
48
|
):
|
|
46
49
|
self.namespace = namespace or DEFAULT_NAMESPACE
|
|
47
50
|
self.assets = assets
|
|
@@ -49,6 +52,7 @@ class AssetsExtractor(BaseExtractor):
|
|
|
49
52
|
self.total = total
|
|
50
53
|
self.limit = min(limit, total) if limit and total else limit
|
|
51
54
|
self.unpack_metadata = unpack_metadata
|
|
55
|
+
self.skip_metadata_values = skip_metadata_values
|
|
52
56
|
|
|
53
57
|
@classmethod
|
|
54
58
|
def from_dataset(
|
|
@@ -162,7 +166,7 @@ class AssetsExtractor(BaseExtractor):
|
|
|
162
166
|
if asset.source:
|
|
163
167
|
triples.append((id_, self.namespace.source, Literal(asset.source)))
|
|
164
168
|
|
|
165
|
-
# properties ref creation and update
|
|
169
|
+
# properties' ref creation and update
|
|
166
170
|
triples.append(
|
|
167
171
|
(
|
|
168
172
|
id_,
|
|
@@ -193,7 +197,9 @@ class AssetsExtractor(BaseExtractor):
|
|
|
193
197
|
if asset.metadata:
|
|
194
198
|
if self.unpack_metadata:
|
|
195
199
|
for key, value in asset.metadata.items():
|
|
196
|
-
if value
|
|
200
|
+
if value and (
|
|
201
|
+
self.skip_metadata_values is None or value.casefold() not in self.skip_metadata_values
|
|
202
|
+
):
|
|
197
203
|
triples.append(
|
|
198
204
|
(
|
|
199
205
|
id_,
|
|
@@ -250,9 +250,9 @@ def _generate_mock_data_property_triples(
|
|
|
250
250
|
python_type = value_type.python
|
|
251
251
|
triples = []
|
|
252
252
|
for id_ in instance_ids:
|
|
253
|
-
if python_type
|
|
253
|
+
if python_type is int:
|
|
254
254
|
triples.append((id_, URIRef(namespace[property_]), Literal(random.randint(1, 1983))))
|
|
255
|
-
elif python_type
|
|
255
|
+
elif python_type is float:
|
|
256
256
|
triples.append((id_, URIRef(namespace[property_]), Literal(numpy.float32(random.uniform(1, 1983)))))
|
|
257
257
|
# generate string
|
|
258
258
|
else:
|
|
@@ -48,18 +48,23 @@ class BaseLoader(ABC, Generic[T_Output]):
|
|
|
48
48
|
class CDFLoader(BaseLoader[T_Output]):
|
|
49
49
|
_UPLOAD_BATCH_SIZE: ClassVar[int] = 1000
|
|
50
50
|
|
|
51
|
-
def load_into_cdf(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
def load_into_cdf(
|
|
52
|
+
self, client: CogniteClient, dry_run: bool = False, check_client: bool = True
|
|
53
|
+
) -> UploadResultList:
|
|
54
|
+
return UploadResultList(self.load_into_cdf_iterable(client, dry_run, check_client))
|
|
55
|
+
|
|
56
|
+
def load_into_cdf_iterable(
|
|
57
|
+
self, client: CogniteClient, dry_run: bool = False, check_client: bool = True
|
|
58
|
+
) -> Iterable[UploadResult]:
|
|
59
|
+
if check_client:
|
|
60
|
+
missing_capabilities = client.iam.verify_capabilities(self._get_required_capabilities())
|
|
61
|
+
if missing_capabilities:
|
|
62
|
+
upload_result = UploadResult[Hashable](name=type(self).__name__)
|
|
63
|
+
upload_result.issues.append(
|
|
64
|
+
FailedAuthorizationError(action="Upload to CDF", reason=str(missing_capabilities))
|
|
65
|
+
)
|
|
66
|
+
yield upload_result
|
|
67
|
+
return
|
|
63
68
|
|
|
64
69
|
issues = NeatIssueList[NeatIssue]()
|
|
65
70
|
items: list[T_Output] = []
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from collections.abc import Iterable, Sequence
|
|
3
|
-
from dataclasses import dataclass, fields
|
|
4
3
|
from pathlib import Path
|
|
5
|
-
from typing import cast
|
|
4
|
+
from typing import Any, cast
|
|
6
5
|
|
|
7
6
|
import yaml
|
|
8
7
|
from cognite.client import CogniteClient
|
|
9
|
-
from cognite.client.data_classes import
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
from cognite.client.data_classes import (
|
|
9
|
+
AssetWrite,
|
|
10
|
+
LabelDefinitionWrite,
|
|
11
|
+
RelationshipWrite,
|
|
12
|
+
)
|
|
13
|
+
from cognite.client.data_classes.capabilities import (
|
|
14
|
+
AssetsAcl,
|
|
15
|
+
Capability,
|
|
16
|
+
RelationshipsAcl,
|
|
17
|
+
)
|
|
18
|
+
from cognite.client.exceptions import CogniteAPIError, CogniteDuplicatedError
|
|
12
19
|
|
|
13
20
|
from cognite.neat.graph._tracking.base import Tracker
|
|
14
21
|
from cognite.neat.graph._tracking.log import LogTracker
|
|
@@ -17,40 +24,15 @@ from cognite.neat.graph.stores import NeatGraphStore
|
|
|
17
24
|
from cognite.neat.issues import NeatIssue, NeatIssueList
|
|
18
25
|
from cognite.neat.rules.analysis._asset import AssetAnalysis
|
|
19
26
|
from cognite.neat.rules.models import AssetRules
|
|
27
|
+
from cognite.neat.rules.models.entities import ClassEntity, EntityTypes
|
|
28
|
+
from cognite.neat.utils.auxiliary import create_sha256_hash
|
|
20
29
|
from cognite.neat.utils.upload import UploadResult
|
|
21
30
|
|
|
22
31
|
from ._base import _END_OF_CLASS, CDFLoader
|
|
23
32
|
|
|
24
33
|
|
|
25
|
-
@dataclass(frozen=True)
|
|
26
|
-
class AssetLoaderMetadataKeys:
|
|
27
|
-
"""Class holding mapping between NEAT metadata key names and their desired names
|
|
28
|
-
in CDF Asset metadata
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
start_time: Start time key name
|
|
32
|
-
end_time: End time key name
|
|
33
|
-
update_time: Update time key name
|
|
34
|
-
resurrection_time: Resurrection time key name
|
|
35
|
-
identifier: Identifier key name
|
|
36
|
-
active: Active key name
|
|
37
|
-
type: Type key name
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
start_time: str = "start_time"
|
|
41
|
-
end_time: str = "end_time"
|
|
42
|
-
update_time: str = "update_time"
|
|
43
|
-
resurrection_time: str = "resurrection_time"
|
|
44
|
-
identifier: str = "identifier"
|
|
45
|
-
active: str = "active"
|
|
46
|
-
type: str = "type"
|
|
47
|
-
|
|
48
|
-
def as_aliases(self) -> dict[str, str]:
|
|
49
|
-
return {str(field.default): getattr(self, field.name) for field in fields(self)}
|
|
50
|
-
|
|
51
|
-
|
|
52
34
|
class AssetLoader(CDFLoader[AssetWrite]):
|
|
53
|
-
"""Load Assets from NeatGraph to Cognite Data Fusions.
|
|
35
|
+
"""Load Assets and their relationships from NeatGraph to Cognite Data Fusions.
|
|
54
36
|
|
|
55
37
|
Args:
|
|
56
38
|
graph_store (NeatGraphStore): The graph store to load the data into.
|
|
@@ -59,10 +41,7 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
59
41
|
use_orphanage (bool): Whether to use an orphanage for assets that are not part
|
|
60
42
|
of the hierarchy. Defaults to False.
|
|
61
43
|
use_labels (bool): Whether to use labels for assets. Defaults to False.
|
|
62
|
-
|
|
63
|
-
Defaults to None.
|
|
64
|
-
metadata_keys (AssetLoaderMetadataKeys | None): Mapping between NEAT metadata key names and
|
|
65
|
-
their desired names in CDF Asset metadata. Defaults to None.
|
|
44
|
+
external_id_prefix (str | None): The prefix to use for the external ids. Defaults to None.
|
|
66
45
|
create_issues (Sequence[NeatIssue] | None): A list of issues that occurred during reading. Defaults to None.
|
|
67
46
|
tracker (type[Tracker] | None): The tracker to use. Defaults to None.
|
|
68
47
|
"""
|
|
@@ -74,8 +53,7 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
74
53
|
data_set_id: int,
|
|
75
54
|
use_orphanage: bool = False,
|
|
76
55
|
use_labels: bool = False,
|
|
77
|
-
|
|
78
|
-
metadata_keys: AssetLoaderMetadataKeys | None = None,
|
|
56
|
+
external_id_prefix: str | None = None,
|
|
79
57
|
create_issues: Sequence[NeatIssue] | None = None,
|
|
80
58
|
tracker: type[Tracker] | None = None,
|
|
81
59
|
):
|
|
@@ -83,15 +61,14 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
83
61
|
|
|
84
62
|
self.rules = rules
|
|
85
63
|
self.data_set_id = data_set_id
|
|
64
|
+
|
|
86
65
|
self.use_labels = use_labels
|
|
87
66
|
|
|
88
67
|
self.orphanage = (
|
|
89
68
|
AssetWrite.load(
|
|
90
69
|
{
|
|
91
70
|
"dataSetId": self.data_set_id,
|
|
92
|
-
"externalId": (
|
|
93
|
-
f"{asset_external_id_prefix or ''}orphanage-{data_set_id}" if use_orphanage else None
|
|
94
|
-
),
|
|
71
|
+
"externalId": (f"{external_id_prefix or ''}orphanage-{data_set_id}" if use_orphanage else None),
|
|
95
72
|
"name": "Orphanage",
|
|
96
73
|
"description": "Orphanage for assets whose parents do not exist",
|
|
97
74
|
}
|
|
@@ -100,9 +77,9 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
100
77
|
else None
|
|
101
78
|
)
|
|
102
79
|
|
|
103
|
-
self.
|
|
104
|
-
self.metadata_keys = metadata_keys or AssetLoaderMetadataKeys()
|
|
80
|
+
self.external_id_prefix = external_id_prefix
|
|
105
81
|
|
|
82
|
+
self.processed_assets: set[str] = set()
|
|
106
83
|
self._issues = NeatIssueList[NeatIssue](create_issues or [])
|
|
107
84
|
self._tracker: type[Tracker] = tracker or LogTracker
|
|
108
85
|
|
|
@@ -124,27 +101,50 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
124
101
|
"classes",
|
|
125
102
|
)
|
|
126
103
|
|
|
127
|
-
|
|
104
|
+
if self.use_labels:
|
|
105
|
+
yield from self._create_labels()
|
|
128
106
|
|
|
129
107
|
if self.orphanage:
|
|
130
108
|
yield self.orphanage
|
|
131
|
-
|
|
109
|
+
self.processed_assets.add(cast(str, self.orphanage.external_id))
|
|
110
|
+
|
|
111
|
+
yield from self._create_assets(ordered_classes, tracker, stop_on_exception)
|
|
112
|
+
yield from self._create_relationship(ordered_classes, tracker, stop_on_exception)
|
|
113
|
+
|
|
114
|
+
def _create_labels(self) -> Iterable[Any]:
|
|
115
|
+
for label in AssetAnalysis(self.rules).define_labels():
|
|
116
|
+
yield LabelDefinitionWrite(name=label, external_id=label, data_set_id=self.data_set_id)
|
|
117
|
+
yield _END_OF_CLASS
|
|
132
118
|
|
|
119
|
+
def _create_assets(
|
|
120
|
+
self,
|
|
121
|
+
ordered_classes: list[ClassEntity],
|
|
122
|
+
tracker: Tracker,
|
|
123
|
+
stop_on_exception: bool,
|
|
124
|
+
) -> Iterable[Any]:
|
|
133
125
|
for class_ in ordered_classes:
|
|
134
126
|
tracker.start(repr(class_.id))
|
|
135
127
|
|
|
136
|
-
property_renaming_config = AssetAnalysis(self.rules).
|
|
128
|
+
property_renaming_config = AssetAnalysis(self.rules).define_asset_property_renaming_config(class_)
|
|
137
129
|
|
|
138
130
|
for identifier, properties in self.graph_store.read(class_.suffix):
|
|
139
|
-
|
|
131
|
+
identifier = f"{self.external_id_prefix or ''}{identifier}"
|
|
132
|
+
|
|
133
|
+
fields = _process_asset_properties(properties, property_renaming_config)
|
|
140
134
|
# set data set id and external id
|
|
141
135
|
fields["dataSetId"] = self.data_set_id
|
|
142
136
|
fields["externalId"] = identifier
|
|
143
137
|
|
|
138
|
+
if self.use_labels:
|
|
139
|
+
fields["labels"] = [class_.suffix]
|
|
140
|
+
|
|
141
|
+
if parent_external_id := fields.get("parentExternalId", None):
|
|
142
|
+
fields["parentExternalId"] = f"{self.external_id_prefix or ''}{parent_external_id}"
|
|
143
|
+
|
|
144
144
|
# check on parent
|
|
145
|
-
if "parentExternalId" in fields and fields["parentExternalId"] not in
|
|
145
|
+
if "parentExternalId" in fields and fields["parentExternalId"] not in self.processed_assets:
|
|
146
146
|
error = loader_issues.InvalidInstanceError(
|
|
147
|
-
type_=
|
|
147
|
+
type_=EntityTypes.asset,
|
|
148
148
|
identifier=identifier,
|
|
149
149
|
reason=(
|
|
150
150
|
f"Parent asset {fields['parentExternalId']} does not exist or failed creation"
|
|
@@ -169,9 +169,11 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
169
169
|
|
|
170
170
|
try:
|
|
171
171
|
yield AssetWrite.load(fields)
|
|
172
|
-
|
|
172
|
+
self.processed_assets.add(identifier)
|
|
173
173
|
except KeyError as e:
|
|
174
|
-
error = loader_issues.InvalidInstanceError(
|
|
174
|
+
error = loader_issues.InvalidInstanceError(
|
|
175
|
+
type_=EntityTypes.asset, identifier=identifier, reason=str(e)
|
|
176
|
+
)
|
|
175
177
|
tracker.issue(error)
|
|
176
178
|
if stop_on_exception:
|
|
177
179
|
raise error.as_exception() from e
|
|
@@ -179,6 +181,87 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
179
181
|
|
|
180
182
|
yield _END_OF_CLASS
|
|
181
183
|
|
|
184
|
+
def _create_relationship(
|
|
185
|
+
self,
|
|
186
|
+
ordered_classes: list[ClassEntity],
|
|
187
|
+
tracker: Tracker,
|
|
188
|
+
stop_on_exception: bool,
|
|
189
|
+
) -> Iterable[Any]:
|
|
190
|
+
for class_ in ordered_classes:
|
|
191
|
+
tracker.start(repr(class_.id))
|
|
192
|
+
|
|
193
|
+
property_renaming_config = AssetAnalysis(self.rules).define_relationship_property_renaming_config(class_)
|
|
194
|
+
|
|
195
|
+
# class does not have any relationship properties
|
|
196
|
+
if not property_renaming_config:
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
for source_external_id, properties in self.graph_store.read(class_.suffix):
|
|
200
|
+
relationships = _process_relationship_properties(properties, property_renaming_config)
|
|
201
|
+
|
|
202
|
+
source_external_id = f"{self.external_id_prefix or ''}{source_external_id}"
|
|
203
|
+
|
|
204
|
+
# check if source asset exists
|
|
205
|
+
if source_external_id not in self.processed_assets:
|
|
206
|
+
error = loader_issues.InvalidInstanceError(
|
|
207
|
+
type_=EntityTypes.relationship,
|
|
208
|
+
identifier=source_external_id,
|
|
209
|
+
reason=(
|
|
210
|
+
f"Asset {source_external_id} does not exist! "
|
|
211
|
+
"Aborting creation of relationships which use this asset as the source."
|
|
212
|
+
),
|
|
213
|
+
)
|
|
214
|
+
tracker.issue(error)
|
|
215
|
+
if stop_on_exception:
|
|
216
|
+
raise error.as_exception()
|
|
217
|
+
yield error
|
|
218
|
+
continue
|
|
219
|
+
|
|
220
|
+
for label, target_external_ids in relationships.items():
|
|
221
|
+
# we can have 1-many relationships
|
|
222
|
+
for target_external_id in target_external_ids:
|
|
223
|
+
target_external_id = f"{self.external_id_prefix or ''}{target_external_id}"
|
|
224
|
+
# check if source asset exists
|
|
225
|
+
if target_external_id not in self.processed_assets:
|
|
226
|
+
error = loader_issues.InvalidInstanceError(
|
|
227
|
+
type_=EntityTypes.relationship,
|
|
228
|
+
identifier=target_external_id,
|
|
229
|
+
reason=(
|
|
230
|
+
f"Asset {target_external_id} does not exist! "
|
|
231
|
+
f"Cannot create relationship between {source_external_id}"
|
|
232
|
+
f" and {target_external_id}. "
|
|
233
|
+
),
|
|
234
|
+
)
|
|
235
|
+
tracker.issue(error)
|
|
236
|
+
if stop_on_exception:
|
|
237
|
+
raise error.as_exception()
|
|
238
|
+
yield error
|
|
239
|
+
continue
|
|
240
|
+
|
|
241
|
+
external_id = "relationship_" + create_sha256_hash(f"{source_external_id}_{target_external_id}")
|
|
242
|
+
try:
|
|
243
|
+
yield RelationshipWrite(
|
|
244
|
+
external_id=external_id,
|
|
245
|
+
source_external_id=source_external_id,
|
|
246
|
+
target_external_id=target_external_id,
|
|
247
|
+
source_type="asset",
|
|
248
|
+
target_type="asset",
|
|
249
|
+
data_set_id=self.data_set_id,
|
|
250
|
+
labels=[label] if self.use_labels else None,
|
|
251
|
+
)
|
|
252
|
+
except KeyError as e:
|
|
253
|
+
error = loader_issues.InvalidInstanceError(
|
|
254
|
+
type_=EntityTypes.relationship,
|
|
255
|
+
identifier=external_id,
|
|
256
|
+
reason=str(e),
|
|
257
|
+
)
|
|
258
|
+
tracker.issue(error)
|
|
259
|
+
if stop_on_exception:
|
|
260
|
+
raise error.as_exception() from e
|
|
261
|
+
yield error
|
|
262
|
+
|
|
263
|
+
yield _END_OF_CLASS
|
|
264
|
+
|
|
182
265
|
def _get_required_capabilities(self) -> list[Capability]:
|
|
183
266
|
return [
|
|
184
267
|
AssetsAcl(
|
|
@@ -187,10 +270,58 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
187
270
|
AssetsAcl.Action.Read,
|
|
188
271
|
],
|
|
189
272
|
scope=AssetsAcl.Scope.DataSet([self.data_set_id]),
|
|
190
|
-
)
|
|
273
|
+
),
|
|
274
|
+
RelationshipsAcl(
|
|
275
|
+
actions=[
|
|
276
|
+
RelationshipsAcl.Action.Write,
|
|
277
|
+
RelationshipsAcl.Action.Read,
|
|
278
|
+
],
|
|
279
|
+
scope=RelationshipsAcl.Scope.DataSet([self.data_set_id]),
|
|
280
|
+
),
|
|
191
281
|
]
|
|
192
282
|
|
|
193
283
|
def _upload_to_cdf(
|
|
284
|
+
self,
|
|
285
|
+
client: CogniteClient,
|
|
286
|
+
items: list[AssetWrite] | list[RelationshipWrite] | list[LabelDefinitionWrite],
|
|
287
|
+
dry_run: bool,
|
|
288
|
+
read_issues: NeatIssueList,
|
|
289
|
+
) -> Iterable[UploadResult]:
|
|
290
|
+
if isinstance(items[0], AssetWrite) and all(isinstance(item, AssetWrite) for item in items):
|
|
291
|
+
yield from self._upload_assets_to_cdf(client, cast(list[AssetWrite], items), dry_run, read_issues)
|
|
292
|
+
elif isinstance(items[0], RelationshipWrite) and all(isinstance(item, RelationshipWrite) for item in items):
|
|
293
|
+
yield from self._upload_relationships_to_cdf(
|
|
294
|
+
client, cast(list[RelationshipWrite], items), dry_run, read_issues
|
|
295
|
+
)
|
|
296
|
+
elif isinstance(items[0], LabelDefinitionWrite) and all(
|
|
297
|
+
isinstance(item, LabelDefinitionWrite) for item in items
|
|
298
|
+
):
|
|
299
|
+
yield from self._upload_labels_to_cdf(client, cast(list[LabelDefinitionWrite], items), dry_run, read_issues)
|
|
300
|
+
else:
|
|
301
|
+
raise ValueError(f"Item {items[0]} is not supported. This is a bug in neat please report it.")
|
|
302
|
+
|
|
303
|
+
def _upload_labels_to_cdf(
|
|
304
|
+
self,
|
|
305
|
+
client: CogniteClient,
|
|
306
|
+
items: list[LabelDefinitionWrite],
|
|
307
|
+
dry_run: bool,
|
|
308
|
+
read_issues: NeatIssueList,
|
|
309
|
+
) -> Iterable[UploadResult]:
|
|
310
|
+
try:
|
|
311
|
+
created = client.labels.create(items)
|
|
312
|
+
except (CogniteAPIError, CogniteDuplicatedError) as e:
|
|
313
|
+
result = UploadResult[str](name="Label", issues=read_issues)
|
|
314
|
+
result.error_messages.append(str(e))
|
|
315
|
+
result.failed_created.update(item.external_id for item in e.failed + e.unknown)
|
|
316
|
+
result.created.update(item.external_id for item in e.successful)
|
|
317
|
+
yield result
|
|
318
|
+
else:
|
|
319
|
+
for label in created:
|
|
320
|
+
result = UploadResult[str](name="Label", issues=read_issues)
|
|
321
|
+
result.upserted.add(cast(str, label.external_id))
|
|
322
|
+
yield result
|
|
323
|
+
|
|
324
|
+
def _upload_assets_to_cdf(
|
|
194
325
|
self,
|
|
195
326
|
client: CogniteClient,
|
|
196
327
|
items: list[AssetWrite],
|
|
@@ -202,22 +333,44 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
202
333
|
except CogniteAPIError as e:
|
|
203
334
|
result = UploadResult[str](name="Asset", issues=read_issues)
|
|
204
335
|
result.error_messages.append(str(e))
|
|
205
|
-
result.failed_upserted.update(item.
|
|
206
|
-
result.upserted.update(item.
|
|
336
|
+
result.failed_upserted.update(item.external_id for item in e.failed + e.unknown)
|
|
337
|
+
result.upserted.update(item.external_id for item in e.successful)
|
|
207
338
|
yield result
|
|
208
339
|
else:
|
|
209
340
|
for asset in upserted:
|
|
210
|
-
result = UploadResult[str](name="
|
|
341
|
+
result = UploadResult[str](name="Asset", issues=read_issues)
|
|
211
342
|
result.upserted.add(cast(str, asset.external_id))
|
|
212
343
|
yield result
|
|
213
344
|
|
|
345
|
+
def _upload_relationships_to_cdf(
|
|
346
|
+
self,
|
|
347
|
+
client: CogniteClient,
|
|
348
|
+
items: list[RelationshipWrite],
|
|
349
|
+
dry_run: bool,
|
|
350
|
+
read_issues: NeatIssueList,
|
|
351
|
+
) -> Iterable[UploadResult]:
|
|
352
|
+
try:
|
|
353
|
+
upserted = client.relationships.upsert(items, mode="replace")
|
|
354
|
+
except CogniteAPIError as e:
|
|
355
|
+
result = UploadResult[str](name="Relationship", issues=read_issues)
|
|
356
|
+
result.error_messages.append(str(e))
|
|
357
|
+
result.failed_upserted.update(item.external_id for item in e.failed + e.unknown)
|
|
358
|
+
result.upserted.update(item.external_id for item in e.successful)
|
|
359
|
+
yield result
|
|
360
|
+
else:
|
|
361
|
+
for relationship in upserted:
|
|
362
|
+
result = UploadResult[str](name="relationship", issues=read_issues)
|
|
363
|
+
result.upserted.add(cast(str, relationship.external_id))
|
|
364
|
+
yield result
|
|
365
|
+
|
|
214
366
|
def write_to_file(self, filepath: Path) -> None:
|
|
215
367
|
if filepath.suffix not in [".json", ".yaml", ".yml"]:
|
|
216
368
|
raise ValueError(f"File format {filepath.suffix} is not supported")
|
|
217
|
-
dumped: dict[str, list] = {"assets": []}
|
|
369
|
+
dumped: dict[str, list] = {"assets": [], "relationship": []}
|
|
218
370
|
for item in self.load(stop_on_exception=False):
|
|
219
371
|
key = {
|
|
220
372
|
AssetWrite: "assets",
|
|
373
|
+
RelationshipWrite: "relationship",
|
|
221
374
|
NeatIssue: "issues",
|
|
222
375
|
_END_OF_CLASS: "end_of_class",
|
|
223
376
|
}.get(type(item))
|
|
@@ -234,7 +387,7 @@ class AssetLoader(CDFLoader[AssetWrite]):
|
|
|
234
387
|
yaml.safe_dump(dumped, f, sort_keys=False)
|
|
235
388
|
|
|
236
389
|
|
|
237
|
-
def
|
|
390
|
+
def _process_asset_properties(properties: dict[str, list[str]], property_renaming_config: dict[str, str]) -> dict:
|
|
238
391
|
metadata: dict[str, str] = {}
|
|
239
392
|
fields: dict[str, str | dict] = {}
|
|
240
393
|
|
|
@@ -251,3 +404,15 @@ def _process_properties(properties: dict[str, list[str]], property_renaming_conf
|
|
|
251
404
|
fields["metadata"] = metadata
|
|
252
405
|
|
|
253
406
|
return fields
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def _process_relationship_properties(
|
|
410
|
+
properties: dict[str, list[str]], property_renaming_config: dict[str, str]
|
|
411
|
+
) -> dict:
|
|
412
|
+
relationships: dict[str, list[str]] = {}
|
|
413
|
+
|
|
414
|
+
for original_property, values in properties.items():
|
|
415
|
+
if renamed_property := property_renaming_config.get(original_property, None):
|
|
416
|
+
relationships[renamed_property] = values
|
|
417
|
+
|
|
418
|
+
return relationships
|
|
@@ -34,7 +34,7 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
|
|
|
34
34
|
data_model (dm.DataModel[dm.View] | None): The data model to load.
|
|
35
35
|
instance_space (str): The instance space to load the data into.
|
|
36
36
|
class_by_view_id (dict[ViewId, str] | None): A mapping from view id to class name. Defaults to None.
|
|
37
|
-
|
|
37
|
+
create_issues (Sequence[NeatIssue] | None): A list of issues that occurred during reading. Defaults to None.
|
|
38
38
|
tracker (type[Tracker] | None): The tracker to use. Defaults to None.
|
|
39
39
|
"""
|
|
40
40
|
|
|
@@ -241,9 +241,9 @@ def _generate_mock_data_property_triples(
|
|
|
241
241
|
python_type = XSD_VALUE_TYPE_MAPPINGS[value_type].python
|
|
242
242
|
triples = []
|
|
243
243
|
for id_ in instance_ids:
|
|
244
|
-
if python_type
|
|
244
|
+
if python_type is int:
|
|
245
245
|
triples.append((id_, URIRef(namespace[property_]), Literal(random.randint(1, 1983))))
|
|
246
|
-
elif python_type
|
|
246
|
+
elif python_type is float:
|
|
247
247
|
triples.append((id_, URIRef(namespace[property_]), Literal(numpy.float32(random.uniform(1, 1983)))))
|
|
248
248
|
# generate string
|
|
249
249
|
else:
|
|
@@ -886,7 +886,7 @@ class Property(Resource):
|
|
|
886
886
|
if self.property_type == "DatatypeProperty" and self.default:
|
|
887
887
|
default_value = self.default[0] if isinstance(self.default, list) else self.default
|
|
888
888
|
|
|
889
|
-
if type(default_value)
|
|
889
|
+
if type(default_value) is not self.expected_value_type.python:
|
|
890
890
|
try:
|
|
891
891
|
if isinstance(self.default, list):
|
|
892
892
|
updated_list = []
|
|
@@ -128,7 +128,7 @@ class AssetAnalysis(BaseAnalysis[AssetRules, AssetClass, AssetProperty, ClassEnt
|
|
|
128
128
|
implementation_type=EntityTypes.relationship,
|
|
129
129
|
)
|
|
130
130
|
|
|
131
|
-
def
|
|
131
|
+
def define_asset_property_renaming_config(self, class_: ClassEntity) -> dict[str, str]:
|
|
132
132
|
property_renaming_configuration = {}
|
|
133
133
|
|
|
134
134
|
if asset_definition := self.asset_definition().get(class_, None):
|
|
@@ -141,3 +141,33 @@ class AssetAnalysis(BaseAnalysis[AssetRules, AssetClass, AssetProperty, ClassEnt
|
|
|
141
141
|
property_renaming_configuration[property_] = f"{asset_property}.{property_}"
|
|
142
142
|
|
|
143
143
|
return property_renaming_configuration
|
|
144
|
+
|
|
145
|
+
def define_relationship_property_renaming_config(self, class_: ClassEntity) -> dict[str, str]:
|
|
146
|
+
property_renaming_configuration = {}
|
|
147
|
+
|
|
148
|
+
if relationship_definition := self.relationship_definition().get(class_, None):
|
|
149
|
+
for property_, transformation in relationship_definition.items():
|
|
150
|
+
relationship = cast(list[RelationshipEntity], transformation.implementation)[0]
|
|
151
|
+
|
|
152
|
+
if relationship.label:
|
|
153
|
+
property_renaming_configuration[property_] = relationship.label
|
|
154
|
+
else:
|
|
155
|
+
property_renaming_configuration[property_] = property_
|
|
156
|
+
|
|
157
|
+
return property_renaming_configuration
|
|
158
|
+
|
|
159
|
+
def define_labels(self) -> set:
|
|
160
|
+
labels = set()
|
|
161
|
+
|
|
162
|
+
for _, properties in AssetAnalysis(self.rules).relationship_definition().items():
|
|
163
|
+
for property_, definition in properties.items():
|
|
164
|
+
labels.add(
|
|
165
|
+
cast(RelationshipEntity, definition.implementation[0]).label
|
|
166
|
+
if cast(RelationshipEntity, definition.implementation[0]).label
|
|
167
|
+
else property_
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
for class_ in AssetAnalysis(self.rules).asset_definition().keys():
|
|
171
|
+
labels.add(class_.suffix)
|
|
172
|
+
|
|
173
|
+
return labels
|
|
@@ -216,7 +216,7 @@ class InformationProperty(SheetEntity):
|
|
|
216
216
|
if self.type_ == EntityTypes.data_property and self.default:
|
|
217
217
|
default_value = self.default[0] if isinstance(self.default, list) else self.default
|
|
218
218
|
|
|
219
|
-
if type(default_value)
|
|
219
|
+
if type(default_value) is not self.value_type.python:
|
|
220
220
|
try:
|
|
221
221
|
if isinstance(self.default, list):
|
|
222
222
|
updated_list = []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=AiexNcHdAHFbrrbo9c65gtil1dqx_SGraDH1PSsXjKE,126
|
|
2
2
|
cognite/neat/_shared.py,sha256=RSaHm2eJceTlvb-hMMe4nHgoHdPYDfN3XcxDXo24k3A,1530
|
|
3
|
-
cognite/neat/_version.py,sha256=
|
|
3
|
+
cognite/neat/_version.py,sha256=zHK3D8i3mdcm2cU252645u9BQTB66eyTBLNGSit98n4,23
|
|
4
4
|
cognite/neat/app/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
cognite/neat/app/api/asgi/metrics.py,sha256=nxFy7L5cChTI0a-zkCiJ59Aq8yLuIJp5c9Dg0wRXtV0,152
|
|
6
6
|
cognite/neat/app/api/configuration.py,sha256=L1DCtLZ1HZku8I2z-JWd5RDsXhIsboFsKwAMhkrm-bY,3600
|
|
@@ -14,7 +14,7 @@ cognite/neat/app/api/routers/core.py,sha256=WznuQHzGkhBzf_GrHFiaSCXewBiQcrT4O6kY
|
|
|
14
14
|
cognite/neat/app/api/routers/crud.py,sha256=VCQMjvcLosELkmMZRiunyd-RK5sltQFjcCSrGk5kwXc,4597
|
|
15
15
|
cognite/neat/app/api/routers/data_exploration.py,sha256=xTE2nK8qfnG7iqIYa4KaLByi_EZPpD6NXQg5HQtqDcg,13703
|
|
16
16
|
cognite/neat/app/api/routers/metrics.py,sha256=S_bUQk_GjfQq7WbEhSVdow4MUYBZ_bZNafzgcKogXK8,210
|
|
17
|
-
cognite/neat/app/api/routers/rules.py,sha256=
|
|
17
|
+
cognite/neat/app/api/routers/rules.py,sha256=olITHs56xyGz7Lo7vOQWH3ju5iHtpy86vh4NzbVuxhQ,8125
|
|
18
18
|
cognite/neat/app/api/routers/workflows.py,sha256=fPqNT0swH-sfcjD8PLK5NzKY1sVSU7GaCMkHfH78gxw,12393
|
|
19
19
|
cognite/neat/app/api/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
cognite/neat/app/api/utils/data_mapping.py,sha256=ocqRyeCLbk3gS1NrQQnDr0w-q-xbkqV60uLZzsJIdyE,564
|
|
@@ -57,7 +57,7 @@ cognite/neat/graph/exceptions.py,sha256=R6pyOH774n9w2x_X_nrUr8OMAdjJMf_XPIqAvxIQ
|
|
|
57
57
|
cognite/neat/graph/extractors/__init__.py,sha256=nXcNp6i3-1HteIkr8Ujxk4b09W5jk27Q3eWuwjcnGnM,1647
|
|
58
58
|
cognite/neat/graph/extractors/_base.py,sha256=8IWygpkQTwo0UOmbbwWVI7540_klTVdUVX2JjVPFRIs,498
|
|
59
59
|
cognite/neat/graph/extractors/_classic_cdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
-
cognite/neat/graph/extractors/_classic_cdf/_assets.py,sha256=
|
|
60
|
+
cognite/neat/graph/extractors/_classic_cdf/_assets.py,sha256=saRtiT-TPvp3pzm-PBfyXf-bCWEEjhwWUel5SBesUvg,8344
|
|
61
61
|
cognite/neat/graph/extractors/_classic_cdf/_events.py,sha256=_XhfNcDVrxhPsQD6jgh3OZVhyzF-bjjrW3onePBUU-A,5113
|
|
62
62
|
cognite/neat/graph/extractors/_classic_cdf/_files.py,sha256=lP_y1HmF5rQ0Ufz4KL0fyPvM02Qv9Rvu6jwBZKyAsBY,6290
|
|
63
63
|
cognite/neat/graph/extractors/_classic_cdf/_labels.py,sha256=Cd2l_WWFypryTc3zB8z5upgxh4BVf-vWSH2G7plh9lo,3015
|
|
@@ -65,14 +65,14 @@ cognite/neat/graph/extractors/_classic_cdf/_relationships.py,sha256=zpJlRbx1Jx5J
|
|
|
65
65
|
cognite/neat/graph/extractors/_classic_cdf/_sequences.py,sha256=K6A_vZ_3HNI-51DSB23y9hhVajxCdkQKw3gv1TXIyuA,4681
|
|
66
66
|
cognite/neat/graph/extractors/_classic_cdf/_timeseries.py,sha256=5n73uLcA5l30zGZuPq6xSs6hti1Al2qnj3c3q7zkQQg,6126
|
|
67
67
|
cognite/neat/graph/extractors/_dexpi.py,sha256=Q3whJpEi3uFMzJGAAeUfgRnAzz6ZHmtuEdVBWqsZsTM,9384
|
|
68
|
-
cognite/neat/graph/extractors/_mock_graph_generator.py,sha256=
|
|
68
|
+
cognite/neat/graph/extractors/_mock_graph_generator.py,sha256=2qHh3fJxxAR9QdR6TPu-6DOvcjJkjHF4bwZN7lulziY,14678
|
|
69
69
|
cognite/neat/graph/extractors/_rdf_file.py,sha256=ialMCLv9WH5k6v1YMfozfcmAYhz8OVo9jVhsKMyQkDA,763
|
|
70
70
|
cognite/neat/graph/issues/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
71
|
cognite/neat/graph/issues/loader.py,sha256=v8YDsehkUT1QUG61JM9BDV_lqowMUnDmGmbay0aFzN4,3085
|
|
72
72
|
cognite/neat/graph/loaders/__init__.py,sha256=TbeJqifd16JLOglPVNOeb6pN_w060UYag50KquBM_r0,769
|
|
73
|
-
cognite/neat/graph/loaders/_base.py,sha256=
|
|
74
|
-
cognite/neat/graph/loaders/_rdf2asset.py,sha256=
|
|
75
|
-
cognite/neat/graph/loaders/_rdf2dms.py,sha256=
|
|
73
|
+
cognite/neat/graph/loaders/_base.py,sha256=497Jc1Gu3SmBpafUNTQ6fCAJz6dKq8HkweecdUmDsu4,3651
|
|
74
|
+
cognite/neat/graph/loaders/_rdf2asset.py,sha256=CqSXDcF4gVPSvE_9jy7yyuaCv-8HA9g0ld_2hqhnXug,17793
|
|
75
|
+
cognite/neat/graph/loaders/_rdf2dms.py,sha256=7HdFAVMORLaHIWzxKbm1DDGi45TcvqxXZYXYnggLYBI,14596
|
|
76
76
|
cognite/neat/graph/models.py,sha256=AtLgZh2qyRP6NRetjQCy9qLMuTQB0CH52Zsev-qa2sk,149
|
|
77
77
|
cognite/neat/graph/queries/__init__.py,sha256=BgDd-037kvtWwAoGAy8eORVNMiZ5-E9sIV0txIpeaN4,50
|
|
78
78
|
cognite/neat/graph/queries/_base.py,sha256=82WJMT2SreLCKq00hujrk2H5W_w_Rq53bJQTK7E_Bz4,8500
|
|
@@ -98,7 +98,7 @@ cognite/neat/legacy/graph/extractors/__init__.py,sha256=wqCiqz-sXhUpTL5LRcrl_KFT
|
|
|
98
98
|
cognite/neat/legacy/graph/extractors/_base.py,sha256=ohiuEzwZ1Fh9ers07MCbjGOGQ0HLb-ctwgEvGy7o_AQ,363
|
|
99
99
|
cognite/neat/legacy/graph/extractors/_dexpi.py,sha256=R4itgYxWUiPlZgRqUB4IrmLKzpsxhHrxSv7Gq4PeodM,1469
|
|
100
100
|
cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py,sha256=sEV6P4a4OlFx_O-vtKoB1H-ex1RnD5VhqmBcazGfLwk,17695
|
|
101
|
-
cognite/neat/legacy/graph/extractors/_mock_graph_generator.py,sha256=
|
|
101
|
+
cognite/neat/legacy/graph/extractors/_mock_graph_generator.py,sha256=rBWiQGPsEBmI31UNU3v8ZoJO8BvY2ybGUualCGjemxE,14955
|
|
102
102
|
cognite/neat/legacy/graph/loaders/__init__.py,sha256=Nap1LGaXA3AotL5U6pwY1Yc3J92Y7GC60qVPBhGl5LA,701
|
|
103
103
|
cognite/neat/legacy/graph/loaders/_asset_loader.py,sha256=mFYIF7bzwsV7RcEoNgObW5NRj-as7XUJBs97QpogGRU,23873
|
|
104
104
|
cognite/neat/legacy/graph/loaders/_base.py,sha256=oj1vo8dGPXxJORQXPa_kJa5G53VZBXOiIoWOngtMw5E,2383
|
|
@@ -167,7 +167,7 @@ cognite/neat/legacy/rules/models/__init__.py,sha256=23T73EaHuS0dsYTh6tww6gXAc7S4
|
|
|
167
167
|
cognite/neat/legacy/rules/models/_base.py,sha256=1WNXBJHJ3nwnVoeNhpm9B6TBuqWYYgChkrdK4FJIpQM,4989
|
|
168
168
|
cognite/neat/legacy/rules/models/raw_rules.py,sha256=o7iPhV7sS7h22edcyOpvJAQFPE7PiTULZAmGmZtKZPI,12491
|
|
169
169
|
cognite/neat/legacy/rules/models/rdfpath.py,sha256=iXEPnx0rdOzkJ68FoJmsWQBbMBABenQ_cyDlsqwPCBg,7351
|
|
170
|
-
cognite/neat/legacy/rules/models/rules.py,sha256=
|
|
170
|
+
cognite/neat/legacy/rules/models/rules.py,sha256=yBtUwpsd3CDJkTj6jBFPOTND-Q-wZkPiBX70b_2_4GU,51371
|
|
171
171
|
cognite/neat/legacy/rules/models/tables.py,sha256=hj7qjjIpwDXBnkVQrL47V2kjFxDz7aE4mkYOZTwepj8,171
|
|
172
172
|
cognite/neat/legacy/rules/models/value_types.py,sha256=wAjYe0yv90FgKqMjJITxyg4QgCYaolFVM9WAr7g0bJY,4402
|
|
173
173
|
cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml,sha256=dViI5aotf6cvcsePXjDBB_osyw1IUbNu2-rsGS1-5NM,1898
|
|
@@ -184,7 +184,7 @@ cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
184
184
|
cognite/neat/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
185
185
|
cognite/neat/rules/_shared.py,sha256=G0bIu5XSrtEa93qqtOS5P0IDJUkU32gX5ypFhcV6t5c,216
|
|
186
186
|
cognite/neat/rules/analysis/__init__.py,sha256=1qQXgddwSmRjC5s22XfQhsn8XPYfwAV_2n6lqeWJmKc,141
|
|
187
|
-
cognite/neat/rules/analysis/_asset.py,sha256=
|
|
187
|
+
cognite/neat/rules/analysis/_asset.py,sha256=SCiDatwDPi80jj41yQAp740irRWijMKEtAObkwKOKYs,7322
|
|
188
188
|
cognite/neat/rules/analysis/_base.py,sha256=jb9G2g59QaSZDwJmG1Kh9rq7CprvyrokTqfMytr0ZOk,16758
|
|
189
189
|
cognite/neat/rules/analysis/_information.py,sha256=TU9QbhtyhPVYqAxR-9L5awevl9i3q7x1Y25D5xb_Ciw,8085
|
|
190
190
|
cognite/neat/rules/examples/__init__.py,sha256=nxIwueAcHgZhkYriGxnDLQmIyiT8PByPHbScjYKDKe0,374
|
|
@@ -247,7 +247,7 @@ cognite/neat/rules/models/domain.py,sha256=qG1387w6E4XIviOb7EwAjMaavUUQBweYlmYrZ
|
|
|
247
247
|
cognite/neat/rules/models/entities.py,sha256=xYUNZ9nhU2y741xW6tqvF_JeQS1KsLi3YB-3zE0E79w,20771
|
|
248
248
|
cognite/neat/rules/models/information/__init__.py,sha256=HR6g8xgyU53U7Ck8pPdbT70817Q4NC1r1pCRq5SA8iw,291
|
|
249
249
|
cognite/neat/rules/models/information/_converter.py,sha256=J3mY5clqMY1PR_EmIT-GsTBJ16XCpHQG8EkQWvpqdnI,13930
|
|
250
|
-
cognite/neat/rules/models/information/_rules.py,sha256
|
|
250
|
+
cognite/neat/rules/models/information/_rules.py,sha256=-PYfsyQa7IqU8ziVZQkz6h2fl_VeVszVRq6c7zc5hEo,13476
|
|
251
251
|
cognite/neat/rules/models/information/_rules_input.py,sha256=AOTslaehKZH67VJaJO5bu8tT-1iSQz2uwf9mWFpK_44,10580
|
|
252
252
|
cognite/neat/rules/models/information/_serializer.py,sha256=yti9I_xJruxrib66YIBInhze___Io-oPTQH6uWDumPE,3503
|
|
253
253
|
cognite/neat/rules/models/information/_validation.py,sha256=rkDGbRHCLKyoZ6ooBZBfjDslouVUu9GXmfBcCorwxt4,8216
|
|
@@ -312,8 +312,8 @@ cognite/neat/workflows/steps_registry.py,sha256=fkTX14ZA7_gkUYfWIlx7A1XbCidvqR23
|
|
|
312
312
|
cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
|
|
313
313
|
cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
|
|
314
314
|
cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
|
|
315
|
-
cognite_neat-0.87.
|
|
316
|
-
cognite_neat-0.87.
|
|
317
|
-
cognite_neat-0.87.
|
|
318
|
-
cognite_neat-0.87.
|
|
319
|
-
cognite_neat-0.87.
|
|
315
|
+
cognite_neat-0.87.6.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
316
|
+
cognite_neat-0.87.6.dist-info/METADATA,sha256=652vw8eKhaR_1-682l1xl4ODE8CC89qx1jlIjRyxRXg,9493
|
|
317
|
+
cognite_neat-0.87.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
318
|
+
cognite_neat-0.87.6.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
|
|
319
|
+
cognite_neat-0.87.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|