cognite-neat 0.123.26__py3-none-any.whl → 0.123.28__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.
- cognite/neat/_version.py +1 -1
- cognite/neat/core/_data_model/_constants.py +4 -0
- cognite/neat/core/_data_model/models/conceptual/_unverified.py +11 -5
- cognite/neat/core/_data_model/models/entities/__init__.py +4 -0
- cognite/neat/core/_data_model/models/entities/_loaders.py +88 -8
- cognite/neat/core/_data_model/models/entities/_restrictions.py +230 -0
- cognite/neat/core/_data_model/models/entities/_single_value.py +97 -13
- cognite/neat/core/_data_model/models/physical/_unverified.py +68 -21
- cognite/neat/core/_issues/errors/_wrapper.py +5 -1
- {cognite_neat-0.123.26.dist-info → cognite_neat-0.123.28.dist-info}/METADATA +2 -2
- {cognite_neat-0.123.26.dist-info → cognite_neat-0.123.28.dist-info}/RECORD +13 -12
- {cognite_neat-0.123.26.dist-info → cognite_neat-0.123.28.dist-info}/WHEEL +0 -0
- {cognite_neat-0.123.26.dist-info → cognite_neat-0.123.28.dist-info}/licenses/LICENSE +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "0.123.
|
|
1
|
+
__version__ = "0.123.28"
|
|
2
2
|
__engine__ = "^2.0.4"
|
|
@@ -43,6 +43,10 @@ class EntityTypes(StrEnum):
|
|
|
43
43
|
prefix = "prefix"
|
|
44
44
|
space = "space"
|
|
45
45
|
container_index = "container_index"
|
|
46
|
+
concept_restriction = "conceptRestriction"
|
|
47
|
+
value_constraint = "valueConstraint"
|
|
48
|
+
cardinality_constraint = "cardinalityConstraint"
|
|
49
|
+
named_individual = "named_individual"
|
|
46
50
|
|
|
47
51
|
|
|
48
52
|
def get_reserved_words(
|
|
@@ -100,8 +100,8 @@ class UnverifiedConceptualProperty(UnverifiedComponent[ConceptualProperty]):
|
|
|
100
100
|
|
|
101
101
|
def dump(self, default_prefix: str, **kwargs) -> dict[str, Any]: # type: ignore
|
|
102
102
|
output = super().dump()
|
|
103
|
-
output["Concept"] = ConceptEntity.load(self.concept, prefix=default_prefix)
|
|
104
|
-
output["Value Type"] = load_value_type(self.value_type, default_prefix)
|
|
103
|
+
output["Concept"] = ConceptEntity.load(self.concept, prefix=default_prefix, return_on_failure=True)
|
|
104
|
+
output["Value Type"] = load_value_type(self.value_type, default_prefix, return_on_failure=True)
|
|
105
105
|
return output
|
|
106
106
|
|
|
107
107
|
def copy(self, update: dict[str, Any], default_prefix: str) -> "UnverifiedConceptualProperty":
|
|
@@ -135,10 +135,16 @@ class UnverifiedConcept(UnverifiedComponent[Concept]):
|
|
|
135
135
|
parent: list[ConceptEntity] | None = None
|
|
136
136
|
if isinstance(self.implements, str):
|
|
137
137
|
self.implements = self.implements.strip()
|
|
138
|
-
parent = [
|
|
138
|
+
parent = [
|
|
139
|
+
ConceptEntity.load(parent_str, prefix=default_prefix, return_on_failure=True)
|
|
140
|
+
for parent_str in self.implements.split(",")
|
|
141
|
+
]
|
|
139
142
|
elif isinstance(self.implements, list):
|
|
140
|
-
parent = [
|
|
141
|
-
|
|
143
|
+
parent = [
|
|
144
|
+
ConceptEntity.load(parent_str, prefix=default_prefix, return_on_failure=True)
|
|
145
|
+
for parent_str in self.implements
|
|
146
|
+
]
|
|
147
|
+
output["Concept"] = ConceptEntity.load(self.concept, prefix=default_prefix, return_on_failure=True)
|
|
142
148
|
output["Implements"] = parent
|
|
143
149
|
return output
|
|
144
150
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from ._constants import Undefined, Unknown
|
|
2
2
|
from ._loaders import load_connection, load_dms_value_type, load_value_type
|
|
3
3
|
from ._multi_value import MultiValueTypeInfo
|
|
4
|
+
from ._restrictions import ConceptPropertyCardinalityConstraint, ConceptPropertyValueConstraint, parse_restriction
|
|
4
5
|
from ._single_value import (
|
|
5
6
|
AssetEntity,
|
|
6
7
|
AssetFields,
|
|
@@ -31,6 +32,8 @@ __all__ = [
|
|
|
31
32
|
"CdfResourceEntityList",
|
|
32
33
|
"ClassEntityList",
|
|
33
34
|
"ConceptEntity",
|
|
35
|
+
"ConceptPropertyCardinalityConstraint",
|
|
36
|
+
"ConceptPropertyValueConstraint",
|
|
34
37
|
"ConceptualEntity",
|
|
35
38
|
"ContainerEntity",
|
|
36
39
|
"ContainerEntityList",
|
|
@@ -61,4 +64,5 @@ __all__ = [
|
|
|
61
64
|
"load_connection",
|
|
62
65
|
"load_dms_value_type",
|
|
63
66
|
"load_value_type",
|
|
67
|
+
"parse_restriction",
|
|
64
68
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Literal
|
|
1
|
+
from typing import Literal, overload
|
|
2
2
|
|
|
3
3
|
from cognite.neat.core._data_model.models.data_types import DataType
|
|
4
4
|
from cognite.neat.core._issues.errors import NeatTypeError
|
|
@@ -15,10 +15,38 @@ from ._single_value import (
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
@overload
|
|
18
19
|
def load_value_type(
|
|
19
20
|
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
20
21
|
default_prefix: str,
|
|
21
|
-
|
|
22
|
+
return_on_failure: Literal[False] = False,
|
|
23
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity: ...
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@overload
|
|
27
|
+
def load_value_type(
|
|
28
|
+
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
29
|
+
default_prefix: str,
|
|
30
|
+
return_on_failure: Literal[True],
|
|
31
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity | None | str: ...
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def load_value_type(
|
|
35
|
+
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
36
|
+
default_prefix: str,
|
|
37
|
+
return_on_failure: Literal[True, False] = False,
|
|
38
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity | None | str:
|
|
39
|
+
"""
|
|
40
|
+
Loads a value type from a raw string or entity.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
raw: The raw value to load.
|
|
44
|
+
default_prefix: The default prefix to use if not specified in the raw value.
|
|
45
|
+
return_on_failure: If True, returns the raw value on parsing failure instead of raising an error.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
The loaded value type entity, or the raw value if loading fails and `return_on_failure` is True.
|
|
49
|
+
"""
|
|
22
50
|
if isinstance(raw, MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity):
|
|
23
51
|
return raw
|
|
24
52
|
elif isinstance(raw, str):
|
|
@@ -37,16 +65,47 @@ def load_value_type(
|
|
|
37
65
|
|
|
38
66
|
# property holding link to class
|
|
39
67
|
else:
|
|
40
|
-
return ConceptEntity.load(raw, prefix=default_prefix)
|
|
68
|
+
return ConceptEntity.load(raw, prefix=default_prefix, return_on_failure=return_on_failure)
|
|
41
69
|
else:
|
|
42
70
|
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
43
71
|
|
|
44
72
|
|
|
73
|
+
@overload
|
|
74
|
+
def load_dms_value_type(
|
|
75
|
+
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
76
|
+
default_space: str,
|
|
77
|
+
default_version: str,
|
|
78
|
+
return_on_failure: Literal[False],
|
|
79
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity: ...
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@overload
|
|
83
|
+
def load_dms_value_type(
|
|
84
|
+
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
85
|
+
default_space: str,
|
|
86
|
+
default_version: str,
|
|
87
|
+
return_on_failure: Literal[True],
|
|
88
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity | str: ...
|
|
89
|
+
|
|
90
|
+
|
|
45
91
|
def load_dms_value_type(
|
|
46
92
|
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
47
93
|
default_space: str,
|
|
48
94
|
default_version: str,
|
|
49
|
-
|
|
95
|
+
return_on_failure: Literal[True, False] = False,
|
|
96
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity | str:
|
|
97
|
+
"""
|
|
98
|
+
Loads a value type from a raw string or entity in the context of a data modeling service
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
raw: The raw value to load.
|
|
102
|
+
default_space: The default space to use if not specified in the raw value.
|
|
103
|
+
default_version: The default version to use if not specified in the raw value.
|
|
104
|
+
return_on_failure: If True, returns the raw value on parsing failure instead of raising an error.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
The loaded value type entity, or the raw value if loading fails and `return_on_failure` is True.
|
|
108
|
+
"""
|
|
50
109
|
if isinstance(raw, DataType | ViewEntity | PhysicalUnknownEntity):
|
|
51
110
|
return raw
|
|
52
111
|
elif isinstance(raw, str):
|
|
@@ -55,21 +114,42 @@ def load_dms_value_type(
|
|
|
55
114
|
elif raw == str(Unknown):
|
|
56
115
|
return PhysicalUnknownEntity()
|
|
57
116
|
else:
|
|
58
|
-
return ViewEntity.load(
|
|
117
|
+
return ViewEntity.load(
|
|
118
|
+
raw, space=default_space, version=default_version, return_on_failure=return_on_failure
|
|
119
|
+
)
|
|
59
120
|
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
60
121
|
|
|
61
122
|
|
|
123
|
+
@overload
|
|
124
|
+
def load_connection(
|
|
125
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
126
|
+
default_space: str,
|
|
127
|
+
default_version: str,
|
|
128
|
+
return_on_failure: Literal[False] = False,
|
|
129
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None: ...
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@overload
|
|
133
|
+
def load_connection(
|
|
134
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
135
|
+
default_space: str,
|
|
136
|
+
default_version: str,
|
|
137
|
+
return_on_failure: Literal[True],
|
|
138
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None | str: ...
|
|
139
|
+
|
|
140
|
+
|
|
62
141
|
def load_connection(
|
|
63
142
|
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
64
143
|
default_space: str,
|
|
65
144
|
default_version: str,
|
|
66
|
-
|
|
145
|
+
return_on_failure: Literal[True, False] = False,
|
|
146
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None | str:
|
|
67
147
|
if isinstance(raw, str) and raw.lower() == "direct":
|
|
68
148
|
return "direct" # type: ignore[return-value]
|
|
69
149
|
elif isinstance(raw, EdgeEntity | ReverseConnectionEntity) or raw is None:
|
|
70
150
|
return raw # type: ignore[return-value]
|
|
71
151
|
elif isinstance(raw, str) and raw.startswith("edge"):
|
|
72
|
-
return EdgeEntity.load(raw, space=default_space, version=default_version) # type: ignore[return-value]
|
|
152
|
+
return EdgeEntity.load(raw, space=default_space, version=default_version, return_on_failure=return_on_failure) # type: ignore[return-value]
|
|
73
153
|
elif isinstance(raw, str) and raw.startswith("reverse"):
|
|
74
|
-
return ReverseConnectionEntity.load(raw) # type: ignore[return-value]
|
|
154
|
+
return ReverseConnectionEntity.load(raw, return_on_failure=return_on_failure) # type: ignore[return-value]
|
|
75
155
|
raise NeatTypeError(f"Invalid connection: {type(raw)}")
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from typing import Any, ClassVar, Final, Literal, TypeVar, cast, get_args
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
7
|
+
from rdflib import Literal as RDFLiteral
|
|
8
|
+
from rdflib import URIRef
|
|
9
|
+
|
|
10
|
+
from cognite.neat.core._data_model._constants import EntityTypes
|
|
11
|
+
from cognite.neat.core._data_model.models.data_types import _XSD_TYPES, DataType
|
|
12
|
+
from cognite.neat.core._data_model.models.entities._constants import _PARSE
|
|
13
|
+
from cognite.neat.core._data_model.models.entities._single_value import ConceptEntity, ConceptualEntity
|
|
14
|
+
from cognite.neat.core._issues.errors._general import NeatValueError
|
|
15
|
+
from cognite.neat.core._utils.rdf_ import remove_namespace_from_uri
|
|
16
|
+
|
|
17
|
+
if sys.version_info <= (3, 11):
|
|
18
|
+
from typing_extensions import Self
|
|
19
|
+
else:
|
|
20
|
+
from typing import Self
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ValueConstraints = Literal["allValuesFrom", "someValuesFrom", "hasValue"]
|
|
24
|
+
CardinalityConstraints = Literal["minCardinality", "maxCardinality", "cardinality", "qualifiedCardinality"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Constants for regex patterns - more maintainable
|
|
28
|
+
PROPERTY_PATTERN: Final[str] = r"[a-zA-Z0-9._~?@!$&'*+,;=%-]+"
|
|
29
|
+
VALUE_PATTERN: Final[str] = r".+"
|
|
30
|
+
CARDINALITY_VALUE_PATTERN: Final[str] = r"\d+"
|
|
31
|
+
ON_PATTERN: Final[str] = r"[^(]*"
|
|
32
|
+
|
|
33
|
+
VALUE_CONSTRAINT_REGEX = re.compile(
|
|
34
|
+
rf"^{EntityTypes.value_constraint}:(?P<property>{PROPERTY_PATTERN})\((?P<constraint>{'|'.join(get_args(ValueConstraints))}),(?P<value>{VALUE_PATTERN})\)$"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
CARDINALITY_CONSTRAINT_REGEX = re.compile(
|
|
38
|
+
rf"^{EntityTypes.cardinality_constraint}:(?P<property>{PROPERTY_PATTERN})\((?P<constraint>{'|'.join(get_args(CardinalityConstraints))}),(?P<value>{CARDINALITY_VALUE_PATTERN})(?:,(?P<on>{ON_PATTERN}))?\)$"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class NamedIndividualEntity(ConceptualEntity):
|
|
43
|
+
type_: ClassVar[EntityTypes] = EntityTypes.named_individual
|
|
44
|
+
|
|
45
|
+
@model_validator(mode="after")
|
|
46
|
+
def reset_prefix(self) -> Self:
|
|
47
|
+
self.prefix = "ni"
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ConceptPropertyRestriction(ABC, BaseModel):
|
|
52
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(
|
|
53
|
+
str_strip_whitespace=True,
|
|
54
|
+
arbitrary_types_allowed=True,
|
|
55
|
+
strict=False,
|
|
56
|
+
extra="ignore",
|
|
57
|
+
)
|
|
58
|
+
type_: ClassVar[EntityTypes] = EntityTypes.concept_restriction
|
|
59
|
+
property_: str
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def load(cls: "type[T_ConceptPropertyRestriction]", data: Any, **defaults: Any) -> "T_ConceptPropertyRestriction":
|
|
63
|
+
if isinstance(data, cls):
|
|
64
|
+
return data
|
|
65
|
+
elif not isinstance(data, str):
|
|
66
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
67
|
+
|
|
68
|
+
return cls.model_validate({_PARSE: data, "defaults": defaults})
|
|
69
|
+
|
|
70
|
+
@model_validator(mode="before")
|
|
71
|
+
def _load(cls, data: Any) -> dict:
|
|
72
|
+
defaults = {}
|
|
73
|
+
if isinstance(data, dict) and _PARSE in data:
|
|
74
|
+
defaults = data.get("defaults", {})
|
|
75
|
+
data = data[_PARSE]
|
|
76
|
+
if isinstance(data, dict):
|
|
77
|
+
data.update(defaults)
|
|
78
|
+
return data
|
|
79
|
+
|
|
80
|
+
if not isinstance(data, str):
|
|
81
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
82
|
+
|
|
83
|
+
return cls._parse(data, defaults)
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
87
|
+
raise NotImplementedError(f"{cls.__name__} must implement _parse method")
|
|
88
|
+
|
|
89
|
+
def dump(self) -> str:
|
|
90
|
+
return self.__str__()
|
|
91
|
+
|
|
92
|
+
def as_tuple(self) -> tuple[str, ...]:
|
|
93
|
+
# We haver overwritten the serialization to str, so we need to do it manually
|
|
94
|
+
extra: tuple[str, ...] = tuple(
|
|
95
|
+
[
|
|
96
|
+
str(v or "")
|
|
97
|
+
for field_name in self.model_fields.keys()
|
|
98
|
+
if (v := getattr(self, field_name)) and field_name not in {"property_"}
|
|
99
|
+
]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return self.property_, *extra
|
|
103
|
+
|
|
104
|
+
def __lt__(self, other: object) -> bool:
|
|
105
|
+
if not isinstance(other, ConceptPropertyRestriction):
|
|
106
|
+
return NotImplemented
|
|
107
|
+
return self.as_tuple() < other.as_tuple()
|
|
108
|
+
|
|
109
|
+
def __eq__(self, other: object) -> bool:
|
|
110
|
+
if not isinstance(other, ConceptPropertyRestriction):
|
|
111
|
+
return NotImplemented
|
|
112
|
+
return self.as_tuple() == other.as_tuple()
|
|
113
|
+
|
|
114
|
+
def __hash__(self) -> int:
|
|
115
|
+
return hash(str(self))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
T_ConceptPropertyRestriction = TypeVar("T_ConceptPropertyRestriction", bound="ConceptPropertyRestriction")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class ConceptPropertyValueConstraint(ConceptPropertyRestriction):
|
|
122
|
+
type_: ClassVar[EntityTypes] = EntityTypes.value_constraint
|
|
123
|
+
constraint: ValueConstraints
|
|
124
|
+
value: RDFLiteral | ConceptEntity | NamedIndividualEntity
|
|
125
|
+
|
|
126
|
+
@field_validator("value")
|
|
127
|
+
def validate_value(cls, value: Any) -> Any:
|
|
128
|
+
if isinstance(value, RDFLiteral) and value.datatype is None:
|
|
129
|
+
raise NeatValueError("RDFLiteral must have a datatype set, which must be one of the XSD types.")
|
|
130
|
+
return value
|
|
131
|
+
|
|
132
|
+
def __str__(self) -> str:
|
|
133
|
+
value_str = (
|
|
134
|
+
f"{self.value.value}^^{remove_namespace_from_uri(cast(URIRef, self.value.datatype))}"
|
|
135
|
+
if isinstance(self.value, RDFLiteral)
|
|
136
|
+
else str(self.value)
|
|
137
|
+
)
|
|
138
|
+
return f"{self.type_}:{self.property_}({self.constraint},{value_str})"
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
142
|
+
if not (result := VALUE_CONSTRAINT_REGEX.match(data)):
|
|
143
|
+
raise NeatValueError(f"Invalid value constraint format: {data}")
|
|
144
|
+
|
|
145
|
+
property_ = result.group("property")
|
|
146
|
+
constraint = result.group("constraint")
|
|
147
|
+
raw_value = result.group("value")
|
|
148
|
+
|
|
149
|
+
value: NamedIndividualEntity | RDFLiteral | ConceptEntity
|
|
150
|
+
# scenario 1: NamedIndividual as value restriction
|
|
151
|
+
if raw_value.startswith("ni:"):
|
|
152
|
+
value = NamedIndividualEntity.load(raw_value)
|
|
153
|
+
# scenario 2: Datatype as value restriction
|
|
154
|
+
elif "^^" in raw_value:
|
|
155
|
+
if len(value_components := raw_value.split("^^")) == 2 and value_components[1] in _XSD_TYPES:
|
|
156
|
+
value = RDFLiteral(value_components[0], datatype=DataType.load(value_components[1]).as_xml_uri_ref())
|
|
157
|
+
else:
|
|
158
|
+
raise NeatValueError(f"Invalid value format for datatype: {raw_value}")
|
|
159
|
+
|
|
160
|
+
# scenario 3: ConceptEntity as value restriction
|
|
161
|
+
else:
|
|
162
|
+
value = ConceptEntity.load(raw_value, **defaults)
|
|
163
|
+
|
|
164
|
+
return dict(property_=property_, constraint=constraint, value=value)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class ConceptPropertyCardinalityConstraint(ConceptPropertyRestriction):
|
|
168
|
+
type_: ClassVar[EntityTypes] = EntityTypes.cardinality_constraint
|
|
169
|
+
constraint: CardinalityConstraints
|
|
170
|
+
value: int = Field(ge=0)
|
|
171
|
+
on: DataType | ConceptEntity | None = None
|
|
172
|
+
|
|
173
|
+
def __str__(self) -> str:
|
|
174
|
+
on_str = f",{self.on}" if self.on else ""
|
|
175
|
+
return f"{self.type_}:{self.property_}({self.constraint},{self.value}{on_str})"
|
|
176
|
+
|
|
177
|
+
@classmethod
|
|
178
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
179
|
+
if not (result := CARDINALITY_CONSTRAINT_REGEX.match(data)):
|
|
180
|
+
raise NeatValueError(f"Invalid cardinality constraint format: {data}")
|
|
181
|
+
|
|
182
|
+
property_ = result.group("property")
|
|
183
|
+
constraint = result.group("constraint")
|
|
184
|
+
value = result.group("value")
|
|
185
|
+
on = result.group("on")
|
|
186
|
+
if on:
|
|
187
|
+
if on in _XSD_TYPES:
|
|
188
|
+
on = DataType.load(on)
|
|
189
|
+
else:
|
|
190
|
+
on = cast(ConceptEntity, ConceptEntity.load(on, **defaults))
|
|
191
|
+
|
|
192
|
+
return dict(property_=property_, constraint=constraint, value=value, on=on)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def parse_restriction(data: str, **defaults: Any) -> ConceptPropertyRestriction:
|
|
196
|
+
"""Parse a string to create either a value or cardinality restriction.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
data: String representation of the restriction
|
|
200
|
+
**defaults: Default values to use when parsing
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Either a ConceptPropertyValueConstraint or ConceptPropertyCardinalityConstraint
|
|
204
|
+
|
|
205
|
+
Raises:
|
|
206
|
+
NeatValueError: If the string cannot be parsed as either restriction type
|
|
207
|
+
"""
|
|
208
|
+
# Check for value constraint pattern first (more specific)
|
|
209
|
+
if VALUE_CONSTRAINT_REGEX.match(data):
|
|
210
|
+
try:
|
|
211
|
+
return ConceptPropertyValueConstraint.load(data, **defaults)
|
|
212
|
+
except Exception as e:
|
|
213
|
+
raise NeatValueError(f"Failed to parse value constraint: {data}") from e
|
|
214
|
+
|
|
215
|
+
# Check for cardinality constraint pattern
|
|
216
|
+
if CARDINALITY_CONSTRAINT_REGEX.match(data):
|
|
217
|
+
try:
|
|
218
|
+
return ConceptPropertyCardinalityConstraint.load(data, **defaults)
|
|
219
|
+
except Exception as e:
|
|
220
|
+
raise NeatValueError(f"Failed to parse cardinality constraint: {data}") from e
|
|
221
|
+
|
|
222
|
+
# If neither pattern matches, provide a clear error
|
|
223
|
+
raise NeatValueError(
|
|
224
|
+
f"Invalid restriction format: {data}. "
|
|
225
|
+
f"Expected format: '{EntityTypes.value_constraint}:property(constraint,value)' "
|
|
226
|
+
f"or '{EntityTypes.cardinality_constraint}:property(constraint,value[,on])'"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
T_ConceptRestriction = TypeVar("T_ConceptRestriction", bound=ConceptPropertyRestriction)
|
|
@@ -59,7 +59,13 @@ class ConceptualEntity(BaseModel, extra="ignore"):
|
|
|
59
59
|
|
|
60
60
|
@classmethod
|
|
61
61
|
@overload
|
|
62
|
-
def load(
|
|
62
|
+
def load(
|
|
63
|
+
cls: "type[T_Entity]",
|
|
64
|
+
data: Any,
|
|
65
|
+
strict: Literal[True],
|
|
66
|
+
return_on_failure: Literal[False] = False,
|
|
67
|
+
**defaults: Any,
|
|
68
|
+
) -> "T_Entity": ...
|
|
63
69
|
|
|
64
70
|
@classmethod
|
|
65
71
|
@overload
|
|
@@ -67,25 +73,59 @@ class ConceptualEntity(BaseModel, extra="ignore"):
|
|
|
67
73
|
cls: "type[T_Entity]",
|
|
68
74
|
data: Any,
|
|
69
75
|
strict: Literal[False] = False,
|
|
76
|
+
return_on_failure: Literal[False] = False,
|
|
70
77
|
**defaults: Any,
|
|
71
78
|
) -> "T_Entity | UnknownEntity": ...
|
|
72
79
|
|
|
73
80
|
@classmethod
|
|
74
|
-
|
|
81
|
+
@overload
|
|
82
|
+
def load(
|
|
83
|
+
cls: "type[T_Entity]",
|
|
84
|
+
data: Any,
|
|
85
|
+
strict: Literal[False] = False,
|
|
86
|
+
return_on_failure: Literal[True] = True,
|
|
87
|
+
**defaults: Any,
|
|
88
|
+
) -> "T_Entity | Any": ...
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
@overload
|
|
92
|
+
def load(
|
|
93
|
+
cls: "type[T_Entity]",
|
|
94
|
+
data: Any,
|
|
95
|
+
strict: Literal[True] = True,
|
|
96
|
+
return_on_failure: Literal[True] = True,
|
|
97
|
+
**defaults: Any,
|
|
98
|
+
) -> "T_Entity | Any": ...
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def load(
|
|
102
|
+
cls: "type[T_Entity]", data: Any, strict: bool = False, return_on_failure: bool = False, **defaults: Any
|
|
103
|
+
) -> "T_Entity | UnknownEntity | Any":
|
|
104
|
+
"""Loads an entity from a string or dict representation.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
data: The data to load the entity from. Can be a string or a dict.
|
|
108
|
+
strict: If True, will raise an error if the data is "unknown".
|
|
109
|
+
return_on_failure: If True, will return the input data if loading fails.
|
|
110
|
+
This is used when you want to defer error handling to a later stage.
|
|
111
|
+
defaults: Default values to use when loading the entity. These will be used if the corresponding
|
|
112
|
+
"""
|
|
75
113
|
if isinstance(data, cls):
|
|
76
114
|
return data
|
|
77
115
|
elif isinstance(data, str) and data == str(Unknown):
|
|
78
116
|
if strict:
|
|
79
117
|
raise NeatValueError(f"Failed to load entity {data!s}")
|
|
80
118
|
return UnknownEntity(prefix=Undefined, suffix=Unknown)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
119
|
+
try:
|
|
120
|
+
if defaults and isinstance(defaults, dict):
|
|
121
|
+
# This is a trick to pass in default values
|
|
84
122
|
return cls.model_validate({_PARSE: data, "defaults": defaults})
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
123
|
+
else:
|
|
124
|
+
return cls.model_validate(data)
|
|
125
|
+
except ValueError:
|
|
126
|
+
if return_on_failure:
|
|
127
|
+
return data
|
|
128
|
+
raise
|
|
89
129
|
|
|
90
130
|
@model_validator(mode="before")
|
|
91
131
|
def _load(cls, data: Any) -> "dict | ConceptualEntity":
|
|
@@ -342,7 +382,13 @@ class PhysicalEntity(ConceptualEntity, Generic[T_ID], ABC):
|
|
|
342
382
|
|
|
343
383
|
@classmethod # type: ignore[override]
|
|
344
384
|
@overload
|
|
345
|
-
def load(
|
|
385
|
+
def load(
|
|
386
|
+
cls: "type[T_DMSEntity]",
|
|
387
|
+
data: Any,
|
|
388
|
+
strict: Literal[True],
|
|
389
|
+
return_on_failure: Literal[False] = False,
|
|
390
|
+
**defaults: Any,
|
|
391
|
+
) -> "T_DMSEntity": ...
|
|
346
392
|
|
|
347
393
|
@classmethod
|
|
348
394
|
@overload
|
|
@@ -350,18 +396,56 @@ class PhysicalEntity(ConceptualEntity, Generic[T_ID], ABC):
|
|
|
350
396
|
cls: "type[T_DMSEntity]",
|
|
351
397
|
data: Any,
|
|
352
398
|
strict: Literal[False] = False,
|
|
399
|
+
return_on_failure: Literal[False] = False,
|
|
353
400
|
**defaults: Any,
|
|
354
401
|
) -> "T_DMSEntity | PhysicalUnknownEntity": ...
|
|
355
402
|
|
|
356
403
|
@classmethod
|
|
404
|
+
@overload
|
|
357
405
|
def load(
|
|
358
|
-
cls: "type[T_DMSEntity]",
|
|
359
|
-
|
|
406
|
+
cls: "type[T_DMSEntity]",
|
|
407
|
+
data: Any,
|
|
408
|
+
strict: Literal[False] = False,
|
|
409
|
+
return_on_failure: Literal[True] = True,
|
|
410
|
+
**defaults: Any,
|
|
411
|
+
) -> "T_DMSEntity | Any": ...
|
|
412
|
+
|
|
413
|
+
@classmethod
|
|
414
|
+
@overload
|
|
415
|
+
def load(
|
|
416
|
+
cls: "type[T_DMSEntity]",
|
|
417
|
+
data: Any,
|
|
418
|
+
strict: Literal[True] = True,
|
|
419
|
+
return_on_failure: Literal[True] = True,
|
|
420
|
+
**defaults: Any,
|
|
421
|
+
) -> "T_DMSEntity | Any": ...
|
|
422
|
+
|
|
423
|
+
@classmethod
|
|
424
|
+
def load(
|
|
425
|
+
cls: "type[T_DMSEntity]",
|
|
426
|
+
data: Any,
|
|
427
|
+
strict: Literal[True, False] = False,
|
|
428
|
+
return_on_failure: Literal[True, False] = False,
|
|
429
|
+
**defaults: Any,
|
|
430
|
+
) -> "T_DMSEntity | PhysicalUnknownEntity | Any":
|
|
431
|
+
"""Loads a DMS entity from a string or dict representation.
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
data: The data to load the entity from. Can be a string or a dict.
|
|
435
|
+
strict: If True, will raise an error if the data is "unknown".
|
|
436
|
+
return_on_failure: If True, will return the input data if loading fails.
|
|
437
|
+
This is used when you want to defer error handling to a later stage.
|
|
438
|
+
defaults: Default values to use when loading the entity. These will be used if the corresponding
|
|
439
|
+
fields are missing in the input data.
|
|
440
|
+
|
|
441
|
+
"""
|
|
360
442
|
if isinstance(data, str) and data == str(Unknown):
|
|
361
443
|
if strict:
|
|
362
444
|
raise NeatValueError(f"Failed to load entity {data!s}")
|
|
363
445
|
return PhysicalUnknownEntity.from_id(None)
|
|
364
|
-
|
|
446
|
+
if isinstance(data, UnknownEntity):
|
|
447
|
+
return PhysicalUnknownEntity.from_id(None)
|
|
448
|
+
return cast(T_DMSEntity, super().load(data, strict=False, return_on_failure=return_on_failure, **defaults))
|
|
365
449
|
|
|
366
450
|
@property
|
|
367
451
|
def space(self) -> str:
|
|
@@ -3,7 +3,7 @@ import sys
|
|
|
3
3
|
import warnings
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from datetime import datetime
|
|
6
|
-
from typing import Any, Literal
|
|
6
|
+
from typing import Any, Literal, overload
|
|
7
7
|
|
|
8
8
|
import pandas as pd
|
|
9
9
|
from cognite.client import data_modeling as dm
|
|
@@ -161,19 +161,23 @@ class UnverifiedPhysicalProperty(UnverifiedComponent[PhysicalProperty]):
|
|
|
161
161
|
|
|
162
162
|
def dump(self, default_space: str, default_version: str) -> dict[str, Any]: # type: ignore[override]
|
|
163
163
|
output = super().dump()
|
|
164
|
-
output["View"] = ViewEntity.load(
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
output["View"] = ViewEntity.load(
|
|
165
|
+
self.view, space=default_space, version=default_version, return_on_failure=True
|
|
166
|
+
)
|
|
167
|
+
output["Value Type"] = load_dms_value_type(
|
|
168
|
+
self.value_type, default_space, default_version, return_on_failure=True
|
|
169
|
+
)
|
|
170
|
+
output["Connection"] = load_connection(self.connection, default_space, default_version, return_on_failure=True)
|
|
167
171
|
output["Container"] = (
|
|
168
|
-
ContainerEntity.load(self.container, space=default_space, version=default_version)
|
|
172
|
+
ContainerEntity.load(self.container, space=default_space, version=default_version, return_on_failure=True)
|
|
169
173
|
if self.container
|
|
170
174
|
else None
|
|
171
175
|
)
|
|
172
176
|
if isinstance(self.index, ContainerIndexEntity) or (isinstance(self.index, str) and "," not in self.index):
|
|
173
|
-
output["Index"] = [ContainerIndexEntity.load(self.index)]
|
|
177
|
+
output["Index"] = [ContainerIndexEntity.load(self.index, return_on_failure=True)]
|
|
174
178
|
elif isinstance(self.index, str):
|
|
175
179
|
output["Index"] = [
|
|
176
|
-
ContainerIndexEntity.load(index.strip())
|
|
180
|
+
ContainerIndexEntity.load(index.strip(), return_on_failure=True)
|
|
177
181
|
for index in SPLIT_ON_COMMA_PATTERN.split(self.index)
|
|
178
182
|
if index.strip()
|
|
179
183
|
]
|
|
@@ -185,13 +189,11 @@ class UnverifiedPhysicalProperty(UnverifiedComponent[PhysicalProperty]):
|
|
|
185
189
|
elif isinstance(index, str):
|
|
186
190
|
index_list.extend(
|
|
187
191
|
[
|
|
188
|
-
ContainerIndexEntity.load(idx.strip())
|
|
192
|
+
ContainerIndexEntity.load(idx.strip(), return_on_failure=True)
|
|
189
193
|
for idx in SPLIT_ON_COMMA_PATTERN.split(index)
|
|
190
194
|
if idx.strip()
|
|
191
195
|
]
|
|
192
196
|
)
|
|
193
|
-
elif isinstance(index, str):
|
|
194
|
-
index_list.append(ContainerIndexEntity.load(index.strip()))
|
|
195
197
|
else:
|
|
196
198
|
raise TypeError(f"Unexpected type for index: {type(index)}")
|
|
197
199
|
output["Index"] = index_list
|
|
@@ -257,16 +259,29 @@ class UnverifiedPhysicalContainer(UnverifiedComponent[PhysicalContainer]):
|
|
|
257
259
|
|
|
258
260
|
def dump(self, default_space: str) -> dict[str, Any]: # type: ignore[override]
|
|
259
261
|
output = super().dump()
|
|
260
|
-
output["Container"] = self.as_entity_id(default_space)
|
|
262
|
+
output["Container"] = self.as_entity_id(default_space, return_on_failure=True)
|
|
261
263
|
output["Constraint"] = (
|
|
262
|
-
[
|
|
264
|
+
[
|
|
265
|
+
ContainerEntity.load(constraint.strip(), space=default_space, return_on_failure=True)
|
|
266
|
+
for constraint in self.constraint.split(",")
|
|
267
|
+
]
|
|
263
268
|
if self.constraint
|
|
264
269
|
else None
|
|
265
270
|
)
|
|
266
271
|
return output
|
|
267
272
|
|
|
268
|
-
|
|
269
|
-
|
|
273
|
+
@overload
|
|
274
|
+
def as_entity_id(self, default_space: str, return_on_failure: Literal[False] = False) -> ContainerEntity: ...
|
|
275
|
+
|
|
276
|
+
@overload
|
|
277
|
+
def as_entity_id(self, default_space: str, return_on_failure: Literal[True]) -> ContainerEntity | str: ...
|
|
278
|
+
|
|
279
|
+
def as_entity_id(
|
|
280
|
+
self, default_space: str, return_on_failure: Literal[True, False] = False
|
|
281
|
+
) -> ContainerEntity | str:
|
|
282
|
+
return ContainerEntity.load(
|
|
283
|
+
self.container, strict=True, space=default_space, return_on_failure=return_on_failure
|
|
284
|
+
)
|
|
270
285
|
|
|
271
286
|
@classmethod
|
|
272
287
|
def from_container(cls, container: dm.ContainerApply) -> "UnverifiedPhysicalContainer":
|
|
@@ -306,19 +321,51 @@ class UnverifiedPhysicalView(UnverifiedComponent[PhysicalView]):
|
|
|
306
321
|
|
|
307
322
|
def dump(self, default_space: str, default_version: str) -> dict[str, Any]: # type: ignore[override]
|
|
308
323
|
output = super().dump()
|
|
309
|
-
output["View"] = self.as_entity_id(default_space, default_version)
|
|
310
|
-
output["Implements"] = self._load_implements(default_space, default_version)
|
|
324
|
+
output["View"] = self.as_entity_id(default_space, default_version, return_on_failure=True)
|
|
325
|
+
output["Implements"] = self._load_implements(default_space, default_version, return_on_failure=True)
|
|
311
326
|
return output
|
|
312
327
|
|
|
313
|
-
|
|
314
|
-
|
|
328
|
+
@overload
|
|
329
|
+
def as_entity_id(
|
|
330
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[False] = False
|
|
331
|
+
) -> ViewEntity: ...
|
|
332
|
+
|
|
333
|
+
@overload
|
|
334
|
+
def as_entity_id(
|
|
335
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[True]
|
|
336
|
+
) -> ViewEntity | str: ...
|
|
337
|
+
|
|
338
|
+
def as_entity_id(
|
|
339
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[True, False] = False
|
|
340
|
+
) -> ViewEntity | str:
|
|
341
|
+
return ViewEntity.load(
|
|
342
|
+
self.view, strict=True, space=default_space, version=default_version, return_on_failure=return_on_failure
|
|
343
|
+
)
|
|
315
344
|
|
|
316
|
-
|
|
345
|
+
@overload
|
|
346
|
+
def _load_implements(
|
|
347
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[False] = False
|
|
348
|
+
) -> list[ViewEntity] | None: ...
|
|
349
|
+
|
|
350
|
+
@overload
|
|
351
|
+
def _load_implements(
|
|
352
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[True]
|
|
353
|
+
) -> list[ViewEntity | str] | None: ...
|
|
354
|
+
|
|
355
|
+
def _load_implements(
|
|
356
|
+
self, default_space: str, default_version: str, return_on_failure: Literal[True, False] = False
|
|
357
|
+
) -> list[ViewEntity] | list[ViewEntity | str] | None:
|
|
317
358
|
self.implements = self.implements.strip() if self.implements else None
|
|
318
359
|
|
|
319
360
|
return (
|
|
320
361
|
[
|
|
321
|
-
ViewEntity.load(
|
|
362
|
+
ViewEntity.load(
|
|
363
|
+
implement,
|
|
364
|
+
strict=True,
|
|
365
|
+
space=default_space,
|
|
366
|
+
version=default_version,
|
|
367
|
+
return_on_failure=return_on_failure,
|
|
368
|
+
)
|
|
322
369
|
for implement in self.implements.split(",")
|
|
323
370
|
]
|
|
324
371
|
if self.implements
|
|
@@ -361,7 +408,7 @@ class UnverifiedPhysicalNodeType(UnverifiedComponent[PhysicalNodeType]):
|
|
|
361
408
|
|
|
362
409
|
def dump(self, default_space: str, **_) -> dict[str, Any]: # type: ignore
|
|
363
410
|
output = super().dump()
|
|
364
|
-
output["Node"] = DMSNodeEntity.load(self.node, space=default_space)
|
|
411
|
+
output["Node"] = DMSNodeEntity.load(self.node, space=default_space, return_on_failure=True)
|
|
365
412
|
return output
|
|
366
413
|
|
|
367
414
|
|
|
@@ -20,7 +20,11 @@ class SpreadsheetError(NeatError, ValueError, ABC):
|
|
|
20
20
|
spreadsheet_name = cast(str, location[0])
|
|
21
21
|
if spreadsheet_name not in ERROR_CLS_BY_SPREADSHEET_NAME:
|
|
22
22
|
# This happens for the metadata sheet, which are individual fields
|
|
23
|
-
|
|
23
|
+
if spreadsheet_name == "Metadata" and len(location) >= 2 and isinstance(location[1], str):
|
|
24
|
+
field_name = cast(str, location[1])
|
|
25
|
+
else:
|
|
26
|
+
field_name = spreadsheet_name
|
|
27
|
+
return MetadataValueError(error, field_name=field_name)
|
|
24
28
|
|
|
25
29
|
error_cls = ERROR_CLS_BY_SPREADSHEET_NAME[spreadsheet_name]
|
|
26
30
|
row, column = cast(tuple[int, str], location[2:4])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognite-neat
|
|
3
|
-
Version: 0.123.
|
|
3
|
+
Version: 0.123.28
|
|
4
4
|
Summary: Knowledge graph transformation
|
|
5
5
|
Project-URL: Documentation, https://cognite-neat.readthedocs-hosted.com/
|
|
6
6
|
Project-URL: Homepage, https://cognite-neat.readthedocs-hosted.com/
|
|
@@ -18,7 +18,7 @@ Requires-Dist: jsonpath-python<2.0.0,>=1.0.6
|
|
|
18
18
|
Requires-Dist: mixpanel<5.0.0,>=4.10.1
|
|
19
19
|
Requires-Dist: networkx<4.0.0,>=3.4.2
|
|
20
20
|
Requires-Dist: openpyxl<4.0.0,>=3.0.10
|
|
21
|
-
Requires-Dist: packaging
|
|
21
|
+
Requires-Dist: packaging>=22.0
|
|
22
22
|
Requires-Dist: pandas<3.0.0,>=1.5.3
|
|
23
23
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
24
24
|
Requires-Dist: pyvis<1.0.0,>=0.3.2
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=12StS1dzH9_MElqxGvLWrNsxCJl9Hv8A2a9D0E5OD_U,193
|
|
2
|
-
cognite/neat/_version.py,sha256=
|
|
2
|
+
cognite/neat/_version.py,sha256=6seCV2thSh0iPLMJ5f4Ba6srBIKclOMKbKjgQpVgAiA,47
|
|
3
3
|
cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cognite/neat/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
cognite/neat/core/_config.py,sha256=WT1BS8uADcFvGoUYOOfwFOVq_VBl472TisdoA3wLick,280
|
|
@@ -19,7 +19,7 @@ cognite/neat/core/_client/data_classes/neat_sequence.py,sha256=QZWSfWnwk6KlYJvsI
|
|
|
19
19
|
cognite/neat/core/_client/data_classes/schema.py,sha256=SpkBGbC2SUJG38Ixf1vYJINI66i_OZaT03q4XKRtK54,25067
|
|
20
20
|
cognite/neat/core/_client/data_classes/statistics.py,sha256=GU-u41cOTig0Y5pYhW5KqzCsuAUIX9tOmdizMEveYuw,4487
|
|
21
21
|
cognite/neat/core/_data_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
cognite/neat/core/_data_model/_constants.py,sha256=
|
|
22
|
+
cognite/neat/core/_data_model/_constants.py,sha256=37lvnq3UZu4bPSzjRRThXJGdvaxmA7KJzWL0YysYBs8,6040
|
|
23
23
|
cognite/neat/core/_data_model/_shared.py,sha256=at3-TT6pkdwtsjuz94P1lj1W7dO6_Sb3nQ3JSDBNLCY,2088
|
|
24
24
|
cognite/neat/core/_data_model/analysis/__init__.py,sha256=v3hSfz7AEEqcmdjL71I09tP8Hl-gPZYOiDYMp_CW4vg,70
|
|
25
25
|
cognite/neat/core/_data_model/analysis/_base.py,sha256=VT1orVf0xSSZrKnJoc-cJR1F1mtMn9Ybjk7UDO71aFA,24448
|
|
@@ -53,14 +53,15 @@ cognite/neat/core/_data_model/models/_import_contexts.py,sha256=LAQbgwTbyIAY3at2
|
|
|
53
53
|
cognite/neat/core/_data_model/models/_types.py,sha256=70E8fiLdZkVF2sDUGPuDhzXNA5niVECkVDI7YN0NF60,5488
|
|
54
54
|
cognite/neat/core/_data_model/models/data_types.py,sha256=uQ_u9KxCetLjxo-VtFzOXSxQuuf97Kg-9lfTTGzY6hc,10150
|
|
55
55
|
cognite/neat/core/_data_model/models/conceptual/__init__.py,sha256=9A6myEV8s0-LqdXejaljqPj8S0pIpUL75rNdRDZzyR8,585
|
|
56
|
-
cognite/neat/core/_data_model/models/conceptual/_unverified.py,sha256=
|
|
56
|
+
cognite/neat/core/_data_model/models/conceptual/_unverified.py,sha256=2Ju_LJS0xH8Ao-AxZMLwAZwHjg6ITyn4tBwTfzy2Wic,6524
|
|
57
57
|
cognite/neat/core/_data_model/models/conceptual/_validation.py,sha256=CF1jYALTCQFAr5KUwplAzOLdxJGknIeJo-HpxVZsgMY,13859
|
|
58
58
|
cognite/neat/core/_data_model/models/conceptual/_verified.py,sha256=BUB4Ur4kpBoWiwTf57tjxJ2l0tDTSbY7zGrg1g0yVNQ,13716
|
|
59
|
-
cognite/neat/core/_data_model/models/entities/__init__.py,sha256=
|
|
59
|
+
cognite/neat/core/_data_model/models/entities/__init__.py,sha256=qXrnTygYBgu4iE-ehNsHwmZ89pm9pTfU_Qe9rAq-ldg,1789
|
|
60
60
|
cognite/neat/core/_data_model/models/entities/_constants.py,sha256=GXRzVfArwxF3C67VCkzy0JWTZRkRJUYXBQaaecrqcWc,351
|
|
61
|
-
cognite/neat/core/_data_model/models/entities/_loaders.py,sha256=
|
|
61
|
+
cognite/neat/core/_data_model/models/entities/_loaders.py,sha256=vYRHID2SoseyJuzO4sdjjeWaRnv774SdKz9fCeuHTHU,5703
|
|
62
62
|
cognite/neat/core/_data_model/models/entities/_multi_value.py,sha256=4507L7dr_CL4vo1En6EyMiHhUDOWPTDVR1aYZns6S38,2792
|
|
63
|
-
cognite/neat/core/_data_model/models/entities/
|
|
63
|
+
cognite/neat/core/_data_model/models/entities/_restrictions.py,sha256=inztyR2EskFK9cYAdm39GbnjAod7Zmg0TL9NI0ZRleM,8925
|
|
64
|
+
cognite/neat/core/_data_model/models/entities/_single_value.py,sha256=HWANjeBNDo_o3s3oHxRWsxtidvo3d40GObcm7H_7hKo,23753
|
|
64
65
|
cognite/neat/core/_data_model/models/entities/_types.py,sha256=MqrCovqI_nvpMB4UqiUk4eUlKANvr8P7wr8k3y8lXlQ,2183
|
|
65
66
|
cognite/neat/core/_data_model/models/entities/_wrapped.py,sha256=hOvdyxCNFgv1UdfaasviKnbEN4yN09Iip0ggQiaXgB4,7993
|
|
66
67
|
cognite/neat/core/_data_model/models/mapping/__init__.py,sha256=T68Hf7rhiXa7b03h4RMwarAmkGnB-Bbhc1H07b2PyC4,100
|
|
@@ -68,7 +69,7 @@ cognite/neat/core/_data_model/models/mapping/_classic2core.py,sha256=FRDpYP_CX-C
|
|
|
68
69
|
cognite/neat/core/_data_model/models/mapping/_classic2core.yaml,sha256=ei-nuivNWVW9HmvzDBKIPF6ZdgaMq64XHw_rKm0CMxg,22584
|
|
69
70
|
cognite/neat/core/_data_model/models/physical/__init__.py,sha256=ONE_xLw1cxfw88rICG_RtbjCYUZm8yS2kBQ4Di3EGnA,987
|
|
70
71
|
cognite/neat/core/_data_model/models/physical/_exporter.py,sha256=DPOytV-sIzpGJtfDEfi7G4RWnSCVNRLWe1KzY26ewmc,30083
|
|
71
|
-
cognite/neat/core/_data_model/models/physical/_unverified.py,sha256=
|
|
72
|
+
cognite/neat/core/_data_model/models/physical/_unverified.py,sha256=8Sg0-tfSJ6glc5h1yNDlY29sajAOv3xoi9j-Q-Md6ZY,20116
|
|
72
73
|
cognite/neat/core/_data_model/models/physical/_validation.py,sha256=AuBAecOTAVRbGh9VXZ6W91HsU7-B75ko7oaxlX4Mmqw,41140
|
|
73
74
|
cognite/neat/core/_data_model/models/physical/_verified.py,sha256=4_7XUj6-x74DhL8qe-duXhlNnq6ANmShB7UpICjbQW4,26783
|
|
74
75
|
cognite/neat/core/_data_model/transformers/__init__.py,sha256=N6yRBplAkrwwxoTAre_1BE_fdSZL5jihr7xTQjW3KnM,1876
|
|
@@ -130,7 +131,7 @@ cognite/neat/core/_issues/errors/_external.py,sha256=AaKwO5-AvX01d7Hd83vqYl1qNmM
|
|
|
130
131
|
cognite/neat/core/_issues/errors/_general.py,sha256=QEgTp_bvzGjmpRtr09Lj_SBeD9IVdql5_JmP02P7PfM,1391
|
|
131
132
|
cognite/neat/core/_issues/errors/_properties.py,sha256=ZR2_j-TkxT8Zn5NGMNNOuKQ_bKeciaMOGZkRKg1YCvw,2924
|
|
132
133
|
cognite/neat/core/_issues/errors/_resources.py,sha256=lBK65tJZMhV3z3_xi8zJeo7Nt_agXsOklH_RPKQu28s,4002
|
|
133
|
-
cognite/neat/core/_issues/errors/_wrapper.py,sha256=
|
|
134
|
+
cognite/neat/core/_issues/errors/_wrapper.py,sha256=8kJXp9ONNrP7BvXAr8CUicoN4K_9SToR0Iwde3lja24,2533
|
|
134
135
|
cognite/neat/core/_issues/warnings/__init__.py,sha256=3MQS_elyRD3SG3iEWMWLRJDabth7upT3oX4WD0xxOh4,3263
|
|
135
136
|
cognite/neat/core/_issues/warnings/_external.py,sha256=w-1R7ea6DXTIWqwlwMMjY0YxKDMSJ8gKAbp_nIIM1AI,1324
|
|
136
137
|
cognite/neat/core/_issues/warnings/_general.py,sha256=_6dAFaMz-LIv7GsBBIBq2d-kmbuxVXKvU4jZeb7tjAo,972
|
|
@@ -195,7 +196,7 @@ cognite/neat/session/engine/__init__.py,sha256=D3MxUorEs6-NtgoICqtZ8PISQrjrr4dvc
|
|
|
195
196
|
cognite/neat/session/engine/_import.py,sha256=1QxA2_EK613lXYAHKQbZyw2yjo5P9XuiX4Z6_6-WMNQ,169
|
|
196
197
|
cognite/neat/session/engine/_interface.py,sha256=3W-cYr493c_mW3P5O6MKN1xEQg3cA7NHR_ev3zdF9Vk,533
|
|
197
198
|
cognite/neat/session/engine/_load.py,sha256=g52uYakQM03VqHt_RDHtpHso1-mFFifH5M4T2ScuH8A,5198
|
|
198
|
-
cognite_neat-0.123.
|
|
199
|
-
cognite_neat-0.123.
|
|
200
|
-
cognite_neat-0.123.
|
|
201
|
-
cognite_neat-0.123.
|
|
199
|
+
cognite_neat-0.123.28.dist-info/METADATA,sha256=UScQChiQFnF4EpPSGPtFyHZ-JgQuiIiPMlRA_CUHLdA,9166
|
|
200
|
+
cognite_neat-0.123.28.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
201
|
+
cognite_neat-0.123.28.dist-info/licenses/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
202
|
+
cognite_neat-0.123.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|