cognite-neat 0.75.7__py3-none-any.whl → 0.75.8__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.

Files changed (33) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/graph/extractors/_mock_graph_generator.py +6 -5
  3. cognite/neat/rules/analysis/_base.py +1 -1
  4. cognite/neat/rules/analysis/_information_rules.py +4 -4
  5. cognite/neat/rules/exporters/_rules2ontology.py +20 -17
  6. cognite/neat/rules/exporters/_validation.py +2 -2
  7. cognite/neat/rules/importers/_dms2rules.py +14 -15
  8. cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +21 -19
  9. cognite/neat/rules/importers/_dtdl2rules/spec.py +1 -1
  10. cognite/neat/rules/importers/_owl2rules/_owl2rules.py +2 -2
  11. cognite/neat/rules/importers/_spreadsheet2rules.py +6 -1
  12. cognite/neat/rules/importers/_yaml2rules.py +8 -2
  13. cognite/neat/rules/issues/dms.py +1 -1
  14. cognite/neat/rules/models/data_types.py +54 -31
  15. cognite/neat/rules/models/entities.py +184 -41
  16. cognite/neat/rules/models/rdfpath.py +111 -11
  17. cognite/neat/rules/models/rules/_base.py +2 -2
  18. cognite/neat/rules/models/rules/_dms_architect_rules.py +117 -188
  19. cognite/neat/rules/models/rules/_dms_rules_write.py +355 -0
  20. cognite/neat/rules/models/rules/_dms_schema.py +3 -3
  21. cognite/neat/rules/models/rules/_domain_rules.py +6 -3
  22. cognite/neat/rules/models/rules/_information_rules.py +68 -61
  23. cognite/neat/rules/models/rules/_types/__init__.py +0 -47
  24. cognite/neat/rules/models/rules/_types/_base.py +1 -309
  25. cognite/neat/rules/models/rules/_types/_field.py +0 -225
  26. cognite/neat/workflows/steps/lib/rules_importer.py +3 -3
  27. {cognite_neat-0.75.7.dist-info → cognite_neat-0.75.8.dist-info}/METADATA +1 -1
  28. {cognite_neat-0.75.7.dist-info → cognite_neat-0.75.8.dist-info}/RECORD +31 -32
  29. cognite/neat/rules/models/_entity.py +0 -142
  30. cognite/neat/rules/models/rules/_types/_value.py +0 -159
  31. {cognite_neat-0.75.7.dist-info → cognite_neat-0.75.8.dist-info}/LICENSE +0 -0
  32. {cognite_neat-0.75.7.dist-info → cognite_neat-0.75.8.dist-info}/WHEEL +0 -0
  33. {cognite_neat-0.75.7.dist-info → cognite_neat-0.75.8.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.75.7"
1
+ __version__ = "0.75.8"
@@ -14,9 +14,10 @@ from rdflib import RDF, Literal, Namespace, URIRef
14
14
 
15
15
  from cognite.neat.graph.models import Triple
16
16
  from cognite.neat.rules.analysis import InformationArchitectRulesAnalysis
17
+ from cognite.neat.rules.models.data_types import DataType
18
+ from cognite.neat.rules.models.entities import ClassEntity, EntityTypes
17
19
  from cognite.neat.rules.models.rules import DMSRules, InformationRules
18
20
  from cognite.neat.rules.models.rules._information_rules import InformationProperty
19
- from cognite.neat.rules.models.rules._types import ClassEntity, EntityTypes, XSDValueType
20
21
  from cognite.neat.utils.utils import remove_namespace
21
22
 
22
23
  from ._base import BaseExtractor
@@ -55,7 +56,7 @@ class MockGraphGenerator(BaseExtractor):
55
56
  }
56
57
  elif all(isinstance(key, str) for key in class_count.keys()):
57
58
  self.class_count = {
58
- ClassEntity.from_raw(f"{self.rules.metadata.prefix}:{key}"): value for key, value in class_count.items()
59
+ ClassEntity.load(f"{self.rules.metadata.prefix}:{key}"): value for key, value in class_count.items()
59
60
  }
60
61
  elif all(isinstance(key, ClassEntity) for key in class_count.keys()):
61
62
  self.class_count = cast(dict[ClassEntity, int], class_count)
@@ -147,7 +148,7 @@ def generate_triples(
147
148
  triples: list[Triple] = []
148
149
  for class_ in class_count:
149
150
  triples += [
150
- (class_instance_id, RDF.type, URIRef(namespace[class_.suffix]))
151
+ (class_instance_id, RDF.type, URIRef(namespace[str(class_.suffix)]))
151
152
  for class_instance_id in instance_ids[class_]
152
153
  ]
153
154
 
@@ -246,7 +247,7 @@ def _remove_non_requested_sym_pairs(class_linkage: pd.DataFrame, class_count: di
246
247
 
247
248
 
248
249
  def _generate_mock_data_property_triples(
249
- instance_ids: list[URIRef], property_: str, namespace: Namespace, value_type: XSDValueType
250
+ instance_ids: list[URIRef], property_: str, namespace: Namespace, value_type: DataType
250
251
  ) -> list[tuple[URIRef, URIRef, Literal]]:
251
252
  """Generates triples for data properties."""
252
253
 
@@ -338,7 +339,7 @@ def _generate_triples_per_class(
338
339
  instance_ids[class_],
339
340
  property_.property_,
340
341
  namespace,
341
- cast(XSDValueType, property_.value_type),
342
+ cast(DataType, property_.value_type),
342
343
  )
343
344
 
344
345
  elif property_.type_ == EntityTypes.object_property:
@@ -3,7 +3,7 @@ from abc import ABC, abstractmethod
3
3
  from typing import Generic, TypeVar
4
4
 
5
5
  from cognite.neat.rules._shared import Rules
6
- from cognite.neat.rules.models.rules._types import ClassEntity
6
+ from cognite.neat.rules.models.entities import ClassEntity
7
7
 
8
8
  if sys.version_info >= (3, 11):
9
9
  from enum import StrEnum
@@ -7,10 +7,10 @@ from typing import Any, cast
7
7
  import pandas as pd
8
8
  from pydantic import ValidationError
9
9
 
10
+ from cognite.neat.rules.models.entities import ClassEntity, EntityTypes, ParentClassEntity, ReferenceEntity
10
11
  from cognite.neat.rules.models.rdfpath import TransformationRuleType
11
12
  from cognite.neat.rules.models.rules._base import SchemaCompleteness
12
13
  from cognite.neat.rules.models.rules._information_rules import InformationClass, InformationProperty, InformationRules
13
- from cognite.neat.rules.models.rules._types._base import ClassEntity, EntityTypes, ParentClassEntity, ReferenceEntity
14
14
  from cognite.neat.utils.utils import get_inheritance_path
15
15
 
16
16
  from ._base import BaseAnalysis, DataModelingScenario
@@ -126,7 +126,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
126
126
  return class_property_pairs
127
127
 
128
128
  def class_inheritance_path(self, class_: ClassEntity | str, use_reference: bool = False) -> list[ClassEntity]:
129
- class_ = class_ if isinstance(class_, ClassEntity) else ClassEntity.from_raw(class_)
129
+ class_ = class_ if isinstance(class_, ClassEntity) else ClassEntity.load(class_)
130
130
  class_parent_pairs = self.class_parent_pairs(use_reference)
131
131
  return get_inheritance_path(class_, class_parent_pairs)
132
132
 
@@ -328,7 +328,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
328
328
  """This is to simplify access to classes through dict."""
329
329
  class_dict: dict[str, InformationClass] = {}
330
330
  for definition in self.rules.classes:
331
- class_dict[definition.class_.suffix] = definition
331
+ class_dict[str(definition.class_.suffix)] = definition
332
332
  return class_dict
333
333
 
334
334
  def subset_rules(self, desired_classes: set[ClassEntity], use_reference: bool = False) -> InformationRules:
@@ -398,7 +398,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
398
398
 
399
399
  logging.info(f"Reducing data model to only include the following classes: {possible_classes}")
400
400
  for class_ in possible_classes:
401
- reduced_data_model["classes"].append(class_as_dict[class_.suffix])
401
+ reduced_data_model["classes"].append(class_as_dict[str(class_.suffix)])
402
402
 
403
403
  class_property_pairs = self.classes_with_properties(consider_inheritance=False)
404
404
 
@@ -11,6 +11,8 @@ from rdflib.collection import Collection as GraphCollection
11
11
  from cognite.neat.constants import DEFAULT_NAMESPACE as NEAT_NAMESPACE
12
12
  from cognite.neat.rules import exceptions
13
13
  from cognite.neat.rules.analysis import InformationArchitectRulesAnalysis
14
+ from cognite.neat.rules.models.data_types import DataType
15
+ from cognite.neat.rules.models.entities import ClassEntity, EntityTypes
14
16
  from cognite.neat.rules.models.rules import DMSRules
15
17
  from cognite.neat.rules.models.rules._information_rules import (
16
18
  InformationClass,
@@ -18,7 +20,6 @@ from cognite.neat.rules.models.rules._information_rules import (
18
20
  InformationProperty,
19
21
  InformationRules,
20
22
  )
21
- from cognite.neat.rules.models.rules._types import XSD_VALUE_TYPE_MAPPINGS, EntityTypes
22
23
  from cognite.neat.utils.utils import generate_exception_report, remove_namespace
23
24
 
24
25
  from ._base import BaseExporter
@@ -114,7 +115,7 @@ class Ontology(OntologyModel):
114
115
  ],
115
116
  shapes=[
116
117
  SHACLNodeShape.from_rules(
117
- class_dict[class_.suffix],
118
+ class_dict[str(class_.suffix)],
118
119
  list(properties.values()),
119
120
  rules.metadata.namespace,
120
121
  )
@@ -249,15 +250,15 @@ class OWLClass(OntologyModel):
249
250
  sub_class_of = []
250
251
  for parent_class in definition.parent:
251
252
  try:
252
- sub_class_of.append(prefixes[parent_class.prefix][parent_class.suffix])
253
+ sub_class_of.append(prefixes[str(parent_class.prefix)][str(parent_class.suffix)])
253
254
  except KeyError:
254
- sub_class_of.append(namespace[parent_class.suffix])
255
+ sub_class_of.append(namespace[str(parent_class.suffix)])
255
256
  else:
256
257
  sub_class_of = None
257
258
 
258
259
  return cls(
259
- id_=namespace[definition.class_.suffix],
260
- label=definition.name or definition.class_.suffix,
260
+ id_=namespace[str(definition.class_.suffix)],
261
+ label=definition.name or str(definition.class_.suffix),
261
262
  comment=definition.description,
262
263
  sub_class_of=sub_class_of,
263
264
  namespace=namespace,
@@ -324,12 +325,14 @@ class OWLProperty(OntologyModel):
324
325
  )
325
326
  for definition in definitions:
326
327
  owl_property.type_.add(OWL[definition.type_])
327
- owl_property.range_.add(
328
- XSD[definition.value_type.suffix]
329
- if definition.value_type.suffix in XSD_VALUE_TYPE_MAPPINGS
330
- else namespace[definition.value_type.suffix]
331
- )
332
- owl_property.domain.add(namespace[definition.class_.suffix])
328
+
329
+ if isinstance(definition.value_type, DataType):
330
+ owl_property.range_.add(XSD[definition.value_type.xsd])
331
+ elif isinstance(definition.value_type, ClassEntity):
332
+ owl_property.range_.add(namespace[str(definition.value_type.suffix)])
333
+ else:
334
+ raise ValueError(f"Value type {definition.value_type} is not supported")
335
+ owl_property.domain.add(namespace[str(definition.class_.suffix)])
333
336
  owl_property.label.add(definition.name or definition.property_)
334
337
  if definition.description:
335
338
  owl_property.comment.add(definition.description)
@@ -493,12 +496,12 @@ class SHACLNodeShape(OntologyModel):
493
496
  cls, class_definition: InformationClass, property_definitions: list[InformationProperty], namespace: Namespace
494
497
  ) -> "SHACLNodeShape":
495
498
  if class_definition.parent:
496
- parent = [namespace[parent.suffix + "Shape"] for parent in class_definition.parent]
499
+ parent = [namespace[str(parent.suffix) + "Shape"] for parent in class_definition.parent]
497
500
  else:
498
501
  parent = None
499
502
  return cls(
500
- id_=namespace[f"{class_definition.class_.suffix}Shape"],
501
- target_class=namespace[class_definition.class_.suffix],
503
+ id_=namespace[f"{class_definition.class_.suffix!s}Shape"],
504
+ target_class=namespace[str(class_definition.class_.suffix)],
502
505
  parent=parent,
503
506
  property_shapes=[SHACLPropertyShape.from_property(prop, namespace) for prop in property_definitions],
504
507
  namespace=namespace,
@@ -552,8 +555,8 @@ class SHACLPropertyShape(OntologyModel):
552
555
  node_kind=SHACL.IRI if definition.type_ == EntityTypes.object_property else SHACL.Literal,
553
556
  expected_value_type=(
554
557
  namespace[f"{definition.value_type.suffix}Shape"]
555
- if definition.type_ == EntityTypes.object_property
556
- else XSD[definition.value_type.suffix]
558
+ if isinstance(definition.value_type, ClassEntity)
559
+ else XSD[definition.value_type.xsd]
557
560
  ),
558
561
  min_count=definition.min_count,
559
562
  max_count=(
@@ -26,7 +26,7 @@ def are_entity_names_dms_compliant(
26
26
  flag: bool = True
27
27
  with warnings.catch_warnings(record=True) as validation_warnings:
28
28
  for class_ in rules.classes:
29
- if not re.match(VIEW_ID_COMPLIANCE_REGEX, class_.class_.suffix):
29
+ if not re.match(VIEW_ID_COMPLIANCE_REGEX, str(class_.class_.suffix)):
30
30
  warnings.warn(
31
31
  exceptions.EntityIDNotDMSCompliant(
32
32
  "Class", class_.class_.versioned_id, f"[Classes/Class/{class_.class_.versioned_id}]"
@@ -38,7 +38,7 @@ def are_entity_names_dms_compliant(
38
38
 
39
39
  for row, property_ in enumerate(rules.properties):
40
40
  # check class id which would resolve as view/container id
41
- if not re.match(VIEW_ID_COMPLIANCE_REGEX, property_.class_.suffix):
41
+ if not re.match(VIEW_ID_COMPLIANCE_REGEX, str(property_.class_.suffix)):
42
42
  warnings.warn(
43
43
  exceptions.EntityIDNotDMSCompliant(
44
44
  "Class", property_.class_.versioned_id, f"[Properties/Class/{row}]"
@@ -10,6 +10,14 @@ from cognite.client.utils import ms_to_datetime
10
10
  from cognite.neat.rules import issues
11
11
  from cognite.neat.rules.importers._base import BaseImporter, Rules
12
12
  from cognite.neat.rules.issues import IssueList
13
+ from cognite.neat.rules.models.data_types import DataType
14
+ from cognite.neat.rules.models.entities import (
15
+ ClassEntity,
16
+ ContainerEntity,
17
+ DMSUnknownEntity,
18
+ ViewEntity,
19
+ ViewPropertyEntity,
20
+ )
13
21
  from cognite.neat.rules.models.rules import DMSRules, DMSSchema, RoleTypes
14
22
  from cognite.neat.rules.models.rules._base import ExtensionCategory, SchemaCompleteness
15
23
  from cognite.neat.rules.models.rules._dms_architect_rules import (
@@ -19,15 +27,6 @@ from cognite.neat.rules.models.rules._dms_architect_rules import (
19
27
  DMSView,
20
28
  SheetList,
21
29
  )
22
- from cognite.neat.rules.models.rules._types import (
23
- ClassEntity,
24
- ContainerEntity,
25
- DMSValueType,
26
- Undefined,
27
- Unknown,
28
- ViewEntity,
29
- ViewPropEntity,
30
- )
31
30
 
32
31
 
33
32
  class DMSImporter(BaseImporter):
@@ -136,21 +135,21 @@ class DMSImporter(BaseImporter):
136
135
  raise NotImplementedError(f"Constraint type {type(constraint_obj)} not implemented")
137
136
 
138
137
  if isinstance(container_prop.type, dm.DirectRelation):
139
- direct_value_type: str | ViewEntity | DMSValueType
138
+ direct_value_type: str | ViewEntity | DataType | DMSUnknownEntity
140
139
  if prop.source is None:
141
140
  issue_list.append(
142
141
  issues.importing.UnknownValueTypeWarning(class_entity.versioned_id, prop_id)
143
142
  )
144
- direct_value_type = ViewPropEntity(prefix=Undefined, suffix=Unknown)
143
+ direct_value_type = DMSUnknownEntity()
145
144
  else:
146
- direct_value_type = ViewPropEntity.from_id(prop.source)
145
+ direct_value_type = ViewEntity.from_id(prop.source)
147
146
 
148
147
  dms_property = DMSProperty(
149
148
  class_=class_entity,
150
149
  property_=prop_id,
151
150
  description=prop.description,
152
151
  name=prop.name,
153
- value_type=cast(ViewPropEntity | DMSValueType, direct_value_type),
152
+ value_type=direct_value_type,
154
153
  relation="direct",
155
154
  nullable=container_prop.nullable,
156
155
  default=container_prop.default_value,
@@ -168,7 +167,7 @@ class DMSImporter(BaseImporter):
168
167
  property_=prop_id,
169
168
  description=prop.description,
170
169
  name=prop.name,
171
- value_type=cast(ViewPropEntity | DMSValueType, container_prop.type._type),
170
+ value_type=cast(ViewPropertyEntity | DataType, container_prop.type._type),
172
171
  nullable=container_prop.nullable,
173
172
  is_list=container_prop.type.is_list,
174
173
  default=container_prop.default_value,
@@ -180,7 +179,7 @@ class DMSImporter(BaseImporter):
180
179
  constraint=unique_constraints or None,
181
180
  )
182
181
  elif isinstance(prop, dm.MultiEdgeConnectionApply):
183
- view_entity = ViewPropEntity.from_id(prop.source)
182
+ view_entity = ViewEntity.from_id(prop.source)
184
183
  dms_property = DMSProperty(
185
184
  class_=ClassEntity(prefix=view.space, suffix=view.external_id, version=view.version),
186
185
  property_=prop_id,
@@ -1,5 +1,6 @@
1
1
  from collections import Counter
2
2
  from collections.abc import Callable, Sequence
3
+ from typing import cast
3
4
 
4
5
  import cognite.neat.rules.issues.importing
5
6
  from cognite.neat.rules import issues
@@ -20,13 +21,9 @@ from cognite.neat.rules.importers._dtdl2rules.spec import (
20
21
  TelemetryV2,
21
22
  )
22
23
  from cognite.neat.rules.issues import IssueList, ValidationIssue
24
+ from cognite.neat.rules.models.data_types import _DATA_TYPE_BY_NAME, DataType, Json, String
25
+ from cognite.neat.rules.models.entities import ClassEntity, ParentClassEntity
23
26
  from cognite.neat.rules.models.rules._information_rules import InformationClass, InformationProperty
24
- from cognite.neat.rules.models.rules._types import (
25
- XSD_VALUE_TYPE_MAPPINGS,
26
- ClassEntity,
27
- ParentClassEntity,
28
- XSDValueType,
29
- )
30
27
 
31
28
 
32
29
  class _DTDLConverter:
@@ -92,7 +89,12 @@ class _DTDLConverter:
92
89
  name=item.display_name,
93
90
  description=item.description,
94
91
  comment=item.comment,
95
- parent=[ParentClassEntity.from_raw(parent.as_class_id()) for parent in item.extends or []] or None,
92
+ parent=[
93
+ cast(ParentClassEntity, parent_entity)
94
+ for parent in item.extends or []
95
+ if isinstance(parent_entity := ParentClassEntity.load(parent.as_class_id()), ParentClassEntity)
96
+ ]
97
+ or None,
96
98
  )
97
99
  self.classes.append(class_)
98
100
  for sub_item_or_id in item.contents or []:
@@ -123,7 +125,7 @@ class _DTDLConverter:
123
125
  return None
124
126
 
125
127
  prop = InformationProperty(
126
- class_=ClassEntity.from_raw(parent),
128
+ class_=ClassEntity.load(parent),
127
129
  property_=item.name,
128
130
  name=item.display_name,
129
131
  description=item.description,
@@ -175,7 +177,7 @@ class _DTDLConverter:
175
177
  if value_type is None:
176
178
  return
177
179
  prop = InformationProperty(
178
- class_=ClassEntity.from_raw(parent),
180
+ class_=ClassEntity.load(parent),
179
181
  property_=item.name,
180
182
  name=item.display_name,
181
183
  description=item.description,
@@ -195,7 +197,7 @@ class _DTDLConverter:
195
197
  if value_type is None:
196
198
  return
197
199
  prop = InformationProperty(
198
- class_=ClassEntity.from_raw(parent),
200
+ class_=ClassEntity.load(parent),
199
201
  property_=item.name,
200
202
  name=item.display_name,
201
203
  description=item.description,
@@ -211,7 +213,7 @@ class _DTDLConverter:
211
213
  self._missing_parent_warning(item)
212
214
  return None
213
215
  if item.target is not None:
214
- value_type: XSDValueType | ClassEntity
216
+ value_type: DataType | ClassEntity
215
217
  if item.target in self._item_by_id:
216
218
  value_type = item.target.as_class_id()
217
219
  else:
@@ -223,10 +225,10 @@ class _DTDLConverter:
223
225
  instance_id=item.target.model_dump(),
224
226
  )
225
227
  )
226
- value_type = XSD_VALUE_TYPE_MAPPINGS["json"]
228
+ value_type = Json()
227
229
 
228
230
  prop = InformationProperty(
229
- class_=ClassEntity.from_raw(parent),
231
+ class_=ClassEntity.load(parent),
230
232
  property_=item.name,
231
233
  name=item.display_name,
232
234
  description=item.description,
@@ -275,13 +277,13 @@ class _DTDLConverter:
275
277
 
276
278
  def schema_to_value_type(
277
279
  self, schema: Schema | Interface | DTMI | None, item: DTDLBase
278
- ) -> XSDValueType | ClassEntity | None:
280
+ ) -> DataType | ClassEntity | None:
279
281
  input_type = self._item_by_id.get(schema) if isinstance(schema, DTMI) else schema
280
282
 
281
283
  if isinstance(input_type, Enum):
282
- return XSD_VALUE_TYPE_MAPPINGS["string"]
283
- elif isinstance(input_type, str) and input_type in XSD_VALUE_TYPE_MAPPINGS:
284
- return XSD_VALUE_TYPE_MAPPINGS[input_type]
284
+ return String()
285
+ elif isinstance(input_type, str) and input_type.casefold() in _DATA_TYPE_BY_NAME:
286
+ return _DATA_TYPE_BY_NAME[input_type.casefold()]()
285
287
  elif isinstance(input_type, str):
286
288
  self.issues.append(
287
289
  cognite.neat.rules.issues.importing.UnsupportedPropertyTypeError(
@@ -301,11 +303,11 @@ class _DTDLConverter:
301
303
  instance_name=input_type.display_name,
302
304
  )
303
305
  )
304
- return XSD_VALUE_TYPE_MAPPINGS["json"]
306
+ return Json()
305
307
  else:
306
308
  if isinstance(input_type, Object):
307
309
  self.convert_object(input_type, None)
308
- return ClassEntity.from_raw(input_type.id_.as_class_id())
310
+ return ClassEntity.load(input_type.id_.as_class_id())
309
311
  else:
310
312
  self.issues.append(
311
313
  issues.importing.UnknownPropertyWarning(
@@ -14,7 +14,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypeAlias
14
14
 
15
15
  from pydantic import BaseModel, Field, field_validator, model_serializer, model_validator
16
16
 
17
- from cognite.neat.rules.models.rules._types import ClassEntity
17
+ from cognite.neat.rules.models.entities import ClassEntity
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from pydantic.type_adapter import IncEx
@@ -10,8 +10,8 @@ from rdflib import DC, DCTERMS, OWL, RDF, RDFS, SKOS, Graph
10
10
 
11
11
  from cognite.neat.rules.importers._base import BaseImporter, Rules
12
12
  from cognite.neat.rules.issues import IssueList
13
+ from cognite.neat.rules.models.data_types import _XSD_TYPES
13
14
  from cognite.neat.rules.models.rules import InformationRules, RoleTypes
14
- from cognite.neat.rules.models.rules._types import XSD_VALUE_TYPE_MAPPINGS
15
15
 
16
16
  from ._owl2classes import parse_owl_classes
17
17
  from ._owl2metadata import parse_owl_metadata
@@ -126,7 +126,7 @@ def _add_missing_value_types(components: dict) -> dict:
126
126
  Updated tables with missing properties added to containers
127
127
  """
128
128
 
129
- xsd_types = set(XSD_VALUE_TYPE_MAPPINGS.keys())
129
+ xsd_types = _XSD_TYPES
130
130
  candidate_value_types = {definition["Value Type"] for definition in components["Properties"]} - {
131
131
  definition["Class"] for definition in components["Classes"]
132
132
  }
@@ -15,6 +15,7 @@ from cognite.neat.rules import issues
15
15
  from cognite.neat.rules.issues import IssueList
16
16
  from cognite.neat.rules.models.rules import RULES_PER_ROLE, DMSRules, DomainRules, InformationRules
17
17
  from cognite.neat.rules.models.rules._base import RoleTypes, SchemaCompleteness
18
+ from cognite.neat.rules.models.rules._dms_rules_write import DMSRulesWrite
18
19
  from cognite.neat.utils.auxiliary import local_import
19
20
  from cognite.neat.utils.spreadsheet import SpreadsheetRead, read_individual_sheet
20
21
 
@@ -214,7 +215,11 @@ class ExcelImporter(BaseImporter):
214
215
  error_cls=issues.spreadsheet.InvalidSheetError,
215
216
  error_args={"read_info_by_sheet": read_info_by_sheet},
216
217
  ) as future:
217
- rules = rules_cls.model_validate(sheets) # type: ignore[attr-defined]
218
+ rules: Rules
219
+ if rules_cls is DMSRules:
220
+ rules = DMSRulesWrite.load(sheets).as_read()
221
+ else:
222
+ rules = rules_cls.model_validate(sheets) # type: ignore[attr-defined]
218
223
 
219
224
  if future.result == "failure" or issue_list.has_errors:
220
225
  return self._return_or_raise(issue_list, errors)
@@ -5,7 +5,8 @@ import yaml
5
5
 
6
6
  from cognite.neat.rules import issues
7
7
  from cognite.neat.rules.issues import IssueList, NeatValidationError, ValidationIssue
8
- from cognite.neat.rules.models.rules import RULES_PER_ROLE, RoleTypes
8
+ from cognite.neat.rules.models.rules import RULES_PER_ROLE, DMSRules, RoleTypes
9
+ from cognite.neat.rules.models.rules._dms_rules_write import DMSRulesWrite
9
10
 
10
11
  from ._base import BaseImporter, Rules, _handle_issues
11
12
 
@@ -97,7 +98,12 @@ class YAMLImporter(BaseImporter):
97
98
  rules_model = RULES_PER_ROLE[role_enum]
98
99
 
99
100
  with _handle_issues(issue_list) as future:
100
- rules = rules_model.model_validate(self.raw_data)
101
+ rules: Rules
102
+ if rules_model is DMSRules:
103
+ rules = DMSRulesWrite.load(self.raw_data).as_read()
104
+ else:
105
+ rules = rules_model.model_validate(self.raw_data)
106
+
101
107
  if future.result == "failure":
102
108
  if errors == "continue":
103
109
  return None, issue_list
@@ -195,7 +195,7 @@ class DirectRelationMissingSourceWarning(DMSSchemaWarning):
195
195
  property: str
196
196
 
197
197
  def message(self) -> str:
198
- return f"The source view referred to by {self.view_id}.{self.property} does not exist"
198
+ return f"The source view referred to by '{self.view_id.external_id}.{self.property}' does not exist."
199
199
 
200
200
  def dump(self) -> dict[str, Any]:
201
201
  output = super().dump()