cognite-neat 0.77.2__py3-none-any.whl → 0.77.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.

Files changed (31) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/rules/analysis/_information_rules.py +2 -12
  3. cognite/neat/rules/exporters/_rules2excel.py +78 -89
  4. cognite/neat/rules/importers/_dms2rules.py +24 -11
  5. cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +1 -0
  6. cognite/neat/rules/importers/_spreadsheet2rules.py +21 -8
  7. cognite/neat/rules/issues/dms.py +19 -0
  8. cognite/neat/rules/issues/importing.py +16 -0
  9. cognite/neat/rules/issues/spreadsheet.py +60 -5
  10. cognite/neat/rules/models/_base.py +6 -0
  11. cognite/neat/rules/models/dms/_converter.py +25 -19
  12. cognite/neat/rules/models/dms/_exporter.py +2 -1
  13. cognite/neat/rules/models/dms/_rules.py +3 -2
  14. cognite/neat/rules/models/dms/_rules_input.py +4 -11
  15. cognite/neat/rules/models/dms/_schema.py +41 -5
  16. cognite/neat/rules/models/dms/_serializer.py +1 -1
  17. cognite/neat/rules/models/dms/_validation.py +27 -60
  18. cognite/neat/rules/models/information/__init__.py +8 -1
  19. cognite/neat/rules/models/information/_converter.py +27 -19
  20. cognite/neat/rules/models/information/_rules.py +41 -82
  21. cognite/neat/rules/models/information/_rules_input.py +266 -0
  22. cognite/neat/rules/models/information/_serializer.py +85 -0
  23. cognite/neat/rules/models/information/_validation.py +164 -0
  24. cognite/neat/utils/cdf.py +35 -0
  25. cognite/neat/workflows/steps/lib/current/rules_exporter.py +30 -7
  26. cognite/neat/workflows/steps/lib/current/rules_importer.py +21 -2
  27. {cognite_neat-0.77.2.dist-info → cognite_neat-0.77.4.dist-info}/METADATA +1 -1
  28. {cognite_neat-0.77.2.dist-info → cognite_neat-0.77.4.dist-info}/RECORD +31 -28
  29. {cognite_neat-0.77.2.dist-info → cognite_neat-0.77.4.dist-info}/LICENSE +0 -0
  30. {cognite_neat-0.77.2.dist-info → cognite_neat-0.77.4.dist-info}/WHEEL +0 -0
  31. {cognite_neat-0.77.2.dist-info → cognite_neat-0.77.4.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,5 @@
1
1
  import warnings
2
- from datetime import datetime
3
- from typing import cast
2
+ from typing import TYPE_CHECKING, cast
4
3
 
5
4
  from rdflib import Namespace
6
5
 
@@ -20,7 +19,10 @@ from cognite.neat.rules.models.entities import (
20
19
  )
21
20
  from cognite.neat.rules.models.information._rules import InformationRules
22
21
 
23
- from ._rules import DMSProperty, DMSRules, DMSView
22
+ from ._rules import DMSMetadata, DMSProperty, DMSRules, DMSView
23
+
24
+ if TYPE_CHECKING:
25
+ from cognite.neat.rules.models.information._rules import InformationMetadata
24
26
 
25
27
 
26
28
  class _DMSRulesConverter:
@@ -32,31 +34,16 @@ class _DMSRulesConverter:
32
34
 
33
35
  def as_information_architect_rules(
34
36
  self,
35
- created: datetime | None = None,
36
- updated: datetime | None = None,
37
- name: str | None = None,
38
- namespace: Namespace | None = None,
39
37
  ) -> "InformationRules":
40
38
  from cognite.neat.rules.models.information._rules import (
41
39
  InformationClass,
42
- InformationMetadata,
43
40
  InformationProperty,
44
41
  InformationRules,
45
42
  )
46
43
 
47
44
  dms = self.dms.metadata
48
- prefix = dms.space
49
45
 
50
- metadata = InformationMetadata(
51
- schema_=dms.schema_,
52
- prefix=prefix,
53
- namespace=namespace or Namespace(f"https://purl.orgl/neat/{prefix}/"),
54
- version=dms.version,
55
- name=name or dms.name or "Missing name",
56
- creator=dms.creator,
57
- created=dms.created or created or datetime.now(),
58
- updated=dms.updated or updated or datetime.now(),
59
- )
46
+ metadata = self._convert_metadata_to_info(dms)
60
47
 
61
48
  classes = [
62
49
  InformationClass(
@@ -111,6 +98,25 @@ class _DMSRulesConverter:
111
98
  reference=self.dms.reference.as_information_architect_rules() if self.dms.reference else None,
112
99
  )
113
100
 
101
+ @classmethod
102
+ def _convert_metadata_to_info(cls, metadata: DMSMetadata) -> "InformationMetadata":
103
+ from cognite.neat.rules.models.information._rules import InformationMetadata
104
+
105
+ prefix = metadata.space
106
+ return InformationMetadata(
107
+ schema_=metadata.schema_,
108
+ data_model_type=metadata.data_model_type,
109
+ extension=metadata.extension,
110
+ prefix=prefix,
111
+ namespace=Namespace(f"https://purl.orgl/neat/{prefix}/"),
112
+ version=metadata.version,
113
+ description=metadata.description,
114
+ name=metadata.name or metadata.external_id,
115
+ creator=metadata.creator,
116
+ created=metadata.created,
117
+ updated=metadata.updated,
118
+ )
119
+
114
120
  @classmethod
115
121
  def _get_class_reference(cls, view: DMSView) -> ReferenceEntity | None:
116
122
  parents_other_namespace = [parent for parent in view.implements or [] if parent.prefix != view.class_.prefix]
@@ -86,7 +86,8 @@ class _DMSExporter:
86
86
 
87
87
  if self._ref_schema:
88
88
  output.reference = self._ref_schema
89
-
89
+ if self.rules.last:
90
+ output.last = self.rules.last.as_schema()
90
91
  return output
91
92
 
92
93
  def _create_spaces(
@@ -58,7 +58,7 @@ _DEFAULT_VERSION = "1"
58
58
 
59
59
  class DMSMetadata(BaseMetadata):
60
60
  role: ClassVar[RoleTypes] = RoleTypes.dms_architect
61
- data_model_type: DataModelType = Field(DataModelType.solution, alias="dataModelType")
61
+ data_model_type: DataModelType = Field(DataModelType.enterprise, alias="dataModelType")
62
62
  schema_: SchemaCompleteness = Field(alias="schema")
63
63
  extension: ExtensionCategory = ExtensionCategory.addition
64
64
  space: ExternalIdType
@@ -146,10 +146,11 @@ class DMSMetadata(BaseMetadata):
146
146
  return description, creator
147
147
 
148
148
  @classmethod
149
- def from_data_model(cls, data_model: dm.DataModelApply) -> "DMSMetadata":
149
+ def from_data_model(cls, data_model: dm.DataModelApply, has_reference: bool) -> "DMSMetadata":
150
150
  description, creator = cls._get_description_and_creator(data_model.description)
151
151
  return cls(
152
152
  schema_=SchemaCompleteness.complete,
153
+ data_model_type=DataModelType.solution if has_reference else DataModelType.enterprise,
153
154
  space=data_model.space,
154
155
  name=data_model.name or None,
155
156
  description=description,
@@ -3,9 +3,7 @@ from dataclasses import dataclass
3
3
  from datetime import datetime
4
4
  from typing import Any, Literal, cast, overload
5
5
 
6
- from pydantic import BaseModel
7
-
8
- from cognite.neat.rules.models._base import DataModelType, ExtensionCategory, SchemaCompleteness
6
+ from cognite.neat.rules.models._base import DataModelType, ExtensionCategory, SchemaCompleteness, _add_alias
9
7
  from cognite.neat.rules.models.data_types import DataType
10
8
  from cognite.neat.rules.models.entities import (
11
9
  ClassEntity,
@@ -44,8 +42,9 @@ class DMSMetadataInput:
44
42
  external_id=data.get("external_id"), # type: ignore[arg-type]
45
43
  creator=data.get("creator"), # type: ignore[arg-type]
46
44
  version=data.get("version"), # type: ignore[arg-type]
47
- extension=data.get("extension", "addition"),
48
- data_model_type=data.get("data_model_type", "solution"),
45
+ # safeguard from empty cell, i.e. if key provided by value None
46
+ extension=data.get("extension", "addition") or "addition",
47
+ data_model_type=data.get("data_model_type", "solution") or "solution",
49
48
  name=data.get("name"),
50
49
  description=data.get("description"),
51
50
  created=data.get("created"),
@@ -355,9 +354,3 @@ class DMSRulesInput:
355
354
  Last=last,
356
355
  Reference=reference,
357
356
  )
358
-
359
-
360
- def _add_alias(data: dict[str, Any], base_model: type[BaseModel]) -> None:
361
- for field_name, field_ in base_model.model_fields.items():
362
- if field_name not in data and field_.alias in data:
363
- data[field_name] = data[field_.alias]
@@ -12,6 +12,7 @@ from cognite.client import CogniteClient
12
12
  from cognite.client import data_modeling as dm
13
13
  from cognite.client.data_classes import DatabaseWrite, DatabaseWriteList, TransformationWrite, TransformationWriteList
14
14
  from cognite.client.data_classes.data_modeling import ViewApply
15
+ from cognite.client.data_classes.data_modeling.views import ReverseDirectRelation
15
16
  from cognite.client.data_classes.transformations.common import Edges, EdgeType, Nodes, ViewInfo
16
17
 
17
18
  from cognite.neat.rules import issues
@@ -28,6 +29,7 @@ from cognite.neat.rules.issues.dms import (
28
29
  MissingSourceViewError,
29
30
  MissingSpaceError,
30
31
  MissingViewError,
32
+ MissingViewInModelWarning,
31
33
  )
32
34
  from cognite.neat.rules.models.data_types import _DATA_TYPE_BY_DMS_TYPE
33
35
  from cognite.neat.utils.cdf_classes import (
@@ -146,8 +148,26 @@ class DMSSchema:
146
148
  space_write = space_read.as_write()
147
149
 
148
150
  view_loader = ViewLoader(client)
149
- # We need to include parent views in the schema to make sure that the schema is valid.
151
+
150
152
  existing_view_ids = set(views.as_ids())
153
+
154
+ # We need to include all views the edges/direct relations are pointing to have a complete schema.
155
+ connection_referenced_view_ids: set[dm.ViewId] = set()
156
+ for view in views:
157
+ connection_referenced_view_ids |= cls._connection_references(view)
158
+ connection_referenced_view_ids = connection_referenced_view_ids - existing_view_ids
159
+ if connection_referenced_view_ids:
160
+ warnings.warn(
161
+ MissingViewInModelWarning(data_model.as_id(), connection_referenced_view_ids), UserWarning, stacklevel=2
162
+ )
163
+ connection_referenced_views = view_loader.retrieve(list(connection_referenced_view_ids))
164
+ if failed := connection_referenced_view_ids - set(connection_referenced_views.as_ids()):
165
+ warnings.warn(
166
+ issues.importing.FailedImportWarning({repr(v) for v in failed}), UserWarning, stacklevel=2
167
+ )
168
+ views.extend(connection_referenced_views)
169
+
170
+ # We need to include parent views in the schema to make sure that the schema is valid.
151
171
  parent_view_ids = {parent for view in views for parent in view.implements or []}
152
172
  parents = view_loader.retrieve_all_parents(list(parent_view_ids - existing_view_ids))
153
173
  views.extend([parent for parent in parents if parent.as_id() not in existing_view_ids])
@@ -203,6 +223,21 @@ class DMSSchema:
203
223
  reference=ref_schema,
204
224
  )
205
225
 
226
+ @classmethod
227
+ def _connection_references(cls, view: dm.View) -> set[dm.ViewId]:
228
+ view_ids: set[dm.ViewId] = set()
229
+ for prop in (view.properties or {}).values():
230
+ if isinstance(prop, dm.MappedProperty) and isinstance(prop.type, dm.DirectRelation):
231
+ if prop.source:
232
+ view_ids.add(prop.source)
233
+ elif isinstance(prop, dm.EdgeConnection):
234
+ view_ids.add(prop.source)
235
+ if prop.edge_source:
236
+ view_ids.add(prop.edge_source)
237
+ elif isinstance(prop, ReverseDirectRelation):
238
+ view_ids.add(prop.source)
239
+ return view_ids
240
+
206
241
  @classmethod
207
242
  def from_directory(cls, directory: str | Path) -> Self:
208
243
  """Load a schema from a directory containing YAML files.
@@ -481,10 +516,11 @@ class DMSSchema:
481
516
  defined_spaces = self.spaces.copy()
482
517
  defined_containers = self.containers.copy()
483
518
  defined_views = self.views.copy()
484
- if self.reference:
485
- defined_spaces |= self.reference.spaces
486
- defined_containers |= self.reference.containers
487
- defined_views |= self.reference.views
519
+ for other_schema in [self.reference, self.last]:
520
+ if other_schema:
521
+ defined_spaces |= other_schema.spaces
522
+ defined_containers |= other_schema.containers
523
+ defined_views |= other_schema.views
488
524
 
489
525
  for container in self.containers.values():
490
526
  if container.space not in defined_spaces:
@@ -37,7 +37,7 @@ class _DMSRulesSerializer:
37
37
  DMSProperty.model_fields[field].alias or field for field in self.properties_fields
38
38
  ]
39
39
  self.views_fields = [DMSView.model_fields[field].alias or field for field in self.views_fields]
40
- self.container_fields = [
40
+ self.containers_fields = [
41
41
  DMSContainer.model_fields[field].alias or field for field in self.containers_fields
42
42
  ]
43
43
  self.prop_view = DMSProperty.model_fields[self.prop_view].alias or self.prop_view
@@ -5,12 +5,13 @@ from cognite.client import data_modeling as dm
5
5
 
6
6
  from cognite.neat.rules import issues
7
7
  from cognite.neat.rules.issues import IssueList
8
- from cognite.neat.rules.models._base import ExtensionCategory, SchemaCompleteness
8
+ from cognite.neat.rules.models._base import DataModelType, ExtensionCategory, SchemaCompleteness
9
9
  from cognite.neat.rules.models.data_types import DataType
10
10
  from cognite.neat.rules.models.entities import ContainerEntity
11
11
  from cognite.neat.rules.models.wrapped_entities import RawFilter
12
12
 
13
13
  from ._rules import DMSProperty, DMSRules
14
+ from ._schema import DMSSchema
14
15
 
15
16
 
16
17
  class DMSPostValidation:
@@ -26,12 +27,17 @@ class DMSPostValidation:
26
27
  self.issue_list = IssueList()
27
28
 
28
29
  def validate(self) -> IssueList:
29
- self._validate_best_practices()
30
+ self._validate_raw_filter()
30
31
  self._consistent_container_properties()
32
+
31
33
  self._referenced_views_and_containers_are_existing()
32
- self._validate_extension()
33
- self._validate_schema()
34
- self._validate_performance()
34
+ if self.metadata.schema_ is SchemaCompleteness.extended:
35
+ self._validate_extension()
36
+ if self.metadata.schema_ is SchemaCompleteness.partial:
37
+ return self.issue_list
38
+ dms_schema = self.rules.as_schema()
39
+ self.issue_list.extend(dms_schema.validate())
40
+ self._validate_performance(dms_schema)
35
41
  return self.issue_list
36
42
 
37
43
  def _consistent_container_properties(self) -> None:
@@ -106,8 +112,9 @@ class DMSPostValidation:
106
112
  self.issue_list.extend(errors)
107
113
 
108
114
  def _referenced_views_and_containers_are_existing(self) -> None:
109
- # There two checks are done in the same method to raise all the errors at once.
110
115
  defined_views = {view.view.as_id() for view in self.views}
116
+ if self.metadata.schema_ is SchemaCompleteness.extended and self.rules.last:
117
+ defined_views |= {view.view.as_id() for view in self.rules.last.views}
111
118
 
112
119
  errors: list[issues.NeatValidationError] = []
113
120
  for prop_no, prop in enumerate(self.properties):
@@ -125,6 +132,11 @@ class DMSPostValidation:
125
132
  )
126
133
  if self.metadata.schema_ is SchemaCompleteness.complete:
127
134
  defined_containers = {container.container.as_id() for container in self.containers or []}
135
+ if self.metadata.data_model_type == DataModelType.solution and self.rules.reference:
136
+ defined_containers |= {
137
+ container.container.as_id() for container in self.rules.reference.containers or []
138
+ }
139
+
128
140
  for prop_no, prop in enumerate(self.properties):
129
141
  if prop.container and (container_id := prop.container.as_id()) not in defined_containers:
130
142
  errors.append(
@@ -157,19 +169,16 @@ class DMSPostValidation:
157
169
  def _validate_extension(self) -> None:
158
170
  if self.metadata.schema_ is not SchemaCompleteness.extended:
159
171
  return None
160
- if not self.rules.reference:
161
- raise ValueError("The schema is set to 'extended', but no reference rules are provided to validate against")
162
- is_solution = self.metadata.space != self.rules.reference.metadata.space
163
- if is_solution:
164
- return None
172
+ if not self.rules.last:
173
+ raise ValueError("The schema is set to 'extended', but no last rules are provided to validate against")
165
174
  if self.metadata.extension is ExtensionCategory.rebuild:
166
175
  # Everything is allowed
167
176
  return None
168
- # Is an extension of an existing model.
169
177
  user_schema = self.rules.as_schema()
170
- ref_schema = self.rules.reference.as_schema()
171
178
  new_containers = user_schema.containers.copy()
172
- existing_containers = ref_schema.containers.copy()
179
+
180
+ last_schema = self.rules.last.as_schema()
181
+ existing_containers = last_schema.containers.copy()
173
182
 
174
183
  for container_id, container in new_containers.items():
175
184
  existing_container = existing_containers.get(container_id)
@@ -189,14 +198,12 @@ class DMSPostValidation:
189
198
  )
190
199
  )
191
200
 
192
- if self.metadata.extension is ExtensionCategory.reshape and self.issue_list:
193
- return None
194
- elif self.metadata.extension is ExtensionCategory.reshape:
201
+ if self.metadata.extension is ExtensionCategory.reshape:
195
202
  # Reshape allows changes to views
196
203
  return None
197
204
 
198
205
  new_views = user_schema.views.copy()
199
- existing_views = ref_schema.views.copy()
206
+ existing_views = last_schema.views.copy()
200
207
  for view_id, view in new_views.items():
201
208
  existing_view = existing_views.get(view_id)
202
209
  if not existing_view or existing_view == view:
@@ -213,14 +220,7 @@ class DMSPostValidation:
213
220
  )
214
221
  )
215
222
 
216
- def _validate_performance(self) -> None:
217
- # we can only validate performance on complete schemas due to the need
218
- # to access all the container mappings
219
- if self.metadata.schema_ is not SchemaCompleteness.complete:
220
- return None
221
-
222
- dms_schema = self.rules.as_schema()
223
-
223
+ def _validate_performance(self, dms_schema: DMSSchema) -> None:
224
224
  for view_id, view in dms_schema.views.items():
225
225
  mapped_containers = dms_schema._get_mapped_container_from_view(view_id)
226
226
 
@@ -243,7 +243,7 @@ class DMSPostValidation:
243
243
  )
244
244
  )
245
245
 
246
- def _validate_best_practices(self) -> None:
246
+ def _validate_raw_filter(self) -> None:
247
247
  for view in self.views:
248
248
  if view.filter_ and isinstance(view.filter_, RawFilter):
249
249
  self.issue_list.append(
@@ -264,36 +264,3 @@ class DMSPostValidation:
264
264
  existing_properties = existing_dumped.get("properties", {})
265
265
  changed_properties = [prop for prop in new_properties if new_properties[prop] != existing_properties.get(prop)]
266
266
  return changed_attributes, changed_properties
267
-
268
- def _validate_schema(self) -> None:
269
- if self.metadata.schema_ is SchemaCompleteness.partial:
270
- return None
271
- elif self.metadata.schema_ is SchemaCompleteness.complete:
272
- rules: DMSRules = self.rules
273
- elif self.metadata.schema_ is SchemaCompleteness.extended:
274
- if not self.rules.reference:
275
- raise ValueError(
276
- "The schema is set to 'extended', but no reference rules are provided to validate against"
277
- )
278
- # This is an extension of the reference rules, we need to merge the two
279
- rules = self.rules.model_copy(deep=True)
280
- rules.properties.extend(self.rules.reference.properties.data)
281
- existing_views = {view.view.as_id() for view in rules.views}
282
- rules.views.extend([view for view in self.rules.reference.views if view.view.as_id() not in existing_views])
283
- if rules.containers and self.rules.reference.containers:
284
- existing_containers = {container.container.as_id() for container in rules.containers.data}
285
- rules.containers.extend(
286
- [
287
- container
288
- for container in self.rules.reference.containers
289
- if container.container.as_id() not in existing_containers
290
- ]
291
- )
292
- elif not rules.containers and self.rules.reference.containers:
293
- rules.containers = self.rules.reference.containers
294
- else:
295
- raise ValueError("Unknown schema completeness")
296
-
297
- schema = rules.as_schema()
298
- errors = schema.validate()
299
- self.issue_list.extend(errors)
@@ -1,3 +1,10 @@
1
1
  from ._rules import InformationClass, InformationMetadata, InformationProperty, InformationRules
2
+ from ._rules_input import InformationRulesInput
2
3
 
3
- __all__ = ["InformationRules", "InformationMetadata", "InformationClass", "InformationProperty"]
4
+ __all__ = [
5
+ "InformationRules",
6
+ "InformationMetadata",
7
+ "InformationClass",
8
+ "InformationProperty",
9
+ "InformationRulesInput",
10
+ ]
@@ -1,14 +1,11 @@
1
1
  import re
2
2
  from collections import defaultdict
3
- from datetime import datetime
4
- from typing import Literal
3
+ from typing import TYPE_CHECKING, Literal
5
4
 
6
5
  from cognite.neat.rules.models._base import (
7
- DataModelType,
8
6
  SheetList,
9
7
  )
10
8
  from cognite.neat.rules.models.data_types import DataType
11
- from cognite.neat.rules.models.dms._rules import DMSProperty, DMSRules, DMSView
12
9
  from cognite.neat.rules.models.domain import DomainRules
13
10
  from cognite.neat.rules.models.entities import (
14
11
  ClassEntity,
@@ -22,6 +19,9 @@ from cognite.neat.rules.models.entities import (
22
19
 
23
20
  from ._rules import InformationClass, InformationMetadata, InformationProperty, InformationRules
24
21
 
22
+ if TYPE_CHECKING:
23
+ from cognite.neat.rules.models.dms._rules import DMSMetadata, DMSProperty, DMSRules
24
+
25
25
 
26
26
  class _InformationRulesConverter:
27
27
  def __init__(self, information: InformationRules):
@@ -30,30 +30,18 @@ class _InformationRulesConverter:
30
30
  def as_domain_rules(self) -> DomainRules:
31
31
  raise NotImplementedError("DomainRules not implemented yet")
32
32
 
33
- def as_dms_architect_rules(self, created: datetime | None = None, updated: datetime | None = None) -> "DMSRules":
33
+ def as_dms_architect_rules(self) -> "DMSRules":
34
34
  from cognite.neat.rules.models.dms._rules import (
35
35
  DMSContainer,
36
- DMSMetadata,
37
36
  DMSProperty,
38
37
  DMSRules,
38
+ DMSView,
39
39
  )
40
40
 
41
41
  info_metadata = self.information.metadata
42
42
  default_version = info_metadata.version
43
43
  default_space = self._to_space(info_metadata.prefix)
44
- space = self._to_space(info_metadata.prefix)
45
-
46
- metadata = DMSMetadata(
47
- schema_=info_metadata.schema_,
48
- space=space,
49
- data_model_type=DataModelType.solution if self.information.reference else DataModelType.enterprise,
50
- version=info_metadata.version,
51
- external_id=info_metadata.name.replace(" ", "_").lower(),
52
- creator=info_metadata.creator,
53
- name=info_metadata.name,
54
- created=created or datetime.now(),
55
- updated=updated or datetime.now(),
56
- )
44
+ metadata = self._convert_metadata_to_dms(info_metadata)
57
45
 
58
46
  properties_by_class: dict[str, list[DMSProperty]] = defaultdict(list)
59
47
  for prop in self.information.properties:
@@ -111,6 +99,26 @@ class _InformationRulesConverter:
111
99
  reference=self.information.reference.as_dms_architect_rules() if self.information.reference else None,
112
100
  )
113
101
 
102
+ @classmethod
103
+ def _convert_metadata_to_dms(cls, metadata: InformationMetadata) -> "DMSMetadata":
104
+ from cognite.neat.rules.models.dms._rules import (
105
+ DMSMetadata,
106
+ )
107
+
108
+ space = cls._to_space(metadata.prefix)
109
+
110
+ return DMSMetadata(
111
+ schema_=metadata.schema_,
112
+ space=space,
113
+ data_model_type=metadata.data_model_type,
114
+ version=metadata.version,
115
+ external_id=metadata.name.replace(" ", "_").lower(),
116
+ creator=metadata.creator,
117
+ name=metadata.name,
118
+ created=metadata.created,
119
+ updated=metadata.updated,
120
+ )
121
+
114
122
  @classmethod
115
123
  def _as_dms_property(cls, prop: InformationProperty, default_space: str, default_version: str) -> "DMSProperty":
116
124
  """This creates the first"""