cognite-neat 0.87.6__py3-none-any.whl → 0.88.1__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 (171) 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/configuration.py +1 -1
  5. cognite/neat/app/api/routers/crud.py +11 -21
  6. cognite/neat/app/api/routers/workflows.py +24 -94
  7. cognite/neat/app/ui/neat-app/build/asset-manifest.json +7 -7
  8. cognite/neat/app/ui/neat-app/build/index.html +1 -1
  9. cognite/neat/app/ui/neat-app/build/static/css/{main.38a62222.css → main.72e3d92e.css} +2 -2
  10. cognite/neat/app/ui/neat-app/build/static/css/main.72e3d92e.css.map +1 -0
  11. cognite/neat/app/ui/neat-app/build/static/js/main.5a52cf09.js +3 -0
  12. cognite/neat/app/ui/neat-app/build/static/js/{main.ec7f72e2.js.LICENSE.txt → main.5a52cf09.js.LICENSE.txt} +0 -9
  13. cognite/neat/app/ui/neat-app/build/static/js/main.5a52cf09.js.map +1 -0
  14. cognite/neat/config.py +44 -27
  15. cognite/neat/exceptions.py +6 -0
  16. cognite/neat/graph/extractors/_classic_cdf/_assets.py +21 -73
  17. cognite/neat/graph/extractors/_classic_cdf/_base.py +102 -0
  18. cognite/neat/graph/extractors/_classic_cdf/_events.py +46 -42
  19. cognite/neat/graph/extractors/_classic_cdf/_files.py +41 -45
  20. cognite/neat/graph/extractors/_classic_cdf/_labels.py +75 -52
  21. cognite/neat/graph/extractors/_classic_cdf/_relationships.py +49 -27
  22. cognite/neat/graph/extractors/_classic_cdf/_sequences.py +47 -50
  23. cognite/neat/graph/extractors/_classic_cdf/_timeseries.py +47 -49
  24. cognite/neat/graph/queries/_base.py +22 -29
  25. cognite/neat/graph/queries/_shared.py +1 -1
  26. cognite/neat/graph/stores/_base.py +24 -11
  27. cognite/neat/graph/transformers/_rdfpath.py +3 -2
  28. cognite/neat/issues.py +8 -0
  29. cognite/neat/rules/exporters/_rules2ontology.py +28 -20
  30. cognite/neat/rules/exporters/_validation.py +15 -21
  31. cognite/neat/rules/importers/_inference2rules.py +31 -35
  32. cognite/neat/rules/importers/_owl2rules/_owl2metadata.py +3 -7
  33. cognite/neat/rules/importers/_spreadsheet2rules.py +30 -27
  34. cognite/neat/rules/issues/dms.py +20 -0
  35. cognite/neat/rules/issues/importing.py +15 -0
  36. cognite/neat/rules/issues/ontology.py +298 -0
  37. cognite/neat/rules/issues/spreadsheet.py +48 -0
  38. cognite/neat/rules/issues/tables.py +72 -0
  39. cognite/neat/rules/models/_rdfpath.py +4 -4
  40. cognite/neat/rules/models/_types/_field.py +9 -19
  41. cognite/neat/rules/models/information/_rules.py +5 -4
  42. cognite/neat/utils/rdf_.py +17 -9
  43. cognite/neat/utils/regex_patterns.py +52 -0
  44. cognite/neat/workflows/steps/data_contracts.py +17 -43
  45. cognite/neat/workflows/steps/lib/current/graph_extractor.py +28 -24
  46. cognite/neat/workflows/steps/lib/current/graph_loader.py +4 -21
  47. cognite/neat/workflows/steps/lib/current/graph_store.py +18 -134
  48. cognite/neat/workflows/steps_registry.py +5 -7
  49. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.1.dist-info}/METADATA +2 -6
  50. cognite_neat-0.88.1.dist-info/RECORD +209 -0
  51. cognite/neat/app/api/routers/core.py +0 -91
  52. cognite/neat/app/api/routers/data_exploration.py +0 -336
  53. cognite/neat/app/api/routers/rules.py +0 -203
  54. cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css.map +0 -1
  55. cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js +0 -3
  56. cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.map +0 -1
  57. cognite/neat/graph/stores/_oxrdflib.py +0 -247
  58. cognite/neat/legacy/__init__.py +0 -0
  59. cognite/neat/legacy/graph/__init__.py +0 -3
  60. cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -20182
  61. cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml +0 -20163
  62. cognite/neat/legacy/graph/examples/__init__.py +0 -10
  63. cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  64. cognite/neat/legacy/graph/exceptions.py +0 -90
  65. cognite/neat/legacy/graph/extractors/__init__.py +0 -6
  66. cognite/neat/legacy/graph/extractors/_base.py +0 -14
  67. cognite/neat/legacy/graph/extractors/_dexpi.py +0 -44
  68. cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py +0 -403
  69. cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +0 -361
  70. cognite/neat/legacy/graph/loaders/__init__.py +0 -23
  71. cognite/neat/legacy/graph/loaders/_asset_loader.py +0 -511
  72. cognite/neat/legacy/graph/loaders/_base.py +0 -67
  73. cognite/neat/legacy/graph/loaders/_exceptions.py +0 -85
  74. cognite/neat/legacy/graph/loaders/core/__init__.py +0 -0
  75. cognite/neat/legacy/graph/loaders/core/labels.py +0 -58
  76. cognite/neat/legacy/graph/loaders/core/models.py +0 -136
  77. cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +0 -1046
  78. cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +0 -559
  79. cognite/neat/legacy/graph/loaders/rdf_to_dms.py +0 -309
  80. cognite/neat/legacy/graph/loaders/validator.py +0 -87
  81. cognite/neat/legacy/graph/models.py +0 -6
  82. cognite/neat/legacy/graph/stores/__init__.py +0 -13
  83. cognite/neat/legacy/graph/stores/_base.py +0 -400
  84. cognite/neat/legacy/graph/stores/_graphdb_store.py +0 -52
  85. cognite/neat/legacy/graph/stores/_memory_store.py +0 -43
  86. cognite/neat/legacy/graph/stores/_oxigraph_store.py +0 -151
  87. cognite/neat/legacy/graph/stores/_oxrdflib.py +0 -247
  88. cognite/neat/legacy/graph/stores/_rdf_to_graph.py +0 -42
  89. cognite/neat/legacy/graph/transformations/__init__.py +0 -0
  90. cognite/neat/legacy/graph/transformations/entity_matcher.py +0 -101
  91. cognite/neat/legacy/graph/transformations/query_generator/__init__.py +0 -3
  92. cognite/neat/legacy/graph/transformations/query_generator/sparql.py +0 -575
  93. cognite/neat/legacy/graph/transformations/transformer.py +0 -322
  94. cognite/neat/legacy/rules/__init__.py +0 -0
  95. cognite/neat/legacy/rules/analysis.py +0 -231
  96. cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
  97. cognite/neat/legacy/rules/examples/Rules-Nordic44.xlsx +0 -0
  98. cognite/neat/legacy/rules/examples/__init__.py +0 -18
  99. cognite/neat/legacy/rules/examples/power-grid-containers.yaml +0 -124
  100. cognite/neat/legacy/rules/examples/power-grid-example.xlsx +0 -0
  101. cognite/neat/legacy/rules/examples/power-grid-model.yaml +0 -224
  102. cognite/neat/legacy/rules/examples/rules-template.xlsx +0 -0
  103. cognite/neat/legacy/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
  104. cognite/neat/legacy/rules/examples/skos-rules.xlsx +0 -0
  105. cognite/neat/legacy/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
  106. cognite/neat/legacy/rules/examples/wind-energy.owl +0 -1511
  107. cognite/neat/legacy/rules/exceptions.py +0 -2972
  108. cognite/neat/legacy/rules/exporters/__init__.py +0 -20
  109. cognite/neat/legacy/rules/exporters/_base.py +0 -45
  110. cognite/neat/legacy/rules/exporters/_core/__init__.py +0 -5
  111. cognite/neat/legacy/rules/exporters/_core/rules2labels.py +0 -24
  112. cognite/neat/legacy/rules/exporters/_rules2dms.py +0 -885
  113. cognite/neat/legacy/rules/exporters/_rules2excel.py +0 -213
  114. cognite/neat/legacy/rules/exporters/_rules2graphql.py +0 -183
  115. cognite/neat/legacy/rules/exporters/_rules2ontology.py +0 -524
  116. cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +0 -748
  117. cognite/neat/legacy/rules/exporters/_rules2rules.py +0 -105
  118. cognite/neat/legacy/rules/exporters/_rules2triples.py +0 -38
  119. cognite/neat/legacy/rules/exporters/_validation.py +0 -146
  120. cognite/neat/legacy/rules/importers/__init__.py +0 -22
  121. cognite/neat/legacy/rules/importers/_base.py +0 -66
  122. cognite/neat/legacy/rules/importers/_dict2rules.py +0 -158
  123. cognite/neat/legacy/rules/importers/_dms2rules.py +0 -194
  124. cognite/neat/legacy/rules/importers/_graph2rules.py +0 -308
  125. cognite/neat/legacy/rules/importers/_json2rules.py +0 -39
  126. cognite/neat/legacy/rules/importers/_owl2rules/__init__.py +0 -3
  127. cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +0 -239
  128. cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +0 -260
  129. cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +0 -217
  130. cognite/neat/legacy/rules/importers/_owl2rules/_owl2rules.py +0 -290
  131. cognite/neat/legacy/rules/importers/_spreadsheet2rules.py +0 -45
  132. cognite/neat/legacy/rules/importers/_xsd2rules.py +0 -20
  133. cognite/neat/legacy/rules/importers/_yaml2rules.py +0 -39
  134. cognite/neat/legacy/rules/models/__init__.py +0 -5
  135. cognite/neat/legacy/rules/models/_base.py +0 -151
  136. cognite/neat/legacy/rules/models/raw_rules.py +0 -316
  137. cognite/neat/legacy/rules/models/rdfpath.py +0 -237
  138. cognite/neat/legacy/rules/models/rules.py +0 -1289
  139. cognite/neat/legacy/rules/models/tables.py +0 -9
  140. cognite/neat/legacy/rules/models/value_types.py +0 -118
  141. cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml +0 -89
  142. cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -152
  143. cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -139
  144. cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
  145. cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml +0 -65
  146. cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -116
  147. cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml +0 -67
  148. cognite/neat/legacy/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -64
  149. cognite/neat/legacy/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -95
  150. cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -111
  151. cognite/neat/rules/exceptions.py +0 -2972
  152. cognite/neat/rules/models/_types/_base.py +0 -16
  153. cognite/neat/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -152
  154. cognite/neat/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -139
  155. cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -270
  156. cognite/neat/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -116
  157. cognite/neat/workflows/migration/__init__.py +0 -0
  158. cognite/neat/workflows/migration/steps.py +0 -91
  159. cognite/neat/workflows/migration/wf_manifests.py +0 -33
  160. cognite/neat/workflows/steps/lib/legacy/__init__.py +0 -7
  161. cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py +0 -82
  162. cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +0 -746
  163. cognite/neat/workflows/steps/lib/legacy/graph_loader.py +0 -606
  164. cognite/neat/workflows/steps/lib/legacy/graph_store.py +0 -307
  165. cognite/neat/workflows/steps/lib/legacy/graph_transformer.py +0 -58
  166. cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +0 -511
  167. cognite/neat/workflows/steps/lib/legacy/rules_importer.py +0 -612
  168. cognite_neat-0.87.6.dist-info/RECORD +0 -319
  169. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.1.dist-info}/LICENSE +0 -0
  170. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.1.dist-info}/WHEEL +0 -0
  171. {cognite_neat-0.87.6.dist-info → cognite_neat-0.88.1.dist-info}/entry_points.txt +0 -0
@@ -1,213 +0,0 @@
1
- from pathlib import Path
2
- from typing import cast
3
-
4
- from openpyxl import Workbook
5
- from openpyxl.cell import Cell
6
- from openpyxl.styles import Alignment, Border, Font, NamedStyle, PatternFill, Side
7
- from openpyxl.worksheet.worksheet import Worksheet
8
-
9
- from cognite.neat.legacy.rules.models._base import EntityTypes
10
-
11
- from ._base import BaseExporter
12
-
13
-
14
- class ExcelExporter(BaseExporter[Workbook]):
15
- """Class for exporting transformation rules object to excel file."""
16
-
17
- def _export_to_file(self, filepath: Path) -> None:
18
- """Exports transformation rules to excel file."""
19
- data = self.export()
20
- try:
21
- data.save(filepath)
22
- finally:
23
- data.close()
24
-
25
- def export(self) -> Workbook:
26
- """Generates workbook from transformation rules."""
27
- data = Workbook()
28
- # Remove default sheet named "Sheet"
29
- data.remove(data["Sheet"])
30
- # Serialize the rules to the excel file
31
-
32
- # map rules metadata to excel
33
- metadata = self.rules.metadata
34
- metadata_sheet = data.create_sheet("Metadata")
35
-
36
- # add each metadata property to the sheet as a row
37
- metadata_sheet.append(["prefix", metadata.prefix])
38
- metadata_sheet.append(["namespace", metadata.namespace])
39
- metadata_sheet.append(["external_id", metadata.suffix])
40
- metadata_sheet.append(["title", metadata.name])
41
- metadata_sheet.append(["description", metadata.description])
42
- metadata_sheet.append(["version", metadata.version])
43
- metadata_sheet.append(
44
- [
45
- "creator",
46
- (
47
- ",".join(metadata.creator if isinstance(metadata.creator, list) else [metadata.creator])
48
- if metadata.creator
49
- else ""
50
- ),
51
- ]
52
- )
53
- metadata_sheet.append(
54
- [
55
- "contributor",
56
- (
57
- ",".join(metadata.contributor if isinstance(metadata.contributor, list) else [metadata.contributor])
58
- if metadata.contributor
59
- else ""
60
- ),
61
- ]
62
- )
63
- metadata_sheet.append(["created", metadata.created])
64
- metadata_sheet.append(["updated", metadata.updated])
65
- metadata_sheet.append(["rights", metadata.rights])
66
-
67
- # map classes to excel sheet named "Classes" and add each class as a row
68
- classes_sheet = data.create_sheet("Classes")
69
-
70
- classes_sheet.append(["Solution model", "", "", "Knowledge acquisition", "", "", ""])
71
- classes_sheet.merge_cells("A1:C1")
72
- classes_sheet.merge_cells("D1:G1")
73
- classes_sheet.append(
74
- ["Class", "Description", "Parent Class", "Source", "Source Entity Name", "Match Type", "Comment"]
75
- ) # A ... # G
76
-
77
- for class_ in self.rules.classes.values():
78
- classes_sheet.append(
79
- [
80
- class_.class_id,
81
- class_.description,
82
- (
83
- ",".join([parent_class.versioned_id for parent_class in class_.parent_class])
84
- if class_.parent_class
85
- else None
86
- ),
87
- str(class_.source),
88
- class_.source_entity_name,
89
- class_.match_type,
90
- class_.comment,
91
- ]
92
- )
93
-
94
- # map properties to excel sheet named "Properties" and add each property as a row
95
- properties_sheet = data.create_sheet("Properties")
96
- properties_sheet.append(
97
- [
98
- "Solution model", # A
99
- "", # B
100
- "", # C
101
- "", # D
102
- "", # E
103
- "", # F
104
- "Solution classic CDF resources", # G
105
- "", # H
106
- "", # I
107
- "", # J
108
- "", # K
109
- "", # L
110
- "Transformation rules", # M
111
- "", # N
112
- "Knowledge acquisition", # O
113
- "", # P
114
- "", # Q
115
- "", # R
116
- ]
117
- )
118
- properties_sheet.merge_cells("A1:F1")
119
- properties_sheet.merge_cells("G1:L1")
120
- properties_sheet.merge_cells("M1:N1")
121
- properties_sheet.merge_cells("O1:R1")
122
- properties_sheet.append(
123
- [
124
- "Class", # A
125
- "Property", # B
126
- "Description", # C
127
- "Type", # D
128
- "Min Count", # E
129
- "Max Count", # F
130
- "Resource Type", # G
131
- "Resource Type Property", # H
132
- "Relationship Source Type", # I
133
- "Relationship Target Type", # J
134
- "Relationship Label", # K
135
- "Relationship ExternalID Rule", # L
136
- "Rule Type", # M
137
- "Rule", # N
138
- "Source", # O
139
- "Source Entity Name", # P
140
- "Match Type", # Q
141
- "Comment", # R
142
- ]
143
- )
144
-
145
- for property_ in self.rules.properties.values():
146
- properties_sheet.append(
147
- [
148
- property_.class_id, # A
149
- property_.property_id, # B
150
- property_.description, # C
151
- (
152
- property_.expected_value_type.versioned_id
153
- if property_.property_type == EntityTypes.object_property
154
- else property_.expected_value_type.suffix
155
- ), # D
156
- property_.min_count, # E
157
- property_.max_count, # F
158
- ",".join(property_.cdf_resource_type) if property_.cdf_resource_type else "", # G
159
- ",".join(property_.resource_type_property) if property_.resource_type_property else "", # H
160
- property_.source_type, # I
161
- property_.target_type, # J
162
- property_.label, # K
163
- property_.relationship_external_id_rule, # L
164
- property_.rule_type, # M
165
- property_.rule, # N
166
- str(property_.source), # O
167
- property_.source_entity_name, # P
168
- property_.match_type, # Q
169
- property_.comment, # R
170
- ]
171
- )
172
-
173
- prefixes_sheet = data.create_sheet("Prefixes")
174
- prefixes_sheet.append(["Prefix", "URI"]) # A # B
175
-
176
- for prefix, uri in self.rules.prefixes.items():
177
- prefixes_sheet.append([prefix, uri]) # A # B
178
-
179
- return self._set_header_style(data)
180
-
181
- @staticmethod
182
- def _set_header_style(data: Workbook):
183
- """Sets the header style for all sheets in the self.workbook"""
184
- style = NamedStyle(name="header style")
185
- style.font = Font(bold=True, size=16)
186
- side = Side(style="thin", color="000000")
187
- style.border = Border(left=side, right=side, top=side, bottom=side)
188
- data.add_named_style(style)
189
-
190
- for sheet in data.sheetnames:
191
- if sheet == "Metadata":
192
- continue
193
- if sheet == "Classes" or sheet == "Properties":
194
- sheet_obj = cast(Worksheet, data[sheet])
195
- if sheet == "Classes":
196
- sheet_obj.freeze_panes = "A3"
197
- else:
198
- sheet_obj.freeze_panes = "D3"
199
-
200
- for cell in sheet_obj[1]:
201
- cell = cast(Cell, cell) # type: ignore[index]
202
- cell.style = style
203
- cell.fill = PatternFill("solid", start_color="D5B2CF")
204
- cell.alignment = Alignment(horizontal="center", vertical="center")
205
- for cell in sheet_obj[2]:
206
- cell = cast(Cell, cell) # type: ignore[index]
207
- cell.style = style
208
- cell.fill = PatternFill("solid", start_color="D5DBD5")
209
- cell.alignment = Alignment(horizontal="center", vertical="center")
210
- adjusted_width = (len(str(cell.value)) + 5) * 1.2
211
- cast(Worksheet, data[sheet]).column_dimensions[cell.column_letter].width = adjusted_width
212
-
213
- return data
@@ -1,183 +0,0 @@
1
- import sys
2
- import warnings
3
- from dataclasses import dataclass
4
- from pathlib import Path
5
- from typing import TYPE_CHECKING
6
-
7
- if sys.version_info >= (3, 11):
8
- from typing import Self
9
- else:
10
- from typing_extensions import Self
11
-
12
- from cognite.neat.legacy.rules import exceptions
13
- from cognite.neat.legacy.rules.analysis import to_class_property_pairs
14
- from cognite.neat.legacy.rules.exporters._validation import are_entity_names_dms_compliant, are_properties_redefined
15
- from cognite.neat.legacy.rules.models.rules import Rules
16
- from cognite.neat.legacy.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
17
- from cognite.neat.utils.auxiliary import generate_exception_report
18
-
19
- from ._base import BaseExporter
20
-
21
- if TYPE_CHECKING:
22
- from jinja2 import Template
23
-
24
-
25
- class GraphQLSchemaExporter(BaseExporter[str]):
26
- def _export_to_file(self, filepath: Path):
27
- if filepath.suffix != ".graphql":
28
- warnings.warn("File extension is not .graphql, adding it to the file name", stacklevel=2)
29
- filepath = filepath.with_suffix(".graphql")
30
- filepath.write_text(self.export())
31
-
32
- def export(self) -> str:
33
- return GraphQLSchema.from_rules(self.rules).schema
34
-
35
-
36
- _TYPE = (
37
- "{% include 'type_header' %}type {{ class_definition.class_id }} {{'{'}}"
38
- "{%-for property_definition in class_properties%}"
39
- "{% include 'field' %}"
40
- "{% endfor %}\n}\n"
41
- )
42
-
43
- _TYPE_HEADER = (
44
- "{%- if header %}"
45
- "{%- if class_definition.description and class_definition.class_name %}"
46
- '"""\n{{class_definition.description}}\n@name {{ class_definition.class_name }}\n"""\n{##}\n'
47
- "{%- elif class_definition.description %}"
48
- '\n"""\n{{class_definition.description}}\n"""\n'
49
- "{%- endif %}"
50
- "{%- endif %}"
51
- )
52
-
53
-
54
- _FIELD = (
55
- "{% include 'field_header' %}\n"
56
- " {{ property_definition.property_id }}: "
57
- "{%-if property_definition.property_type == 'DatatypeProperty'%}"
58
- "{% include 'attribute_occurrence' %}"
59
- "{%-else%}"
60
- "{% include 'edge_occurrence' %}"
61
- "{%- endif -%}"
62
- )
63
-
64
- _FIELD_HEADER = (
65
- "{%- if header %}"
66
- "{%- if property_definition.description and property_definition.property_name %}"
67
- '\n """\n {{property_definition.description}}'
68
- "\n @name {{ property_definition.property_name }}"
69
- '\n """\n '
70
- "{%- elif property_definition.description %}"
71
- '\n """\n {{property_definition.description}}'
72
- '\n """\n '
73
- "{%- endif %}"
74
- "{%- endif %}"
75
- )
76
-
77
- _ATTRIBUTE_OCCURRENCE = (
78
- "{%-if property_definition.min_count and property_definition.max_count == 1%}"
79
- " {% include 'value_type' %}!"
80
- "{%-elif property_definition.min_count and property_definition.max_count != 1%}"
81
- " [{% include 'value_type' %}!]!"
82
- "{%-elif property_definition.max_count != 1%}"
83
- " [{% include 'value_type' %}!]!"
84
- "{%-else%}{% include 'value_type' %}"
85
- "{%- endif -%}"
86
- )
87
-
88
- _EDGE_OCCURRENCE = (
89
- "{%-if not(property_definition.min_count and property_definition.max_count == 1)%}"
90
- " [{% include 'value_type' %}]"
91
- "{%-else%}"
92
- " {% include 'value_type' %}"
93
- "{%- endif -%}"
94
- )
95
-
96
- _FIELD_VALUE_TYPE = """{{property_definition.expected_value_type.mapping.graphql
97
- if property_definition.expected_value_type.suffix in value_type_mapping
98
- else property_definition.expected_value_type.suffix}}"""
99
-
100
-
101
- @dataclass
102
- class GraphQLSchema:
103
- """
104
- Represents a GraphQL schema.
105
-
106
- This can be used to generate a GraphQL schema from TransformationRules.
107
-
108
- Args:
109
- schema: The GraphQL schema.
110
-
111
- """
112
-
113
- schema: str
114
-
115
- @classmethod
116
- def from_rules(cls, transformation_rules: Rules, verbose: bool = False) -> Self:
117
- """
118
- Generates a GraphQL schema from TransformationRules.
119
-
120
- Args:
121
- transformation_rules: The TransformationRules to generate a GraphQL schema from.
122
- verbose: Whether to include descriptions and names in the schema.
123
-
124
- Returns:
125
- A GraphQLSchema instance.
126
- """
127
- names_compliant, name_warnings = are_entity_names_dms_compliant(transformation_rules, return_report=True)
128
- if not names_compliant:
129
- raise exceptions.EntitiesContainNonDMSCompliantCharacters(report=generate_exception_report(name_warnings))
130
-
131
- properties_redefined, redefinition_warnings = are_properties_redefined(transformation_rules, return_report=True)
132
- if properties_redefined:
133
- raise exceptions.PropertiesDefinedMultipleTimes(report=generate_exception_report(redefinition_warnings))
134
-
135
- return cls(schema=cls.generate_schema(transformation_rules, verbose))
136
-
137
- @staticmethod
138
- def generate_schema(transformation_rules: Rules, verbose: bool) -> str:
139
- """
140
- Generates a GraphQL schema from TransformationRules.
141
-
142
- Args:
143
- transformation_rules: Instance of TransformationRules to generate a GraphQL schema from.
144
- verbose: Whether to include descriptions and names in the schema.
145
-
146
- Returns:
147
- A GraphQL schema.
148
- """
149
- class_properties = to_class_property_pairs(transformation_rules)
150
-
151
- type_definitions = []
152
-
153
- for class_id in class_properties:
154
- parameters = {
155
- "class_definition": transformation_rules.classes[class_id],
156
- "class_properties": list(class_properties[class_id].values()),
157
- "value_type_mapping": XSD_VALUE_TYPE_MAPPINGS,
158
- "header": verbose,
159
- }
160
-
161
- type_definitions.append(GraphQLSchema.template().render(parameters))
162
-
163
- return "\n\n".join(type_definitions)
164
-
165
- @staticmethod
166
- def template() -> "Template":
167
- from jinja2 import DictLoader, Environment, Template
168
-
169
- template: Template = Environment(
170
- loader=DictLoader(
171
- {
172
- "type_header": _TYPE_HEADER,
173
- "type": _TYPE,
174
- "field_header": _FIELD_HEADER,
175
- "field": _FIELD,
176
- "value_type": _FIELD_VALUE_TYPE,
177
- "edge_occurrence": _EDGE_OCCURRENCE,
178
- "attribute_occurrence": _ATTRIBUTE_OCCURRENCE,
179
- }
180
- ),
181
- cache_size=1000,
182
- ).get_template("type")
183
- return template