cognite-neat 0.87.4__py3-none-any.whl → 0.88.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.
- cognite/neat/_version.py +1 -1
- cognite/neat/app/api/data_classes/rest.py +0 -19
- cognite/neat/app/api/explorer.py +6 -4
- cognite/neat/app/api/routers/crud.py +11 -21
- cognite/neat/app/api/routers/workflows.py +24 -94
- cognite/neat/graph/extractors/_classic_cdf/_assets.py +8 -2
- cognite/neat/graph/extractors/_mock_graph_generator.py +2 -2
- cognite/neat/graph/loaders/_base.py +17 -12
- cognite/neat/graph/loaders/_rdf2asset.py +223 -58
- cognite/neat/graph/loaders/_rdf2dms.py +1 -1
- cognite/neat/graph/stores/_base.py +5 -0
- cognite/neat/rules/analysis/_asset.py +31 -1
- cognite/neat/rules/importers/_inference2rules.py +31 -35
- cognite/neat/rules/models/information/_rules.py +1 -1
- cognite/neat/workflows/steps/data_contracts.py +17 -43
- cognite/neat/workflows/steps/lib/current/graph_extractor.py +28 -24
- cognite/neat/workflows/steps/lib/current/graph_loader.py +4 -21
- cognite/neat/workflows/steps/lib/current/graph_store.py +18 -134
- cognite/neat/workflows/steps_registry.py +5 -7
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.88.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.88.0.dist-info}/RECORD +24 -132
- cognite/neat/app/api/routers/core.py +0 -91
- cognite/neat/app/api/routers/data_exploration.py +0 -336
- cognite/neat/app/api/routers/rules.py +0 -203
- cognite/neat/legacy/__init__.py +0 -0
- cognite/neat/legacy/graph/__init__.py +0 -3
- cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -20182
- cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml +0 -20163
- cognite/neat/legacy/graph/examples/__init__.py +0 -10
- cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- cognite/neat/legacy/graph/exceptions.py +0 -90
- cognite/neat/legacy/graph/extractors/__init__.py +0 -6
- cognite/neat/legacy/graph/extractors/_base.py +0 -14
- cognite/neat/legacy/graph/extractors/_dexpi.py +0 -44
- cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py +0 -403
- cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +0 -361
- cognite/neat/legacy/graph/loaders/__init__.py +0 -23
- cognite/neat/legacy/graph/loaders/_asset_loader.py +0 -511
- cognite/neat/legacy/graph/loaders/_base.py +0 -67
- cognite/neat/legacy/graph/loaders/_exceptions.py +0 -85
- cognite/neat/legacy/graph/loaders/core/__init__.py +0 -0
- cognite/neat/legacy/graph/loaders/core/labels.py +0 -58
- cognite/neat/legacy/graph/loaders/core/models.py +0 -136
- cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +0 -1046
- cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +0 -559
- cognite/neat/legacy/graph/loaders/rdf_to_dms.py +0 -309
- cognite/neat/legacy/graph/loaders/validator.py +0 -87
- cognite/neat/legacy/graph/models.py +0 -6
- cognite/neat/legacy/graph/stores/__init__.py +0 -13
- cognite/neat/legacy/graph/stores/_base.py +0 -400
- cognite/neat/legacy/graph/stores/_graphdb_store.py +0 -52
- cognite/neat/legacy/graph/stores/_memory_store.py +0 -43
- cognite/neat/legacy/graph/stores/_oxigraph_store.py +0 -151
- cognite/neat/legacy/graph/stores/_oxrdflib.py +0 -247
- cognite/neat/legacy/graph/stores/_rdf_to_graph.py +0 -42
- cognite/neat/legacy/graph/transformations/__init__.py +0 -0
- cognite/neat/legacy/graph/transformations/entity_matcher.py +0 -101
- cognite/neat/legacy/graph/transformations/query_generator/__init__.py +0 -3
- cognite/neat/legacy/graph/transformations/query_generator/sparql.py +0 -575
- cognite/neat/legacy/graph/transformations/transformer.py +0 -322
- cognite/neat/legacy/rules/__init__.py +0 -0
- cognite/neat/legacy/rules/analysis.py +0 -231
- cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
- cognite/neat/legacy/rules/examples/Rules-Nordic44.xlsx +0 -0
- cognite/neat/legacy/rules/examples/__init__.py +0 -18
- cognite/neat/legacy/rules/examples/power-grid-containers.yaml +0 -124
- cognite/neat/legacy/rules/examples/power-grid-example.xlsx +0 -0
- cognite/neat/legacy/rules/examples/power-grid-model.yaml +0 -224
- cognite/neat/legacy/rules/examples/rules-template.xlsx +0 -0
- cognite/neat/legacy/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
- cognite/neat/legacy/rules/examples/skos-rules.xlsx +0 -0
- cognite/neat/legacy/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
- cognite/neat/legacy/rules/examples/wind-energy.owl +0 -1511
- cognite/neat/legacy/rules/exceptions.py +0 -2972
- cognite/neat/legacy/rules/exporters/__init__.py +0 -20
- cognite/neat/legacy/rules/exporters/_base.py +0 -45
- cognite/neat/legacy/rules/exporters/_core/__init__.py +0 -5
- cognite/neat/legacy/rules/exporters/_core/rules2labels.py +0 -24
- cognite/neat/legacy/rules/exporters/_rules2dms.py +0 -885
- cognite/neat/legacy/rules/exporters/_rules2excel.py +0 -213
- cognite/neat/legacy/rules/exporters/_rules2graphql.py +0 -183
- cognite/neat/legacy/rules/exporters/_rules2ontology.py +0 -524
- cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +0 -748
- cognite/neat/legacy/rules/exporters/_rules2rules.py +0 -105
- cognite/neat/legacy/rules/exporters/_rules2triples.py +0 -38
- cognite/neat/legacy/rules/exporters/_validation.py +0 -146
- cognite/neat/legacy/rules/importers/__init__.py +0 -22
- cognite/neat/legacy/rules/importers/_base.py +0 -66
- cognite/neat/legacy/rules/importers/_dict2rules.py +0 -158
- cognite/neat/legacy/rules/importers/_dms2rules.py +0 -194
- cognite/neat/legacy/rules/importers/_graph2rules.py +0 -308
- cognite/neat/legacy/rules/importers/_json2rules.py +0 -39
- cognite/neat/legacy/rules/importers/_owl2rules/__init__.py +0 -3
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +0 -239
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +0 -260
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +0 -217
- cognite/neat/legacy/rules/importers/_owl2rules/_owl2rules.py +0 -290
- cognite/neat/legacy/rules/importers/_spreadsheet2rules.py +0 -45
- cognite/neat/legacy/rules/importers/_xsd2rules.py +0 -20
- cognite/neat/legacy/rules/importers/_yaml2rules.py +0 -39
- cognite/neat/legacy/rules/models/__init__.py +0 -5
- cognite/neat/legacy/rules/models/_base.py +0 -151
- cognite/neat/legacy/rules/models/raw_rules.py +0 -316
- cognite/neat/legacy/rules/models/rdfpath.py +0 -237
- cognite/neat/legacy/rules/models/rules.py +0 -1289
- cognite/neat/legacy/rules/models/tables.py +0 -9
- cognite/neat/legacy/rules/models/value_types.py +0 -118
- cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml +0 -89
- cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -152
- cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -139
- cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
- cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml +0 -65
- cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -116
- cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml +0 -67
- cognite/neat/legacy/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -64
- cognite/neat/legacy/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -95
- cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -111
- cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
- cognite/neat/workflows/migration/__init__.py +0 -0
- cognite/neat/workflows/migration/steps.py +0 -91
- cognite/neat/workflows/migration/wf_manifests.py +0 -33
- cognite/neat/workflows/steps/lib/legacy/__init__.py +0 -7
- cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py +0 -82
- cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +0 -746
- cognite/neat/workflows/steps/lib/legacy/graph_loader.py +0 -606
- cognite/neat/workflows/steps/lib/legacy/graph_store.py +0 -307
- cognite/neat/workflows/steps/lib/legacy/graph_transformer.py +0 -58
- cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +0 -511
- cognite/neat/workflows/steps/lib/legacy/rules_importer.py +0 -612
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.88.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.88.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.87.4.dist-info → cognite_neat-0.88.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
"""This module is used to generate mock graph data for purposes of testing of NEAT."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
import random
|
|
5
|
-
import warnings
|
|
6
|
-
from collections import OrderedDict
|
|
7
|
-
|
|
8
|
-
import numpy
|
|
9
|
-
import pandas as pd
|
|
10
|
-
from prometheus_client import Gauge
|
|
11
|
-
from rdflib import RDF, Literal, Namespace, URIRef
|
|
12
|
-
|
|
13
|
-
from cognite.neat.legacy.graph.models import Triple
|
|
14
|
-
from cognite.neat.legacy.rules.analysis import (
|
|
15
|
-
get_class_linkage,
|
|
16
|
-
get_classes_with_properties,
|
|
17
|
-
get_defined_classes,
|
|
18
|
-
get_symmetric_pairs,
|
|
19
|
-
)
|
|
20
|
-
from cognite.neat.legacy.rules.exporters._rules2rules import subset_rules
|
|
21
|
-
from cognite.neat.legacy.rules.models import Rules
|
|
22
|
-
from cognite.neat.legacy.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
|
|
23
|
-
from cognite.neat.utils.rdf_ import remove_namespace_from_uri
|
|
24
|
-
|
|
25
|
-
from ._base import BaseExtractor
|
|
26
|
-
|
|
27
|
-
neat_total_processed_mock_triples = Gauge(
|
|
28
|
-
"neat_total_processed_mock_triples", "Number of processed mock triples", ["state"]
|
|
29
|
-
)
|
|
30
|
-
neat_mock_triples_processing_timing = Gauge(
|
|
31
|
-
"neat_mock_triples_processing_timing", "Generation of mock knowledge graph timing metrics", ["aggregation"]
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class MockGraphGenerator(BaseExtractor):
|
|
36
|
-
"""
|
|
37
|
-
Class used to generate mock graph data for purposes of testing of NEAT.
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
rules: Transformation rules defining the classes with their properties.
|
|
41
|
-
class_count: Target class count for each class in the ontology
|
|
42
|
-
stop_on_exception: To stop if exception is encountered or not, default is False
|
|
43
|
-
allow_isolated_classes: To allow generation of instances for classes that are not
|
|
44
|
-
connected to any other class, default is True
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
def __init__(
|
|
48
|
-
self, rules: Rules, class_count: dict, stop_on_exception: bool = False, allow_isolated_classes: bool = True
|
|
49
|
-
):
|
|
50
|
-
self.rules = rules
|
|
51
|
-
self.class_count = class_count
|
|
52
|
-
self.stop_on_exception = stop_on_exception
|
|
53
|
-
self.allow_isolated_classes = allow_isolated_classes
|
|
54
|
-
|
|
55
|
-
def extract(self) -> list[Triple]:
|
|
56
|
-
"""Generate mock triples based on data model defined transformation rules and desired number
|
|
57
|
-
of class instances
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
List of RDF triples, represented as tuples `(subject, predicate, object)`, that define data model instances
|
|
61
|
-
"""
|
|
62
|
-
return generate_triples(
|
|
63
|
-
self.rules,
|
|
64
|
-
self.class_count,
|
|
65
|
-
stop_on_exception=self.stop_on_exception,
|
|
66
|
-
allow_isolated_classes=self.allow_isolated_classes,
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def generate_triples(
|
|
71
|
-
transformation_rules: Rules, class_count: dict, stop_on_exception: bool = False, allow_isolated_classes: bool = True
|
|
72
|
-
) -> list[Triple]:
|
|
73
|
-
"""Generate mock triples based on data model defined transformation rules and desired number
|
|
74
|
-
of class instances
|
|
75
|
-
|
|
76
|
-
Args:
|
|
77
|
-
transformation_rules : Transformation rules defining the data model
|
|
78
|
-
class_count: Target class count for each class in the ontology
|
|
79
|
-
stop_on_exception: To stop if exception is encountered or not, default is False
|
|
80
|
-
allow_isolated_classes: To allow generation of instances for classes that are not
|
|
81
|
-
connected to any other class, default is True
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
List of RDF triples, represented as tuples `(subject, predicate, object)`, that define data model instances
|
|
85
|
-
"""
|
|
86
|
-
|
|
87
|
-
# Figure out which classes are defined in the data model and which are not
|
|
88
|
-
if transformation_rules.metadata.namespace is None:
|
|
89
|
-
raise ValueError("Namespace must be defined in transformation rules!")
|
|
90
|
-
namespace = transformation_rules.metadata.namespace
|
|
91
|
-
|
|
92
|
-
defined_classes = get_defined_classes(transformation_rules)
|
|
93
|
-
|
|
94
|
-
if non_existing_classes := set(class_count.keys()) - defined_classes:
|
|
95
|
-
msg = f"Class count contains classes {non_existing_classes} for which properties are not defined in Data Model!"
|
|
96
|
-
if stop_on_exception:
|
|
97
|
-
logging.error(msg)
|
|
98
|
-
raise ValueError(msg)
|
|
99
|
-
else:
|
|
100
|
-
msg += " These classes will be ignored."
|
|
101
|
-
logging.warning(msg)
|
|
102
|
-
warnings.warn(msg, stacklevel=2)
|
|
103
|
-
for class_ in non_existing_classes:
|
|
104
|
-
class_count.pop(class_)
|
|
105
|
-
|
|
106
|
-
# Subset data model to only classes that are defined in class count
|
|
107
|
-
transformation_rules = (
|
|
108
|
-
subset_rules(transformation_rules, set(class_count.keys()), skip_validation=True)
|
|
109
|
-
if defined_classes != set(class_count.keys())
|
|
110
|
-
else transformation_rules
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
class_linkage = get_class_linkage(transformation_rules)
|
|
114
|
-
|
|
115
|
-
# Remove one of symmetric pairs from class linkage to maintain proper linking
|
|
116
|
-
# among instances of symmetrically linked classes
|
|
117
|
-
if sym_pairs := get_symmetric_pairs(transformation_rules):
|
|
118
|
-
class_linkage = _remove_higher_occurring_sym_pair(class_linkage, sym_pairs)
|
|
119
|
-
|
|
120
|
-
# Remove any of symmetric pairs containing classes that are not present class count
|
|
121
|
-
class_linkage = _remove_non_requested_sym_pairs(class_linkage, class_count)
|
|
122
|
-
|
|
123
|
-
# Generate generation order for classes instances
|
|
124
|
-
generation_order = _prettify_generation_order(_get_generation_order(class_linkage))
|
|
125
|
-
|
|
126
|
-
# Generated simple view of data model
|
|
127
|
-
class_definitions = _rules_to_dict(transformation_rules)
|
|
128
|
-
|
|
129
|
-
# pregenerate instance ids for each remaining class
|
|
130
|
-
instance_ids = {key: [URIRef(namespace[f"{key}-{i}"]) for i in range(value)] for key, value in class_count.items()}
|
|
131
|
-
|
|
132
|
-
# create triple for each class instance defining its type
|
|
133
|
-
triples: list[Triple] = []
|
|
134
|
-
for class_ in class_count:
|
|
135
|
-
triples += [
|
|
136
|
-
(class_instance_id, RDF.type, URIRef(namespace[class_])) for class_instance_id in instance_ids[class_]
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
# generate triples for connected classes
|
|
140
|
-
for class_ in generation_order:
|
|
141
|
-
triples += _generate_triples_per_class(
|
|
142
|
-
class_, class_definitions, sym_pairs, instance_ids, namespace, stop_on_exception
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
# generate triples for isolated classes
|
|
146
|
-
if allow_isolated_classes:
|
|
147
|
-
for class_ in set(class_count.keys()) - set(generation_order):
|
|
148
|
-
triples += _generate_triples_per_class(
|
|
149
|
-
class_, class_definitions, sym_pairs, instance_ids, namespace, stop_on_exception
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
return triples
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def _get_generation_order(
|
|
156
|
-
class_linkage: pd.DataFrame, parent_col: str = "source_class", child_col: str = "target_class"
|
|
157
|
-
) -> dict:
|
|
158
|
-
parent_child_list: list[list[str]] = class_linkage[[parent_col, child_col]].values.tolist()
|
|
159
|
-
# Build a directed graph and a list of all names that have no parent
|
|
160
|
-
graph: dict[str, set] = {name: set() for tup in parent_child_list for name in tup}
|
|
161
|
-
has_parent: dict[str, bool] = {name: False for tup in parent_child_list for name in tup}
|
|
162
|
-
for parent, child in parent_child_list:
|
|
163
|
-
graph[parent].add(child)
|
|
164
|
-
has_parent[child] = True
|
|
165
|
-
|
|
166
|
-
# All names that have absolutely no parent:
|
|
167
|
-
roots = [name for name, parents in has_parent.items() if not parents]
|
|
168
|
-
|
|
169
|
-
return _traverse({}, graph, roots)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def _traverse(hierarchy: dict, graph: dict, names: list[str]) -> dict:
|
|
173
|
-
"""traverse the graph and return the hierarchy"""
|
|
174
|
-
for name in names:
|
|
175
|
-
hierarchy[name] = _traverse({}, graph, graph[name])
|
|
176
|
-
return hierarchy
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def _prettify_generation_order(generation_order: dict, depth: dict | None = None, start=-1) -> dict:
|
|
180
|
-
"""Prettifies generation order dictionary for easier consumption."""
|
|
181
|
-
depth = depth or {}
|
|
182
|
-
for key, value in generation_order.items():
|
|
183
|
-
depth[key] = start + 1
|
|
184
|
-
if isinstance(value, dict):
|
|
185
|
-
_prettify_generation_order(value, depth, start=start + 1)
|
|
186
|
-
return OrderedDict(sorted(depth.items(), key=lambda item: item[1]))
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def _remove_non_hierarchy_linking(class_linkage: pd.DataFrame) -> pd.DataFrame:
|
|
190
|
-
"""Remove linkage which is not creating asset hierarchy."""
|
|
191
|
-
return class_linkage[class_linkage.linking_type == "hierarchy"]
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def _remove_higher_occurring_sym_pair(class_linkage: pd.DataFrame, sym_pairs: set[tuple[str, str]]) -> pd.DataFrame:
|
|
195
|
-
"""Remove symmetric pair which is higher in occurrence."""
|
|
196
|
-
rows_to_remove = set()
|
|
197
|
-
for source, target in sym_pairs:
|
|
198
|
-
first_sym_property_occurrence = class_linkage[
|
|
199
|
-
(class_linkage.source_class == source) & (class_linkage.target_class == target)
|
|
200
|
-
].max_occurrence.values[0]
|
|
201
|
-
second_sym_property_occurrence = class_linkage[
|
|
202
|
-
(class_linkage.source_class == target) & (class_linkage.target_class == source)
|
|
203
|
-
].max_occurrence.values[0]
|
|
204
|
-
|
|
205
|
-
if first_sym_property_occurrence is None:
|
|
206
|
-
# this means that source occurrence is unbounded
|
|
207
|
-
index = class_linkage[
|
|
208
|
-
(class_linkage.source_class == source) & (class_linkage.target_class == target)
|
|
209
|
-
].index.values[0]
|
|
210
|
-
elif (
|
|
211
|
-
second_sym_property_occurrence is None
|
|
212
|
-
or first_sym_property_occurrence <= second_sym_property_occurrence
|
|
213
|
-
and second_sym_property_occurrence > first_sym_property_occurrence
|
|
214
|
-
):
|
|
215
|
-
# this means that target occurrence is unbounded
|
|
216
|
-
index = class_linkage[
|
|
217
|
-
(class_linkage.source_class == target) & (class_linkage.target_class == source)
|
|
218
|
-
].index.values[0]
|
|
219
|
-
else:
|
|
220
|
-
index = class_linkage[
|
|
221
|
-
(class_linkage.source_class == source) & (class_linkage.target_class == target)
|
|
222
|
-
].index.values[0]
|
|
223
|
-
rows_to_remove.add(index)
|
|
224
|
-
|
|
225
|
-
return class_linkage.drop(list(rows_to_remove))
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def _remove_non_requested_sym_pairs(class_linkage: pd.DataFrame, class_count: dict) -> pd.DataFrame:
|
|
229
|
-
"""Remove symmetric pairs which classes are not found in class count."""
|
|
230
|
-
rows_to_remove = set(class_linkage[~(class_linkage["source_class"].isin(set(class_count.keys())))].index.values)
|
|
231
|
-
rows_to_remove |= set(class_linkage[~(class_linkage["target_class"].isin(set(class_count.keys())))].index.values)
|
|
232
|
-
|
|
233
|
-
return class_linkage.drop(list(rows_to_remove))
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def _generate_mock_data_property_triples(
|
|
237
|
-
instance_ids: list[URIRef], property_: str, namespace: Namespace, value_type: str = "string"
|
|
238
|
-
) -> list[tuple[URIRef, URIRef, Literal]]:
|
|
239
|
-
"""Generates triples for data properties."""
|
|
240
|
-
|
|
241
|
-
python_type = XSD_VALUE_TYPE_MAPPINGS[value_type].python
|
|
242
|
-
triples = []
|
|
243
|
-
for id_ in instance_ids:
|
|
244
|
-
if python_type == int:
|
|
245
|
-
triples.append((id_, URIRef(namespace[property_]), Literal(random.randint(1, 1983))))
|
|
246
|
-
elif python_type == float:
|
|
247
|
-
triples.append((id_, URIRef(namespace[property_]), Literal(numpy.float32(random.uniform(1, 1983)))))
|
|
248
|
-
# generate string
|
|
249
|
-
else:
|
|
250
|
-
triples.append(
|
|
251
|
-
(id_, URIRef(namespace[property_]), Literal(remove_namespace_from_uri(id_).replace("-", " ")))
|
|
252
|
-
)
|
|
253
|
-
return triples
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def _generate_mock_object_property_triples(
|
|
257
|
-
class_: str,
|
|
258
|
-
property_definition: pd.Series,
|
|
259
|
-
class_definitions: dict[str, pd.DataFrame],
|
|
260
|
-
sym_pairs: set[tuple[str, str]],
|
|
261
|
-
instance_ids: dict[str, list[URIRef]],
|
|
262
|
-
namespace: Namespace,
|
|
263
|
-
stop_on_exception: bool,
|
|
264
|
-
) -> list[tuple[URIRef, URIRef, URIRef]]:
|
|
265
|
-
"""Generates triples for object properties."""
|
|
266
|
-
if property_definition.value_type not in instance_ids:
|
|
267
|
-
msg = f"Class {property_definition.value_type} not found in class count! "
|
|
268
|
-
if stop_on_exception:
|
|
269
|
-
logging.error(msg)
|
|
270
|
-
raise ValueError(msg)
|
|
271
|
-
else:
|
|
272
|
-
msg += (
|
|
273
|
-
f"Skipping creating triples for property {property_definition.name} "
|
|
274
|
-
f"of class {class_} which expects values of this type!"
|
|
275
|
-
)
|
|
276
|
-
logging.warning(msg)
|
|
277
|
-
warnings.warn(msg, stacklevel=2)
|
|
278
|
-
return []
|
|
279
|
-
|
|
280
|
-
# Handling symmetric property
|
|
281
|
-
symmetric_property = (
|
|
282
|
-
class_definitions[property_definition.value_type][
|
|
283
|
-
class_definitions[property_definition.value_type].value_type == class_
|
|
284
|
-
].index.values[0]
|
|
285
|
-
if tuple((class_, property_definition.value_type)) in sym_pairs
|
|
286
|
-
else None
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
triples = []
|
|
290
|
-
|
|
291
|
-
for i, source in enumerate(instance_ids[class_]):
|
|
292
|
-
target = instance_ids[property_definition.value_type][i % len(instance_ids[property_definition.value_type])]
|
|
293
|
-
triples += [(URIRef(source), URIRef(namespace[str(property_definition.name)]), URIRef(target))]
|
|
294
|
-
|
|
295
|
-
if symmetric_property:
|
|
296
|
-
triples += [(URIRef(target), URIRef(namespace[symmetric_property]), URIRef(source))]
|
|
297
|
-
|
|
298
|
-
# remove symmetric property from class definition of downstream class
|
|
299
|
-
# to avoid asymmetric linking in mock graph
|
|
300
|
-
if symmetric_property:
|
|
301
|
-
class_definitions[property_definition.value_type].drop(symmetric_property, inplace=True)
|
|
302
|
-
|
|
303
|
-
return triples
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
def _generate_triples_per_class(
|
|
307
|
-
class_: str,
|
|
308
|
-
class_definitions: dict[str, pd.DataFrame],
|
|
309
|
-
sym_pairs: set[tuple[str, str]],
|
|
310
|
-
instance_ids: dict[str, list[URIRef]],
|
|
311
|
-
namespace: Namespace,
|
|
312
|
-
stop_on_exception: bool,
|
|
313
|
-
) -> list[Triple]:
|
|
314
|
-
"""Generate triples for a given class."""
|
|
315
|
-
triples: list[Triple] = []
|
|
316
|
-
for _, property_definition in class_definitions[class_].iterrows():
|
|
317
|
-
if property_definition.property_type == "DatatypeProperty":
|
|
318
|
-
triples += _generate_mock_data_property_triples(
|
|
319
|
-
instance_ids[class_], str(property_definition.name), namespace, property_definition.value_type
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
elif property_definition.property_type == "ObjectProperty":
|
|
323
|
-
triples += _generate_mock_object_property_triples(
|
|
324
|
-
class_, property_definition, class_definitions, sym_pairs, instance_ids, namespace, stop_on_exception
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
else:
|
|
328
|
-
logging.error(f"Property type {property_definition.property_type} not supported!")
|
|
329
|
-
raise ValueError(f"Property type {property_definition.property_type} not supported!")
|
|
330
|
-
|
|
331
|
-
return triples
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
def _rules_to_dict(transformation_rules: Rules) -> dict[str, pd.DataFrame]:
|
|
335
|
-
"""Represent data model as a dictionary of data frames, where each data frame
|
|
336
|
-
represents properties defined for a given class.
|
|
337
|
-
|
|
338
|
-
Args:
|
|
339
|
-
transformation_rules: Transformation rules defining the data model
|
|
340
|
-
|
|
341
|
-
Returns:
|
|
342
|
-
Simplified representation of the data model
|
|
343
|
-
"""
|
|
344
|
-
|
|
345
|
-
data_model: dict[str, pd.DataFrame] = {}
|
|
346
|
-
|
|
347
|
-
defined_classes = get_classes_with_properties(transformation_rules)
|
|
348
|
-
|
|
349
|
-
for class_ in defined_classes:
|
|
350
|
-
properties = {}
|
|
351
|
-
for property_ in defined_classes[class_]:
|
|
352
|
-
if property_.property_id not in properties:
|
|
353
|
-
properties[property_.property_id] = {
|
|
354
|
-
"property_type": property_.property_type,
|
|
355
|
-
"value_type": property_.expected_value_type.suffix,
|
|
356
|
-
"min_count": property_.min_count,
|
|
357
|
-
"max_count": property_.max_count,
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
data_model[class_] = pd.DataFrame(properties).T
|
|
361
|
-
return data_model
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from cognite.neat.legacy.graph.loaders.core.labels import upload_labels
|
|
2
|
-
|
|
3
|
-
from ._asset_loader import AssetLoader
|
|
4
|
-
from ._base import BaseLoader, CogniteLoader
|
|
5
|
-
from .core.rdf_to_assets import categorize_assets, rdf2assets, upload_assets
|
|
6
|
-
from .core.rdf_to_relationships import categorize_relationships, rdf2relationships, upload_relationships
|
|
7
|
-
from .rdf_to_dms import DMSLoader, upload_edges, upload_nodes
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"BaseLoader",
|
|
11
|
-
"CogniteLoader",
|
|
12
|
-
"AssetLoader",
|
|
13
|
-
"rdf2relationships",
|
|
14
|
-
"categorize_assets",
|
|
15
|
-
"upload_assets",
|
|
16
|
-
"rdf2assets",
|
|
17
|
-
"categorize_relationships",
|
|
18
|
-
"upload_relationships",
|
|
19
|
-
"upload_labels",
|
|
20
|
-
"upload_nodes",
|
|
21
|
-
"upload_edges",
|
|
22
|
-
"DMSLoader",
|
|
23
|
-
]
|