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

Files changed (129) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/constants.py +3 -0
  3. cognite/neat/graph/__init__.py +0 -3
  4. cognite/neat/graph/extractors/_mock_graph_generator.py +2 -1
  5. cognite/neat/graph/loaders/_base.py +3 -3
  6. cognite/neat/graph/loaders/_rdf2asset.py +24 -25
  7. cognite/neat/graph/loaders/_rdf2dms.py +20 -15
  8. cognite/neat/issues/__init__.py +1 -3
  9. cognite/neat/issues/_base.py +261 -71
  10. cognite/neat/issues/errors/__init__.py +73 -0
  11. cognite/neat/issues/errors/_external.py +67 -0
  12. cognite/neat/issues/errors/_general.py +35 -0
  13. cognite/neat/issues/errors/_properties.py +62 -0
  14. cognite/neat/issues/errors/_resources.py +111 -0
  15. cognite/neat/issues/errors/_workflow.py +36 -0
  16. cognite/neat/issues/formatters.py +1 -1
  17. cognite/neat/issues/warnings/__init__.py +66 -0
  18. cognite/neat/issues/warnings/_external.py +40 -0
  19. cognite/neat/issues/warnings/_general.py +29 -0
  20. cognite/neat/issues/warnings/_models.py +92 -0
  21. cognite/neat/issues/warnings/_properties.py +44 -0
  22. cognite/neat/issues/warnings/_resources.py +55 -0
  23. cognite/neat/issues/warnings/user_modeling.py +113 -0
  24. cognite/neat/rules/_shared.py +53 -2
  25. cognite/neat/rules/analysis/_base.py +1 -1
  26. cognite/neat/rules/exporters/_base.py +7 -18
  27. cognite/neat/rules/exporters/_rules2dms.py +17 -20
  28. cognite/neat/rules/exporters/_rules2excel.py +9 -16
  29. cognite/neat/rules/exporters/_rules2ontology.py +77 -64
  30. cognite/neat/rules/exporters/_rules2yaml.py +6 -9
  31. cognite/neat/rules/exporters/_validation.py +11 -96
  32. cognite/neat/rules/importers/_base.py +9 -58
  33. cognite/neat/rules/importers/_dms2rules.py +188 -135
  34. cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +48 -35
  35. cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +36 -45
  36. cognite/neat/rules/importers/_dtdl2rules/spec.py +7 -0
  37. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2classes.py +8 -4
  38. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2metadata.py +3 -3
  39. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2properties.py +18 -11
  40. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2rules.py +12 -19
  41. cognite/neat/rules/importers/_rdf/_inference2rules.py +14 -37
  42. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2classes.py +1 -0
  43. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2properties.py +1 -0
  44. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +9 -20
  45. cognite/neat/rules/importers/_rdf/_shared.py +4 -4
  46. cognite/neat/rules/importers/_spreadsheet2rules.py +46 -97
  47. cognite/neat/rules/importers/_yaml2rules.py +32 -58
  48. cognite/neat/rules/models/__init__.py +21 -5
  49. cognite/neat/rules/models/_base_input.py +162 -0
  50. cognite/neat/rules/models/{_base.py → _base_rules.py} +1 -12
  51. cognite/neat/rules/models/_rdfpath.py +4 -4
  52. cognite/neat/rules/models/{_types/_field.py → _types.py} +5 -10
  53. cognite/neat/rules/models/asset/__init__.py +5 -2
  54. cognite/neat/rules/models/asset/_rules.py +3 -23
  55. cognite/neat/rules/models/asset/_rules_input.py +40 -115
  56. cognite/neat/rules/models/asset/_validation.py +14 -10
  57. cognite/neat/rules/models/data_types.py +150 -44
  58. cognite/neat/rules/models/dms/__init__.py +19 -7
  59. cognite/neat/rules/models/dms/_exporter.py +102 -34
  60. cognite/neat/rules/models/dms/_rules.py +65 -162
  61. cognite/neat/rules/models/dms/_rules_input.py +186 -254
  62. cognite/neat/rules/models/dms/_schema.py +87 -78
  63. cognite/neat/rules/models/dms/_serializer.py +44 -3
  64. cognite/neat/rules/models/dms/_validation.py +106 -68
  65. cognite/neat/rules/models/domain.py +52 -1
  66. cognite/neat/rules/models/entities/__init__.py +63 -0
  67. cognite/neat/rules/models/entities/_constants.py +73 -0
  68. cognite/neat/rules/models/entities/_loaders.py +76 -0
  69. cognite/neat/rules/models/entities/_multi_value.py +67 -0
  70. cognite/neat/rules/models/{entities.py → entities/_single_value.py} +74 -232
  71. cognite/neat/rules/models/entities/_types.py +86 -0
  72. cognite/neat/rules/models/{wrapped_entities.py → entities/_wrapped.py} +1 -1
  73. cognite/neat/rules/models/information/__init__.py +10 -2
  74. cognite/neat/rules/models/information/_rules.py +10 -22
  75. cognite/neat/rules/models/information/_rules_input.py +57 -204
  76. cognite/neat/rules/models/information/_validation.py +48 -25
  77. cognite/neat/rules/transformers/__init__.py +21 -0
  78. cognite/neat/rules/transformers/_base.py +81 -0
  79. cognite/neat/rules/{models/information/_converter.py → transformers/_converters.py} +217 -21
  80. cognite/neat/rules/transformers/_map_onto.py +97 -0
  81. cognite/neat/rules/transformers/_pipelines.py +61 -0
  82. cognite/neat/rules/transformers/_verification.py +136 -0
  83. cognite/neat/{graph/stores → store}/_provenance.py +10 -1
  84. cognite/neat/utils/auxiliary.py +2 -35
  85. cognite/neat/utils/cdf/data_classes.py +20 -0
  86. cognite/neat/utils/regex_patterns.py +6 -0
  87. cognite/neat/utils/text.py +17 -0
  88. cognite/neat/workflows/base.py +4 -4
  89. cognite/neat/workflows/cdf_store.py +3 -3
  90. cognite/neat/workflows/steps/data_contracts.py +1 -1
  91. cognite/neat/workflows/steps/lib/current/graph_extractor.py +3 -3
  92. cognite/neat/workflows/steps/lib/current/graph_loader.py +2 -2
  93. cognite/neat/workflows/steps/lib/current/graph_store.py +1 -1
  94. cognite/neat/workflows/steps/lib/current/rules_exporter.py +116 -47
  95. cognite/neat/workflows/steps/lib/current/rules_importer.py +30 -28
  96. cognite/neat/workflows/steps/lib/current/rules_validator.py +5 -6
  97. cognite/neat/workflows/steps/lib/io/io_steps.py +5 -5
  98. cognite/neat/workflows/steps_registry.py +4 -5
  99. {cognite_neat-0.88.2.dist-info → cognite_neat-0.89.0.dist-info}/METADATA +1 -1
  100. {cognite_neat-0.88.2.dist-info → cognite_neat-0.89.0.dist-info}/RECORD +105 -106
  101. cognite/neat/exceptions.py +0 -145
  102. cognite/neat/graph/exceptions.py +0 -90
  103. cognite/neat/issues/errors/external.py +0 -21
  104. cognite/neat/issues/errors/properties.py +0 -75
  105. cognite/neat/issues/errors/resources.py +0 -123
  106. cognite/neat/issues/errors/schema.py +0 -0
  107. cognite/neat/issues/neat_warnings/__init__.py +0 -2
  108. cognite/neat/issues/neat_warnings/identifier.py +0 -27
  109. cognite/neat/issues/neat_warnings/models.py +0 -22
  110. cognite/neat/issues/neat_warnings/properties.py +0 -77
  111. cognite/neat/issues/neat_warnings/resources.py +0 -125
  112. cognite/neat/rules/issues/__init__.py +0 -22
  113. cognite/neat/rules/issues/base.py +0 -63
  114. cognite/neat/rules/issues/dms.py +0 -549
  115. cognite/neat/rules/issues/fileread.py +0 -197
  116. cognite/neat/rules/issues/ontology.py +0 -298
  117. cognite/neat/rules/issues/spreadsheet.py +0 -563
  118. cognite/neat/rules/issues/spreadsheet_file.py +0 -151
  119. cognite/neat/rules/issues/tables.py +0 -72
  120. cognite/neat/rules/models/_constants.py +0 -1
  121. cognite/neat/rules/models/_types/__init__.py +0 -19
  122. cognite/neat/rules/models/asset/_converter.py +0 -4
  123. cognite/neat/rules/models/dms/_converter.py +0 -145
  124. cognite/neat/workflows/_exceptions.py +0 -41
  125. /cognite/neat/{graph/stores → store}/__init__.py +0 -0
  126. /cognite/neat/{graph/stores → store}/_base.py +0 -0
  127. {cognite_neat-0.88.2.dist-info → cognite_neat-0.89.0.dist-info}/LICENSE +0 -0
  128. {cognite_neat-0.88.2.dist-info → cognite_neat-0.89.0.dist-info}/WHEEL +0 -0
  129. {cognite_neat-0.88.2.dist-info → cognite_neat-0.89.0.dist-info}/entry_points.txt +0 -0
@@ -1,99 +1,14 @@
1
- import warnings
2
- from typing import Literal, overload
1
+ from collections import defaultdict
2
+ from collections.abc import Iterable
3
3
 
4
- from cognite.neat.exceptions import wrangle_warnings
5
- from cognite.neat.issues.neat_warnings.properties import PropertyRedefinedWarning
6
- from cognite.neat.rules.issues.dms import EntityIDNotDMSCompliantWarning
7
- from cognite.neat.rules.models import InformationRules
8
- from cognite.neat.utils.regex_patterns import DMS_PROPERTY_ID_COMPLIANCE_REGEX, PATTERNS, VIEW_ID_COMPLIANCE_REGEX
4
+ from cognite.neat.rules.models.entities import ClassEntity
5
+ from cognite.neat.rules.models.information import InformationProperty
9
6
 
10
7
 
11
- @overload
12
- def are_entity_names_dms_compliant(
13
- rules: InformationRules, return_report: Literal[True]
14
- ) -> tuple[bool, list[dict]]: ...
15
-
16
-
17
- @overload
18
- def are_entity_names_dms_compliant(rules: InformationRules, return_report: Literal[False] = False) -> bool: ...
19
-
20
-
21
- def are_entity_names_dms_compliant(
22
- rules: InformationRules, return_report: bool = False
23
- ) -> bool | tuple[bool, list[dict]]:
24
- """Check if data model definitions are valid."""
25
-
26
- flag: bool = True
27
- with warnings.catch_warnings(record=True) as validation_warnings:
28
- for class_ in rules.classes:
29
- if not PATTERNS.view_id_compliance.match(class_.class_.suffix):
30
- warnings.warn(
31
- EntityIDNotDMSCompliantWarning(class_.class_.versioned_id, "Class", VIEW_ID_COMPLIANCE_REGEX),
32
- stacklevel=2,
33
- )
34
- flag = False
35
-
36
- for _, property_ in enumerate(rules.properties):
37
- # check class id which would resolve as view/container id
38
- if not PATTERNS.view_id_compliance.match(property_.class_.suffix):
39
- warnings.warn(
40
- EntityIDNotDMSCompliantWarning(
41
- property_.class_.versioned_id,
42
- "Class",
43
- VIEW_ID_COMPLIANCE_REGEX,
44
- ),
45
- stacklevel=2,
46
- )
47
- flag = False
48
-
49
- # check property id which would resolve as view/container id
50
- if not PATTERNS.dms_property_id_compliance.match(property_.property_):
51
- warnings.warn(
52
- EntityIDNotDMSCompliantWarning(property_.property_, "Property", DMS_PROPERTY_ID_COMPLIANCE_REGEX),
53
- stacklevel=2,
54
- )
55
- flag = False
56
-
57
- if return_report:
58
- return flag, wrangle_warnings(validation_warnings)
59
- else:
60
- return flag
61
-
62
-
63
- @overload
64
- def are_properties_redefined(rules: InformationRules, return_report: Literal[True]) -> tuple[bool, list[dict]]: ...
65
-
66
-
67
- @overload
68
- def are_properties_redefined(rules: InformationRules, return_report: Literal[False] = False) -> bool: ...
69
-
70
-
71
- def are_properties_redefined(rules: InformationRules, return_report: bool = False) -> bool | tuple[bool, list[dict]]:
72
- flag: bool = False
73
- with warnings.catch_warnings(record=True) as validation_warnings:
74
- analyzed_properties: dict[str, list[str]] = {}
75
- for property_ in rules.properties:
76
- if property_.property_ not in analyzed_properties:
77
- analyzed_properties[property_.property_] = [property_.class_.versioned_id]
78
- elif property_.class_ in analyzed_properties[property_.property_]:
79
- flag = True
80
- warnings.warn(
81
- PropertyRedefinedWarning[str](property_.class_.versioned_id, "Class", property_.property_),
82
- stacklevel=2,
83
- )
84
-
85
- else:
86
- analyzed_properties[property_.property_].append(property_.class_.versioned_id)
87
-
88
- if return_report:
89
- return flag, wrangle_warnings(validation_warnings)
90
- else:
91
- return flag
92
-
93
-
94
- def property_ids_camel_case_compliant(rules) -> bool | tuple[bool, list[dict]]:
95
- raise NotImplementedError()
96
-
97
-
98
- def class_id_pascal_case_compliant(rules) -> bool | tuple[bool, list[dict]]:
99
- raise NotImplementedError()
8
+ def duplicated_properties(
9
+ properties: Iterable[InformationProperty],
10
+ ) -> dict[tuple[ClassEntity, str], list[tuple[int, InformationProperty]]]:
11
+ class_properties_by_id: dict[tuple[ClassEntity, str], list[tuple[int, InformationProperty]]] = defaultdict(list)
12
+ for prop_no, prop in enumerate(properties):
13
+ class_properties_by_id[(prop.class_, prop.property_)].append((prop_no, prop))
14
+ return {k: v for k, v in class_properties_by_id.items() if len(v) > 1}
@@ -4,76 +4,27 @@ from abc import ABC, abstractmethod
4
4
  from collections.abc import Iterator
5
5
  from contextlib import contextmanager
6
6
  from datetime import datetime
7
- from typing import Any, Literal, overload
7
+ from typing import Any, Generic, Literal
8
8
 
9
9
  from pydantic import ValidationError
10
10
  from rdflib import Namespace
11
11
 
12
12
  from cognite.neat.issues import IssueList, NeatError, NeatWarning
13
- from cognite.neat.rules._shared import Rules
14
- from cognite.neat.rules.issues.base import (
15
- NeatValidationError,
16
- ValidationWarning,
17
- )
18
- from cognite.neat.rules.models import AssetRules, DMSRules, InformationRules, RoleTypes
13
+ from cognite.neat.rules._shared import ReadRules, T_InputRules
19
14
  from cognite.neat.utils.auxiliary import class_html_doc
20
15
 
21
16
 
22
- class BaseImporter(ABC):
17
+ class BaseImporter(ABC, Generic[T_InputRules]):
23
18
  """
24
19
  BaseImporter class which all importers inherit from.
25
20
  """
26
21
 
27
- @overload
28
- def to_rules(self, errors: Literal["raise"], role: RoleTypes | None = None) -> Rules: ...
29
-
30
- @overload
31
- def to_rules(
32
- self, errors: Literal["continue"] = "continue", role: RoleTypes | None = None
33
- ) -> tuple[Rules | None, IssueList]: ...
34
-
35
22
  @abstractmethod
36
- def to_rules(
37
- self,
38
- errors: Literal["raise", "continue"] = "continue",
39
- role: RoleTypes | None = None,
40
- ) -> tuple[Rules | None, IssueList] | Rules:
41
- """
42
- Creates `Rules` object from the data for target role.
43
- """
44
- ...
45
-
46
- @classmethod
47
- def _to_output(
48
- cls,
49
- rules: Rules,
50
- issues: IssueList,
51
- errors: Literal["raise", "continue"] = "continue",
52
- role: RoleTypes | None = None,
53
- ) -> tuple[Rules | None, IssueList] | Rules:
54
- """Converts the rules to the output format."""
55
-
56
- if rules.metadata.role is role or role is None:
57
- output = rules
58
- elif isinstance(rules, DMSRules) or isinstance(rules, AssetRules) and role is RoleTypes.information:
59
- output = rules.as_information_rules()
60
- elif isinstance(rules, InformationRules) or isinstance(rules, AssetRules) and role is RoleTypes.dms:
61
- output = rules.as_dms_rules()
62
- else:
63
- raise NotImplementedError(f"Role {role} is not supported for {type(rules).__name__} rules")
64
-
65
- if errors == "raise":
66
- return output
67
- else:
68
- return output, issues
69
-
70
- @classmethod
71
- def _return_or_raise(cls, issue_list: IssueList, errors: Literal["raise", "continue"]) -> tuple[None, IssueList]:
72
- if errors == "raise":
73
- raise issue_list.as_errors()
74
- return None, issue_list
23
+ def to_rules(self) -> ReadRules[T_InputRules]:
24
+ """Creates `Rules` object from the data for target role."""
25
+ raise NotImplementedError()
75
26
 
76
- def _default_metadata(self):
27
+ def _default_metadata(self) -> dict[str, Any]:
77
28
  return {
78
29
  "prefix": "neat",
79
30
  "schema": "partial",
@@ -103,8 +54,8 @@ class _FutureResult:
103
54
  @contextmanager
104
55
  def _handle_issues(
105
56
  issues: IssueList,
106
- error_cls: type[NeatError] = NeatValidationError,
107
- warning_cls: type[NeatWarning] = ValidationWarning,
57
+ error_cls: type[NeatError] = NeatError,
58
+ warning_cls: type[NeatWarning] = NeatWarning,
108
59
  error_args: dict[str, Any] | None = None,
109
60
  ) -> Iterator[_FutureResult]:
110
61
  """This is an internal help function to handle issues and warnings.