cognite-neat 0.97.3__py3-none-any.whl → 0.99.0__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 +512 -0
- cognite/neat/_client/_api/schema.py +50 -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/{_rules/models/dms/_schema.py → _client/data_classes/schema.py} +32 -281
- 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 +23 -12
- 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/__init__.py +1 -2
- cognite/neat/_graph/queries/_base.py +17 -1
- cognite/neat/_graph/transformers/_classic_cdf.py +50 -134
- cognite/neat/_graph/transformers/_prune_graph.py +1 -1
- cognite/neat/_graph/transformers/_rdfpath.py +1 -1
- cognite/neat/_issues/warnings/__init__.py +6 -0
- cognite/neat/_issues/warnings/_external.py +8 -0
- cognite/neat/_issues/warnings/_models.py +9 -0
- cognite/neat/_issues/warnings/_properties.py +16 -0
- cognite/neat/_rules/_constants.py +7 -6
- cognite/neat/_rules/_shared.py +3 -8
- cognite/neat/_rules/analysis/__init__.py +1 -2
- cognite/neat/_rules/analysis/_base.py +10 -27
- cognite/neat/_rules/analysis/_dms.py +4 -10
- cognite/neat/_rules/analysis/_information.py +2 -10
- cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
- cognite/neat/_rules/exporters/_base.py +3 -4
- cognite/neat/_rules/exporters/_rules2dms.py +29 -40
- cognite/neat/_rules/exporters/_rules2excel.py +15 -72
- cognite/neat/_rules/exporters/_rules2ontology.py +4 -4
- cognite/neat/_rules/importers/_base.py +3 -4
- cognite/neat/_rules/importers/_dms2rules.py +21 -45
- cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +1 -7
- cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +7 -10
- cognite/neat/_rules/importers/_rdf/_base.py +17 -29
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2classes.py +2 -2
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2metadata.py +5 -10
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2properties.py +1 -2
- cognite/neat/_rules/importers/_rdf/_inference2rules.py +55 -51
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2classes.py +2 -2
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2metadata.py +5 -8
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2properties.py +1 -2
- cognite/neat/_rules/importers/_rdf/_shared.py +25 -140
- cognite/neat/_rules/importers/_spreadsheet2rules.py +10 -41
- cognite/neat/_rules/models/__init__.py +3 -17
- cognite/neat/_rules/models/_base_rules.py +118 -62
- cognite/neat/_rules/models/dms/__init__.py +2 -2
- cognite/neat/_rules/models/dms/_exporter.py +20 -178
- cognite/neat/_rules/models/dms/_rules.py +65 -128
- cognite/neat/_rules/models/dms/_rules_input.py +72 -56
- cognite/neat/_rules/models/dms/_validation.py +16 -109
- cognite/neat/_rules/models/entities/_single_value.py +32 -4
- cognite/neat/_rules/models/information/_rules.py +19 -122
- cognite/neat/_rules/models/information/_rules_input.py +32 -41
- cognite/neat/_rules/models/information/_validation.py +34 -102
- 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 +339 -0
- cognite/neat/_rules/transformers/__init__.py +3 -6
- cognite/neat/_rules/transformers/_converters.py +128 -206
- cognite/neat/_rules/transformers/_mapping.py +105 -34
- cognite/neat/_rules/transformers/_verification.py +5 -16
- cognite/neat/_session/_base.py +83 -21
- cognite/neat/_session/_collector.py +126 -0
- cognite/neat/_session/_drop.py +35 -0
- cognite/neat/_session/_inspect.py +22 -10
- cognite/neat/_session/_mapping.py +39 -0
- cognite/neat/_session/_prepare.py +222 -27
- cognite/neat/_session/_read.py +109 -19
- cognite/neat/_session/_set.py +2 -2
- cognite/neat/_session/_show.py +11 -11
- cognite/neat/_session/_to.py +27 -14
- cognite/neat/_session/exceptions.py +20 -3
- cognite/neat/_store/_base.py +27 -24
- cognite/neat/_store/_provenance.py +2 -2
- cognite/neat/_utils/auxiliary.py +19 -0
- cognite/neat/_utils/rdf_.py +28 -1
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/steps/data_contracts.py +2 -10
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +14 -49
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +4 -1
- cognite/neat/_workflows/steps/lib/current/rules_validator.py +5 -9
- {cognite_neat-0.97.3.dist-info → cognite_neat-0.99.0.dist-info}/METADATA +4 -3
- {cognite_neat-0.97.3.dist-info → cognite_neat-0.99.0.dist-info}/RECORD +97 -100
- cognite/neat/_graph/loaders/_rdf2asset.py +0 -416
- cognite/neat/_rules/analysis/_asset.py +0 -173
- cognite/neat/_rules/models/asset/__init__.py +0 -13
- cognite/neat/_rules/models/asset/_rules.py +0 -109
- cognite/neat/_rules/models/asset/_rules_input.py +0 -101
- cognite/neat/_rules/models/asset/_validation.py +0 -45
- cognite/neat/_rules/models/domain.py +0 -136
- 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.97.3.dist-info → cognite_neat-0.99.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.97.3.dist-info → cognite_neat-0.99.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.97.3.dist-info → cognite_neat-0.99.0.dist-info}/entry_points.txt +0 -0
|
@@ -2,10 +2,9 @@ import datetime
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import pandas as pd
|
|
5
|
-
from rdflib import
|
|
5
|
+
from rdflib import Literal
|
|
6
6
|
|
|
7
7
|
from cognite.neat._rules._constants import PATTERNS
|
|
8
|
-
from cognite.neat._rules.models._base_rules import MatchType
|
|
9
8
|
from cognite.neat._rules.models.data_types import _XSD_TYPES
|
|
10
9
|
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
11
10
|
|
|
@@ -17,10 +16,7 @@ def parse_raw_classes_dataframe(query_results: list[tuple]) -> pd.DataFrame:
|
|
|
17
16
|
"Class",
|
|
18
17
|
"Name",
|
|
19
18
|
"Description",
|
|
20
|
-
"
|
|
21
|
-
"Reference",
|
|
22
|
-
"Match",
|
|
23
|
-
"Comment",
|
|
19
|
+
"Implements",
|
|
24
20
|
],
|
|
25
21
|
)
|
|
26
22
|
|
|
@@ -31,9 +27,8 @@ def parse_raw_classes_dataframe(query_results: list[tuple]) -> pd.DataFrame:
|
|
|
31
27
|
df.replace(np.nan, "", regex=True, inplace=True)
|
|
32
28
|
|
|
33
29
|
df.Class = df.Class.apply(lambda x: remove_namespace_from_uri(x))
|
|
34
|
-
df["Match Type"] = len(df) * [MatchType.exact]
|
|
35
30
|
df["Comment"] = len(df) * [None]
|
|
36
|
-
df["
|
|
31
|
+
df["Implements"] = df["Implements"].apply(lambda x: remove_namespace_from_uri(x))
|
|
37
32
|
|
|
38
33
|
return df
|
|
39
34
|
|
|
@@ -44,10 +39,7 @@ def clean_up_classes(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
44
39
|
"Class": class_,
|
|
45
40
|
"Name": group_df["Name"].unique()[0],
|
|
46
41
|
"Description": "\n".join(list(group_df.Description.unique())),
|
|
47
|
-
"
|
|
48
|
-
"Reference": group_df["Reference"].unique()[0],
|
|
49
|
-
"Match Type": group_df["Match Type"].unique()[0],
|
|
50
|
-
"Comment": group_df["Comment"].unique()[0],
|
|
42
|
+
"Implements": ", ".join(list(group_df["Implements"].unique())),
|
|
51
43
|
}
|
|
52
44
|
for class_, group_df in df.groupby("Class")
|
|
53
45
|
]
|
|
@@ -57,8 +49,8 @@ def clean_up_classes(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
57
49
|
# bring NaNs back
|
|
58
50
|
df.replace("", None, inplace=True)
|
|
59
51
|
|
|
60
|
-
# split
|
|
61
|
-
df["
|
|
52
|
+
# split Implements column back into list
|
|
53
|
+
df["Implements"] = df["Implements"].apply(lambda x: x.split(", ") if isinstance(x, str) else None)
|
|
62
54
|
|
|
63
55
|
return df
|
|
64
56
|
|
|
@@ -76,18 +68,6 @@ def make_classes_compliant(classes: pd.DataFrame, importer: str = "RDF-based") -
|
|
|
76
68
|
starts with a number, etc. This will cause issues when trying to create the class in CDF.
|
|
77
69
|
"""
|
|
78
70
|
|
|
79
|
-
# Replace empty or non-string values in "Match" column with "exact"
|
|
80
|
-
classes["Match Type"] = classes["Match Type"].fillna(MatchType.exact)
|
|
81
|
-
classes["Match Type"] = classes["Match Type"].apply(
|
|
82
|
-
lambda x: MatchType.exact if not isinstance(x, str) or len(x) == 0 else x
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
# Replace empty or non-string values in "Comment" column with a default value
|
|
86
|
-
classes["Comment"] = classes["Comment"].fillna(f"Imported using {importer} importer")
|
|
87
|
-
classes["Comment"] = classes["Comment"].apply(
|
|
88
|
-
lambda x: (f"Imported using {importer} importer" if not isinstance(x, str) or len(x) == 0 else x)
|
|
89
|
-
)
|
|
90
|
-
|
|
91
71
|
# Add _object_property_class, _data_type_property_class, _thing_class to the dataframe
|
|
92
72
|
classes = pd.concat(
|
|
93
73
|
[
|
|
@@ -114,10 +94,7 @@ def object_property_class() -> dict:
|
|
|
114
94
|
"Class": "ObjectProperty",
|
|
115
95
|
"Name": None,
|
|
116
96
|
"Description": "The class of object properties.",
|
|
117
|
-
"
|
|
118
|
-
"Reference": OWL.ObjectProperty,
|
|
119
|
-
"Match Type": MatchType.exact,
|
|
120
|
-
"Comment": "Added by NEAT based on owl:ObjectProperty but adapted to NEAT and use in CDF.",
|
|
97
|
+
"Implements": None,
|
|
121
98
|
}
|
|
122
99
|
|
|
123
100
|
|
|
@@ -126,10 +103,7 @@ def data_type_property_class() -> dict:
|
|
|
126
103
|
"Class": "DatatypeProperty",
|
|
127
104
|
"Name": None,
|
|
128
105
|
"Description": "The class of data properties.",
|
|
129
|
-
"
|
|
130
|
-
"Reference": OWL.DatatypeProperty,
|
|
131
|
-
"Match Type": MatchType.exact,
|
|
132
|
-
"Comment": "Added by NEAT based on owl:DatatypeProperty but adapted to NEAT and use in CDF.",
|
|
106
|
+
"Implements": None,
|
|
133
107
|
}
|
|
134
108
|
|
|
135
109
|
|
|
@@ -138,24 +112,13 @@ def thing_class() -> dict:
|
|
|
138
112
|
"Class": "Thing",
|
|
139
113
|
"Name": None,
|
|
140
114
|
"Description": "The class of holding class individuals.",
|
|
141
|
-
"
|
|
142
|
-
"Reference": OWL.Thing,
|
|
143
|
-
"Match Type": MatchType.exact,
|
|
144
|
-
"Comment": (
|
|
145
|
-
"Added by NEAT. "
|
|
146
|
-
"Imported from OWL base ontology, it is meant for use as a default"
|
|
147
|
-
" value type for object properties which miss a declared range."
|
|
148
|
-
),
|
|
115
|
+
"Implements": None,
|
|
149
116
|
}
|
|
150
117
|
|
|
151
118
|
|
|
152
119
|
def add_parent_class(df: pd.DataFrame) -> list[dict]:
|
|
153
120
|
parent_set = {
|
|
154
|
-
item
|
|
155
|
-
for sublist in df["Parent Class"].tolist()
|
|
156
|
-
if sublist
|
|
157
|
-
for item in sublist
|
|
158
|
-
if item != "" and item is not None
|
|
121
|
+
item for sublist in df["Implements"].tolist() if sublist for item in sublist if item != "" and item is not None
|
|
159
122
|
}
|
|
160
123
|
class_set = set(df["Class"].tolist())
|
|
161
124
|
|
|
@@ -166,14 +129,7 @@ def add_parent_class(df: pd.DataFrame) -> list[dict]:
|
|
|
166
129
|
"Class": missing_parent_class,
|
|
167
130
|
"Name": None,
|
|
168
131
|
"Description": None,
|
|
169
|
-
"
|
|
170
|
-
"Reference": None,
|
|
171
|
-
"Match Type": None,
|
|
172
|
-
"Comment": (
|
|
173
|
-
"Added by NEAT. "
|
|
174
|
-
"This is a parent class that is missing in the ontology. "
|
|
175
|
-
"It is added by NEAT to make the ontology compliant with CDF."
|
|
176
|
-
),
|
|
132
|
+
"Implements": None,
|
|
177
133
|
}
|
|
178
134
|
]
|
|
179
135
|
|
|
@@ -192,9 +148,6 @@ def parse_raw_properties_dataframe(query_results: list[tuple]) -> pd.DataFrame:
|
|
|
192
148
|
"Min Count",
|
|
193
149
|
"Max Count",
|
|
194
150
|
"Default",
|
|
195
|
-
"Reference",
|
|
196
|
-
"Match Type",
|
|
197
|
-
"Comment",
|
|
198
151
|
"_property_type",
|
|
199
152
|
],
|
|
200
153
|
)
|
|
@@ -206,8 +159,6 @@ def parse_raw_properties_dataframe(query_results: list[tuple]) -> pd.DataFrame:
|
|
|
206
159
|
df.Class = df.Class.apply(lambda x: remove_namespace_from_uri(x))
|
|
207
160
|
df.Property = df.Property.apply(lambda x: remove_namespace_from_uri(x))
|
|
208
161
|
df["Value Type"] = df["Value Type"].apply(lambda x: remove_namespace_from_uri(x))
|
|
209
|
-
df["Match Type"] = len(df) * [MatchType.exact]
|
|
210
|
-
df["Comment"] = len(df) * [None]
|
|
211
162
|
df["_property_type"] = df["_property_type"].apply(lambda x: remove_namespace_from_uri(x))
|
|
212
163
|
|
|
213
164
|
return df
|
|
@@ -231,9 +182,6 @@ def clean_up_properties(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
231
182
|
"Min Count": property_grouped_df["Min Count"].unique()[0],
|
|
232
183
|
"Max Count": property_grouped_df["Max Count"].unique()[0],
|
|
233
184
|
"Default": property_grouped_df["Default"].unique()[0],
|
|
234
|
-
"Reference": property_grouped_df["Reference"].unique()[0],
|
|
235
|
-
"Match Type": property_grouped_df["Match Type"].unique()[0],
|
|
236
|
-
"Comment": property_grouped_df["Comment"].unique()[0],
|
|
237
185
|
"_property_type": property_grouped_df["_property_type"].unique()[0],
|
|
238
186
|
}
|
|
239
187
|
]
|
|
@@ -251,18 +199,6 @@ def make_properties_compliant(properties: pd.DataFrame, importer: str = "RDF-bas
|
|
|
251
199
|
# default to 1 if "Max Count" is not specified
|
|
252
200
|
properties["Max Count"] = properties["Max Count"].apply(lambda x: 1 if not isinstance(x, Literal) or x == "" else x)
|
|
253
201
|
|
|
254
|
-
# Replace empty or non-string values in "Match Type" column with "exact"
|
|
255
|
-
properties["Match Type"] = properties["Match Type"].fillna("exact")
|
|
256
|
-
properties["Match Type"] = properties["Match Type"].apply(
|
|
257
|
-
lambda x: "exact" if not isinstance(x, str) or len(x) == 0 else x
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
# Replace empty or non-string values in "Comment" column with a default value
|
|
261
|
-
properties["Comment"] = properties["Comment"].fillna(f"Imported using {importer} importer")
|
|
262
|
-
properties["Comment"] = properties["Comment"].apply(
|
|
263
|
-
lambda x: (f"Imported using {importer} importer" if not isinstance(x, str) or len(x) == 0 else x)
|
|
264
|
-
)
|
|
265
|
-
|
|
266
202
|
# Reduce length of elements in the "Description" column to 1024 characters
|
|
267
203
|
properties["Description"] = properties["Description"].apply(lambda x: x[:1024] if isinstance(x, str) else None)
|
|
268
204
|
|
|
@@ -335,8 +271,7 @@ def make_metadata_compliant(metadata: dict) -> dict:
|
|
|
335
271
|
Dictionary containing metadata with fixed errors
|
|
336
272
|
"""
|
|
337
273
|
|
|
338
|
-
metadata =
|
|
339
|
-
metadata = fix_prefix(metadata)
|
|
274
|
+
metadata = fix_space(metadata)
|
|
340
275
|
metadata = fix_version(metadata)
|
|
341
276
|
metadata = fix_date(
|
|
342
277
|
metadata,
|
|
@@ -348,37 +283,13 @@ def make_metadata_compliant(metadata: dict) -> dict:
|
|
|
348
283
|
date_type="updated",
|
|
349
284
|
default=datetime.datetime.now().replace(microsecond=0),
|
|
350
285
|
)
|
|
351
|
-
metadata =
|
|
286
|
+
metadata = fix_name(metadata)
|
|
352
287
|
metadata = fix_description(metadata)
|
|
353
288
|
metadata = fix_author(metadata, "creator")
|
|
354
|
-
metadata = fix_rights(metadata)
|
|
355
|
-
metadata = fix_license(metadata)
|
|
356
289
|
|
|
357
290
|
return metadata
|
|
358
291
|
|
|
359
292
|
|
|
360
|
-
def fix_license(metadata: dict, default: str = "Unknown license") -> dict:
|
|
361
|
-
if license := metadata.get("license", None):
|
|
362
|
-
if not isinstance(license, str):
|
|
363
|
-
metadata["license"] = default
|
|
364
|
-
elif isinstance(license, str) and len(license) == 0:
|
|
365
|
-
metadata["license"] = default
|
|
366
|
-
else:
|
|
367
|
-
metadata["license"] = default
|
|
368
|
-
return metadata
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
def fix_rights(metadata: dict, default: str = "Unknown rights") -> dict:
|
|
372
|
-
if rights := metadata.get("rights", None):
|
|
373
|
-
if not isinstance(rights, str):
|
|
374
|
-
metadata["rights"] = default
|
|
375
|
-
elif isinstance(rights, str) and len(rights) == 0:
|
|
376
|
-
metadata["rights"] = default
|
|
377
|
-
else:
|
|
378
|
-
metadata["rights"] = default
|
|
379
|
-
return metadata
|
|
380
|
-
|
|
381
|
-
|
|
382
293
|
def fix_author(metadata: dict, author_type: str = "creator", default: str = "NEAT") -> dict:
|
|
383
294
|
if author := metadata.get(author_type, None):
|
|
384
295
|
if not isinstance(author, str) or isinstance(author, list):
|
|
@@ -401,25 +312,12 @@ def fix_description(metadata: dict, default: str = "This model has been inferred
|
|
|
401
312
|
return metadata
|
|
402
313
|
|
|
403
314
|
|
|
404
|
-
def
|
|
405
|
-
if
|
|
406
|
-
if not isinstance(
|
|
407
|
-
metadata["
|
|
315
|
+
def fix_space(metadata: dict, default: str = "neat") -> dict:
|
|
316
|
+
if space := metadata.get("space", None):
|
|
317
|
+
if not isinstance(space, str) or not PATTERNS.space_compliance.match(space):
|
|
318
|
+
metadata["space"] = default
|
|
408
319
|
else:
|
|
409
|
-
metadata["
|
|
410
|
-
return metadata
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
def fix_namespace(metadata: dict, default: Namespace) -> dict:
|
|
414
|
-
if namespace := metadata.get("namespace", None):
|
|
415
|
-
if not isinstance(namespace, Namespace):
|
|
416
|
-
try:
|
|
417
|
-
metadata["namespace"] = Namespace(namespace)
|
|
418
|
-
except Exception:
|
|
419
|
-
metadata["namespace"] = default
|
|
420
|
-
else:
|
|
421
|
-
metadata["namespace"] = default
|
|
422
|
-
|
|
320
|
+
metadata["space"] = default
|
|
423
321
|
return metadata
|
|
424
322
|
|
|
425
323
|
|
|
@@ -456,18 +354,18 @@ def fix_version(metadata: dict, default: str = "1.0.0") -> dict:
|
|
|
456
354
|
return metadata
|
|
457
355
|
|
|
458
356
|
|
|
459
|
-
def
|
|
460
|
-
if
|
|
461
|
-
if not isinstance(
|
|
357
|
+
def fix_name(metadata: dict, default: str = "OWL Inferred Data Model") -> dict:
|
|
358
|
+
if name := metadata.get("name", None):
|
|
359
|
+
if not isinstance(name, str):
|
|
462
360
|
metadata["title"] = default
|
|
463
|
-
elif isinstance(
|
|
361
|
+
elif isinstance(name, str) and len(name) == 0:
|
|
464
362
|
metadata["title"] = default
|
|
465
|
-
elif isinstance(
|
|
363
|
+
elif isinstance(name, str) and len(name) > 255:
|
|
466
364
|
metadata["title"] = metadata["title"][:255]
|
|
467
365
|
else:
|
|
468
366
|
pass
|
|
469
367
|
else:
|
|
470
|
-
metadata["
|
|
368
|
+
metadata["name"] = default
|
|
471
369
|
|
|
472
370
|
return metadata
|
|
473
371
|
|
|
@@ -539,11 +437,6 @@ def add_missing_value_types(components: dict) -> dict:
|
|
|
539
437
|
components["Classes"].append(
|
|
540
438
|
{
|
|
541
439
|
"Class": class_,
|
|
542
|
-
"Comment": (
|
|
543
|
-
"Added by NEAT. "
|
|
544
|
-
"This is a class that a domain of a property but was not defined in the ontology. "
|
|
545
|
-
"It is added by NEAT to make the ontology compliant with CDF."
|
|
546
|
-
),
|
|
547
440
|
}
|
|
548
441
|
)
|
|
549
442
|
|
|
@@ -561,25 +454,17 @@ def add_default_property_to_dangling_classes(components: dict[str, list[dict]])
|
|
|
561
454
|
"""
|
|
562
455
|
|
|
563
456
|
dangling_classes = {
|
|
564
|
-
definition["Class"] for definition in components["Classes"] if not definition.get("
|
|
457
|
+
definition["Class"] for definition in components["Classes"] if not definition.get("Implements", None)
|
|
565
458
|
} - {definition["Class"] for definition in components["Properties"]}
|
|
566
459
|
|
|
567
|
-
comment = (
|
|
568
|
-
"Added by NEAT. "
|
|
569
|
-
"This is property has been added to this class since otherwise it will create "
|
|
570
|
-
"dangling classes in the ontology."
|
|
571
|
-
)
|
|
572
|
-
|
|
573
460
|
for class_ in dangling_classes:
|
|
574
461
|
components["Properties"].append(
|
|
575
462
|
{
|
|
576
463
|
"Class": class_,
|
|
577
464
|
"Property": "label",
|
|
578
465
|
"Value Type": "string",
|
|
579
|
-
"Comment": comment,
|
|
580
466
|
"Min Count": 0,
|
|
581
467
|
"Max Count": 1,
|
|
582
|
-
"Reference": "http://www.w3.org/2000/01/rdf-schema#label",
|
|
583
468
|
}
|
|
584
469
|
)
|
|
585
470
|
|
|
@@ -18,7 +18,6 @@ from cognite.neat._issues.errors import (
|
|
|
18
18
|
FileMissingRequiredFieldError,
|
|
19
19
|
FileNotFoundNeatError,
|
|
20
20
|
FileReadError,
|
|
21
|
-
PropertyDefinitionDuplicatedError,
|
|
22
21
|
)
|
|
23
22
|
from cognite.neat._issues.warnings import FileMissingRequiredFieldWarning
|
|
24
23
|
from cognite.neat._rules._shared import ReadRules, T_InputRules
|
|
@@ -38,9 +37,7 @@ SOURCE_SHEET__TARGET_FIELD__HEADERS = [
|
|
|
38
37
|
"Properties",
|
|
39
38
|
"Properties",
|
|
40
39
|
{
|
|
41
|
-
RoleTypes.domain_expert: "Property",
|
|
42
40
|
RoleTypes.information: "Property",
|
|
43
|
-
RoleTypes.asset: "Property",
|
|
44
41
|
RoleTypes.dms: "View Property",
|
|
45
42
|
},
|
|
46
43
|
),
|
|
@@ -51,8 +48,17 @@ SOURCE_SHEET__TARGET_FIELD__HEADERS = [
|
|
|
51
48
|
("Nodes", "Nodes", "Node"),
|
|
52
49
|
]
|
|
53
50
|
|
|
51
|
+
|
|
54
52
|
MANDATORY_SHEETS_BY_ROLE: dict[RoleTypes, set[str]] = {
|
|
55
|
-
role_type: {
|
|
53
|
+
role_type: {
|
|
54
|
+
str(sheet_name)
|
|
55
|
+
for sheet_name in (
|
|
56
|
+
VERIFIED_RULES_BY_ROLE.get(role_type).mandatory_fields(use_alias=True) # type: ignore
|
|
57
|
+
if VERIFIED_RULES_BY_ROLE.get(role_type)
|
|
58
|
+
else []
|
|
59
|
+
)
|
|
60
|
+
if sheet_name is not None
|
|
61
|
+
}
|
|
56
62
|
for role_type in RoleTypes.__members__.values()
|
|
57
63
|
}
|
|
58
64
|
|
|
@@ -85,10 +91,6 @@ class MetadataRaw(UserDict):
|
|
|
85
91
|
issue_list.append(FileMissingRequiredFieldError(filepath, "metadata", "role"))
|
|
86
92
|
return False
|
|
87
93
|
|
|
88
|
-
# check if there is a schema field if role is not domain expert
|
|
89
|
-
if self.role != RoleTypes.domain_expert and not self.has_schema_field:
|
|
90
|
-
issue_list.append(FileMissingRequiredFieldError(filepath, "metadata", "schema"))
|
|
91
|
-
return False
|
|
92
94
|
return True
|
|
93
95
|
|
|
94
96
|
|
|
@@ -261,45 +263,12 @@ class ExcelImporter(BaseImporter[T_InputRules]):
|
|
|
261
263
|
if user_read is None or issue_list.has_errors:
|
|
262
264
|
return ReadRules(None, issue_list, {})
|
|
263
265
|
|
|
264
|
-
last_read: ReadResult | None = None
|
|
265
|
-
if any(sheet_name.startswith("Last") for sheet_name in user_reader.seen_sheets):
|
|
266
|
-
last_read = SpreadsheetReader(issue_list, required=False, sheet_prefix="Last").read(
|
|
267
|
-
excel_file, self.filepath
|
|
268
|
-
)
|
|
269
|
-
reference_read: ReadResult | None = None
|
|
270
|
-
if any(sheet_name.startswith("Ref") for sheet_name in user_reader.seen_sheets):
|
|
271
|
-
reference_read = SpreadsheetReader(issue_list, sheet_prefix="Ref").read(excel_file, self.filepath)
|
|
272
|
-
elif any(sheet_name.startswith("CDMRef") for sheet_name in user_reader.seen_sheets):
|
|
273
|
-
reference_read = SpreadsheetReader(issue_list, sheet_prefix="CDMRef").read(excel_file, self.filepath)
|
|
274
|
-
|
|
275
266
|
if issue_list.has_errors:
|
|
276
267
|
return ReadRules(None, issue_list, {})
|
|
277
268
|
|
|
278
|
-
if reference_read and user_read.role != reference_read.role:
|
|
279
|
-
issue_list.append(
|
|
280
|
-
PropertyDefinitionDuplicatedError(
|
|
281
|
-
self.filepath.as_posix(),
|
|
282
|
-
"spreadsheet.metadata", # type: ignore[arg-type]
|
|
283
|
-
"role",
|
|
284
|
-
frozenset({user_read.role, reference_read.role}),
|
|
285
|
-
("user", "reference"),
|
|
286
|
-
"sheet",
|
|
287
|
-
)
|
|
288
|
-
)
|
|
289
|
-
return ReadRules(None, issue_list, {})
|
|
290
|
-
|
|
291
269
|
sheets = user_read.sheets
|
|
292
270
|
original_role = user_read.role
|
|
293
271
|
read_info_by_sheet = user_read.read_info_by_sheet
|
|
294
|
-
if last_read:
|
|
295
|
-
sheets["last"] = last_read.sheets
|
|
296
|
-
read_info_by_sheet.update(last_read.read_info_by_sheet)
|
|
297
|
-
if reference_read:
|
|
298
|
-
# The last rules will also be validated against the reference rules
|
|
299
|
-
sheets["last"]["reference"] = reference_read.sheets # type: ignore[call-overload]
|
|
300
|
-
if reference_read:
|
|
301
|
-
sheets["reference"] = reference_read.sheets
|
|
302
|
-
read_info_by_sheet.update(reference_read.read_info_by_sheet)
|
|
303
272
|
|
|
304
273
|
rules_cls = INPUT_RULES_BY_ROLE[original_role]
|
|
305
274
|
rules = cast(T_InputRules, rules_cls.load(sheets))
|
|
@@ -1,39 +1,25 @@
|
|
|
1
|
-
from cognite.neat.
|
|
2
|
-
from cognite.neat._rules.models.asset._rules_input import AssetInputRules
|
|
3
|
-
from cognite.neat._rules.models.domain import DomainInputRules, DomainRules
|
|
1
|
+
from cognite.neat._client.data_classes.schema import DMSSchema
|
|
4
2
|
from cognite.neat._rules.models.information._rules import InformationRules
|
|
5
3
|
from cognite.neat._rules.models.information._rules_input import InformationInputRules
|
|
6
4
|
|
|
7
5
|
from ._base_rules import DataModelType, ExtensionCategory, RoleTypes, SchemaCompleteness, SheetList, SheetRow
|
|
8
6
|
from .dms._rules import DMSRules
|
|
9
7
|
from .dms._rules_input import DMSInputRules
|
|
10
|
-
from .dms._schema import DMSSchema
|
|
11
8
|
|
|
12
|
-
INPUT_RULES_BY_ROLE: dict[
|
|
13
|
-
RoleTypes, type[InformationInputRules] | type[AssetInputRules] | type[DMSInputRules] | type[DomainInputRules]
|
|
14
|
-
] = {
|
|
15
|
-
RoleTypes.domain_expert: DomainInputRules,
|
|
9
|
+
INPUT_RULES_BY_ROLE: dict[RoleTypes, type[InformationInputRules] | type[DMSInputRules]] = {
|
|
16
10
|
RoleTypes.information: InformationInputRules,
|
|
17
|
-
RoleTypes.asset: AssetInputRules,
|
|
18
11
|
RoleTypes.dms: DMSInputRules,
|
|
19
12
|
}
|
|
20
|
-
VERIFIED_RULES_BY_ROLE: dict[
|
|
21
|
-
RoleTypes, type[InformationRules] | type[AssetRules] | type[DMSRules] | type[DomainRules]
|
|
22
|
-
] = {
|
|
23
|
-
RoleTypes.domain_expert: DomainRules,
|
|
13
|
+
VERIFIED_RULES_BY_ROLE: dict[RoleTypes, type[InformationRules] | type[DMSRules]] = {
|
|
24
14
|
RoleTypes.information: InformationRules,
|
|
25
|
-
RoleTypes.asset: AssetRules,
|
|
26
15
|
RoleTypes.dms: DMSRules,
|
|
27
16
|
}
|
|
28
17
|
|
|
29
18
|
|
|
30
19
|
__all__ = [
|
|
31
|
-
"DomainRules",
|
|
32
20
|
"DMSInputRules",
|
|
33
21
|
"InformationInputRules",
|
|
34
|
-
"AssetInputRules",
|
|
35
22
|
"InformationRules",
|
|
36
|
-
"AssetRules",
|
|
37
23
|
"DMSRules",
|
|
38
24
|
"INPUT_RULES_BY_ROLE",
|
|
39
25
|
"DMSSchema",
|