cognite-neat 0.97.3__py3-none-any.whl → 0.98.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 (65) hide show
  1. cognite/neat/_graph/loaders/__init__.py +1 -2
  2. cognite/neat/_issues/warnings/_models.py +9 -0
  3. cognite/neat/_rules/_shared.py +3 -8
  4. cognite/neat/_rules/analysis/__init__.py +1 -2
  5. cognite/neat/_rules/analysis/_base.py +2 -23
  6. cognite/neat/_rules/analysis/_dms.py +4 -10
  7. cognite/neat/_rules/analysis/_information.py +2 -10
  8. cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  9. cognite/neat/_rules/exporters/_rules2excel.py +15 -72
  10. cognite/neat/_rules/exporters/_rules2ontology.py +4 -4
  11. cognite/neat/_rules/importers/_base.py +3 -4
  12. cognite/neat/_rules/importers/_dms2rules.py +17 -40
  13. cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +1 -7
  14. cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +7 -10
  15. cognite/neat/_rules/importers/_rdf/_base.py +17 -29
  16. cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2classes.py +2 -2
  17. cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2metadata.py +5 -10
  18. cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2properties.py +1 -2
  19. cognite/neat/_rules/importers/_rdf/_inference2rules.py +30 -18
  20. cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2classes.py +2 -2
  21. cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2metadata.py +5 -8
  22. cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2properties.py +1 -2
  23. cognite/neat/_rules/importers/_rdf/_shared.py +25 -140
  24. cognite/neat/_rules/importers/_spreadsheet2rules.py +10 -41
  25. cognite/neat/_rules/models/__init__.py +2 -16
  26. cognite/neat/_rules/models/_base_rules.py +98 -52
  27. cognite/neat/_rules/models/dms/_exporter.py +7 -160
  28. cognite/neat/_rules/models/dms/_rules.py +18 -126
  29. cognite/neat/_rules/models/dms/_rules_input.py +20 -48
  30. cognite/neat/_rules/models/dms/_schema.py +11 -0
  31. cognite/neat/_rules/models/dms/_validation.py +9 -107
  32. cognite/neat/_rules/models/information/_rules.py +19 -114
  33. cognite/neat/_rules/models/information/_rules_input.py +32 -41
  34. cognite/neat/_rules/models/information/_validation.py +34 -102
  35. cognite/neat/_rules/transformers/__init__.py +1 -4
  36. cognite/neat/_rules/transformers/_converters.py +18 -195
  37. cognite/neat/_rules/transformers/_mapping.py +1 -5
  38. cognite/neat/_rules/transformers/_verification.py +0 -14
  39. cognite/neat/_session/_base.py +34 -13
  40. cognite/neat/_session/_collector.py +126 -0
  41. cognite/neat/_session/_inspect.py +5 -5
  42. cognite/neat/_session/_prepare.py +4 -4
  43. cognite/neat/_session/_read.py +62 -9
  44. cognite/neat/_session/_set.py +2 -2
  45. cognite/neat/_session/_show.py +11 -11
  46. cognite/neat/_session/_to.py +24 -11
  47. cognite/neat/_session/exceptions.py +20 -3
  48. cognite/neat/_store/_provenance.py +2 -2
  49. cognite/neat/_utils/auxiliary.py +19 -0
  50. cognite/neat/_version.py +1 -1
  51. cognite/neat/_workflows/steps/data_contracts.py +2 -10
  52. cognite/neat/_workflows/steps/lib/current/rules_exporter.py +6 -46
  53. cognite/neat/_workflows/steps/lib/current/rules_validator.py +2 -7
  54. {cognite_neat-0.97.3.dist-info → cognite_neat-0.98.0.dist-info}/METADATA +2 -1
  55. {cognite_neat-0.97.3.dist-info → cognite_neat-0.98.0.dist-info}/RECORD +58 -64
  56. cognite/neat/_graph/loaders/_rdf2asset.py +0 -416
  57. cognite/neat/_rules/analysis/_asset.py +0 -173
  58. cognite/neat/_rules/models/asset/__init__.py +0 -13
  59. cognite/neat/_rules/models/asset/_rules.py +0 -109
  60. cognite/neat/_rules/models/asset/_rules_input.py +0 -101
  61. cognite/neat/_rules/models/asset/_validation.py +0 -45
  62. cognite/neat/_rules/models/domain.py +0 -136
  63. {cognite_neat-0.97.3.dist-info → cognite_neat-0.98.0.dist-info}/LICENSE +0 -0
  64. {cognite_neat-0.97.3.dist-info → cognite_neat-0.98.0.dist-info}/WHEEL +0 -0
  65. {cognite_neat-0.97.3.dist-info → cognite_neat-0.98.0.dist-info}/entry_points.txt +0 -0
@@ -1,109 +0,0 @@
1
- import sys
2
- from typing import Any, ClassVar, cast
3
-
4
- from pydantic import Field, field_validator, model_validator
5
- from rdflib import Namespace, URIRef
6
-
7
- from cognite.neat._constants import DEFAULT_NAMESPACE, get_default_prefixes
8
- from cognite.neat._rules.models._base_rules import BaseRules, RoleTypes, SheetList
9
- from cognite.neat._rules.models.entities import (
10
- CdfResourceEntityList,
11
- ClassEntity,
12
- MultiValueTypeInfo,
13
- Undefined,
14
- )
15
- from cognite.neat._rules.models.information import (
16
- InformationClass,
17
- InformationMetadata,
18
- InformationProperty,
19
- InformationRules,
20
- )
21
-
22
- if sys.version_info >= (3, 11):
23
- from typing import Self
24
- else:
25
- from typing_extensions import Self
26
-
27
-
28
- class AssetMetadata(InformationMetadata):
29
- role: ClassVar[RoleTypes] = RoleTypes.asset
30
-
31
-
32
- class AssetClass(InformationClass): ...
33
-
34
-
35
- class AssetProperty(InformationProperty):
36
- """
37
- A property is a characteristic of a class. It is a named attribute of a class that describes a range of values
38
- or a relationship to another class.
39
-
40
- Args:
41
- class_: Class ID to which property belongs
42
- property_: Property ID of the property
43
- name: Property name.
44
- value_type: Type of value property will hold (data or link to another class)
45
- min_count: Minimum count of the property values. Defaults to 0
46
- max_count: Maximum count of the property values. Defaults to None
47
- default: Default value of the property
48
- reference: Reference to the source of the information, HTTP URI
49
- match_type: The match type of the resource being described and the source entity.
50
- transformation: Actual rule for the transformation from source to target representation of
51
- knowledge graph. Defaults to None (no transformation)
52
- implementation: Details on how given class-property is implemented in the classic CDF
53
- """
54
-
55
- implementation: CdfResourceEntityList = Field(alias="Implementation")
56
-
57
-
58
- class AssetRules(BaseRules):
59
- metadata: AssetMetadata = Field(alias="Metadata")
60
- properties: SheetList[AssetProperty] = Field(alias="Properties")
61
- classes: SheetList[AssetClass] = Field(alias="Classes")
62
- prefixes: dict[str, Namespace] = Field(default_factory=get_default_prefixes)
63
- last: "AssetRules | None" = Field(None, alias="Last")
64
- reference: "AssetRules | None" = Field(None, alias="Reference")
65
-
66
- @field_validator("prefixes", mode="before")
67
- def parse_str(cls, values: Any) -> Any:
68
- if isinstance(values, dict):
69
- return {key: Namespace(value) if isinstance(value, str) else value for key, value in values.items()}
70
- return values
71
-
72
- @model_validator(mode="after")
73
- def update_entities_prefix(self) -> Self:
74
- # update expected_value_types
75
- for property_ in self.properties:
76
- if isinstance(property_.value_type, ClassEntity) and property_.value_type.prefix is Undefined:
77
- property_.value_type.prefix = self.metadata.prefix
78
-
79
- if isinstance(property_.value_type, MultiValueTypeInfo):
80
- property_.value_type.set_default_prefix(self.metadata.prefix)
81
-
82
- if property_.class_.prefix is Undefined:
83
- property_.class_.prefix = self.metadata.prefix
84
-
85
- # update parent classes
86
- for class_ in self.classes:
87
- if class_.parent:
88
- for parent in class_.parent:
89
- if not isinstance(parent.prefix, str):
90
- parent.prefix = self.metadata.prefix
91
- if class_.class_.prefix is Undefined:
92
- class_.class_.prefix = self.metadata.prefix
93
-
94
- return self
95
-
96
- @model_validator(mode="after")
97
- def post_validation(self) -> "AssetRules":
98
- from ._validation import AssetPostValidation
99
-
100
- issue_list = AssetPostValidation(cast(InformationRules, self)).validate()
101
- if issue_list.warnings:
102
- issue_list.trigger_warnings()
103
- if issue_list.has_errors:
104
- raise issue_list.as_exception()
105
- return self
106
-
107
- @property
108
- def id_(self) -> URIRef:
109
- return DEFAULT_NAMESPACE[f"data-model/verified/asset/{self.metadata.prefix}/{self.metadata.version}"]
@@ -1,101 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Any
3
-
4
- from rdflib import Namespace, URIRef
5
-
6
- from cognite.neat._constants import DEFAULT_NAMESPACE
7
- from cognite.neat._rules.models._base_input import InputComponent, InputRules
8
- from cognite.neat._rules.models.data_types import DataType
9
- from cognite.neat._rules.models.entities import (
10
- ClassEntity,
11
- MultiValueTypeInfo,
12
- UnknownEntity,
13
- load_value_type,
14
- )
15
- from cognite.neat._rules.models.information._rules_input import InformationInputClass, InformationInputMetadata
16
-
17
- from ._rules import AssetClass, AssetMetadata, AssetProperty, AssetRules
18
-
19
-
20
- @dataclass
21
- class AssetInputMetadata(InformationInputMetadata):
22
- @classmethod
23
- def _get_verified_cls(cls) -> type[AssetMetadata]:
24
- return AssetMetadata
25
-
26
-
27
- @dataclass
28
- class AssetInputProperty(InputComponent[AssetProperty]):
29
- class_: ClassEntity | str
30
- property_: str
31
- value_type: DataType | ClassEntity | MultiValueTypeInfo | UnknownEntity | str
32
- name: str | None = None
33
- description: str | None = None
34
- comment: str | None = None
35
- min_count: int | None = None
36
- max_count: int | float | None = None
37
- default: Any | None = None
38
- reference: str | None = None
39
- match_type: str | None = None
40
- transformation: str | None = None
41
- implementation: str | None = None
42
- # Only used internally
43
- inherited: bool = False
44
-
45
- @classmethod
46
- def _get_verified_cls(cls) -> type[AssetProperty]:
47
- return AssetProperty
48
-
49
- def dump(self, default_prefix: str) -> dict[str, Any]: # type: ignore[override]
50
- output = super().dump()
51
- output["Class"] = ClassEntity.load(self.class_, prefix=default_prefix)
52
- output["Value Type"] = load_value_type(self.value_type, default_prefix)
53
- return output
54
-
55
-
56
- @dataclass
57
- class AssetInputClass(InformationInputClass):
58
- @classmethod
59
- def _get_verified_cls(cls) -> type[AssetClass]:
60
- return AssetClass
61
-
62
-
63
- @dataclass
64
- class AssetInputRules(InputRules[AssetRules]):
65
- metadata: AssetInputMetadata
66
- properties: list[AssetInputProperty]
67
- classes: list[AssetInputClass]
68
- prefixes: dict[str, Namespace] | None = None
69
- last: "AssetInputRules | None" = None
70
- reference: "AssetInputRules | None" = None
71
-
72
- @classmethod
73
- def _get_verified_cls(cls) -> type[AssetRules]:
74
- return AssetRules
75
-
76
- def dump(self) -> dict[str, Any]:
77
- default_prefix = self.metadata.prefix
78
- reference: dict[str, Any] | None = None
79
- if isinstance(self.reference, AssetInputRules):
80
- reference = self.reference.dump()
81
- elif isinstance(self.reference, AssetRules):
82
- # We need to load through the AssetRulesInput to set the correct default space and version
83
- reference = AssetInputRules.load(self.reference.model_dump()).dump()
84
- last: dict[str, Any] | None = None
85
- if isinstance(self.last, AssetInputRules):
86
- last = self.last.dump()
87
- elif isinstance(self.last, AssetRules):
88
- # We need to load through the AssetRulesInput to set the correct default space and version
89
- last = AssetInputRules.load(self.last.model_dump()).dump()
90
-
91
- return dict(
92
- Metadata=self.metadata.dump(),
93
- Properties=[prop.dump(default_prefix) for prop in self.properties],
94
- Classes=[class_.dump(default_prefix) for class_ in self.classes],
95
- Last=last,
96
- Reference=reference,
97
- )
98
-
99
- @property
100
- def id_(self) -> URIRef:
101
- return DEFAULT_NAMESPACE[f"data-model/unverified/asset/{self.metadata.prefix}/{self.metadata.version}"]
@@ -1,45 +0,0 @@
1
- from graphlib import CycleError
2
- from typing import cast
3
-
4
- from cognite.neat._issues import IssueList
5
- from cognite.neat._issues.errors import NeatValueError, PropertyDefinitionError
6
- from cognite.neat._rules.models._base_rules import SheetList
7
- from cognite.neat._rules.models.asset._rules import AssetProperty, AssetRules
8
- from cognite.neat._rules.models.entities import AssetEntity, AssetFields, ClassEntity
9
- from cognite.neat._rules.models.information._validation import InformationPostValidation
10
-
11
-
12
- class AssetPostValidation(InformationPostValidation):
13
- def validate(self) -> IssueList:
14
- self.issue_list = super().validate()
15
- self._parent_property_point_to_class()
16
- self._circular_dependency()
17
- return self.issue_list
18
-
19
- def _parent_property_point_to_class(self) -> None:
20
- for property_ in cast(SheetList[AssetProperty], self.properties):
21
- for implementation in property_.implementation:
22
- if (
23
- isinstance(implementation, AssetEntity)
24
- and implementation.property_ == AssetFields.parentExternalId
25
- and not isinstance(property_.value_type, ClassEntity)
26
- ):
27
- self.issue_list.append(
28
- PropertyDefinitionError(
29
- property_.class_,
30
- "class",
31
- property_.property_,
32
- "parentExternalId is only allowed to "
33
- f"point to a Class not {type(property_.value_type).__name__}",
34
- )
35
- )
36
-
37
- def _circular_dependency(self) -> None:
38
- from cognite.neat._rules.analysis import AssetAnalysis
39
-
40
- try:
41
- _ = AssetAnalysis(cast(AssetRules, self.rules)).class_topological_sort()
42
- except CycleError as error:
43
- self.issue_list.append(
44
- NeatValueError(f"Invalid Asset Hierarchy, circular dependency detected: {error.args[1]}")
45
- )
@@ -1,136 +0,0 @@
1
- import math
2
- from collections.abc import Hashable
3
- from dataclasses import dataclass, field
4
- from typing import ClassVar
5
-
6
- from pydantic import Field, field_serializer, field_validator
7
- from rdflib import URIRef
8
-
9
- from cognite.neat._constants import DEFAULT_NAMESPACE
10
- from cognite.neat._rules.models.data_types import DataType
11
- from cognite.neat._rules.models.entities import ClassEntity, ClassEntityList
12
-
13
- from ._base_input import InputComponent, InputRules
14
- from ._base_rules import (
15
- BaseMetadata,
16
- BaseRules,
17
- RoleTypes,
18
- SheetList,
19
- SheetRow,
20
- )
21
- from ._types import ClassEntityType, InformationPropertyType, StrOrListType
22
-
23
-
24
- class DomainMetadata(BaseMetadata):
25
- role: ClassVar[RoleTypes] = RoleTypes.domain_expert
26
- creator: StrOrListType
27
-
28
- def as_identifier(self) -> str:
29
- return "DomainRules"
30
-
31
- def get_prefix(self) -> str:
32
- return "domain"
33
-
34
-
35
- class DomainProperty(SheetRow):
36
- class_: ClassEntityType = Field(alias="Class")
37
- property_: InformationPropertyType = Field(alias="Property")
38
- name: str | None = Field(alias="Name", default=None)
39
- description: str | None = Field(alias="Description", default=None)
40
- value_type: DataType | ClassEntity = Field(alias="Value Type")
41
- min_count: int | None = Field(alias="Min Count", default=None)
42
- max_count: int | float | None = Field(alias="Max Count", default=None)
43
-
44
- def _identifier(self) -> tuple[Hashable, ...]:
45
- return self.class_, self.property_
46
-
47
- @field_serializer("max_count", when_used="json-unless-none")
48
- def serialize_max_count(self, value: int | float | None) -> int | float | None | str:
49
- if isinstance(value, float) and math.isinf(value):
50
- return None
51
- return value
52
-
53
- @field_validator("max_count", mode="before")
54
- def parse_max_count(cls, value: int | float | None) -> int | float | None:
55
- if value is None:
56
- return float("inf")
57
- return value
58
-
59
-
60
- class DomainClass(SheetRow):
61
- class_: ClassEntityType = Field(alias="Class")
62
- name: str | None = Field(alias="Name", default=None)
63
- description: str | None = Field(None, alias="Description")
64
- parent: ClassEntityList | None = Field(alias="Parent Class")
65
-
66
- def _identifier(self) -> tuple[Hashable, ...]:
67
- return (self.class_,)
68
-
69
- @field_serializer("parent", when_used="unless-none")
70
- def serialize_parent(self, value: list[ClassEntity]) -> str:
71
- return ",".join([str(entry) for entry in value])
72
-
73
-
74
- class DomainRules(BaseRules):
75
- metadata: DomainMetadata = Field(alias="Metadata")
76
- properties: SheetList[DomainProperty] = Field(alias="Properties")
77
- classes: SheetList[DomainClass] | None = Field(None, alias="Classes")
78
- last: "DomainRules | None" = Field(None, alias="Last")
79
- reference: "DomainRules | None" = Field(None, alias="Reference")
80
-
81
- @property
82
- def id_(self) -> URIRef:
83
- return DEFAULT_NAMESPACE["data-model/verified/domain"]
84
-
85
-
86
- @dataclass
87
- class DomainInputMetadata(InputComponent[DomainMetadata]):
88
- creator: str
89
-
90
- @classmethod
91
- def _get_verified_cls(cls) -> type[DomainMetadata]:
92
- return DomainMetadata
93
-
94
-
95
- @dataclass
96
- class DomainInputProperty(InputComponent[DomainProperty]):
97
- class_: str
98
- property_: str
99
- value_type: str
100
- name: str | None = None
101
- description: str | None = None
102
- min_count: int | None = None
103
- max_count: int | float | None = None
104
-
105
- @classmethod
106
- def _get_verified_cls(cls) -> type[DomainProperty]:
107
- return DomainProperty
108
-
109
-
110
- @dataclass
111
- class DomainInputClass(InputComponent[DomainClass]):
112
- class_: str
113
- name: str | None = None
114
- description: str | None = None
115
- parent: list[str] | None = None
116
-
117
- @classmethod
118
- def _get_verified_cls(cls) -> type[DomainClass]:
119
- return DomainClass
120
-
121
-
122
- @dataclass
123
- class DomainInputRules(InputRules[DomainRules]):
124
- metadata: DomainInputMetadata
125
- properties: list[DomainInputProperty] = field(default_factory=list)
126
- classes: list[DomainInputClass] = field(default_factory=list)
127
- last: "DomainInputRules | None" = None
128
- reference: "DomainInputRules | None" = None
129
-
130
- @classmethod
131
- def _get_verified_cls(cls) -> type[DomainRules]:
132
- return DomainRules
133
-
134
- @property
135
- def id_(self) -> URIRef:
136
- return DEFAULT_NAMESPACE["data-model/unverified/domain"]