cognite-neat 0.75.6__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 (37) 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/_models.py +6 -1
  6. cognite/neat/rules/exporters/_rules2dms.py +67 -14
  7. cognite/neat/rules/exporters/_rules2ontology.py +20 -17
  8. cognite/neat/rules/exporters/_validation.py +2 -2
  9. cognite/neat/rules/importers/_dms2rules.py +14 -15
  10. cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +21 -19
  11. cognite/neat/rules/importers/_dtdl2rules/spec.py +1 -1
  12. cognite/neat/rules/importers/_owl2rules/_owl2rules.py +2 -2
  13. cognite/neat/rules/importers/_spreadsheet2rules.py +6 -1
  14. cognite/neat/rules/importers/_yaml2rules.py +8 -2
  15. cognite/neat/rules/issues/dms.py +1 -1
  16. cognite/neat/rules/models/data_types.py +282 -0
  17. cognite/neat/rules/models/entities.py +442 -0
  18. cognite/neat/rules/models/rdfpath.py +111 -11
  19. cognite/neat/rules/models/rules/_base.py +2 -2
  20. cognite/neat/rules/models/rules/_dms_architect_rules.py +117 -188
  21. cognite/neat/rules/models/rules/_dms_rules_write.py +355 -0
  22. cognite/neat/rules/models/rules/_dms_schema.py +3 -3
  23. cognite/neat/rules/models/rules/_domain_rules.py +6 -3
  24. cognite/neat/rules/models/rules/_information_rules.py +68 -61
  25. cognite/neat/rules/models/rules/_types/__init__.py +0 -47
  26. cognite/neat/rules/models/rules/_types/_base.py +1 -309
  27. cognite/neat/rules/models/rules/_types/_field.py +0 -225
  28. cognite/neat/utils/cdf_loaders/_data_modeling.py +4 -2
  29. cognite/neat/workflows/steps/lib/rules_exporter.py +97 -0
  30. cognite/neat/workflows/steps/lib/rules_importer.py +3 -3
  31. {cognite_neat-0.75.6.dist-info → cognite_neat-0.75.8.dist-info}/METADATA +1 -1
  32. {cognite_neat-0.75.6.dist-info → cognite_neat-0.75.8.dist-info}/RECORD +35 -34
  33. cognite/neat/rules/models/_entity.py +0 -142
  34. cognite/neat/rules/models/rules/_types/_value.py +0 -159
  35. {cognite_neat-0.75.6.dist-info → cognite_neat-0.75.8.dist-info}/LICENSE +0 -0
  36. {cognite_neat-0.75.6.dist-info → cognite_neat-0.75.8.dist-info}/WHEEL +0 -0
  37. {cognite_neat-0.75.6.dist-info → cognite_neat-0.75.8.dist-info}/entry_points.txt +0 -0
@@ -1,142 +0,0 @@
1
- import re
2
- import sys
3
- from functools import total_ordering
4
- from typing import ClassVar
5
-
6
- from pydantic import BaseModel
7
-
8
- if sys.version_info >= (3, 11):
9
- from enum import StrEnum
10
- from typing import Self
11
- else:
12
- from backports.strenum import StrEnum
13
- from typing_extensions import Self
14
-
15
-
16
- class EntityTypes(StrEnum):
17
- subject = "subject"
18
- predicate = "predicate"
19
- object = "object"
20
- class_ = "class"
21
- parent_class = "parent_class"
22
- property_ = "property"
23
- object_property = "ObjectProperty"
24
- data_property = "DatatypeProperty"
25
- annotation_property = "AnnotationProperty"
26
- object_value_type = "object_value_type"
27
- data_value_type = "data_value_type" # these are strings, floats, ...
28
- xsd_value_type = "xsd_value_type"
29
- dms_value_type = "dms_value_type"
30
- view = "view"
31
- view_prop = "view_prop"
32
- reference_entity = "reference_entity"
33
- container = "container"
34
- datamodel = "datamodel"
35
- undefined = "undefined"
36
-
37
-
38
- # ALLOWED
39
- ALLOWED_PATTERN = r"[^a-zA-Z0-9-_.]"
40
-
41
- # FOR PARSING STRINGS:
42
- PREFIX_REGEX = r"[a-zA-Z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+"
43
- SUFFIX_REGEX = r"[a-zA-Z0-9-_.]+[a-zA-Z0-9]|[-_.]*[a-zA-Z0-9]+"
44
- VERSION_REGEX = r"[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?"
45
- PROPERTY_REGEX = r"[a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9]?"
46
- ENTITY_ID_REGEX = rf"{PREFIX_REGEX}:({SUFFIX_REGEX})"
47
- ENTITY_ID_REGEX_COMPILED = re.compile(rf"^(?P<prefix>{PREFIX_REGEX}):(?P<suffix>{SUFFIX_REGEX})$")
48
- VERSIONED_ENTITY_REGEX_COMPILED = re.compile(
49
- rf"^(?P<prefix>{PREFIX_REGEX}):(?P<suffix>{SUFFIX_REGEX})\(version=(?P<version>{VERSION_REGEX})\)$"
50
- )
51
- CLASS_ID_REGEX = rf"(?P<{EntityTypes.class_}>{ENTITY_ID_REGEX})"
52
- CLASS_ID_REGEX_COMPILED = re.compile(rf"^{CLASS_ID_REGEX}$")
53
- PROPERTY_ID_REGEX = rf"\((?P<{EntityTypes.property_}>{ENTITY_ID_REGEX})\)"
54
-
55
- Undefined = type(object())
56
- Unknown = type(object())
57
-
58
-
59
- # mypy does not like the sentinel value, and it is not possible to ignore only the line with it below.
60
- # so we ignore all errors beyond this point.
61
- # mypy: ignore-errors
62
- @total_ordering
63
- class Entity(BaseModel, arbitrary_types_allowed=True):
64
- """Entity is a class or property in OWL/RDF sense."""
65
-
66
- type_: ClassVar[EntityTypes] = EntityTypes.undefined
67
- prefix: str | Undefined = Undefined
68
- suffix: str | Unknown
69
- version: str | None = None
70
- name: str | None = None
71
- description: str | None = None
72
-
73
- def __lt__(self, other: object) -> bool:
74
- if type(self) is not type(other) or not isinstance(other, Entity):
75
- return NotImplemented
76
- return self.versioned_id < other.versioned_id
77
-
78
- def __eq__(self, other: object) -> bool:
79
- if type(self) is not type(other) or not isinstance(other, Entity):
80
- return NotImplemented
81
- return self.versioned_id == other.versioned_id
82
-
83
- def __hash__(self) -> int:
84
- return hash(self.versioned_id)
85
-
86
- def as_non_versioned_entity(self) -> Self:
87
- return self.from_string(f"{self.prefix}:{self.suffix}")
88
-
89
- @property
90
- def id(self) -> str:
91
- if self.suffix is Unknown:
92
- return "#N/A"
93
- elif self.prefix is Undefined:
94
- return self.suffix
95
- else:
96
- return f"{self.prefix}:{self.suffix}"
97
-
98
- @property
99
- def versioned_id(self) -> str:
100
- if self.version is None:
101
- return self.id
102
- else:
103
- return f"{self.id}(version={self.version})"
104
-
105
- @property
106
- def space(self) -> str:
107
- """Returns entity space in CDF."""
108
- return self.prefix
109
-
110
- @property
111
- def external_id(self) -> str:
112
- """Returns entity external id in CDF."""
113
- return self.suffix
114
-
115
- def __repr__(self):
116
- return self.versioned_id
117
-
118
- def __str__(self):
119
- return self.versioned_id
120
-
121
- @classmethod
122
- def from_string(cls, entity_string: str, base_prefix: str | None = None) -> Self:
123
- if entity_string == "#N/A":
124
- return cls(prefix=Undefined, suffix=Unknown)
125
- elif result := VERSIONED_ENTITY_REGEX_COMPILED.match(entity_string):
126
- return cls(
127
- prefix=result.group("prefix"),
128
- suffix=result.group("suffix"),
129
- version=result.group("version"),
130
- )
131
- elif result := ENTITY_ID_REGEX_COMPILED.match(entity_string):
132
- return cls(prefix=result.group("prefix"), suffix=result.group("suffix"))
133
- elif base_prefix and re.match(SUFFIX_REGEX, entity_string) and re.match(PREFIX_REGEX, base_prefix):
134
- return cls(prefix=base_prefix, suffix=entity_string)
135
- else:
136
- raise ValueError(f"{cls.__name__} is expected to be prefix:suffix, got {entity_string}")
137
-
138
- @classmethod
139
- def from_list(cls, entity_strings: list[str], base_prefix: str | None = None) -> list[Self]:
140
- return [
141
- cls.from_string(entity_string=entity_string, base_prefix=base_prefix) for entity_string in entity_strings
142
- ]
@@ -1,159 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from datetime import date, datetime
4
- from typing import ClassVar, cast
5
-
6
- from cognite.client.data_classes.data_modeling import (
7
- Boolean,
8
- Date,
9
- FileReference,
10
- Float32,
11
- Float64,
12
- Int32,
13
- Int64,
14
- Json,
15
- SequenceReference,
16
- Text,
17
- TimeSeriesReference,
18
- Timestamp,
19
- )
20
- from pydantic import BaseModel
21
-
22
- from ._base import Entity, EntityTypes
23
-
24
-
25
- class ValueTypeMapping(BaseModel):
26
- """Mapping between XSD, Python, DMS and Graphql types."""
27
-
28
- xsd: str
29
- python: type
30
- dms: type
31
- graphql: str
32
- sql: str
33
-
34
-
35
- # mypy: ignore-errors
36
- class XSDValueType(Entity):
37
- """Value type is a data/object type defined as a child of Entity model."""
38
-
39
- type_: ClassVar[EntityTypes] = EntityTypes.xsd_value_type
40
- mapping: ValueTypeMapping
41
-
42
- @property
43
- def python(self) -> type:
44
- """Returns the Python type for a given value type."""
45
- return cast(ValueTypeMapping, self.mapping).python
46
-
47
- @property
48
- def xsd(self) -> str:
49
- """Returns the XSD type for a given value type."""
50
- return cast(ValueTypeMapping, self.mapping).xsd
51
-
52
- @property
53
- def dms(self) -> type:
54
- """Returns the DMS type for a given value type."""
55
- return cast(ValueTypeMapping, self.mapping).dms
56
-
57
- @property
58
- def graphql(self) -> str:
59
- """Returns the Graphql type for a given value type."""
60
- return cast(ValueTypeMapping, self.mapping).graphql
61
-
62
- @property
63
- def sql(self) -> str:
64
- """Returns the SQL type for a given value type."""
65
- return cast(ValueTypeMapping, self.mapping).sql
66
-
67
-
68
- class DMSValueType(XSDValueType):
69
- type_: ClassVar[EntityTypes] = EntityTypes.dms_value_type
70
-
71
- def __str__(self) -> str:
72
- return self.dms._type
73
-
74
-
75
- _DATA_TYPES: list[dict] = [
76
- {"name": "boolean", "python": bool, "GraphQL": "Boolean", "dms": Boolean, "SQL": "BOOLEAN"},
77
- {"name": "float", "python": float, "GraphQL": "Float", "dms": Float64, "SQL": "FLOAT"},
78
- {"name": "double", "python": float, "GraphQL": "Float", "dms": Float64, "SQL": "DOUBLE"},
79
- {"name": "integer", "python": int, "GraphQL": "Int", "dms": Int32, "SQL": "INTEGER"},
80
- {"name": "nonPositiveInteger", "python": int, "GraphQL": "Int", "dms": Int32, "SQL": "INTEGER"},
81
- {"name": "nonNegativeInteger", "python": int, "GraphQL": "Int", "dms": Int32, "SQL": "INTEGER"},
82
- {"name": "negativeInteger", "python": int, "GraphQL": "Int", "dms": Int32, "SQL": "INTEGER"},
83
- {"name": "long", "python": int, "GraphQL": "Int", "dms": Int64, "SQL": "INTEGER"},
84
- {"name": "string", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
85
- {"name": "langString", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
86
- {"name": "anyURI", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
87
- {"name": "normalizedString", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
88
- {"name": "token", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
89
- # Graphql does not have a datetime/date type this is CDF specific
90
- {"name": "dateTime", "python": datetime, "GraphQL": "Timestamp", "dms": Timestamp, "SQL": "TIMESTAMP"},
91
- {"name": "dateTimeStamp", "python": datetime, "GraphQL": "Timestamp", "dms": Timestamp, "SQL": "TIMESTAMP"},
92
- {"name": "date", "python": date, "GraphQL": "String", "dms": Date, "SQL": "DATE"},
93
- # Some RDF types which are not in XSD
94
- {"name": "PlainLiteral", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
95
- {"name": "Literal", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
96
- # CDF specific types, not in XSD
97
- {
98
- "name": "timeseries",
99
- "python": TimeSeriesReference,
100
- "GraphQL": "TimeSeries",
101
- "dms": TimeSeriesReference,
102
- "SQL": "STRING",
103
- },
104
- {"name": "file", "python": FileReference, "GraphQL": "File", "dms": FileReference, "SQL": "STRING"},
105
- {"name": "sequence", "python": SequenceReference, "GraphQL": "Sequence", "dms": SequenceReference, "SQL": "STRING"},
106
- {"name": "json", "python": Json, "GraphQL": "Json", "dms": Json, "SQL": "STRING"},
107
- ]
108
-
109
- _DMS_TYPES: list[dict] = [
110
- {"name": "boolean", "python": bool, "GraphQL": "Boolean", "dms": Boolean, "SQL": "BOOLEAN"},
111
- {"name": "float", "python": float, "GraphQL": "Float", "dms": Float32, "SQL": "FLOAT"},
112
- {"name": "double", "python": float, "GraphQL": "Float", "dms": Float64, "SQL": "DOUBLE"},
113
- {"name": "integer", "python": int, "GraphQL": "Int", "dms": Int32, "SQL": "INTEGER"},
114
- {"name": "long", "python": int, "GraphQL": "Int", "dms": Int64, "SQL": "INTEGER"},
115
- {"name": "string", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
116
- {"name": "dateTimeStamp", "python": datetime, "GraphQL": "Timestamp", "dms": Timestamp, "SQL": "TIMESTAMP"},
117
- {
118
- "name": "timeseries",
119
- "python": TimeSeriesReference,
120
- "GraphQL": "TimeSeries",
121
- "dms": TimeSeriesReference,
122
- "SQL": "STRING",
123
- },
124
- {"name": "file", "python": FileReference, "GraphQL": "File", "dms": FileReference, "SQL": "STRING"},
125
- {"name": "sequence", "python": SequenceReference, "GraphQL": "Sequence", "dms": SequenceReference, "SQL": "STRING"},
126
- {"name": "json", "python": Json, "GraphQL": "Json", "dms": Json, "SQL": "STRING"},
127
- ]
128
-
129
- XSD_VALUE_TYPE_MAPPINGS: dict[str, XSDValueType] = {
130
- data_type["name"]: XSDValueType(
131
- prefix="xsd",
132
- suffix=cast(str, data_type["name"]),
133
- name=cast(str, data_type["name"]),
134
- mapping=ValueTypeMapping(
135
- xsd=data_type["name"],
136
- python=data_type["python"],
137
- dms=data_type["dms"],
138
- graphql=data_type["GraphQL"],
139
- sql=data_type["SQL"],
140
- ),
141
- )
142
- for data_type in _DATA_TYPES
143
- }
144
-
145
- DMS_VALUE_TYPE_MAPPINGS: dict[str, DMSValueType] = {
146
- data_type["dms"]._type.casefold(): DMSValueType(
147
- prefix="dms",
148
- suffix=data_type["dms"]._type.casefold(),
149
- name=data_type["dms"]._type.casefold(),
150
- mapping=ValueTypeMapping(
151
- xsd=data_type["name"],
152
- python=data_type["python"],
153
- dms=data_type["dms"],
154
- graphql=data_type["GraphQL"],
155
- sql=data_type["SQL"],
156
- ),
157
- )
158
- for data_type in _DMS_TYPES
159
- }