cognite-neat 0.85.4__py3-none-any.whl → 0.85.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.

Files changed (28) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/constants.py +0 -8
  3. cognite/neat/graph/loaders/_rdf2dms.py +12 -4
  4. cognite/neat/legacy/graph/examples/__init__.py +3 -0
  5. cognite/neat/legacy/graph/extractors/_dexpi.py +2 -2
  6. cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +1 -1
  7. cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
  8. cognite/neat/legacy/rules/examples/Rules-Nordic44.xlsx +0 -0
  9. cognite/neat/legacy/rules/examples/__init__.py +1 -1
  10. cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +1 -1
  11. cognite/neat/rules/analysis/__init__.py +5 -2
  12. cognite/neat/rules/analysis/_base.py +0 -12
  13. cognite/neat/rules/analysis/_information_rules.py +116 -27
  14. cognite/neat/rules/exporters/_rules2excel.py +11 -3
  15. cognite/neat/rules/importers/_base.py +8 -2
  16. cognite/neat/rules/importers/_inference2rules.py +13 -7
  17. cognite/neat/rules/issues/spreadsheet.py +46 -6
  18. cognite/neat/rules/models/information/_rules.py +3 -1
  19. cognite/neat/rules/models/information/_rules_input.py +23 -4
  20. cognite/neat/rules/models/information/_validation.py +15 -0
  21. cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +1 -1
  22. cognite/neat/workflows/steps/lib/legacy/graph_store.py +27 -9
  23. {cognite_neat-0.85.4.dist-info → cognite_neat-0.85.6.dist-info}/METADATA +1 -1
  24. {cognite_neat-0.85.4.dist-info → cognite_neat-0.85.6.dist-info}/RECORD +27 -27
  25. cognite/neat/legacy/rules/examples/Rules-Nordic44-to-TNT.xlsx +0 -0
  26. {cognite_neat-0.85.4.dist-info → cognite_neat-0.85.6.dist-info}/LICENSE +0 -0
  27. {cognite_neat-0.85.4.dist-info → cognite_neat-0.85.6.dist-info}/WHEEL +0 -0
  28. {cognite_neat-0.85.4.dist-info → cognite_neat-0.85.6.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.85.4"
1
+ __version__ = "0.85.6"
cognite/neat/constants.py CHANGED
@@ -22,14 +22,6 @@ PREFIXES = {
22
22
  "owl": OWL._NS,
23
23
  "xsd": XSD._NS,
24
24
  "pav": Namespace("http://purl.org/pav/"),
25
- "cim": Namespace("http://iec.ch/TC57/2013/CIM-schema-cim16#"),
26
- "icim": Namespace("http://iec.ch/TC57/2013/CIM-schema-cim16-info#"),
27
- "entsoe": Namespace("http://entsoe.eu/CIM/SchemaExtension/3/1#"),
28
- "entsoe2": Namespace("http://entsoe.eu/CIM/SchemaExtension/3/2#"),
29
- "md": Namespace("http://iec.ch/TC57/61970-552/ModelDescription/1#"),
30
- "pti": Namespace("http://www.pti-us.com/PTI_CIM-schema-cim16#"),
31
- "tnt": Namespace("http://purl.org/cognite/tnt#"),
32
- "neat": DEFAULT_NAMESPACE,
33
25
  }
34
26
 
35
27
 
@@ -82,7 +82,9 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
82
82
  except Exception as e:
83
83
  issues.append(
84
84
  loader_issues.FailedConvertError(
85
- identifier=rules.metadata.as_identifier(), target_format="read DMS model", reason=str(e)
85
+ identifier=rules.metadata.as_identifier(),
86
+ target_format="read DMS model",
87
+ reason=str(e),
86
88
  )
87
89
  )
88
90
  return cls(graph_store, data_model, instance_space, {}, issues)
@@ -199,7 +201,11 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
199
201
  return pydantic_cls, edge_by_property, issues
200
202
 
201
203
  def _create_node(
202
- self, identifier: str, properties: dict[str, list[str]], pydantic_cls: type[Model], view_id: dm.ViewId
204
+ self,
205
+ identifier: str,
206
+ properties: dict[str, list[str]],
207
+ pydantic_cls: type[Model],
208
+ view_id: dm.ViewId,
203
209
  ) -> dm.InstanceApply:
204
210
  created = pydantic_cls.model_validate(properties)
205
211
 
@@ -233,7 +239,7 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
233
239
  external_id = f"{identifier}.{prop}.{target}"
234
240
  yield dm.EdgeApply(
235
241
  space=self.instance_space,
236
- external_id=external_id if len(external_id) < 256 else create_sha256_hash(external_id),
242
+ external_id=(external_id if len(external_id) < 256 else create_sha256_hash(external_id)),
237
243
  type=edge.type,
238
244
  start_node=dm.DirectRelationReference(self.instance_space, identifier),
239
245
  end_node=dm.DirectRelationReference(self.instance_space, target),
@@ -290,5 +296,7 @@ def _triples2dictionary(
290
296
  """Converts list of triples to dictionary"""
291
297
  values_by_property_by_identifier: dict[str, dict[str, list[str]]] = defaultdict(lambda: defaultdict(list))
292
298
  for id_, property_, value in triples:
293
- values_by_property_by_identifier[id_][property_].append(value)
299
+ # avoid issue with strings "None", "nan", "null" being treated as values
300
+ if value.lower() not in ["", "None", "nan", "null"]:
301
+ values_by_property_by_identifier[id_][property_].append(value)
294
302
  return values_by_property_by_identifier
@@ -5,3 +5,6 @@ from pathlib import Path
5
5
  # https://github.com/pydata/xarray/blob/main/xarray/tutorial.py
6
6
  # Currently there are simple paths to the examples which are then easily loaded in the notebooks
7
7
  nordic44_knowledge_graph = Path(__file__).parent / "Knowledge-Graph-Nordic44.xml"
8
+ nordic44_knowledge_graph_dirty = (
9
+ Path(__file__).parent / "Knowledge-Graph-Nordic44-dirty.xml"
10
+ )
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
 
4
4
  from rdflib import Namespace
5
5
 
6
- from cognite.neat.constants import PREFIXES
6
+ from cognite.neat.constants import DEFAULT_NAMESPACE
7
7
  from cognite.neat.graph.extractors._dexpi import DexpiExtractor
8
8
  from cognite.neat.legacy.graph.models import Triple
9
9
 
@@ -31,7 +31,7 @@ class DexpiXML(BaseExtractor):
31
31
  base_namespace: str | None = None,
32
32
  ):
33
33
  self.filepath = Path(filepath)
34
- self.namespace = Namespace(base_namespace) if isinstance(base_namespace, str | Namespace) else PREFIXES["neat"]
34
+ self.namespace = Namespace(base_namespace) if isinstance(base_namespace, str | Namespace) else DEFAULT_NAMESPACE
35
35
 
36
36
  def extract(self) -> set[Triple]:
37
37
  """
@@ -271,7 +271,7 @@ def _class2asset_instance(
271
271
  if "name" in remapped_class_instance and remapped_class_instance["name"] == "":
272
272
  remapped_class_instance["name"] = empty_name_default
273
273
  # To maintain shape across of all assets of specific type we are adding missing metadata
274
- # keys as empty strings, this was request by Statnett
274
+ # keys as empty strings, this was request by a customer
275
275
  # Generally this is bad practice, but more of a workaround of their bad data
276
276
  if missing_metadata and add_missing_metadata:
277
277
  msg = f"Adding missing metadata keys with values set to empty string for {class_}"
@@ -12,7 +12,7 @@ power_grid_containers = _EXAMPLES / "power-grid-containers.yaml"
12
12
  power_grid_data_model = _EXAMPLES / "power-grid-model.yaml"
13
13
  simple_example = _EXAMPLES / "sheet2cdf-transformation-rules.xlsx"
14
14
  source_to_solution_mapping = _EXAMPLES / "source-to-solution-mapping-rules.xlsx"
15
- nordic44 = _EXAMPLES / "Rules-Nordic44-to-TNT.xlsx"
15
+ nordic44 = _EXAMPLES / "Rules-Nordic44.xlsx"
16
16
  nordic44_graphql = _EXAMPLES / "Rules-Nordic44-to-graphql.xlsx"
17
17
  skos = _EXAMPLES / "skos-rules.xlsx"
18
18
  wind_energy_ontology = _EXAMPLES / "wind-energy.owl"
@@ -24,7 +24,7 @@ steps:
24
24
  pos_y: 77
25
25
  - complex_configs: {}
26
26
  configs:
27
- file_name: Rules-Nordic44-to-TNT.xlsx
27
+ file_name: Rules-Nordic44.xlsx
28
28
  validation_report_file: rules_validation_report.txt
29
29
  validation_report_storage_dir: rules_validation_report
30
30
  version: ""
@@ -1,3 +1,6 @@
1
- from ._information_rules import InformationArchitectRulesAnalysis
1
+ from ._information_rules import (
2
+ AssetArchitectRulesAnalysis,
3
+ InformationArchitectRulesAnalysis,
4
+ )
2
5
 
3
- __all__ = ["InformationArchitectRulesAnalysis"]
6
+ __all__ = ["InformationArchitectRulesAnalysis", "AssetArchitectRulesAnalysis"]
@@ -1,15 +1,9 @@
1
- import sys
2
1
  from abc import ABC, abstractmethod
3
2
  from typing import Generic, TypeVar
4
3
 
5
4
  from cognite.neat.rules._shared import Rules
6
5
  from cognite.neat.rules.models.entities import ClassEntity
7
6
 
8
- if sys.version_info >= (3, 11):
9
- from enum import StrEnum
10
- else:
11
- from backports.strenum import StrEnum
12
-
13
7
  T_Rules = TypeVar("T_Rules", bound=Rules)
14
8
 
15
9
 
@@ -17,9 +11,3 @@ class BaseAnalysis(ABC, Generic[T_Rules]):
17
11
  @abstractmethod
18
12
  def subset_rules(self, desired_classes: set[ClassEntity]) -> T_Rules:
19
13
  raise NotImplementedError()
20
-
21
-
22
- class DataModelingScenario(StrEnum):
23
- from_scratch = "from scratch"
24
- build_solution = "build solution"
25
- extend_reference = "extend reference"
@@ -2,25 +2,37 @@ import itertools
2
2
  import logging
3
3
  import warnings
4
4
  from collections import defaultdict
5
- from typing import Any
5
+ from typing import Any, Generic, TypeVar
6
6
 
7
7
  import pandas as pd
8
8
  from pydantic import ValidationError
9
9
 
10
10
  from cognite.neat.rules.models import SchemaCompleteness
11
11
  from cognite.neat.rules.models._rdfpath import RDFPath
12
- from cognite.neat.rules.models.entities import ClassEntity, EntityTypes, ParentClassEntity, ReferenceEntity
13
- from cognite.neat.rules.models.information import InformationClass, InformationProperty, InformationRules
12
+ from cognite.neat.rules.models.asset import AssetClass, AssetProperty, AssetRules
13
+ from cognite.neat.rules.models.entities import (
14
+ AssetEntity,
15
+ ClassEntity,
16
+ EntityTypes,
17
+ ParentClassEntity,
18
+ ReferenceEntity,
19
+ RelationshipEntity,
20
+ )
21
+ from cognite.neat.rules.models.information import (
22
+ InformationClass,
23
+ InformationProperty,
24
+ InformationRules,
25
+ )
14
26
  from cognite.neat.utils.utils import get_inheritance_path
15
27
 
16
- from ._base import BaseAnalysis
28
+ T_Rules = TypeVar("T_Rules", InformationRules, AssetRules)
29
+ T_Property = TypeVar("T_Property", InformationProperty, AssetProperty)
30
+ T_Class = TypeVar("T_Class", InformationClass, AssetClass)
17
31
 
18
32
 
19
- class InformationArchitectRulesAnalysis(BaseAnalysis):
20
- """Assumes analysis over only the complete schema"""
21
-
22
- def __init__(self, rules: InformationRules):
23
- self.rules = rules
33
+ class _SharedAnalysis(Generic[T_Rules, T_Property, T_Class]):
34
+ def __init__(self, rules: T_Rules):
35
+ self.rules: T_Rules = rules
24
36
 
25
37
  @property
26
38
  def directly_referred_classes(self) -> set[ClassEntity]:
@@ -65,9 +77,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
65
77
 
66
78
  return class_subclass_pairs
67
79
 
68
- def classes_with_properties(
69
- self, consider_inheritance: bool = False
70
- ) -> dict[ClassEntity, list[InformationProperty]]:
80
+ def classes_with_properties(self, consider_inheritance: bool = False) -> dict[ClassEntity, list[T_Property]]:
71
81
  """Returns classes that have been defined in the data model.
72
82
 
73
83
  Args:
@@ -85,10 +95,10 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
85
95
  it will not be included in the returned dictionary.
86
96
  """
87
97
 
88
- class_property_pairs: dict[ClassEntity, list[InformationProperty]] = defaultdict(list)
98
+ class_property_pairs: dict[ClassEntity, list[T_Property]] = defaultdict(list)
89
99
 
90
100
  for property_ in self.rules.properties:
91
- class_property_pairs[property_.class_].append(property_)
101
+ class_property_pairs[property_.class_].append(property_) # type: ignore
92
102
 
93
103
  if consider_inheritance:
94
104
  class_parent_pairs = self.class_parent_pairs()
@@ -106,7 +116,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
106
116
  def _add_inherited_properties(
107
117
  cls,
108
118
  class_: ClassEntity,
109
- class_property_pairs: dict[ClassEntity, list[InformationProperty]],
119
+ class_property_pairs: dict[ClassEntity, list[T_Property]],
110
120
  class_parent_pairs: dict[ClassEntity, list[ParentClassEntity]],
111
121
  ):
112
122
  inheritance_path = get_inheritance_path(class_, class_parent_pairs)
@@ -130,7 +140,7 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
130
140
 
131
141
  def class_property_pairs(
132
142
  self, only_rdfpath: bool = False, consider_inheritance: bool = False
133
- ) -> dict[ClassEntity, dict[str, InformationProperty]]:
143
+ ) -> dict[ClassEntity, dict[str, T_Property]]:
134
144
  """Returns a dictionary of classes with a dictionary of properties associated with them.
135
145
 
136
146
  Args:
@@ -193,7 +203,14 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
193
203
  Dataframe with the class linkage of the data model
194
204
  """
195
205
 
196
- class_linkage = pd.DataFrame(columns=["source_class", "target_class", "connecting_property", "max_occurrence"])
206
+ class_linkage = pd.DataFrame(
207
+ columns=[
208
+ "source_class",
209
+ "target_class",
210
+ "connecting_property",
211
+ "max_occurrence",
212
+ ]
213
+ )
197
214
 
198
215
  class_property_pairs = self.classes_with_properties(consider_inheritance)
199
216
  properties = list(itertools.chain.from_iterable(class_property_pairs.values()))
@@ -286,21 +303,21 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
286
303
 
287
304
  def as_property_dict(
288
305
  self,
289
- ) -> dict[str, list[InformationProperty]]:
306
+ ) -> dict[str, list[T_Property]]:
290
307
  """This is used to capture all definitions of a property in the data model."""
291
- property_dict: dict[str, list[InformationProperty]] = defaultdict(list)
308
+ property_dict: dict[str, list[T_Property]] = defaultdict(list)
292
309
  for definition in self.rules.properties:
293
- property_dict[definition.property_].append(definition)
310
+ property_dict[definition.property_].append(definition) # type: ignore
294
311
  return property_dict
295
312
 
296
- def as_class_dict(self) -> dict[str, InformationClass]:
313
+ def as_class_dict(self) -> dict[str, T_Class]:
297
314
  """This is to simplify access to classes through dict."""
298
- class_dict: dict[str, InformationClass] = {}
315
+ class_dict: dict[str, T_Class] = {}
299
316
  for definition in self.rules.classes:
300
- class_dict[str(definition.class_.suffix)] = definition
317
+ class_dict[str(definition.class_.suffix)] = definition # type: ignore
301
318
  return class_dict
302
319
 
303
- def subset_rules(self, desired_classes: set[ClassEntity]) -> InformationRules:
320
+ def subset_rules(self, desired_classes: set[ClassEntity]) -> T_Rules:
304
321
  """
305
322
  Subset rules to only include desired classes and their properties.
306
323
 
@@ -352,7 +369,8 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
352
369
  if impossible_classes:
353
370
  logging.warning(f"Could not find the following classes defined in the data model: {impossible_classes}")
354
371
  warnings.warn(
355
- f"Could not find the following classes defined in the data model: {impossible_classes}", stacklevel=2
372
+ f"Could not find the following classes defined in the data model: {impossible_classes}",
373
+ stacklevel=2,
356
374
  )
357
375
 
358
376
  reduced_data_model: dict[str, Any] = {
@@ -373,8 +391,79 @@ class InformationArchitectRulesAnalysis(BaseAnalysis):
373
391
  reduced_data_model["properties"].extend(properties)
374
392
 
375
393
  try:
376
- return InformationRules(**reduced_data_model)
394
+ return type(self.rules)(**reduced_data_model)
377
395
  except ValidationError as e:
378
396
  warnings.warn(f"Reduced data model is not complete: {e}", stacklevel=2)
379
397
  reduced_data_model["metadata"].schema_ = SchemaCompleteness.partial
380
- return InformationRules.model_construct(**reduced_data_model)
398
+ return type(self.rules).model_construct(**reduced_data_model)
399
+
400
+
401
+ class InformationArchitectRulesAnalysis(_SharedAnalysis[InformationRules, InformationProperty, InformationClass]):
402
+ """Assumes analysis over only the complete schema"""
403
+
404
+ ...
405
+
406
+
407
+ class AssetArchitectRulesAnalysis(_SharedAnalysis[AssetRules, AssetProperty, AssetClass]):
408
+ """Assumes analysis over only the complete schema"""
409
+
410
+ def class_property_pairs(
411
+ self,
412
+ only_rdfpath: bool = False,
413
+ consider_inheritance: bool = False,
414
+ implementation_type: EntityTypes = EntityTypes.asset,
415
+ ) -> dict[ClassEntity, dict[str, AssetProperty]]:
416
+ class_property_pairs = {}
417
+
418
+ T_implementation = AssetEntity if implementation_type == EntityTypes.asset else RelationshipEntity
419
+
420
+ for class_, properties in self.classes_with_properties(consider_inheritance).items():
421
+ processed_properties = {}
422
+ for property_ in properties:
423
+ if property_.property_ in processed_properties:
424
+ # TODO: use appropriate Warning class from _exceptions.py
425
+ # if missing make one !
426
+ warnings.warn(
427
+ f"Property {property_.property_} for {class_} has been defined more than once!"
428
+ " Only the first definition will be considered, skipping the rest..",
429
+ stacklevel=2,
430
+ )
431
+ continue
432
+
433
+ if (
434
+ property_.implementation
435
+ and any(isinstance(implementation, T_implementation) for implementation in property_.implementation)
436
+ and (not only_rdfpath or (only_rdfpath and isinstance(property_.transformation, RDFPath)))
437
+ ):
438
+ implementation = [
439
+ implementation
440
+ for implementation in property_.implementation
441
+ if isinstance(implementation, T_implementation)
442
+ ]
443
+
444
+ processed_properties[property_.property_] = property_.model_copy(
445
+ deep=True, update={"implementation": implementation}
446
+ )
447
+
448
+ if processed_properties:
449
+ class_property_pairs[class_] = processed_properties
450
+
451
+ return class_property_pairs
452
+
453
+ def asset_definition(
454
+ self, only_rdfpath: bool = False, consider_inheritance: bool = False
455
+ ) -> dict[ClassEntity, dict[str, AssetProperty]]:
456
+ return self.class_property_pairs(
457
+ consider_inheritance=consider_inheritance,
458
+ only_rdfpath=only_rdfpath,
459
+ implementation_type=EntityTypes.asset,
460
+ )
461
+
462
+ def relationship_definition(
463
+ self, only_rdfpath: bool = False, consider_inheritance: bool = False
464
+ ) -> dict[ClassEntity, dict[str, AssetProperty]]:
465
+ return self.class_property_pairs(
466
+ consider_inheritance=consider_inheritance,
467
+ only_rdfpath=only_rdfpath,
468
+ implementation_type=EntityTypes.relationship,
469
+ )
@@ -143,9 +143,15 @@ class ExcelExporter(BaseExporter[Workbook]):
143
143
 
144
144
  return workbook
145
145
 
146
- def _write_sheets(self, workbook: Workbook, dumped_rules: dict[str, Any], rules: Rules, sheet_prefix: str = ""):
146
+ def _write_sheets(
147
+ self,
148
+ workbook: Workbook,
149
+ dumped_rules: dict[str, Any],
150
+ rules: Rules,
151
+ sheet_prefix: str = "",
152
+ ):
147
153
  for sheet_name, headers in rules.headers_by_sheet(by_alias=True).items():
148
- if sheet_name in ("Metadata", "prefixes", "Reference", "Last"):
154
+ if sheet_name in ("Metadata", "Prefixes", "Reference", "Last"):
149
155
  continue
150
156
  sheet = workbook.create_sheet(f"{sheet_prefix}{sheet_name}")
151
157
 
@@ -273,7 +279,9 @@ class _MetadataCreator:
273
279
 
274
280
  new_metadata = self._create_new_info(now)
275
281
  if isinstance(metadata, DMSMetadata):
276
- from cognite.neat.rules.models.information._converter import _InformationRulesConverter
282
+ from cognite.neat.rules.models.information._converter import (
283
+ _InformationRulesConverter,
284
+ )
277
285
 
278
286
  output_metadata: DMSMetadata | InformationMetadata = _InformationRulesConverter._convert_metadata_to_dms(
279
287
  new_metadata
@@ -10,7 +10,11 @@ from pydantic import ValidationError
10
10
  from rdflib import Namespace
11
11
 
12
12
  from cognite.neat.rules._shared import Rules
13
- from cognite.neat.rules.issues.base import IssueList, NeatValidationError, ValidationWarning
13
+ from cognite.neat.rules.issues.base import (
14
+ IssueList,
15
+ NeatValidationError,
16
+ ValidationWarning,
17
+ )
14
18
  from cognite.neat.rules.models import AssetRules, DMSRules, InformationRules, RoleTypes
15
19
  from cognite.neat.utils.auxiliary import class_html_doc
16
20
 
@@ -30,7 +34,9 @@ class BaseImporter(ABC):
30
34
 
31
35
  @abstractmethod
32
36
  def to_rules(
33
- self, errors: Literal["raise", "continue"] = "continue", role: RoleTypes | None = None
37
+ self,
38
+ errors: Literal["raise", "continue"] = "continue",
39
+ role: RoleTypes | None = None,
34
40
  ) -> tuple[Rules | None, IssueList] | Rules:
35
41
  """
36
42
  Creates `Rules` object from the data for target role.
@@ -91,7 +91,9 @@ class InferenceImporter(BaseImporter):
91
91
  ) -> tuple[Rules | None, IssueList]: ...
92
92
 
93
93
  def to_rules(
94
- self, errors: Literal["raise", "continue"] = "continue", role: RoleTypes | None = None
94
+ self,
95
+ errors: Literal["raise", "continue"] = "continue",
96
+ role: RoleTypes | None = None,
95
97
  ) -> tuple[Rules | None, IssueList] | Rules:
96
98
  """
97
99
  Creates `Rules` object from the data for target role.
@@ -103,9 +105,6 @@ class InferenceImporter(BaseImporter):
103
105
 
104
106
  rules_dict = self._to_rules_components()
105
107
 
106
- # adding additional prefix
107
- rules_dict["prefixes"][rules_dict["metadata"]["prefix"]] = rules_dict["metadata"]["namespace"]
108
-
109
108
  with _handle_issues(self.issue_list) as future:
110
109
  rules: InformationRules
111
110
  rules = InformationRulesInput.load(rules_dict).as_rules()
@@ -134,7 +133,10 @@ class InferenceImporter(BaseImporter):
134
133
  """
135
134
  classes: dict[str, dict] = {}
136
135
  properties: dict[str, dict] = {}
137
- prefixes: dict[str, Namespace] = PREFIXES
136
+ prefixes: dict[str, Namespace] = PREFIXES.copy()
137
+
138
+ # Adds default namespace to prefixes
139
+ prefixes[self._default_metadata().prefix] = self._default_metadata().namespace
138
140
 
139
141
  # Infers all the classes in the graph
140
142
  for class_uri, no_instances in self.graph.query(ORDERED_CLASSES_QUERY): # type: ignore[misc]
@@ -246,7 +248,7 @@ class InferenceImporter(BaseImporter):
246
248
  created=datetime.now(),
247
249
  updated=datetime.now(),
248
250
  description="Inferred model from knowledge graph",
249
- prefix="neat",
251
+ prefix="inferred",
250
252
  namespace=DEFAULT_NAMESPACE,
251
253
  )
252
254
 
@@ -262,6 +264,10 @@ class InferenceImporter(BaseImporter):
262
264
  def _read_value_type_occurrence_from_comment(cls, value_type: str, comment: str) -> int:
263
265
  return int(
264
266
  cast(
265
- re.Match, re.search(rf"with value type <{value_type}> which occurs <(\d+)> times in the graph", comment)
267
+ re.Match,
268
+ re.search(
269
+ rf"with value type <{value_type}> which occurs <(\d+)> times in the graph",
270
+ comment,
271
+ ),
266
272
  ).group(1)
267
273
  )
@@ -7,6 +7,7 @@ from typing import Any, ClassVar
7
7
  from cognite.client.data_classes import data_modeling as dm
8
8
  from cognite.client.data_classes.data_modeling import ContainerId, ViewId
9
9
  from pydantic_core import ErrorDetails
10
+ from rdflib import Namespace
10
11
 
11
12
  from cognite.neat.issues import MultiValueError
12
13
  from cognite.neat.utils.spreadsheet import SpreadsheetRead
@@ -23,6 +24,7 @@ __all__ = [
23
24
  "InvalidRowError",
24
25
  "InvalidPropertyError",
25
26
  "InvalidClassError",
27
+ "PrefixNamespaceCollisionError",
26
28
  "InvalidContainerError",
27
29
  "InvalidViewError",
28
30
  "InvalidRowUnknownSheetError",
@@ -44,13 +46,18 @@ class InvalidSheetError(NeatValidationError, ABC):
44
46
  @classmethod
45
47
  @abstractmethod
46
48
  def from_pydantic_error(
47
- cls, error: ErrorDetails, read_info_by_sheet: dict[str, SpreadsheetRead] | None = None
49
+ cls,
50
+ error: ErrorDetails,
51
+ read_info_by_sheet: dict[str, SpreadsheetRead] | None = None,
48
52
  ) -> Self:
49
53
  raise NotImplementedError
50
54
 
51
55
  @classmethod
52
56
  def from_pydantic_errors(
53
- cls, errors: list[ErrorDetails], read_info_by_sheet: dict[str, SpreadsheetRead] | None = None, **kwargs: Any
57
+ cls,
58
+ errors: list[ErrorDetails],
59
+ read_info_by_sheet: dict[str, SpreadsheetRead] | None = None,
60
+ **kwargs: Any,
54
61
  ) -> "list[NeatValidationError]":
55
62
  output: list[NeatValidationError] = []
56
63
  for error in errors:
@@ -100,16 +107,26 @@ class InvalidRowError(InvalidSheetError, ABC):
100
107
  def __lt__(self, other: object) -> bool:
101
108
  if not isinstance(other, InvalidRowError):
102
109
  return NotImplemented
103
- return (self.sheet_name, self.row, self.column) < (other.sheet_name, other.row, other.column)
110
+ return (self.sheet_name, self.row, self.column) < (
111
+ other.sheet_name,
112
+ other.row,
113
+ other.column,
114
+ )
104
115
 
105
116
  def __eq__(self, other: object) -> bool:
106
117
  if not isinstance(other, InvalidRowError):
107
118
  return NotImplemented
108
- return (self.sheet_name, self.row, self.column) == (other.sheet_name, other.row, other.column)
119
+ return (self.sheet_name, self.row, self.column) == (
120
+ other.sheet_name,
121
+ other.row,
122
+ other.column,
123
+ )
109
124
 
110
125
  @classmethod
111
126
  def from_pydantic_error(
112
- cls, error: ErrorDetails, read_info_by_sheet: dict[str, SpreadsheetRead] | None = None
127
+ cls,
128
+ error: ErrorDetails,
129
+ read_info_by_sheet: dict[str, SpreadsheetRead] | None = None,
113
130
  ) -> Self:
114
131
  sheet_name, _, row, column, *__ = error["loc"]
115
132
  reader = (read_info_by_sheet or {}).get(str(sheet_name), SpreadsheetRead())
@@ -173,7 +190,9 @@ class InvalidRowUnknownSheetError(InvalidRowError):
173
190
 
174
191
  @classmethod
175
192
  def from_pydantic_error(
176
- cls, error: ErrorDetails, read_info_by_sheet: dict[str, SpreadsheetRead] | None = None
193
+ cls,
194
+ error: ErrorDetails,
195
+ read_info_by_sheet: dict[str, SpreadsheetRead] | None = None,
177
196
  ) -> Self:
178
197
  sheet_name, _, row, column, *__ = error["loc"]
179
198
  reader = (read_info_by_sheet or {}).get(str(sheet_name), SpreadsheetRead())
@@ -294,6 +313,27 @@ class ParentClassesNotDefinedError(NeatValidationError):
294
313
  return f"Parent classes {', '.join(self.classes[0])} are not defined. This may be a mistake."
295
314
 
296
315
 
316
+ @dataclass(frozen=True)
317
+ class PrefixNamespaceCollisionError(NeatValidationError):
318
+ description = "Same namespaces are assigned to different prefixes."
319
+ fix = "Make sure that each unique namespace is assigned to a unique prefix"
320
+
321
+ namespaces: list[Namespace]
322
+ prefixes: list[str]
323
+
324
+ def dump(self) -> dict[str, list[str]]:
325
+ output = super().dump()
326
+ output["prefixes"] = self.prefixes
327
+ output["namespaces"] = self.namespaces
328
+ return output
329
+
330
+ def message(self) -> str:
331
+ return (
332
+ f"Namespaces {', '.join(self.namespaces)} are assigned multiple times."
333
+ f" Impacted prefixes: {', '.join(self.prefixes)}."
334
+ )
335
+
336
+
297
337
  @dataclass(frozen=True)
298
338
  class ValueTypeNotDefinedError(NeatValidationError):
299
339
  description = "Value types referred by properties are not defined in Rules."
@@ -259,7 +259,7 @@ class InformationRules(BaseRules):
259
259
  metadata: InformationMetadata = Field(alias="Metadata")
260
260
  properties: SheetList[InformationProperty] = Field(alias="Properties")
261
261
  classes: SheetList[InformationClass] = Field(alias="Classes")
262
- prefixes: dict[str, Namespace] = Field(default_factory=lambda: PREFIXES.copy())
262
+ prefixes: dict[str, Namespace] = Field(default_factory=lambda: PREFIXES.copy(), alias="Prefixes")
263
263
  last: "InformationRules | None" = Field(None, alias="Last")
264
264
  reference: "InformationRules | None" = Field(None, alias="Reference")
265
265
 
@@ -267,6 +267,8 @@ class InformationRules(BaseRules):
267
267
  def parse_str(cls, values: Any) -> Any:
268
268
  if isinstance(values, dict):
269
269
  return {key: Namespace(value) if isinstance(value, str) else value for key, value in values.items()}
270
+ elif values is None:
271
+ values = PREFIXES.copy()
270
272
  return values
271
273
 
272
274
  @model_validator(mode="after")
@@ -5,7 +5,12 @@ from typing import Any, Literal, cast, overload
5
5
 
6
6
  from rdflib import Namespace
7
7
 
8
- from cognite.neat.rules.models._base import DataModelType, ExtensionCategory, SchemaCompleteness, _add_alias
8
+ from cognite.neat.rules.models._base import (
9
+ DataModelType,
10
+ ExtensionCategory,
11
+ SchemaCompleteness,
12
+ _add_alias,
13
+ )
9
14
  from cognite.neat.rules.models.data_types import DataType
10
15
  from cognite.neat.rules.models.entities import (
11
16
  ClassEntity,
@@ -15,7 +20,12 @@ from cognite.neat.rules.models.entities import (
15
20
  UnknownEntity,
16
21
  )
17
22
 
18
- from ._rules import InformationClass, InformationMetadata, InformationProperty, InformationRules
23
+ from ._rules import (
24
+ InformationClass,
25
+ InformationMetadata,
26
+ InformationProperty,
27
+ InformationRules,
28
+ )
19
29
 
20
30
 
21
31
  @dataclass
@@ -105,7 +115,10 @@ class InformationPropertyInput:
105
115
  if data is None:
106
116
  return None
107
117
  if isinstance(data, list) or (isinstance(data, dict) and isinstance(data.get("data"), list)):
108
- items = cast(list[dict[str, Any]], data.get("data") if isinstance(data, dict) else data)
118
+ items = cast(
119
+ list[dict[str, Any]],
120
+ data.get("data") if isinstance(data, dict) else data,
121
+ )
109
122
  return [loaded for item in items if (loaded := cls.load(item)) is not None]
110
123
 
111
124
  _add_alias(data, InformationProperty)
@@ -189,7 +202,10 @@ class InformationClassInput:
189
202
  if data is None:
190
203
  return None
191
204
  if isinstance(data, list) or (isinstance(data, dict) and isinstance(data.get("data"), list)):
192
- items = cast(list[dict[str, Any]], data.get("data") if isinstance(data, dict) else data)
205
+ items = cast(
206
+ list[dict[str, Any]],
207
+ data.get("data") if isinstance(data, dict) else data,
208
+ )
193
209
  return [loaded for item in items if (loaded := cls.load(item)) is not None]
194
210
  _add_alias(data, InformationClass)
195
211
  return cls(
@@ -223,6 +239,7 @@ class InformationRulesInput:
223
239
  metadata: InformationMetadataInput
224
240
  properties: Sequence[InformationPropertyInput]
225
241
  classes: Sequence[InformationClassInput]
242
+ prefixes: "dict[str, Namespace] | None" = None
226
243
  last: "InformationRulesInput | InformationRules | None" = None
227
244
  reference: "InformationRulesInput | InformationRules | None" = None
228
245
 
@@ -244,6 +261,7 @@ class InformationRulesInput:
244
261
  metadata=InformationMetadataInput.load(data.get("metadata")), # type: ignore[arg-type]
245
262
  properties=InformationPropertyInput.load(data.get("properties")), # type: ignore[arg-type]
246
263
  classes=InformationClassInput.load(data.get("classes")), # type: ignore[arg-type]
264
+ prefixes=data.get("prefixes"),
247
265
  last=InformationRulesInput.load(data.get("last")),
248
266
  reference=InformationRulesInput.load(data.get("reference")),
249
267
  )
@@ -270,6 +288,7 @@ class InformationRulesInput:
270
288
  Metadata=self.metadata.dump(),
271
289
  Properties=[prop.dump(default_prefix) for prop in self.properties],
272
290
  Classes=[class_.dump(default_prefix) for class_ in self.classes],
291
+ Prefixes=self.prefixes,
273
292
  Last=last,
274
293
  Reference=reference,
275
294
  )
@@ -1,4 +1,5 @@
1
1
  import itertools
2
+ from collections import Counter
2
3
  from typing import cast
3
4
 
4
5
  from cognite.neat.rules import issues
@@ -35,6 +36,7 @@ class InformationPostValidation:
35
36
  self._referenced_parent_classes_exist()
36
37
  self._referenced_classes_exist()
37
38
  self._referenced_value_types_exist()
39
+ self._namespaces_reassigned()
38
40
 
39
41
  return self.issue_list
40
42
 
@@ -162,3 +164,16 @@ class InformationPostValidation:
162
164
  class_subclass_pairs[class_.class_].extend([parent.as_class_entity() for parent in class_.parent])
163
165
 
164
166
  return class_subclass_pairs
167
+
168
+ def _namespaces_reassigned(self) -> None:
169
+ prefixes = self.rules.prefixes.copy()
170
+ prefixes[self.rules.metadata.namespace.prefix] = self.rules.metadata.namespace
171
+
172
+ if len(set(prefixes.values())) != len(prefixes):
173
+ reused_namespaces = [value for value, count in Counter(prefixes.values()).items() if count > 1]
174
+ impacted_prefixes = [key for key, value in prefixes.items() if value in reused_namespaces]
175
+ self.issue_list.append(
176
+ issues.spreadsheet.PrefixNamespaceCollisionError(
177
+ prefixes=impacted_prefixes, namespaces=reused_namespaces
178
+ )
179
+ )
@@ -24,7 +24,7 @@ steps:
24
24
  pos_y: 77
25
25
  - complex_configs: {}
26
26
  configs:
27
- file_name: Rules-Nordic44-to-TNT.xlsx
27
+ file_name: Rules-Nordic44.xlsx
28
28
  validation_report_file: rules_validation_report.txt
29
29
  validation_report_storage_dir: rules_validation_report
30
30
  version: ""
@@ -2,11 +2,15 @@ import logging
2
2
  from pathlib import Path
3
3
  from typing import ClassVar, cast
4
4
 
5
- from cognite.neat.constants import PREFIXES
5
+ from cognite.neat.constants import DEFAULT_NAMESPACE, PREFIXES
6
6
  from cognite.neat.legacy.graph import stores
7
7
  from cognite.neat.workflows._exceptions import StepNotInitialized
8
8
  from cognite.neat.workflows.model import FlowMessage
9
- from cognite.neat.workflows.steps.data_contracts import RulesData, SolutionGraph, SourceGraph
9
+ from cognite.neat.workflows.steps.data_contracts import (
10
+ RulesData,
11
+ SolutionGraph,
12
+ SourceGraph,
13
+ )
10
14
  from cognite.neat.workflows.steps.step_model import Configurable, Step
11
15
 
12
16
  __all__ = ["ResetGraphStores", "ConfigureGraphStore"]
@@ -71,7 +75,11 @@ class ConfigureDefaultGraphStores(Step):
71
75
  label="Defines which stores to configure",
72
76
  options=["all", "source", "solution"],
73
77
  ),
74
- Configurable(name="solution_rdf_store.api_root_url", value="", label="Root url for graphdb or sparql endpoint"),
78
+ Configurable(
79
+ name="solution_rdf_store.api_root_url",
80
+ value="",
81
+ label="Root url for graphdb or sparql endpoint",
82
+ ),
75
83
  ]
76
84
 
77
85
  def run(self, rules_data: RulesData | None = None) -> (FlowMessage, SourceGraph, SolutionGraph): # type: ignore[override, syntax]
@@ -92,7 +100,7 @@ class ConfigureDefaultGraphStores(Step):
92
100
  store_cls = stores.STORE_BY_TYPE[source_store_type]
93
101
  except KeyError:
94
102
  return FlowMessage(output_text="Invalid store type")
95
- source_graph = store_cls(prefixes=prefixes, base_prefix="neat", namespace=PREFIXES["neat"])
103
+ source_graph = store_cls(prefixes=prefixes, base_prefix="neat", namespace=DEFAULT_NAMESPACE)
96
104
 
97
105
  source_graph.init_graph(
98
106
  self.configs["source_rdf_store.query_url"],
@@ -207,13 +215,19 @@ class ConfigureGraphStore(Step):
207
215
  label="Local directory that is used as local graph store.Only for oxigraph, file store types",
208
216
  ),
209
217
  Configurable(
210
- name="sparql_query_url", value="", label="Query url for sparql endpoint.Only for sparql store type"
218
+ name="sparql_query_url",
219
+ value="",
220
+ label="Query url for sparql endpoint.Only for sparql store type",
211
221
  ),
212
222
  Configurable(
213
- name="sparql_update_url", value="", label="Update url for sparql endpoint.Only for sparql store type"
223
+ name="sparql_update_url",
224
+ value="",
225
+ label="Update url for sparql endpoint.Only for sparql store type",
214
226
  ),
215
227
  Configurable(
216
- name="db_server_api_root_url", value="", label="Root url for graphdb or sparql endpoint.Only for graphdb"
228
+ name="db_server_api_root_url",
229
+ value="",
230
+ label="Root url for graphdb or sparql endpoint.Only for graphdb",
217
231
  ),
218
232
  Configurable(
219
233
  name="init_procedure",
@@ -255,7 +269,7 @@ class ConfigureGraphStore(Step):
255
269
  except KeyError:
256
270
  return FlowMessage(output_text="Invalid store type")
257
271
 
258
- new_graph_store = store_cls(prefixes=prefixes, base_prefix="neat", namespace=PREFIXES["neat"])
272
+ new_graph_store = store_cls(prefixes=prefixes, base_prefix="neat", namespace=DEFAULT_NAMESPACE)
259
273
  new_graph_store.init_graph(
260
274
  self.configs["sparql_query_url"],
261
275
  self.configs["sparql_update_url"],
@@ -271,7 +285,11 @@ class ConfigureGraphStore(Step):
271
285
 
272
286
  return (
273
287
  FlowMessage(output_text="Graph store configured successfully"),
274
- SourceGraph(graph=new_graph_store) if graph_name == "SourceGraph" else SolutionGraph(graph=new_graph_store),
288
+ (
289
+ SourceGraph(graph=new_graph_store)
290
+ if graph_name == "SourceGraph"
291
+ else SolutionGraph(graph=new_graph_store)
292
+ ),
275
293
  )
276
294
 
277
295
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.85.4
3
+ Version: 0.85.6
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -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=V_Xc9MnufQ3zoV5zfHW-c7bzt12iSPI-0T4LTlWx_1E,23
3
+ cognite/neat/_version.py,sha256=Jb8O_xuhfbPElCzRmGQ-MeowF4OZMwHexwUjrGHto1g,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=2U5M6M252swvQPQyooA1EBzFUZNtcTmuSaywfJDgckM,4232
@@ -42,7 +42,7 @@ cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.LICENSE.txt,sha256
42
42
  cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.map,sha256=740AFz-4z3gZtpgAopleqHGGH2rjp9NGV8lVi-vQniI,6282875
43
43
  cognite/neat/app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg,sha256=EYf9q9JoVJ1L1np-XloeEZXCmaibzKmmpXCKn_44xzA,240334
44
44
  cognite/neat/config.py,sha256=oBrWw-KEo0YMbfjVeW6A1FBW7HpP2Pq2ByIq2vlJ10M,6145
45
- cognite/neat/constants.py,sha256=GYVcrFrvqcznYgB_0jAyykIIiIamxyOpv4dTZWj4K4U,1300
45
+ cognite/neat/constants.py,sha256=0iCHO3Xgn9m54F9QxMKE-v_JpU_aikJmnclALHWcZY8,792
46
46
  cognite/neat/exceptions.py,sha256=CM7aCvbek9klOgjTsJ9bfEA8t7KTAL6dc7Mviu4NvSI,4268
47
47
  cognite/neat/graph/__init__.py,sha256=J8JSJj3s4gFbuAexma__KGpBXPN8wuydPTKd6EwgKPA,65
48
48
  cognite/neat/graph/_shared.py,sha256=9QRETdm7hvqIeiHv_n1xi1DUq91Nq7oRRpnPKE0Pnag,181
@@ -72,7 +72,7 @@ cognite/neat/graph/issues/loader.py,sha256=v8YDsehkUT1QUG61JM9BDV_lqowMUnDmGmbay
72
72
  cognite/neat/graph/loaders/__init__.py,sha256=BteVkTklPVUB2W-bbzZug-cEUrx8ZFA-YcQPSxWVpTI,678
73
73
  cognite/neat/graph/loaders/_base.py,sha256=t33I-Olw0xYz3Icf2RJZq9cs5_dEKeY87npxsA597Sw,3012
74
74
  cognite/neat/graph/loaders/_rdf2asset.py,sha256=aFby7BwIrW253LEJ4XqGeUuf4jG9VUe8Lg7OlUnXMlM,4493
75
- cognite/neat/graph/loaders/_rdf2dms.py,sha256=xyr0SfIusfjYjlAXZcIGS1-IQ6LoVWeOB3_q6D304oo,13603
75
+ cognite/neat/graph/loaders/_rdf2dms.py,sha256=eIev7iiNCvzmLA18L6cZb3muGlCvP_t-4Rd48BQHmvY,13825
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=pSc6nHpcDEStGtIeeboAI-QD2PbckWaaNMK3As04jOI,4658
@@ -90,12 +90,12 @@ cognite/neat/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
90
90
  cognite/neat/legacy/graph/__init__.py,sha256=31uTeejWOSd-I8iUG8GOZFhHZcQCsBitJ6X8vu2r1nU,73
91
91
  cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml,sha256=ujJip6XBs5n8enVDPzNnuGkMBwv8g21tIr1sEVJpK5M,1439359
92
92
  cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml,sha256=U2Ns-M4LRjT1fBkhmRj63ur7jDzlRtHK9yOLf_npZ_g,1437996
93
- cognite/neat/legacy/graph/examples/__init__.py,sha256=yAjHVY3b5jOjmbW-iLbhvu7BG014TpGi3K4igkDqW5I,368
93
+ cognite/neat/legacy/graph/examples/__init__.py,sha256=Pj_7Nwek6YrPkeH_vBeXo_VL0UQ0lbv2wE2kjEOfe50,470
94
94
  cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx,sha256=CV_yK5ZSbYS_ktfIZUPD8Sevs47zpswLXQUDFkGE4Gw,45798
95
95
  cognite/neat/legacy/graph/exceptions.py,sha256=R6pyOH774n9w2x_X_nrUr8OMAdjJMf_XPIqAvxIQaWo,3401
96
96
  cognite/neat/legacy/graph/extractors/__init__.py,sha256=wqCiqz-sXhUpTL5LRcrl_KFTNF0yTBRY4EzXT8pyCvA,258
97
97
  cognite/neat/legacy/graph/extractors/_base.py,sha256=ohiuEzwZ1Fh9ers07MCbjGOGQ0HLb-ctwgEvGy7o_AQ,363
98
- cognite/neat/legacy/graph/extractors/_dexpi.py,sha256=0VRylPi_c_ZkOAg-RsslQzhRwatK_qbwZlwnm-n0j_c,1603
98
+ cognite/neat/legacy/graph/extractors/_dexpi.py,sha256=KIGkMYFGRSp86DASARSk77z-qzHqf-MMZkgZjq3rRWw,1613
99
99
  cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py,sha256=sEV6P4a4OlFx_O-vtKoB1H-ex1RnD5VhqmBcazGfLwk,17695
100
100
  cognite/neat/legacy/graph/extractors/_mock_graph_generator.py,sha256=op4eN0-YNzBZoQUkU0OVmaqFNMMwzgpOEjoxqI4034U,14908
101
101
  cognite/neat/legacy/graph/loaders/__init__.py,sha256=Nap1LGaXA3AotL5U6pwY1Yc3J92Y7GC60qVPBhGl5LA,701
@@ -105,7 +105,7 @@ cognite/neat/legacy/graph/loaders/_exceptions.py,sha256=Ep59S5ExVG7phHpfcMEpHu82
105
105
  cognite/neat/legacy/graph/loaders/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
106
  cognite/neat/legacy/graph/loaders/core/labels.py,sha256=z_03w35RcAWtJFVV94jCobHlT1d2AfoJa8FgMSrHBeA,2321
107
107
  cognite/neat/legacy/graph/loaders/core/models.py,sha256=47KwgRuMAwTbDwPC_yRmyhhOVvqTiwgApQEPCFlmU24,5023
108
- cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py,sha256=XkvJhPRI6BD8hWT00I0T28A2jUbuWI3AmILVeQkbJW0,40464
108
+ cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py,sha256=83S992R6CcK6f492bLrER2AkoUZYGu3oDZefrqXv6ek,40466
109
109
  cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py,sha256=hkjCKE7coNbNBbduzy1GCT2Lgt4dtfTrke2_Pl9S67I,22707
110
110
  cognite/neat/legacy/graph/loaders/rdf_to_dms.py,sha256=v1Fjsf69RCxDo_YdYNJBgsmxy5sbmjIYONQKiSUAstI,12979
111
111
  cognite/neat/legacy/graph/loaders/validator.py,sha256=JiEp3gJUzJ8JIbb2crFfFCZ_3cGviXbb31aGusXAM_Y,3328
@@ -124,9 +124,9 @@ cognite/neat/legacy/graph/transformations/query_generator/sparql.py,sha256=v-o1J
124
124
  cognite/neat/legacy/graph/transformations/transformer.py,sha256=FnpjVpJ5Ud6Yho57s06GPKUrgTBm9e2y4XRf03FEzek,14737
125
125
  cognite/neat/legacy/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
126
  cognite/neat/legacy/rules/analysis.py,sha256=-PWaFqzvMlUA6nrZissMvoQm8xwFqniIDApZSUWs9sA,8610
127
- cognite/neat/legacy/rules/examples/Rules-Nordic44-to-TNT.xlsx,sha256=pT2skrX3uWZtw-HIfIipVuPVr3bgb8zOAIqkguVjhCI,58987
128
- cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx,sha256=eo6K177Xrz0CKyUFsbsGF8qZJsJI1Qf1JrzozdbmkeU,80226
129
- cognite/neat/legacy/rules/examples/__init__.py,sha256=rLVPMLdcxpiW6LzfIgJodDKXfpdoYbD4Q60nmK_wAqU,858
127
+ cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx,sha256=KxiQxBdBWaXYvVAwUwVSazpDjHaG8CXamg24ZUf9Nqw,80404
128
+ cognite/neat/legacy/rules/examples/Rules-Nordic44.xlsx,sha256=GyJQHv8Ec0Cvg_Qqf0jGiaHFpGOZzSEGaZd0HGdUkRY,78798
129
+ cognite/neat/legacy/rules/examples/__init__.py,sha256=NrHDTZZTSOkxdX5JC83uJPY1oBpeBlAHHJvGeaBQkb0,851
130
130
  cognite/neat/legacy/rules/examples/power-grid-containers.yaml,sha256=dgAQ5KYT9_FHwsxPapvm00K4XJtKMbGmTs4-KnfpjDg,2782
131
131
  cognite/neat/legacy/rules/examples/power-grid-example.xlsx,sha256=gUklgEhawhJ-EquwZpNp7dFvrLGAOzbKIGh8hTObxMg,77055
132
132
  cognite/neat/legacy/rules/examples/power-grid-model.yaml,sha256=UBtwOBUkdSfkuNOOJhnOdpdPHx3Agx_BZHPMjMmTEU0,5767
@@ -172,7 +172,7 @@ cognite/neat/legacy/rules/models/value_types.py,sha256=wAjYe0yv90FgKqMjJITxyg4Qg
172
172
  cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml,sha256=dViI5aotf6cvcsePXjDBB_osyw1IUbNu2-rsGS1-5NM,1898
173
173
  cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml,sha256=ZYLsdLM2SQD3t3aB3JYoK7ps0xjuMavEhqKo49Uy1Ro,3604
174
174
  cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml,sha256=Iqgxs8EzKcBI4zZoXouQ6UsSZfDW-dJUqkdBmeWUx2c,3384
175
- cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml,sha256=H4aBaeygoZuTb5lCMLxBaOHMrzi45OwtVLwx2NnvOis,6205
175
+ cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml,sha256=naGAGz5uklYvI0fiNj7opLMGsrqTAC-zh6Rizh_hR60,6198
176
176
  cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml,sha256=i7FeD0dzUBhzorjMgo7v1mjShhgsEpobbxIAL-czt34,1364
177
177
  cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml,sha256=0syRT8wghjooFVaZvl1YjmtkSxelRGd0K56VWPlbKcs,2722
178
178
  cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml,sha256=lmuC-zttewtZl5EjnUv8RuM9t2dC-F053duNQHKoPGg,1395
@@ -182,28 +182,28 @@ cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.ya
182
182
  cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
183
  cognite/neat/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
184
  cognite/neat/rules/_shared.py,sha256=Ak2K9YnLhvmp8womNI3bmjaooQZkY9E33-DJ97P9wZg,195
185
- cognite/neat/rules/analysis/__init__.py,sha256=J2yL0QWSvXOWLbaYPyA0HXHh3aqOWmkwobScdgVQpw8,115
186
- cognite/neat/rules/analysis/_base.py,sha256=PmN5NLgGsovsHtsnvUzc_zuarWl-Xwk1azWcYKKuWdA,669
187
- cognite/neat/rules/analysis/_information_rules.py,sha256=fdSMyInsPJdgLHKwSkj2N9bcEXld9ETxUIXWqeDH8L4,17478
185
+ cognite/neat/rules/analysis/__init__.py,sha256=ne6VlpFloufvxddDMbm7pLugnRpDv6ymaxB6_1XBxXw,188
186
+ cognite/neat/rules/analysis/_base.py,sha256=JLYWYM6ZOviH_Lfu-kMX8UYmGHKt2LHq2BMITL-Plrw,395
187
+ cognite/neat/rules/analysis/_information_rules.py,sha256=EW0hDTsYSaWgfdndLg299q4jlq1r0dZkP2Gmnj8R2Ew,20846
188
188
  cognite/neat/rules/examples/__init__.py,sha256=nxIwueAcHgZhkYriGxnDLQmIyiT8PByPHbScjYKDKe0,374
189
189
  cognite/neat/rules/examples/wind-energy.owl,sha256=NuomCA9FuuLF0JlSuG3OKqD4VBcHgSjDKFLV17G1zV8,65934
190
190
  cognite/neat/rules/exceptions.py,sha256=YLnsbXXJdDSr_szQoioEtOdqDV8PR7RdQjpMP2SWeCs,123868
191
191
  cognite/neat/rules/exporters/__init__.py,sha256=nRMUBUf7yr1QPjyITeX2rTLtLLawHv24hhRE39d2-e0,1109
192
192
  cognite/neat/rules/exporters/_base.py,sha256=qZt236sNKTbiM41sgVEYcEtuK5v8Pt14LMLBNiZrNWs,1936
193
193
  cognite/neat/rules/exporters/_rules2dms.py,sha256=xK9xXJ7lLQnzrRlBUJQVLlY4SC-vnnjGUXOzaWvOKmY,14553
194
- cognite/neat/rules/exporters/_rules2excel.py,sha256=HvUdXYHxfLMijYWdTnfqCsw3Izf8S-XDSve-2ZbqF8Y,14248
194
+ cognite/neat/rules/exporters/_rules2excel.py,sha256=bVYq0zmMLDEzSDD39_DQOL6rFGBgRMq5lE7xVMAg8i8,14328
195
195
  cognite/neat/rules/exporters/_rules2ontology.py,sha256=bt8IuxaAYFRyZc1AlS-gYw9Jf6jBr5CYFOaJ3qPeoaA,20527
196
196
  cognite/neat/rules/exporters/_rules2yaml.py,sha256=GA8eUYRxUfIU6IMvlyGO5JidkOD5eUKSbH3qAiFiaCg,3026
197
197
  cognite/neat/rules/exporters/_validation.py,sha256=OlKIyf4nhSDehJwFHDQ8Zdf6HpNfW7dSe2s67eywHu4,4078
198
198
  cognite/neat/rules/importers/__init__.py,sha256=Vxl2Iq1dMXUsI6Wb411xPI3rromdq50xZUci-S8faSw,1097
199
- cognite/neat/rules/importers/_base.py,sha256=3LmDfR-f0nlLGcioWB8IbeZJ6uW5dvnzxJlqaMWc-u0,4516
199
+ cognite/neat/rules/importers/_base.py,sha256=C8_Q99H3Sxds7HO_5aLkw8PItk3Zojxbz4uwx1xgxQM,4550
200
200
  cognite/neat/rules/importers/_dms2rules.py,sha256=Dqoh4qO5IVvjRpxLHZaqCgPC99_r4y7ncEo2WYMxwqU,19302
201
201
  cognite/neat/rules/importers/_dtdl2rules/__init__.py,sha256=CNR-sUihs2mnR1bPMKs3j3L4ds3vFTsrl6YycExZTfU,68
202
202
  cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py,sha256=wW4saKva61Q_i17guY0dc4OseJDQfqHy_QZBtm0OD6g,12134
203
203
  cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py,sha256=ysmWUxZ0npwrTB0uiH5jA0v37sfCwowGaYk17IyxPUU,12663
204
204
  cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py,sha256=Psj3C2jembY_Wu7WWJIFIwrMawvjISjeqfBnoRy_csw,6740
205
205
  cognite/neat/rules/importers/_dtdl2rules/spec.py,sha256=tim_MfN1J0F3Oeqk3BMgIA82d_MZvhRuRMsLK3B4PYc,11897
206
- cognite/neat/rules/importers/_inference2rules.py,sha256=bBpzrioIZl3xdzz5Pal_GJyVPx08ascYW7uckixUy0Q,11667
206
+ cognite/neat/rules/importers/_inference2rules.py,sha256=YJl1xlPDH4lypCQedQh6uQwGwtWTQ466p63bEo_x8Rk,11765
207
207
  cognite/neat/rules/importers/_owl2rules/__init__.py,sha256=tdGcrgtozdQyST-pTlxIa4cLBNTLvtk1nNYR4vOdFSw,63
208
208
  cognite/neat/rules/importers/_owl2rules/_owl2classes.py,sha256=QpTxvrTGczIa48X8lgXGnMN1AWPhHK0DR6uNq175xak,7357
209
209
  cognite/neat/rules/importers/_owl2rules/_owl2metadata.py,sha256=nwnUaBNAAYMoBre2UmsnkJXUuaqGEpR3U3txDrH2w6g,7527
@@ -217,7 +217,7 @@ cognite/neat/rules/issues/dms.py,sha256=eZmbQhdo97SufNLKJu4QWlrhZCxmngiWTwPWIOx7
217
217
  cognite/neat/rules/issues/fileread.py,sha256=ao199mtvhPSW0IA8ZQZ0RzuLIIipYtL0jp6fLqxb4_c,5748
218
218
  cognite/neat/rules/issues/formatters.py,sha256=_ag2bJ9hncOj8pAGJvTTEPs9kTtxbD7vkqvS9Zcnizc,3385
219
219
  cognite/neat/rules/issues/importing.py,sha256=uSk4TXo_CO3bglBZkaiWekXLXXd31UWIZE95clVSLz4,13417
220
- cognite/neat/rules/issues/spreadsheet.py,sha256=jBEczqon1G0H_mCfdCCffWdRLHO5ER8SnGKuR4q4eKs,15882
220
+ cognite/neat/rules/issues/spreadsheet.py,sha256=Nu4yThMhQcYD1bbcTsnaz5ij8XahqzrxnWyoyw1MN58,16805
221
221
  cognite/neat/rules/issues/spreadsheet_file.py,sha256=YCp0Pk_TsiqYuOPdWpjUpre-zvi2c5_MvrC_dxw10YY,4964
222
222
  cognite/neat/rules/models/__init__.py,sha256=IqAg-h8PlcXcR_l-MECNMcVxMecF57vdg-Y488mBgWM,917
223
223
  cognite/neat/rules/models/_base.py,sha256=uZrP_TRu3aljL3XZGMyNtlQDsMPwUEsfSNjGhRdMg88,11234
@@ -245,10 +245,10 @@ cognite/neat/rules/models/domain.py,sha256=wZ-DeIPFnacbNlxSrRuLzUpnhHdTpzNc22z0s
245
245
  cognite/neat/rules/models/entities.py,sha256=qZa_PJOjFk3yTu5NyTSbAjsrU0HUxVnme_7YruBJoRQ,20460
246
246
  cognite/neat/rules/models/information/__init__.py,sha256=HR6g8xgyU53U7Ck8pPdbT70817Q4NC1r1pCRq5SA8iw,291
247
247
  cognite/neat/rules/models/information/_converter.py,sha256=nsfOCe13c3gqbbF1mrQHofemzYKpvg_NKjJZDwSXo5E,13960
248
- cognite/neat/rules/models/information/_rules.py,sha256=TIFZhsPJhYkZjhAIu7iKegcp7Jgbd7iatDKMeC9x4gs,13403
249
- cognite/neat/rules/models/information/_rules_input.py,sha256=ExCjcD0pvsThXYDf3uWYLzSLqN_2OtXFggbW_RB8hr4,10343
248
+ cognite/neat/rules/models/information/_rules.py,sha256=v8ptTif8X55wYaNHvsx65jK7PP2ClSYWyFWUyI2rbyY,13487
249
+ cognite/neat/rules/models/information/_rules_input.py,sha256=1aVaF7VrqaLR-NOq4RR0lnzMp0USCvAPfMA9PjS_mgo,10609
250
250
  cognite/neat/rules/models/information/_serializer.py,sha256=yti9I_xJruxrib66YIBInhze___Io-oPTQH6uWDumPE,3503
251
- cognite/neat/rules/models/information/_validation.py,sha256=Is2GzL2lZU3A5zPu3NjvlXfmIU2_Y10C5Nxi5Denz4g,7528
251
+ cognite/neat/rules/models/information/_validation.py,sha256=K4RTd1I8jrqTHUaPFtAQ8bvS8a4ES9efqXRqQX9wQ8I,8258
252
252
  cognite/neat/rules/models/wrapped_entities.py,sha256=ThhjnNNrpgz0HeORIQ8Q894trxP73P7T_TuZj6qH2CU,7157
253
253
  cognite/neat/utils/__init__.py,sha256=l5Nyqhqo25bcQXCOb_lk01cr-UXsG8cczz_y_I0u6bg,68
254
254
  cognite/neat/utils/auth.py,sha256=rBzx92IN4xGj3UK95UExKlK2dCwQi3svTZ_YBMWaTVo,11739
@@ -273,7 +273,7 @@ cognite/neat/workflows/cdf_store.py,sha256=HCn76PJ7_vrBeTtBv9GDBH77B7wCzVnH13AoS
273
273
  cognite/neat/workflows/examples/Export_DMS/workflow.yaml,sha256=XmyaUAsZrN-GnoBejg9eXHQBm1U1Z-NhdKc11Wm1ieM,1987
274
274
  cognite/neat/workflows/examples/Export_Rules_to_Ontology/workflow.yaml,sha256=ZYLsdLM2SQD3t3aB3JYoK7ps0xjuMavEhqKo49Uy1Ro,3604
275
275
  cognite/neat/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml,sha256=Iqgxs8EzKcBI4zZoXouQ6UsSZfDW-dJUqkdBmeWUx2c,3384
276
- cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml,sha256=H4aBaeygoZuTb5lCMLxBaOHMrzi45OwtVLwx2NnvOis,6205
276
+ cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml,sha256=naGAGz5uklYvI0fiNj7opLMGsrqTAC-zh6Rizh_hR60,6198
277
277
  cognite/neat/workflows/examples/Import_DMS/workflow.yaml,sha256=i7FeD0dzUBhzorjMgo7v1mjShhgsEpobbxIAL-czt34,1364
278
278
  cognite/neat/workflows/examples/Ontology_to_Data_Model/workflow.yaml,sha256=0syRT8wghjooFVaZvl1YjmtkSxelRGd0K56VWPlbKcs,2722
279
279
  cognite/neat/workflows/examples/Validate_Rules/workflow.yaml,sha256=lmuC-zttewtZl5EjnUv8RuM9t2dC-F053duNQHKoPGg,1395
@@ -301,7 +301,7 @@ cognite/neat/workflows/steps/lib/legacy/__init__.py,sha256=725aFzVqhE0tbVOAW70zW
301
301
  cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py,sha256=I5ZD1xeO5LvBhtecZZHxZn2a4reJQPxCo9-UYVnTMYU,3919
302
302
  cognite/neat/workflows/steps/lib/legacy/graph_extractor.py,sha256=OuXATcdQBNaTuthn5EY1KsgFQqijcsBYkb-ZltxWb4U,29357
303
303
  cognite/neat/workflows/steps/lib/legacy/graph_loader.py,sha256=A6le-9AprnT_VXvYcA-DXBuIc1oJ4iS75_hvHBAhNbQ,27265
304
- cognite/neat/workflows/steps/lib/legacy/graph_store.py,sha256=f93iCTvonA3aEyBA2lj7SuK2NxkBv99m1-i06Tx5HxQ,12704
304
+ cognite/neat/workflows/steps/lib/legacy/graph_store.py,sha256=0ldk7EgCZUKfvasFCC8eA-B_nzj5ZeD7p3TLstvyYv4,12928
305
305
  cognite/neat/workflows/steps/lib/legacy/graph_transformer.py,sha256=jTM620LOHrx9bW7rzfktFY-8DMvQJPvzdpuVsWxyU9M,2351
306
306
  cognite/neat/workflows/steps/lib/legacy/rules_exporter.py,sha256=RDpXkXTmKpRqsLF3Akq4v7Npv7r2Rl5sNxxFNUtqIGU,20462
307
307
  cognite/neat/workflows/steps/lib/legacy/rules_importer.py,sha256=u7pkIV4-yVYcyzKYGrmJnAEX6Yy8fGx1XPYnZAsE7pQ,28065
@@ -310,8 +310,8 @@ cognite/neat/workflows/steps_registry.py,sha256=fkTX14ZA7_gkUYfWIlx7A1XbCidvqR23
310
310
  cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
311
311
  cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
312
312
  cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
313
- cognite_neat-0.85.4.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
314
- cognite_neat-0.85.4.dist-info/METADATA,sha256=e2_hXFswjMoSSsiRU61ni4g9KPKXDBspBe73oF7H-30,9493
315
- cognite_neat-0.85.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
316
- cognite_neat-0.85.4.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
317
- cognite_neat-0.85.4.dist-info/RECORD,,
313
+ cognite_neat-0.85.6.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
314
+ cognite_neat-0.85.6.dist-info/METADATA,sha256=3olTyHLxlfFuZug6acBg7dlDCtJps1KTstqlZPNBaKg,9493
315
+ cognite_neat-0.85.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
316
+ cognite_neat-0.85.6.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
317
+ cognite_neat-0.85.6.dist-info/RECORD,,