cognite-neat 0.87.6__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.

Files changed (125) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/app/api/data_classes/rest.py +0 -19
  3. cognite/neat/app/api/explorer.py +6 -4
  4. cognite/neat/app/api/routers/crud.py +11 -21
  5. cognite/neat/app/api/routers/workflows.py +24 -94
  6. cognite/neat/graph/stores/_base.py +5 -0
  7. cognite/neat/rules/importers/_inference2rules.py +31 -35
  8. cognite/neat/workflows/steps/data_contracts.py +17 -43
  9. cognite/neat/workflows/steps/lib/current/graph_extractor.py +28 -24
  10. cognite/neat/workflows/steps/lib/current/graph_loader.py +4 -21
  11. cognite/neat/workflows/steps/lib/current/graph_store.py +18 -134
  12. cognite/neat/workflows/steps_registry.py +5 -7
  13. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.0.dist-info}/METADATA +1 -1
  14. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.0.dist-info}/RECORD +17 -125
  15. cognite/neat/app/api/routers/core.py +0 -91
  16. cognite/neat/app/api/routers/data_exploration.py +0 -336
  17. cognite/neat/app/api/routers/rules.py +0 -203
  18. cognite/neat/legacy/__init__.py +0 -0
  19. cognite/neat/legacy/graph/__init__.py +0 -3
  20. cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -20182
  21. cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml +0 -20163
  22. cognite/neat/legacy/graph/examples/__init__.py +0 -10
  23. cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  24. cognite/neat/legacy/graph/exceptions.py +0 -90
  25. cognite/neat/legacy/graph/extractors/__init__.py +0 -6
  26. cognite/neat/legacy/graph/extractors/_base.py +0 -14
  27. cognite/neat/legacy/graph/extractors/_dexpi.py +0 -44
  28. cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py +0 -403
  29. cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +0 -361
  30. cognite/neat/legacy/graph/loaders/__init__.py +0 -23
  31. cognite/neat/legacy/graph/loaders/_asset_loader.py +0 -511
  32. cognite/neat/legacy/graph/loaders/_base.py +0 -67
  33. cognite/neat/legacy/graph/loaders/_exceptions.py +0 -85
  34. cognite/neat/legacy/graph/loaders/core/__init__.py +0 -0
  35. cognite/neat/legacy/graph/loaders/core/labels.py +0 -58
  36. cognite/neat/legacy/graph/loaders/core/models.py +0 -136
  37. cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +0 -1046
  38. cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +0 -559
  39. cognite/neat/legacy/graph/loaders/rdf_to_dms.py +0 -309
  40. cognite/neat/legacy/graph/loaders/validator.py +0 -87
  41. cognite/neat/legacy/graph/models.py +0 -6
  42. cognite/neat/legacy/graph/stores/__init__.py +0 -13
  43. cognite/neat/legacy/graph/stores/_base.py +0 -400
  44. cognite/neat/legacy/graph/stores/_graphdb_store.py +0 -52
  45. cognite/neat/legacy/graph/stores/_memory_store.py +0 -43
  46. cognite/neat/legacy/graph/stores/_oxigraph_store.py +0 -151
  47. cognite/neat/legacy/graph/stores/_oxrdflib.py +0 -247
  48. cognite/neat/legacy/graph/stores/_rdf_to_graph.py +0 -42
  49. cognite/neat/legacy/graph/transformations/__init__.py +0 -0
  50. cognite/neat/legacy/graph/transformations/entity_matcher.py +0 -101
  51. cognite/neat/legacy/graph/transformations/query_generator/__init__.py +0 -3
  52. cognite/neat/legacy/graph/transformations/query_generator/sparql.py +0 -575
  53. cognite/neat/legacy/graph/transformations/transformer.py +0 -322
  54. cognite/neat/legacy/rules/__init__.py +0 -0
  55. cognite/neat/legacy/rules/analysis.py +0 -231
  56. cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
  57. cognite/neat/legacy/rules/examples/Rules-Nordic44.xlsx +0 -0
  58. cognite/neat/legacy/rules/examples/__init__.py +0 -18
  59. cognite/neat/legacy/rules/examples/power-grid-containers.yaml +0 -124
  60. cognite/neat/legacy/rules/examples/power-grid-example.xlsx +0 -0
  61. cognite/neat/legacy/rules/examples/power-grid-model.yaml +0 -224
  62. cognite/neat/legacy/rules/examples/rules-template.xlsx +0 -0
  63. cognite/neat/legacy/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
  64. cognite/neat/legacy/rules/examples/skos-rules.xlsx +0 -0
  65. cognite/neat/legacy/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
  66. cognite/neat/legacy/rules/examples/wind-energy.owl +0 -1511
  67. cognite/neat/legacy/rules/exceptions.py +0 -2972
  68. cognite/neat/legacy/rules/exporters/__init__.py +0 -20
  69. cognite/neat/legacy/rules/exporters/_base.py +0 -45
  70. cognite/neat/legacy/rules/exporters/_core/__init__.py +0 -5
  71. cognite/neat/legacy/rules/exporters/_core/rules2labels.py +0 -24
  72. cognite/neat/legacy/rules/exporters/_rules2dms.py +0 -885
  73. cognite/neat/legacy/rules/exporters/_rules2excel.py +0 -213
  74. cognite/neat/legacy/rules/exporters/_rules2graphql.py +0 -183
  75. cognite/neat/legacy/rules/exporters/_rules2ontology.py +0 -524
  76. cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +0 -748
  77. cognite/neat/legacy/rules/exporters/_rules2rules.py +0 -105
  78. cognite/neat/legacy/rules/exporters/_rules2triples.py +0 -38
  79. cognite/neat/legacy/rules/exporters/_validation.py +0 -146
  80. cognite/neat/legacy/rules/importers/__init__.py +0 -22
  81. cognite/neat/legacy/rules/importers/_base.py +0 -66
  82. cognite/neat/legacy/rules/importers/_dict2rules.py +0 -158
  83. cognite/neat/legacy/rules/importers/_dms2rules.py +0 -194
  84. cognite/neat/legacy/rules/importers/_graph2rules.py +0 -308
  85. cognite/neat/legacy/rules/importers/_json2rules.py +0 -39
  86. cognite/neat/legacy/rules/importers/_owl2rules/__init__.py +0 -3
  87. cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +0 -239
  88. cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +0 -260
  89. cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +0 -217
  90. cognite/neat/legacy/rules/importers/_owl2rules/_owl2rules.py +0 -290
  91. cognite/neat/legacy/rules/importers/_spreadsheet2rules.py +0 -45
  92. cognite/neat/legacy/rules/importers/_xsd2rules.py +0 -20
  93. cognite/neat/legacy/rules/importers/_yaml2rules.py +0 -39
  94. cognite/neat/legacy/rules/models/__init__.py +0 -5
  95. cognite/neat/legacy/rules/models/_base.py +0 -151
  96. cognite/neat/legacy/rules/models/raw_rules.py +0 -316
  97. cognite/neat/legacy/rules/models/rdfpath.py +0 -237
  98. cognite/neat/legacy/rules/models/rules.py +0 -1289
  99. cognite/neat/legacy/rules/models/tables.py +0 -9
  100. cognite/neat/legacy/rules/models/value_types.py +0 -118
  101. cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml +0 -89
  102. cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -152
  103. cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -139
  104. cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
  105. cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml +0 -65
  106. cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -116
  107. cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml +0 -67
  108. cognite/neat/legacy/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -64
  109. cognite/neat/legacy/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -95
  110. cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -111
  111. cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
  112. cognite/neat/workflows/migration/__init__.py +0 -0
  113. cognite/neat/workflows/migration/steps.py +0 -91
  114. cognite/neat/workflows/migration/wf_manifests.py +0 -33
  115. cognite/neat/workflows/steps/lib/legacy/__init__.py +0 -7
  116. cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py +0 -82
  117. cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +0 -746
  118. cognite/neat/workflows/steps/lib/legacy/graph_loader.py +0 -606
  119. cognite/neat/workflows/steps/lib/legacy/graph_store.py +0 -307
  120. cognite/neat/workflows/steps/lib/legacy/graph_transformer.py +0 -58
  121. cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +0 -511
  122. cognite/neat/workflows/steps/lib/legacy/rules_importer.py +0 -612
  123. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.0.dist-info}/LICENSE +0 -0
  124. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.0.dist-info}/WHEEL +0 -0
  125. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.0.dist-info}/entry_points.txt +0 -0
@@ -1,239 +0,0 @@
1
- from typing import cast
2
-
3
- import numpy as np
4
- import pandas as pd
5
- from rdflib import OWL, Graph
6
-
7
- from cognite.neat.utils.rdf_ import remove_namespace_from_uri
8
-
9
-
10
- def parse_owl_classes(graph: Graph, make_compliant: bool = False, language: str = "en") -> pd.DataFrame:
11
- """Parse owl classes from graph to pandas dataframe.
12
-
13
- Args:
14
- graph: Graph containing owl classes
15
- make_compliant: Flag for generating compliant classes, by default False
16
- language: Language to use for parsing, by default "en"
17
-
18
- Returns:
19
- Dataframe containing owl classes
20
-
21
- !!! note "make_compliant"
22
- If `make_compliant` is set to True, in presence of errors, default values will be used instead.
23
- This makes the method very opinionated, but results in a compliant classes.
24
- """
25
-
26
- query = """
27
- SELECT ?class ?name ?description ?parentClass ?deprecated ?deprecationDate
28
- ?replacedBy ?source ?sourceEntity ?match ?comment
29
- WHERE {
30
- ?class a owl:Class .
31
- OPTIONAL {?class rdfs:subClassOf ?parentClass }.
32
- OPTIONAL {?class rdfs:label ?name }.
33
- OPTIONAL {?class rdfs:comment ?description} .
34
- OPTIONAL {?class owl:deprecated ?deprecated} .
35
- FILTER (!isBlank(?class))
36
- FILTER (!bound(?parentClass) || !isBlank(?parentClass))
37
- FILTER (!bound(?name) || LANG(?name) = "" || LANGMATCHES(LANG(?name), "en"))
38
- FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "en"))
39
- }
40
- """
41
-
42
- # create raw dataframe
43
-
44
- raw_df = _parse_raw_dataframe(cast(list[tuple], list(graph.query(query.replace("en", language)))))
45
- if raw_df.empty:
46
- return pd.concat([raw_df, pd.DataFrame([len(raw_df) * [""]])], ignore_index=True)
47
-
48
- # group values and clean up
49
- processed_df = _clean_up_classes(raw_df)
50
-
51
- # make compliant
52
- if make_compliant:
53
- processed_df = make_classes_compliant(processed_df)
54
-
55
- # Make Parent Class list elements into string joined with comma
56
- processed_df["Parent Class"] = processed_df["Parent Class"].apply(
57
- lambda x: ", ".join(x) if isinstance(x, list) and x else None
58
- )
59
-
60
- return processed_df
61
-
62
-
63
- def _parse_raw_dataframe(query_results: list[tuple]) -> pd.DataFrame:
64
- df = pd.DataFrame(
65
- query_results,
66
- columns=[
67
- "Class",
68
- "Name",
69
- "Description",
70
- "Parent Class",
71
- "Deprecated",
72
- "Deprecation Date",
73
- "Replaced By",
74
- "Source",
75
- "Source Entity Name",
76
- "Match",
77
- "Comment",
78
- ],
79
- )
80
- if df.empty:
81
- return df
82
-
83
- # # remove NaNs
84
- df.replace(np.nan, "", regex=True, inplace=True)
85
-
86
- df.Source = df.Class
87
- df.Class = df.Class.apply(lambda x: remove_namespace_from_uri(x))
88
- df["Source Entity Name"] = df.Class
89
- df["Match"] = len(df) * ["exact"]
90
- df["Parent Class"] = df["Parent Class"].apply(lambda x: remove_namespace_from_uri(x))
91
-
92
- return df
93
-
94
-
95
- def _clean_up_classes(df: pd.DataFrame) -> pd.DataFrame:
96
- clean_list = [
97
- {
98
- "Class": class_,
99
- "Name": group_df["Name"].unique()[0],
100
- "Description": "\n".join(list(group_df.Description.unique())),
101
- "Parent Class": ", ".join(list(group_df["Parent Class"].unique())),
102
- "Deprecated": group_df.Deprecated.unique()[0],
103
- "Deprecation Date": group_df["Deprecation Date"].unique()[0],
104
- "Replaced By": group_df["Replaced By"].unique()[0],
105
- "Source": group_df["Source"].unique()[0],
106
- "Source Entity Name": group_df["Name"].unique()[0],
107
- "Match Type": group_df["Match"].unique()[0],
108
- "Comment": group_df["Comment"].unique()[0],
109
- }
110
- for class_, group_df in df.groupby("Class")
111
- ]
112
-
113
- df = pd.DataFrame(clean_list)
114
-
115
- # bring NaNs back
116
- df.replace("", None, inplace=True)
117
-
118
- # split Parent Class column back into list
119
- df["Parent Class"] = df["Parent Class"].apply(lambda x: x.split(", ") if isinstance(x, str) else None)
120
-
121
- return df
122
-
123
-
124
- def make_classes_compliant(classes: pd.DataFrame) -> pd.DataFrame:
125
- """Make classes compliant.
126
-
127
- Returns:
128
- Dataframe containing compliant classes
129
-
130
- !!! note "About the compliant classes"
131
- The compliant classes are based on the OWL base ontology, but adapted to NEAT and use in CDF.
132
- One thing to note is that this method would not be able to fix issues with class ids which
133
- are not compliant with the CDF naming convention. For example, if a class id contains a space,
134
- starts with a number, etc. This will cause issues when trying to create the class in CDF.
135
- """
136
-
137
- # Replace empty or non-string values in "Match Type" column with "exact"
138
- classes["Match Type"] = classes["Match Type"].fillna("exact")
139
- classes["Match Type"] = classes["Match Type"].apply(
140
- lambda x: "exact" if not isinstance(x, str) or len(x) == 0 else x
141
- )
142
-
143
- # Replace empty or non-string values in "Comment" column with a default value
144
- classes["Comment"] = classes["Comment"].fillna("Imported from Ontology by NEAT")
145
- classes["Comment"] = classes["Comment"].apply(
146
- lambda x: "Imported from Ontology by NEAT" if not isinstance(x, str) or len(x) == 0 else x
147
- )
148
-
149
- # Replace empty or non-boolean values in "Deprecated" column with False
150
- classes["Deprecated"] = classes["Deprecated"].fillna(False)
151
- classes["Deprecated"] = classes["Deprecated"].apply(lambda x: False if not isinstance(x, bool) else x)
152
-
153
- # Add _object_property_class, _data_type_property_class, _thing_class to the dataframe
154
- classes = pd.concat(
155
- [classes, pd.DataFrame([_object_property_class(), _data_type_property_class(), _thing_class()])],
156
- ignore_index=True,
157
- )
158
-
159
- # Reduce length of elements in the "Description" column to 1024 characters
160
- classes["Description"] = classes["Description"].apply(lambda x: x[:1024] if isinstance(x, str) else None)
161
-
162
- # Add missing parent classes to the dataframe
163
- classes = pd.concat(
164
- [classes, pd.DataFrame(_add_parent_class(classes))],
165
- ignore_index=True,
166
- )
167
-
168
- return classes
169
-
170
-
171
- def _object_property_class() -> dict:
172
- return {
173
- "Class": "ObjectProperty",
174
- "Name": None,
175
- "Description": "The class of object properties.",
176
- "Parent Class": None,
177
- "Source": OWL.ObjectProperty,
178
- "Match Type": "exact",
179
- "Comment": "Added by NEAT based on owl:ObjectProperty but adapted to NEAT and use in CDF.",
180
- }
181
-
182
-
183
- def _data_type_property_class() -> dict:
184
- return {
185
- "Class": "DatatypeProperty",
186
- "Name": None,
187
- "Description": "The class of data properties.",
188
- "Parent Class": None,
189
- "Source": OWL.DatatypeProperty,
190
- "Match Type": "exact",
191
- "Comment": "Added by NEAT based on owl:DatatypeProperty but adapted to NEAT and use in CDF.",
192
- }
193
-
194
-
195
- def _thing_class() -> dict:
196
- return {
197
- "Class": "ThingContainer",
198
- "Name": None,
199
- "Description": "The class of holding class individuals.",
200
- "Parent Class": None,
201
- "Source": OWL.Thing,
202
- "Match Type": "exact",
203
- "Comment": (
204
- "Added by NEAT. "
205
- "Imported from OWL base ontology, it is meant for use as a default"
206
- " value type for object properties which miss a declared range."
207
- ),
208
- }
209
-
210
-
211
- def _add_parent_class(df: pd.DataFrame) -> list[dict]:
212
- parent_set = {
213
- item
214
- for sublist in df["Parent Class"].tolist()
215
- if sublist
216
- for item in sublist
217
- if item != "" and item is not None
218
- }
219
- class_set = set(df["Class"].tolist())
220
-
221
- rows = []
222
- for missing_parent_class in parent_set.difference(class_set):
223
- rows += [
224
- {
225
- "Class": missing_parent_class,
226
- "Name": None,
227
- "Description": None,
228
- "Parent Class": None,
229
- "Source": None,
230
- "Match Type": None,
231
- "Comment": (
232
- "Added by NEAT. "
233
- "This is a parent class that is missing in the ontology. "
234
- "It is added by NEAT to make the ontology compliant with CDF."
235
- ),
236
- }
237
- ]
238
-
239
- return rows
@@ -1,260 +0,0 @@
1
- import datetime
2
- import re
3
-
4
- import pandas as pd
5
- from rdflib import Graph, Namespace
6
-
7
- from cognite.neat.legacy.rules.models.rules import (
8
- cdf_space_compliance_regex,
9
- data_model_id_compliance_regex,
10
- prefix_compliance_regex,
11
- version_compliance_regex,
12
- )
13
- from cognite.neat.utils.collection_ import remove_none_elements_from_set
14
- from cognite.neat.utils.rdf_ import convert_rdflib_content
15
-
16
-
17
- def parse_owl_metadata(graph: Graph, make_compliant: bool = False) -> pd.DataFrame:
18
- """Parse owl metadata from graph to pandas dataframe.
19
-
20
- Args:
21
- graph: Graph containing owl metadata
22
- make_compliant: Flag for generating compliant metadata, by default False
23
-
24
- Returns:
25
- Dataframe containing owl metadata
26
-
27
- !!! note "make_compliant"
28
- If `make_compliant` is set to True, in presence of errors, default values will be used instead.
29
- This makes the method very opinionated, but results in a compliant metadata.
30
-
31
-
32
- """
33
- # TODO: Move dataframe to dict representation
34
-
35
- query = """SELECT ?namespace ?prefix ?dataModelName ?cdfSpaceName ?version ?isCurrentVersion
36
- ?created ?updated ?title ?description ?creator ?contributor ?rights ?license
37
- WHERE {
38
- ?namespace a owl:Ontology .
39
- OPTIONAL {?namespace owl:versionInfo ?version }.
40
- OPTIONAL {?namespace dcterms:creator ?creator }.
41
- OPTIONAL {?namespace dcterms:title|rdfs:label|skos:prefLabel ?title }.
42
- OPTIONAL {?namespace dcterms:contributor ?contributor }.
43
- OPTIONAL {?namespace dcterms:modified ?updated }.
44
- OPTIONAL {?namespace dcterms:created ?created }.
45
- OPTIONAL {?namespace dcterms:description ?description }.
46
-
47
- OPTIONAL {?namespace dcterms:rights|dc:rights ?rights }.
48
-
49
- OPTIONAL {?namespace dcterms:license|dc:license ?license }.
50
- FILTER (!isBlank(?namespace))
51
- FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "en"))
52
- FILTER (!bound(?title) || LANG(?title) = "" || LANGMATCHES(LANG(?title), "en"))
53
- }
54
- """
55
-
56
- results = [{item for item in sublist} for sublist in list(zip(*graph.query(query), strict=True))]
57
-
58
- clean_list = convert_rdflib_content(
59
- {
60
- "namespace": Namespace(results[0].pop()),
61
- "prefix": results[1].pop(),
62
- "dataModelName": results[2].pop(),
63
- "cdfSpaceName": results[3].pop(),
64
- "version": results[4].pop(),
65
- "isCurrentVersion": results[5].pop(),
66
- "created": results[6].pop(),
67
- "updated": results[7].pop(),
68
- "title": results[8].pop(),
69
- "description": results[9].pop(),
70
- "creator": (
71
- ", ".join(remove_none_elements_from_set(results[10]))
72
- if remove_none_elements_from_set(results[10])
73
- else None
74
- ),
75
- "contributor": (
76
- ", ".join(remove_none_elements_from_set(results[11]))
77
- if remove_none_elements_from_set(results[11])
78
- else None
79
- ),
80
- "rights": results[12].pop(),
81
- "license": results[13].pop(),
82
- }
83
- )
84
-
85
- if make_compliant:
86
- clean_list.pop("created")
87
- return pd.DataFrame(list(make_metadata_compliant(clean_list).items()), columns=["Key", "Value"])
88
-
89
- return pd.DataFrame(list(clean_list.items()), columns=["Key", "Value"])
90
-
91
-
92
- def make_metadata_compliant(metadata: dict) -> dict:
93
- """Attempts to fix errors in metadata, otherwise defaults to values that will pass validation.
94
-
95
- Args:
96
- metadata: Dictionary containing metadata
97
-
98
- Returns:
99
- Dictionary containing metadata with fixed errors
100
- """
101
-
102
- metadata = fix_namespace(metadata, default=Namespace("http://purl.org/cognite/neat#"))
103
- metadata = fix_prefix(metadata)
104
- metadata = fix_dataModelName(metadata)
105
- metadata = fix_cdfSpaceName(metadata)
106
- metadata = fix_version(metadata)
107
- metadata = fix_isCurrentVersion(metadata)
108
- metadata = fix_date(metadata, date_type="created", default=datetime.datetime.now().replace(microsecond=0))
109
- metadata = fix_date(metadata, date_type="updated", default=datetime.datetime.now().replace(microsecond=0))
110
- metadata = fix_title(metadata)
111
- metadata = fix_description(metadata)
112
- metadata = fix_author(metadata, "creator")
113
- metadata = fix_author(metadata, "contributor", "Cognite")
114
- metadata = fix_rights(metadata)
115
- metadata = fix_license(metadata)
116
-
117
- return metadata
118
-
119
-
120
- def fix_license(metadata: dict, default: str = "Unknown license") -> dict:
121
- if license := metadata.get("license", None):
122
- if not isinstance(license, str):
123
- metadata["license"] = default
124
- elif isinstance(license, str) and len(license) == 0:
125
- metadata["license"] = default
126
- else:
127
- metadata["license"] = default
128
- return metadata
129
-
130
-
131
- def fix_rights(metadata: dict, default: str = "Unknown rights") -> dict:
132
- if rights := metadata.get("rights", None):
133
- if not isinstance(rights, str):
134
- metadata["rights"] = default
135
- elif isinstance(rights, str) and len(rights) == 0:
136
- metadata["rights"] = default
137
- else:
138
- metadata["rights"] = default
139
- return metadata
140
-
141
-
142
- def fix_author(metadata: dict, author_type: str = "creator", default: str = "NEAT") -> dict:
143
- if author := metadata.get(author_type, None):
144
- if not isinstance(author, str) or isinstance(author, list):
145
- metadata[author_type] = default
146
- elif isinstance(author, str) and len(author) == 0:
147
- metadata[author_type] = default
148
- else:
149
- metadata[author_type] = default
150
- return metadata
151
-
152
-
153
- def fix_description(metadata: dict, default: str = "This model has been inferred from OWL ontology") -> dict:
154
- if description := metadata.get("description", None):
155
- if not isinstance(description, str) or len(description) == 0:
156
- metadata["description"] = default
157
- elif isinstance(description, str) and len(description) > 1024:
158
- metadata["description"] = metadata["description"][:1024]
159
- else:
160
- metadata["description"] = default
161
- return metadata
162
-
163
-
164
- def fix_cdfSpaceName(metadata: dict, default: str = "playground") -> dict:
165
- if space := metadata.get("cdfSpaceName", None):
166
- if not isinstance(space, str) or not re.match(cdf_space_compliance_regex, space):
167
- metadata["cdfSpaceName"] = default
168
- else:
169
- metadata["cdfSpaceName"] = default
170
- return metadata
171
-
172
-
173
- def fix_dataModelName(metadata: dict, default: str = "neat") -> dict:
174
- if data_model_name := metadata.get("dataModelName", None):
175
- if not isinstance(data_model_name, str) or not re.match(data_model_id_compliance_regex, data_model_name):
176
- metadata["dataModelName"] = default
177
- else:
178
- metadata["dataModelName"] = default
179
- return metadata
180
-
181
-
182
- def fix_prefix(metadata: dict, default: str = "neat") -> dict:
183
- if prefix := metadata.get("prefix", None):
184
- if not isinstance(prefix, str) or not re.match(prefix_compliance_regex, prefix):
185
- metadata["prefix"] = default
186
- else:
187
- metadata["prefix"] = default
188
- return metadata
189
-
190
-
191
- def fix_namespace(metadata: dict, default: Namespace) -> dict:
192
- if namespace := metadata.get("namespace", None):
193
- if not isinstance(namespace, Namespace):
194
- try:
195
- metadata["namespace"] = Namespace(namespace)
196
- except Exception:
197
- metadata["namespace"] = default
198
- else:
199
- metadata["namespace"] = default
200
-
201
- return metadata
202
-
203
-
204
- def fix_date(
205
- metadata: dict,
206
- date_type: str,
207
- default: datetime.datetime,
208
- ) -> dict:
209
- if date := metadata.get(date_type, None):
210
- try:
211
- if isinstance(date, datetime.datetime):
212
- pass
213
- elif isinstance(date, datetime.date):
214
- metadata[date_type] = datetime.datetime.combine(metadata[date_type], datetime.datetime.min.time())
215
- elif isinstance(date, str):
216
- metadata[date_type] = datetime.datetime.strptime(metadata[date_type], "%Y-%m-%dT%H:%M:%SZ")
217
- else:
218
- metadata[date_type] = default
219
- except Exception:
220
- metadata[date_type] = default
221
- else:
222
- metadata[date_type] = default
223
-
224
- return metadata
225
-
226
-
227
- def fix_version(metadata: dict, default: str = "1.0.0") -> dict:
228
- if version := metadata.get("version", None):
229
- if not re.match(version_compliance_regex, version):
230
- metadata["version"] = default
231
- else:
232
- metadata["version"] = default
233
-
234
- return metadata
235
-
236
-
237
- def fix_isCurrentVersion(metadata: dict, default: bool = True) -> dict:
238
- if isCurrentVersion := metadata.get("isCurrentVersion", None):
239
- if not isinstance(isCurrentVersion, bool):
240
- metadata["isCurrentVersion"] = default
241
- else:
242
- metadata["isCurrentVersion"] = default
243
-
244
- return metadata
245
-
246
-
247
- def fix_title(metadata: dict, default: str = "OWL Inferred Data Model") -> dict:
248
- if title := metadata.get("title", None):
249
- if not isinstance(title, str):
250
- metadata["title"] = default
251
- elif isinstance(title, str) and len(title) == 0:
252
- metadata["title"] = default
253
- elif isinstance(title, str) and len(title) > 255:
254
- metadata["title"] = metadata["title"][:255]
255
- else:
256
- pass
257
- else:
258
- metadata["title"] = default
259
-
260
- return metadata