cognite-neat 0.87.0__py3-none-any.whl → 0.87.4__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/app/api/configuration.py +1 -10
- cognite/neat/app/api/routers/data_exploration.py +1 -1
- cognite/neat/config.py +84 -17
- cognite/neat/graph/extractors/_classic_cdf/_assets.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_events.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_files.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_labels.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_relationships.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_sequences.py +1 -1
- cognite/neat/graph/extractors/_classic_cdf/_timeseries.py +1 -1
- cognite/neat/graph/extractors/_dexpi.py +1 -1
- cognite/neat/graph/extractors/_mock_graph_generator.py +1 -1
- cognite/neat/graph/loaders/_rdf2asset.py +108 -52
- cognite/neat/graph/loaders/_rdf2dms.py +6 -6
- cognite/neat/graph/queries/_base.py +20 -11
- cognite/neat/graph/queries/_construct.py +3 -3
- cognite/neat/graph/queries/_shared.py +1 -1
- cognite/neat/graph/stores/_base.py +14 -3
- cognite/neat/graph/transformers/__init__.py +3 -0
- cognite/neat/graph/transformers/_rdfpath.py +42 -0
- cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +1 -1
- cognite/neat/legacy/graph/loaders/_asset_loader.py +2 -2
- cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +5 -2
- cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +4 -1
- cognite/neat/legacy/graph/loaders/rdf_to_dms.py +3 -1
- cognite/neat/legacy/graph/transformations/query_generator/sparql.py +1 -1
- cognite/neat/legacy/graph/transformations/transformer.py +1 -1
- cognite/neat/legacy/rules/exporters/_rules2dms.py +8 -3
- cognite/neat/legacy/rules/exporters/_rules2graphql.py +1 -1
- cognite/neat/legacy/rules/exporters/_rules2ontology.py +2 -1
- cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +3 -4
- cognite/neat/legacy/rules/importers/_dms2rules.py +4 -1
- cognite/neat/legacy/rules/importers/_graph2rules.py +5 -32
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +1 -1
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +2 -1
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +1 -1
- cognite/neat/legacy/rules/models/raw_rules.py +1 -1
- cognite/neat/rules/analysis/_asset.py +15 -0
- cognite/neat/rules/analysis/_base.py +1 -1
- cognite/neat/rules/analysis/_information.py +40 -12
- cognite/neat/rules/exporters/_rules2dms.py +1 -1
- cognite/neat/rules/exporters/_rules2ontology.py +2 -1
- cognite/neat/rules/importers/_dms2rules.py +10 -1
- cognite/neat/rules/importers/_inference2rules.py +1 -5
- cognite/neat/rules/importers/_owl2rules/_owl2classes.py +1 -1
- cognite/neat/rules/importers/_owl2rules/_owl2metadata.py +2 -1
- cognite/neat/rules/importers/_owl2rules/_owl2properties.py +1 -1
- cognite/neat/rules/issues/spreadsheet.py +35 -0
- cognite/neat/rules/models/_rdfpath.py +17 -21
- cognite/neat/rules/models/asset/_validation.py +38 -1
- cognite/neat/rules/models/dms/_exporter.py +9 -3
- cognite/neat/rules/models/dms/_rules.py +1 -0
- cognite/neat/rules/models/dms/_rules_input.py +3 -0
- cognite/neat/rules/models/dms/_schema.py +5 -4
- cognite/neat/rules/models/entities.py +26 -8
- cognite/neat/rules/models/information/_validation.py +1 -1
- cognite/neat/utils/__init__.py +0 -3
- cognite/neat/utils/auth.py +47 -28
- cognite/neat/utils/auxiliary.py +141 -1
- cognite/neat/utils/cdf/__init__.py +0 -0
- cognite/neat/utils/{cdf_classes.py → cdf/data_classes.py} +122 -2
- cognite/neat/utils/{cdf_loaders → cdf/loaders}/_data_modeling.py +37 -0
- cognite/neat/utils/{cdf_loaders → cdf/loaders}/_ingestion.py +2 -1
- cognite/neat/utils/collection_.py +18 -0
- cognite/neat/utils/rdf_.py +165 -0
- cognite/neat/utils/text.py +4 -0
- cognite/neat/utils/time_.py +17 -0
- cognite/neat/utils/upload.py +13 -1
- cognite/neat/workflows/_exceptions.py +5 -5
- cognite/neat/workflows/base.py +1 -1
- cognite/neat/workflows/steps/lib/current/rules_validator.py +2 -2
- cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +1 -1
- cognite/neat/workflows/steps/lib/legacy/graph_loader.py +1 -1
- cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +1 -1
- cognite/neat/workflows/steps/lib/legacy/rules_importer.py +1 -1
- {cognite_neat-0.87.0.dist-info → cognite_neat-0.87.4.dist-info}/METADATA +2 -2
- {cognite_neat-0.87.0.dist-info → cognite_neat-0.87.4.dist-info}/RECORD +83 -83
- cognite/neat/utils/cdf.py +0 -59
- cognite/neat/utils/cdf_loaders/data_classes.py +0 -121
- cognite/neat/utils/exceptions.py +0 -41
- cognite/neat/utils/utils.py +0 -429
- /cognite/neat/utils/{cdf_loaders → cdf/loaders}/__init__.py +0 -0
- /cognite/neat/utils/{cdf_loaders → cdf/loaders}/_base.py +0 -0
- {cognite_neat-0.87.0.dist-info → cognite_neat-0.87.4.dist-info}/LICENSE +0 -0
- {cognite_neat-0.87.0.dist-info → cognite_neat-0.87.4.dist-info}/WHEEL +0 -0
- {cognite_neat-0.87.0.dist-info → cognite_neat-0.87.4.dist-info}/entry_points.txt +0 -0
|
@@ -179,9 +179,21 @@ class NeatGraphStore:
|
|
|
179
179
|
warnings.warn("Desired type not found in graph!", stacklevel=2)
|
|
180
180
|
return None
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
analysis = InformationAnalysis(self.rules)
|
|
183
|
+
has_hop_transformations = analysis.has_hop_transformations()
|
|
184
|
+
has_self_reference_transformations = analysis.has_self_reference_property_transformations()
|
|
185
|
+
if has_hop_transformations or has_self_reference_transformations:
|
|
186
|
+
msg = (
|
|
187
|
+
f"Rules contain [{'Hop' if has_hop_transformations else '' }"
|
|
188
|
+
f", {'SelfReferenceProperty' if has_self_reference_transformations else '' }]"
|
|
189
|
+
" rdfpath."
|
|
190
|
+
f" Run [{'ReduceHopTraversal' if has_hop_transformations else '' }"
|
|
191
|
+
f", {'AddSelfReferenceProperty' if has_self_reference_transformations else '' }]"
|
|
192
|
+
" transformer(s) first!"
|
|
193
|
+
)
|
|
194
|
+
|
|
183
195
|
warnings.warn(
|
|
184
|
-
|
|
196
|
+
msg,
|
|
185
197
|
stacklevel=2,
|
|
186
198
|
)
|
|
187
199
|
return None
|
|
@@ -189,7 +201,6 @@ class NeatGraphStore:
|
|
|
189
201
|
instance_ids = self.queries.list_instances_ids_of_class(self.rules.metadata.namespace[class_])
|
|
190
202
|
|
|
191
203
|
property_renaming_config = InformationAnalysis(self.rules).define_property_renaming_config(class_entity)
|
|
192
|
-
print(property_renaming_config)
|
|
193
204
|
|
|
194
205
|
for instance_id in instance_ids:
|
|
195
206
|
yield self.queries.describe(instance_id, property_renaming_config)
|
|
@@ -6,6 +6,7 @@ from ._classic_cdf import (
|
|
|
6
6
|
AssetSequenceConnector,
|
|
7
7
|
AssetTimeSeriesConnector,
|
|
8
8
|
)
|
|
9
|
+
from ._rdfpath import AddSelfReferenceProperty
|
|
9
10
|
|
|
10
11
|
__all__ = [
|
|
11
12
|
"AddAssetDepth",
|
|
@@ -14,6 +15,7 @@ __all__ = [
|
|
|
14
15
|
"AssetFileConnector",
|
|
15
16
|
"AssetEventConnector",
|
|
16
17
|
"AssetRelationshipConnector",
|
|
18
|
+
"AddSelfReferenceProperty",
|
|
17
19
|
]
|
|
18
20
|
|
|
19
21
|
Transformers = (
|
|
@@ -23,4 +25,5 @@ Transformers = (
|
|
|
23
25
|
| AssetFileConnector
|
|
24
26
|
| AssetEventConnector
|
|
25
27
|
| AssetRelationshipConnector
|
|
28
|
+
| AddSelfReferenceProperty
|
|
26
29
|
)
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
from rdflib import RDF, Graph
|
|
2
|
+
|
|
3
|
+
from cognite.neat.rules.analysis import InformationAnalysis
|
|
4
|
+
from cognite.neat.rules.models._rdfpath import RDFPath, SingleProperty
|
|
5
|
+
from cognite.neat.rules.models.information import InformationRules
|
|
6
|
+
|
|
1
7
|
from ._base import BaseTransformer
|
|
2
8
|
|
|
3
9
|
|
|
@@ -5,3 +11,39 @@ class ReduceHopTraversal(BaseTransformer):
|
|
|
5
11
|
"""ReduceHopTraversal is a transformer that reduces the number of hops to direct connection."""
|
|
6
12
|
|
|
7
13
|
...
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AddSelfReferenceProperty(BaseTransformer):
|
|
17
|
+
description: str = "Adds property that contains id of reference to all references of given class in Rules"
|
|
18
|
+
_use_only_once: bool = True
|
|
19
|
+
_need_changes = frozenset({})
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
rules: InformationRules,
|
|
24
|
+
):
|
|
25
|
+
self.rules = rules
|
|
26
|
+
self.properties = InformationAnalysis(rules).all_reference_transformations()
|
|
27
|
+
|
|
28
|
+
def transform(self, graph: Graph) -> None:
|
|
29
|
+
for property_ in self.properties:
|
|
30
|
+
prefix = property_.transformation.traversal.class_.prefix
|
|
31
|
+
suffix = property_.transformation.traversal.class_.suffix
|
|
32
|
+
|
|
33
|
+
namespace = self.rules.prefixes[prefix] if prefix in self.rules.prefixes else self.rules.metadata.namespace
|
|
34
|
+
|
|
35
|
+
for reference in graph.subjects(RDF.type, namespace[suffix]):
|
|
36
|
+
graph.add(
|
|
37
|
+
(
|
|
38
|
+
reference,
|
|
39
|
+
self.rules.metadata.namespace[property_.property_],
|
|
40
|
+
reference,
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
traversal = SingleProperty.from_string(
|
|
45
|
+
class_=property_.class_.id,
|
|
46
|
+
property_=f"{self.rules.metadata.prefix}:{property_.property_}",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
property_.transformation = RDFPath(traversal=traversal)
|
|
@@ -20,7 +20,7 @@ from cognite.neat.legacy.rules.analysis import (
|
|
|
20
20
|
from cognite.neat.legacy.rules.exporters._rules2rules import subset_rules
|
|
21
21
|
from cognite.neat.legacy.rules.models import Rules
|
|
22
22
|
from cognite.neat.legacy.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
|
|
23
|
-
from cognite.neat.utils.
|
|
23
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
24
24
|
|
|
25
25
|
from ._base import BaseExtractor
|
|
26
26
|
|
|
@@ -15,8 +15,8 @@ from rdflib.query import ResultRow
|
|
|
15
15
|
from cognite.neat.legacy.graph.stores import NeatGraphStoreBase
|
|
16
16
|
from cognite.neat.legacy.rules.models import Rules
|
|
17
17
|
from cognite.neat.legacy.rules.models.rules import Property
|
|
18
|
-
from cognite.neat.utils import remove_namespace_from_uri
|
|
19
|
-
from cognite.neat.utils.
|
|
18
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
19
|
+
from cognite.neat.utils.time_ import epoch_now_ms
|
|
20
20
|
|
|
21
21
|
from ._base import CogniteLoader
|
|
22
22
|
|
|
@@ -18,7 +18,10 @@ from rdflib.term import URIRef
|
|
|
18
18
|
from cognite.neat.legacy.graph.loaders.core.models import AssetTemplate
|
|
19
19
|
from cognite.neat.legacy.graph.stores import NeatGraphStoreBase
|
|
20
20
|
from cognite.neat.legacy.rules.models.rules import Property, Rules
|
|
21
|
-
from cognite.neat.utils.
|
|
21
|
+
from cognite.neat.utils.auxiliary import retry_decorator
|
|
22
|
+
from cognite.neat.utils.collection_ import chunker
|
|
23
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
24
|
+
from cognite.neat.utils.time_ import datetime_utc_now
|
|
22
25
|
|
|
23
26
|
if sys.version_info >= (3, 11):
|
|
24
27
|
from datetime import UTC
|
|
@@ -899,7 +902,7 @@ def _micro_batch_push(
|
|
|
899
902
|
except CogniteDuplicatedError:
|
|
900
903
|
# this is handling of very rare case when some assets might be lost . Normally this should not happen.
|
|
901
904
|
# Last attempt to recover
|
|
902
|
-
client.assets.create_hierarchy(batch, upsert=True)
|
|
905
|
+
client.assets.create_hierarchy(batch, upsert=True) # type: ignore[arg-type]
|
|
903
906
|
|
|
904
907
|
delta_time = (datetime_utc_now() - start_time).seconds
|
|
905
908
|
|
|
@@ -14,7 +14,10 @@ from cognite.neat.legacy.graph.loaders.core.models import RelationshipDefinition
|
|
|
14
14
|
from cognite.neat.legacy.graph.loaders.core.rdf_to_assets import _categorize_cdf_assets
|
|
15
15
|
from cognite.neat.legacy.graph.stores import NeatGraphStoreBase
|
|
16
16
|
from cognite.neat.legacy.rules.models.rules import Rules
|
|
17
|
-
from cognite.neat.utils.
|
|
17
|
+
from cognite.neat.utils.auxiliary import retry_decorator
|
|
18
|
+
from cognite.neat.utils.collection_ import chunker
|
|
19
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
20
|
+
from cognite.neat.utils.time_ import datetime_utc_now, epoch_now_ms
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
def define_relationships(rules: Rules, data_set_id: int, stop_on_exception: bool = False) -> RelationshipDefinitions:
|
|
@@ -13,7 +13,9 @@ from cognite.neat.legacy.graph.transformations.query_generator.sparql import tri
|
|
|
13
13
|
from cognite.neat.legacy.rules.exporters._rules2dms import DMSSchemaComponents
|
|
14
14
|
from cognite.neat.legacy.rules.exporters._rules2pydantic_models import add_class_prefix_to_xid, rules_to_pydantic_models
|
|
15
15
|
from cognite.neat.legacy.rules.models.rules import Rules
|
|
16
|
-
from cognite.neat.utils.
|
|
16
|
+
from cognite.neat.utils.auxiliary import retry_decorator
|
|
17
|
+
from cognite.neat.utils.collection_ import chunker
|
|
18
|
+
from cognite.neat.utils.time_ import datetime_utc_now
|
|
17
19
|
|
|
18
20
|
from ._base import CogniteLoader
|
|
19
21
|
|
|
@@ -21,7 +21,7 @@ from cognite.neat.legacy.rules.models.rdfpath import (
|
|
|
21
21
|
parse_traversal,
|
|
22
22
|
)
|
|
23
23
|
from cognite.neat.legacy.rules.models.rules import Rules
|
|
24
|
-
from cognite.neat.utils.
|
|
24
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def _generate_prefix_header(prefixes: dict[str, Namespace] | None = None) -> str:
|
|
@@ -24,7 +24,7 @@ from cognite.neat.legacy.rules.models.rdfpath import (
|
|
|
24
24
|
parse_rule,
|
|
25
25
|
)
|
|
26
26
|
from cognite.neat.legacy.rules.models.rules import Rules
|
|
27
|
-
from cognite.neat.utils.
|
|
27
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
28
28
|
|
|
29
29
|
prom_total_proc_rules_g = Gauge("neat_total_processed_rules", "Number of processed rules", ["state"])
|
|
30
30
|
rules_processing_timing_metric = Gauge(
|
|
@@ -8,6 +8,7 @@ from pathlib import Path
|
|
|
8
8
|
from typing import ClassVar, Literal, cast, no_type_check
|
|
9
9
|
|
|
10
10
|
import yaml
|
|
11
|
+
from cognite.client.data_classes.data_modeling.data_types import ListablePropertyType
|
|
11
12
|
|
|
12
13
|
from cognite.neat.legacy.rules.models.value_types import ValueTypeMapping
|
|
13
14
|
|
|
@@ -45,7 +46,7 @@ from cognite.neat.legacy.rules.exporters._base import BaseExporter
|
|
|
45
46
|
from cognite.neat.legacy.rules.exporters._validation import are_entity_names_dms_compliant
|
|
46
47
|
from cognite.neat.legacy.rules.models._base import ContainerEntity, EntityTypes, ParentClass
|
|
47
48
|
from cognite.neat.legacy.rules.models.rules import Class, Property, Rules
|
|
48
|
-
from cognite.neat.utils.
|
|
49
|
+
from cognite.neat.utils.auxiliary import generate_exception_report
|
|
49
50
|
|
|
50
51
|
if sys.version_info < (3, 11):
|
|
51
52
|
from exceptiongroup import ExceptionGroup
|
|
@@ -278,13 +279,17 @@ class DMSSchemaComponents(BaseModel):
|
|
|
278
279
|
existing_property, default_value=None
|
|
279
280
|
)
|
|
280
281
|
|
|
281
|
-
# scenario: property
|
|
282
|
+
# scenario: property holds multiple values -> set is_list to True
|
|
282
283
|
if (
|
|
283
284
|
not isinstance(existing_property.type, DirectRelation)
|
|
284
285
|
and not isinstance(api_container_property.type, DirectRelation)
|
|
286
|
+
and isinstance(existing_property.type, ListablePropertyType)
|
|
287
|
+
and isinstance(api_container_property.type, ListablePropertyType)
|
|
285
288
|
and existing_property.type.is_list != api_container_property.type.is_list
|
|
286
289
|
):
|
|
287
|
-
containers[container_id].properties[container_property_id].type
|
|
290
|
+
type_ = containers[container_id].properties[container_property_id].type
|
|
291
|
+
if isinstance(type_, ListablePropertyType):
|
|
292
|
+
type_.is_list = True
|
|
288
293
|
|
|
289
294
|
if errors:
|
|
290
295
|
raise ExceptionGroup("Properties value types have been redefined! This is prohibited! Aborting!", errors)
|
|
@@ -14,7 +14,7 @@ from cognite.neat.legacy.rules.analysis import to_class_property_pairs
|
|
|
14
14
|
from cognite.neat.legacy.rules.exporters._validation import are_entity_names_dms_compliant, are_properties_redefined
|
|
15
15
|
from cognite.neat.legacy.rules.models.rules import Rules
|
|
16
16
|
from cognite.neat.legacy.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
|
|
17
|
-
from cognite.neat.utils.
|
|
17
|
+
from cognite.neat.utils.auxiliary import generate_exception_report
|
|
18
18
|
|
|
19
19
|
from ._base import BaseExporter
|
|
20
20
|
|
|
@@ -14,7 +14,8 @@ from cognite.neat.legacy.rules.exporters._base import BaseExporter
|
|
|
14
14
|
from cognite.neat.legacy.rules.exporters._validation import are_properties_redefined
|
|
15
15
|
from cognite.neat.legacy.rules.models.rules import Class, Metadata, Property, Rules
|
|
16
16
|
from cognite.neat.legacy.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
|
|
17
|
-
from cognite.neat.utils.
|
|
17
|
+
from cognite.neat.utils.auxiliary import generate_exception_report
|
|
18
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
18
19
|
|
|
19
20
|
if sys.version_info >= (3, 11):
|
|
20
21
|
from typing import Self
|
|
@@ -11,7 +11,6 @@ from cognite.client.data_classes.data_modeling.views import SingleHopConnectionD
|
|
|
11
11
|
from pydantic import BaseModel, ConfigDict, Field, create_model
|
|
12
12
|
from pydantic._internal._model_construction import ModelMetaclass
|
|
13
13
|
from rdflib import Graph, URIRef
|
|
14
|
-
from typing_extensions import TypeAliasType
|
|
15
14
|
|
|
16
15
|
from cognite.neat.legacy.graph.loaders.core.rdf_to_assets import NeatMetadataKeys
|
|
17
16
|
from cognite.neat.legacy.graph.transformations.query_generator.sparql import build_construct_query, triples2dictionary
|
|
@@ -21,7 +20,7 @@ from cognite.neat.legacy.rules.exporters._rules2dms import DMSSchemaComponents
|
|
|
21
20
|
from cognite.neat.legacy.rules.exporters._validation import are_entity_names_dms_compliant
|
|
22
21
|
from cognite.neat.legacy.rules.models.rules import Property, Rules
|
|
23
22
|
from cognite.neat.legacy.rules.models.value_types import ValueTypeMapping
|
|
24
|
-
from cognite.neat.utils.
|
|
23
|
+
from cognite.neat.utils.auxiliary import create_sha256_hash, generate_exception_report
|
|
25
24
|
|
|
26
25
|
if sys.version_info >= (3, 11):
|
|
27
26
|
from datetime import UTC
|
|
@@ -30,8 +29,8 @@ else:
|
|
|
30
29
|
|
|
31
30
|
UTC = timezone.utc
|
|
32
31
|
|
|
33
|
-
EdgeOneToOne: TypeAlias =
|
|
34
|
-
EdgeOneToMany: TypeAlias =
|
|
32
|
+
EdgeOneToOne: TypeAlias = str # type: ignore[valid-type]
|
|
33
|
+
EdgeOneToMany: TypeAlias = list[str] # type: ignore[valid-type]
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
def default_model_configuration(
|
|
@@ -13,6 +13,7 @@ from cognite.client.data_classes.data_modeling import (
|
|
|
13
13
|
SingleHopConnectionDefinition,
|
|
14
14
|
View,
|
|
15
15
|
)
|
|
16
|
+
from cognite.client.data_classes.data_modeling.data_types import ListablePropertyType
|
|
16
17
|
from cognite.client.data_classes.data_modeling.ids import DataModelIdentifier, ViewId
|
|
17
18
|
|
|
18
19
|
from cognite.neat.legacy.rules.models.tables import Tables
|
|
@@ -129,7 +130,9 @@ class DMSImporter(BaseImporter):
|
|
|
129
130
|
|
|
130
131
|
max_count: str | float = "1"
|
|
131
132
|
if isinstance(prop, SingleHopConnectionDefinition) or (
|
|
132
|
-
isinstance(prop, MappedProperty)
|
|
133
|
+
isinstance(prop, MappedProperty)
|
|
134
|
+
and isinstance(prop.type, ListablePropertyType)
|
|
135
|
+
and prop.type.is_list
|
|
133
136
|
):
|
|
134
137
|
max_count = float("nan")
|
|
135
138
|
|
|
@@ -14,11 +14,7 @@ from cognite.neat.constants import get_default_prefixes
|
|
|
14
14
|
from cognite.neat.legacy.rules import exceptions
|
|
15
15
|
from cognite.neat.legacy.rules.exporters._rules2rules import to_dms_name
|
|
16
16
|
from cognite.neat.legacy.rules.models.tables import Tables
|
|
17
|
-
from cognite.neat.utils.
|
|
18
|
-
get_namespace,
|
|
19
|
-
remove_namespace_from_uri,
|
|
20
|
-
uri_to_short_form,
|
|
21
|
-
)
|
|
17
|
+
from cognite.neat.utils.rdf_ import get_namespace, remove_namespace_from_uri, uri_to_short_form
|
|
22
18
|
|
|
23
19
|
from ._base import BaseImporter
|
|
24
20
|
|
|
@@ -78,26 +74,11 @@ def _create_default_properties_parsing_config() -> dict[str, tuple[str, ...]]:
|
|
|
78
74
|
|
|
79
75
|
def _create_default_classes_parsing_config() -> dict[str, tuple[str, ...]]:
|
|
80
76
|
# TODO: these are to be read from Class pydantic model
|
|
81
|
-
return {
|
|
82
|
-
"header": (
|
|
83
|
-
"Class",
|
|
84
|
-
"Description",
|
|
85
|
-
"Parent Class",
|
|
86
|
-
"Source",
|
|
87
|
-
"Source Entity Name",
|
|
88
|
-
"Match Type",
|
|
89
|
-
"Comment",
|
|
90
|
-
)
|
|
91
|
-
}
|
|
77
|
+
return {"header": ("Class", "Description", "Parent Class", "Source", "Source Entity Name", "Match Type", "Comment")}
|
|
92
78
|
|
|
93
79
|
|
|
94
80
|
def _parse_prefixes_df(prefixes: dict[str, Namespace]) -> pd.DataFrame:
|
|
95
|
-
return pd.DataFrame.from_dict(
|
|
96
|
-
{
|
|
97
|
-
"Prefix": list(prefixes.keys()),
|
|
98
|
-
"URI": [str(uri) for uri in prefixes.values()],
|
|
99
|
-
}
|
|
100
|
-
)
|
|
81
|
+
return pd.DataFrame.from_dict({"Prefix": list(prefixes.keys()), "URI": [str(uri) for uri in prefixes.values()]})
|
|
101
82
|
|
|
102
83
|
|
|
103
84
|
def _parse_metadata_df() -> pd.DataFrame:
|
|
@@ -202,18 +183,10 @@ def _graph_to_data_model_dict(graph: Graph, max_number_of_instance: int = -1) ->
|
|
|
202
183
|
)
|
|
203
184
|
class_name = f"{class_name}_{len(data_model)+1}"
|
|
204
185
|
|
|
205
|
-
data_model[class_name] = {
|
|
206
|
-
"properties": {},
|
|
207
|
-
"uri": uri_to_short_form(class_, prefixes),
|
|
208
|
-
}
|
|
186
|
+
data_model[class_name] = {"properties": {}, "uri": uri_to_short_form(class_, prefixes)}
|
|
209
187
|
|
|
210
188
|
for instance in _get_class_instance_ids(graph, class_, max_number_of_instance):
|
|
211
|
-
for (
|
|
212
|
-
property_,
|
|
213
|
-
occurrence,
|
|
214
|
-
data_type,
|
|
215
|
-
object_type,
|
|
216
|
-
) in _define_instance_properties(graph, instance):
|
|
189
|
+
for property_, occurrence, data_type, object_type in _define_instance_properties(graph, instance):
|
|
217
190
|
property_name = remove_namespace_from_uri(property_)
|
|
218
191
|
_add_uri_namespace_to_prefixes(property_, prefixes)
|
|
219
192
|
|
|
@@ -4,7 +4,7 @@ import numpy as np
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
from rdflib import OWL, Graph
|
|
6
6
|
|
|
7
|
-
from cognite.neat.utils.
|
|
7
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def parse_owl_classes(graph: Graph, make_compliant: bool = False, language: str = "en") -> pd.DataFrame:
|
|
@@ -10,7 +10,8 @@ from cognite.neat.legacy.rules.models.rules import (
|
|
|
10
10
|
prefix_compliance_regex,
|
|
11
11
|
version_compliance_regex,
|
|
12
12
|
)
|
|
13
|
-
from cognite.neat.utils.
|
|
13
|
+
from cognite.neat.utils.collection_ import remove_none_elements_from_set
|
|
14
|
+
from cognite.neat.utils.rdf_ import convert_rdflib_content
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def parse_owl_metadata(graph: Graph, make_compliant: bool = False) -> pd.DataFrame:
|
|
@@ -4,7 +4,7 @@ import numpy as np
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
from rdflib import Graph
|
|
6
6
|
|
|
7
|
-
from cognite.neat.utils.
|
|
7
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
8
8
|
|
|
9
9
|
from ._owl2classes import _data_type_property_class, _object_property_class, _thing_class
|
|
10
10
|
|
|
@@ -24,7 +24,7 @@ from cognite.neat.legacy.rules.models.tables import Tables
|
|
|
24
24
|
|
|
25
25
|
# importers:
|
|
26
26
|
from cognite.neat.rules import exceptions
|
|
27
|
-
from cognite.neat.utils.
|
|
27
|
+
from cognite.neat.utils.auxiliary import generate_exception_report
|
|
28
28
|
|
|
29
29
|
__all__ = ["RawRules"]
|
|
30
30
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
from graphlib import TopologicalSorter
|
|
2
3
|
from typing import cast
|
|
3
4
|
|
|
4
5
|
from cognite.neat.rules.models import AssetRules
|
|
@@ -6,6 +7,7 @@ from cognite.neat.rules.models._rdfpath import RDFPath
|
|
|
6
7
|
from cognite.neat.rules.models.asset import AssetClass, AssetProperty
|
|
7
8
|
from cognite.neat.rules.models.entities import (
|
|
8
9
|
AssetEntity,
|
|
10
|
+
AssetFields,
|
|
9
11
|
ClassEntity,
|
|
10
12
|
EntityTypes,
|
|
11
13
|
ReferenceEntity,
|
|
@@ -95,6 +97,19 @@ class AssetAnalysis(BaseAnalysis[AssetRules, AssetClass, AssetProperty, ClassEnt
|
|
|
95
97
|
|
|
96
98
|
return class_property_pairs
|
|
97
99
|
|
|
100
|
+
def class_topological_sort(self) -> list[ClassEntity]:
|
|
101
|
+
child_parent_asset: dict[ClassEntity, set[ClassEntity]] = {}
|
|
102
|
+
for class_, properties in self.asset_definition().items():
|
|
103
|
+
child_parent_asset[class_] = set()
|
|
104
|
+
for property_ in properties.values():
|
|
105
|
+
if any(
|
|
106
|
+
cast(AssetEntity, implementation).property_ == AssetFields.parentExternalId
|
|
107
|
+
for implementation in property_.implementation
|
|
108
|
+
):
|
|
109
|
+
child_parent_asset[property_.class_].add(cast(ClassEntity, property_.value_type))
|
|
110
|
+
|
|
111
|
+
return list(TopologicalSorter(child_parent_asset).static_order())
|
|
112
|
+
|
|
98
113
|
def asset_definition(
|
|
99
114
|
self, only_rdfpath: bool = False, consider_inheritance: bool = False
|
|
100
115
|
) -> dict[ClassEntity, dict[str, AssetProperty]]:
|
|
@@ -17,7 +17,7 @@ from cognite.neat.rules.models.entities import (
|
|
|
17
17
|
ReferenceEntity,
|
|
18
18
|
)
|
|
19
19
|
from cognite.neat.rules.models.information import InformationProperty
|
|
20
|
-
from cognite.neat.utils.
|
|
20
|
+
from cognite.neat.utils.rdf_ import get_inheritance_path
|
|
21
21
|
|
|
22
22
|
T_Rules = TypeVar("T_Rules", bound=BaseRules)
|
|
23
23
|
T_Property = TypeVar("T_Property", bound=BaseModel)
|
|
@@ -3,16 +3,22 @@ import warnings
|
|
|
3
3
|
from typing import Any, cast
|
|
4
4
|
|
|
5
5
|
from pydantic import ValidationError
|
|
6
|
+
from rdflib import URIRef
|
|
6
7
|
|
|
7
8
|
from cognite.neat.rules.models import SchemaCompleteness
|
|
8
|
-
from cognite.neat.rules.models._rdfpath import
|
|
9
|
+
from cognite.neat.rules.models._rdfpath import (
|
|
10
|
+
Hop,
|
|
11
|
+
RDFPath,
|
|
12
|
+
SelfReferenceProperty,
|
|
13
|
+
SingleProperty,
|
|
14
|
+
)
|
|
9
15
|
from cognite.neat.rules.models.entities import ClassEntity, ReferenceEntity
|
|
10
16
|
from cognite.neat.rules.models.information import (
|
|
11
17
|
InformationClass,
|
|
12
18
|
InformationProperty,
|
|
13
19
|
InformationRules,
|
|
14
20
|
)
|
|
15
|
-
from cognite.neat.utils.
|
|
21
|
+
from cognite.neat.utils.rdf_ import get_inheritance_path
|
|
16
22
|
|
|
17
23
|
from ._base import BaseAnalysis
|
|
18
24
|
|
|
@@ -56,24 +62,46 @@ class InformationAnalysis(BaseAnalysis[InformationRules, InformationClass, Infor
|
|
|
56
62
|
prop_.transformation and isinstance(prop_.transformation.traversal, Hop) for prop_ in self.rules.properties
|
|
57
63
|
)
|
|
58
64
|
|
|
59
|
-
def
|
|
60
|
-
|
|
65
|
+
def has_self_reference_property_transformations(self):
|
|
66
|
+
return any(
|
|
67
|
+
prop_.transformation and isinstance(prop_.transformation.traversal, SelfReferenceProperty)
|
|
68
|
+
for prop_ in self.rules.properties
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def all_reference_transformations(self):
|
|
72
|
+
return [
|
|
73
|
+
prop_
|
|
74
|
+
for prop_ in self.rules.properties
|
|
75
|
+
if prop_.transformation and isinstance(prop_.transformation.traversal, SelfReferenceProperty)
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
def define_property_renaming_config(self, class_: ClassEntity) -> dict[str | URIRef, str]:
|
|
79
|
+
property_renaming_configuration: dict[str | URIRef, str] = {}
|
|
61
80
|
|
|
62
81
|
if definitions := self.class_property_pairs(only_rdfpath=True, consider_inheritance=True).get(class_, None):
|
|
63
82
|
for property_id, definition in definitions.items():
|
|
83
|
+
transformation = cast(RDFPath, definition.transformation)
|
|
84
|
+
|
|
85
|
+
# use case we have a single property rdf path, and defined prefix
|
|
86
|
+
# in either metadata or prefixes of rules
|
|
64
87
|
if isinstance(
|
|
65
|
-
|
|
88
|
+
transformation.traversal,
|
|
66
89
|
SingleProperty,
|
|
90
|
+
) and (
|
|
91
|
+
transformation.traversal.property.prefix in self.rules.prefixes
|
|
92
|
+
or transformation.traversal.property.prefix == self.rules.metadata.prefix
|
|
67
93
|
):
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
namespace = (
|
|
95
|
+
self.rules.metadata.namespace
|
|
96
|
+
if transformation.traversal.property.prefix == self.rules.metadata.prefix
|
|
97
|
+
else self.rules.prefixes[transformation.traversal.property.prefix]
|
|
98
|
+
)
|
|
72
99
|
|
|
73
|
-
|
|
74
|
-
graph_property = property_id
|
|
100
|
+
property_renaming_configuration[namespace[transformation.traversal.property.suffix]] = property_id
|
|
75
101
|
|
|
76
|
-
|
|
102
|
+
# otherwise we default to the property id
|
|
103
|
+
else:
|
|
104
|
+
property_renaming_configuration[property_id] = property_id
|
|
77
105
|
|
|
78
106
|
return property_renaming_configuration
|
|
79
107
|
|
|
@@ -20,7 +20,7 @@ from cognite.neat.rules._shared import Rules
|
|
|
20
20
|
from cognite.neat.rules.issues import IssueList
|
|
21
21
|
from cognite.neat.rules.models import InformationRules
|
|
22
22
|
from cognite.neat.rules.models.dms import DMSRules, DMSSchema, PipelineSchema
|
|
23
|
-
from cognite.neat.utils.
|
|
23
|
+
from cognite.neat.utils.cdf.loaders import (
|
|
24
24
|
ContainerLoader,
|
|
25
25
|
DataModelingLoader,
|
|
26
26
|
DataModelLoader,
|
|
@@ -20,7 +20,8 @@ from cognite.neat.rules.models.information import (
|
|
|
20
20
|
InformationProperty,
|
|
21
21
|
InformationRules,
|
|
22
22
|
)
|
|
23
|
-
from cognite.neat.utils.
|
|
23
|
+
from cognite.neat.utils.auxiliary import generate_exception_report
|
|
24
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
24
25
|
|
|
25
26
|
from ._base import BaseExporter
|
|
26
27
|
from ._validation import are_properties_redefined
|
|
@@ -8,6 +8,7 @@ from cognite.client import CogniteClient
|
|
|
8
8
|
from cognite.client import data_modeling as dm
|
|
9
9
|
from cognite.client.data_classes.data_modeling import DataModelId, DataModelIdentifier
|
|
10
10
|
from cognite.client.data_classes.data_modeling.containers import BTreeIndex, InvertedIndex
|
|
11
|
+
from cognite.client.data_classes.data_modeling.data_types import ListablePropertyType
|
|
11
12
|
from cognite.client.data_classes.data_modeling.views import (
|
|
12
13
|
MultiEdgeConnectionApply,
|
|
13
14
|
MultiReverseDirectRelationApply,
|
|
@@ -345,6 +346,7 @@ class DMSImporter(BaseImporter):
|
|
|
345
346
|
value_type=value_type,
|
|
346
347
|
is_list=self._get_is_list(prop),
|
|
347
348
|
nullable=self._get_nullable(prop),
|
|
349
|
+
immutable=self._get_immutable(prop),
|
|
348
350
|
default=self._get_default(prop),
|
|
349
351
|
container=ContainerEntity.from_id(prop.container) if isinstance(prop, dm.MappedPropertyApply) else None,
|
|
350
352
|
container_property=prop.container_property_identifier if isinstance(prop, dm.MappedPropertyApply) else None,
|
|
@@ -401,9 +403,16 @@ class DMSImporter(BaseImporter):
|
|
|
401
403
|
else:
|
|
402
404
|
return None
|
|
403
405
|
|
|
406
|
+
def _get_immutable(self, prop: ViewPropertyApply) -> bool | None:
|
|
407
|
+
if isinstance(prop, dm.MappedPropertyApply):
|
|
408
|
+
return self._container_prop_unsafe(prop).immutable
|
|
409
|
+
else:
|
|
410
|
+
return None
|
|
411
|
+
|
|
404
412
|
def _get_is_list(self, prop: ViewPropertyApply) -> bool | None:
|
|
405
413
|
if isinstance(prop, dm.MappedPropertyApply):
|
|
406
|
-
|
|
414
|
+
prop_type = self._container_prop_unsafe(prop).type
|
|
415
|
+
return isinstance(prop_type, ListablePropertyType) and prop_type.is_list
|
|
407
416
|
elif isinstance(prop, MultiEdgeConnectionApply | MultiReverseDirectRelationApply):
|
|
408
417
|
return True
|
|
409
418
|
elif isinstance(prop, SingleEdgeConnectionApply | SingleReverseDirectRelationApply):
|
|
@@ -17,11 +17,7 @@ from cognite.neat.rules.models.information import (
|
|
|
17
17
|
InformationMetadata,
|
|
18
18
|
InformationRulesInput,
|
|
19
19
|
)
|
|
20
|
-
from cognite.neat.utils.
|
|
21
|
-
get_namespace,
|
|
22
|
-
remove_namespace_from_uri,
|
|
23
|
-
uri_to_short_form,
|
|
24
|
-
)
|
|
20
|
+
from cognite.neat.utils.rdf_ import get_namespace, remove_namespace_from_uri, uri_to_short_form
|
|
25
21
|
|
|
26
22
|
ORDERED_CLASSES_QUERY = """SELECT ?class (count(?s) as ?instances )
|
|
27
23
|
WHERE { ?s a ?class . }
|
|
@@ -5,7 +5,7 @@ import pandas as pd
|
|
|
5
5
|
from rdflib import OWL, Graph
|
|
6
6
|
|
|
7
7
|
from cognite.neat.rules.models._base import MatchType
|
|
8
|
-
from cognite.neat.utils.
|
|
8
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def parse_owl_classes(graph: Graph, language: str = "en") -> list[dict]:
|
|
@@ -9,7 +9,8 @@ from cognite.neat.rules.models._types._base import (
|
|
|
9
9
|
PREFIX_COMPLIANCE_REGEX,
|
|
10
10
|
VERSION_COMPLIANCE_REGEX,
|
|
11
11
|
)
|
|
12
|
-
from cognite.neat.utils.
|
|
12
|
+
from cognite.neat.utils.collection_ import remove_none_elements_from_set
|
|
13
|
+
from cognite.neat.utils.rdf_ import convert_rdflib_content
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def parse_owl_metadata(graph: Graph) -> dict:
|
|
@@ -5,7 +5,7 @@ import pandas as pd
|
|
|
5
5
|
from rdflib import Graph
|
|
6
6
|
|
|
7
7
|
from cognite.neat.rules.models._base import MatchType
|
|
8
|
-
from cognite.neat.utils.
|
|
8
|
+
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
9
9
|
|
|
10
10
|
from ._owl2classes import _data_type_property_class, _object_property_class, _thing_class
|
|
11
11
|
|