cognite-neat 1.0.31__py3-none-any.whl → 1.0.32__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.
Files changed (29) hide show
  1. cognite/neat/_client/data_classes.py +32 -0
  2. cognite/neat/_client/statistics_api.py +28 -1
  3. cognite/neat/_data_model/_analysis.py +3 -0
  4. cognite/neat/_data_model/_constants.py +4 -0
  5. cognite/neat/_data_model/{validation/dms → rules}/_base.py +11 -5
  6. cognite/neat/_data_model/rules/cdf/__init__.py +3 -0
  7. cognite/neat/_data_model/rules/cdf/_base.py +5 -0
  8. cognite/neat/_data_model/rules/cdf/_orchestrator.py +56 -0
  9. cognite/neat/_data_model/rules/cdf/_spaces.py +47 -0
  10. cognite/neat/_data_model/{validation → rules}/dms/__init__.py +2 -2
  11. cognite/neat/_data_model/{validation → rules}/dms/_ai_readiness.py +17 -17
  12. cognite/neat/_data_model/rules/dms/_base.py +5 -0
  13. cognite/neat/_data_model/{validation → rules}/dms/_connections.py +23 -23
  14. cognite/neat/_data_model/{validation → rules}/dms/_consistency.py +3 -3
  15. cognite/neat/_data_model/{validation → rules}/dms/_containers.py +9 -9
  16. cognite/neat/_data_model/{validation → rules}/dms/_limits.py +14 -14
  17. cognite/neat/_data_model/{validation → rules}/dms/_orchestrator.py +7 -7
  18. cognite/neat/_data_model/{validation → rules}/dms/_performance.py +7 -7
  19. cognite/neat/_data_model/{validation → rules}/dms/_views.py +7 -7
  20. cognite/neat/_session/_cdf.py +15 -1
  21. cognite/neat/_session/_physical.py +6 -6
  22. cognite/neat/_session/_wrappers.py +1 -1
  23. cognite/neat/_state_machine/_states.py +1 -1
  24. cognite/neat/_store/_store.py +19 -1
  25. cognite/neat/_version.py +1 -1
  26. {cognite_neat-1.0.31.dist-info → cognite_neat-1.0.32.dist-info}/METADATA +1 -1
  27. {cognite_neat-1.0.31.dist-info → cognite_neat-1.0.32.dist-info}/RECORD +29 -24
  28. {cognite_neat-1.0.31.dist-info → cognite_neat-1.0.32.dist-info}/WHEEL +1 -1
  29. /cognite/neat/_data_model/{validation → rules}/__init__.py +0 -0
@@ -4,13 +4,13 @@ from pyparsing import cast
4
4
 
5
5
  from cognite.neat._data_model.models.dms._constraints import Constraint, RequiresConstraintDefinition
6
6
  from cognite.neat._data_model.models.dms._view_property import ViewCorePropertyRequest
7
- from cognite.neat._data_model.validation.dms._base import DataModelValidator
7
+ from cognite.neat._data_model.rules.dms._base import DataModelRule
8
8
  from cognite.neat._issues import ConsistencyError
9
9
 
10
10
  BASE_CODE = "NEAT-DMS-CONTAINER"
11
11
 
12
12
 
13
- class ExternalContainerDoesNotExist(DataModelValidator):
13
+ class ExternalContainerDoesNotExist(DataModelRule):
14
14
  """
15
15
  Validates that any container referenced by a view property, when the
16
16
  referenced container does not belong to the data model's space, exists in CDF.
@@ -33,7 +33,7 @@ class ExternalContainerDoesNotExist(DataModelValidator):
33
33
  code = f"{BASE_CODE}-001"
34
34
  issue_type = ConsistencyError
35
35
 
36
- def run(self) -> list[ConsistencyError]:
36
+ def validate(self) -> list[ConsistencyError]:
37
37
  errors: list[ConsistencyError] = []
38
38
 
39
39
  if not self.validation_resources.merged_data_model.views:
@@ -73,7 +73,7 @@ class ExternalContainerDoesNotExist(DataModelValidator):
73
73
  return errors
74
74
 
75
75
 
76
- class ExternalContainerPropertyDoesNotExist(DataModelValidator):
76
+ class ExternalContainerPropertyDoesNotExist(DataModelRule):
77
77
  """
78
78
  Validates that any container property referenced by a view property, when the
79
79
  referenced container does not belong to the data model's space, exists in CDF.
@@ -97,7 +97,7 @@ class ExternalContainerPropertyDoesNotExist(DataModelValidator):
97
97
  code = f"{BASE_CODE}-002"
98
98
  issue_type = ConsistencyError
99
99
 
100
- def run(self) -> list[ConsistencyError]:
100
+ def validate(self) -> list[ConsistencyError]:
101
101
  errors: list[ConsistencyError] = []
102
102
 
103
103
  if self.validation_resources.merged_data_model.views:
@@ -144,7 +144,7 @@ class ExternalContainerPropertyDoesNotExist(DataModelValidator):
144
144
  return errors
145
145
 
146
146
 
147
- class RequiredContainerDoesNotExist(DataModelValidator):
147
+ class RequiredContainerDoesNotExist(DataModelRule):
148
148
  """
149
149
  Validates that any container required by another container exists in the data model.
150
150
 
@@ -165,7 +165,7 @@ class RequiredContainerDoesNotExist(DataModelValidator):
165
165
  code = f"{BASE_CODE}-003"
166
166
  issue_type = ConsistencyError
167
167
 
168
- def run(self) -> list[ConsistencyError]:
168
+ def validate(self) -> list[ConsistencyError]:
169
169
  errors: list[ConsistencyError] = []
170
170
 
171
171
  for container_ref in self.validation_resources.merged.containers:
@@ -199,7 +199,7 @@ class RequiredContainerDoesNotExist(DataModelValidator):
199
199
  return errors
200
200
 
201
201
 
202
- class RequiresConstraintCycle(DataModelValidator):
202
+ class RequiresConstraintCycle(DataModelRule):
203
203
  """
204
204
  Validates that requires constraints between containers do not form cycles.
205
205
 
@@ -221,7 +221,7 @@ class RequiresConstraintCycle(DataModelValidator):
221
221
  issue_type = ConsistencyError
222
222
  alpha = True # Still in development
223
223
 
224
- def run(self) -> list[ConsistencyError]:
224
+ def validate(self) -> list[ConsistencyError]:
225
225
  errors: list[ConsistencyError] = []
226
226
  optimal_edges = self.validation_resources.oriented_mst_edges
227
227
 
@@ -8,15 +8,15 @@ from cognite.neat._data_model.models.dms._indexes import BtreeIndex, InvertedInd
8
8
  from cognite.neat._data_model.models.dms._view_property import (
9
9
  ViewCorePropertyRequest,
10
10
  )
11
- from cognite.neat._data_model.validation.dms._base import (
12
- DataModelValidator,
11
+ from cognite.neat._data_model.rules.dms._base import (
12
+ DataModelRule,
13
13
  )
14
14
  from cognite.neat._issues import ConsistencyError, Recommendation
15
15
 
16
16
  BASE_CODE = "NEAT-DMS-LIMITS"
17
17
 
18
18
 
19
- class DataModelViewCountIsOutOfLimits(DataModelValidator):
19
+ class DataModelViewCountIsOutOfLimits(DataModelRule):
20
20
  """Validates that the data model does not exceed the maximum number of views.
21
21
 
22
22
  ## What it does
@@ -36,7 +36,7 @@ class DataModelViewCountIsOutOfLimits(DataModelValidator):
36
36
  code = f"{BASE_CODE}-DATA-MODEL-001"
37
37
  issue_type = ConsistencyError
38
38
 
39
- def run(self) -> list[ConsistencyError]:
39
+ def validate(self) -> list[ConsistencyError]:
40
40
  errors: list[ConsistencyError] = []
41
41
 
42
42
  if self.validation_resources.merged_data_model.views is None:
@@ -66,7 +66,7 @@ class DataModelViewCountIsOutOfLimits(DataModelValidator):
66
66
  ### View level limits
67
67
 
68
68
 
69
- class ViewPropertyCountIsOutOfLimits(DataModelValidator):
69
+ class ViewPropertyCountIsOutOfLimits(DataModelRule):
70
70
  """Validates that a view does not exceed the maximum number of properties.
71
71
 
72
72
  ## What it does
@@ -83,7 +83,7 @@ class ViewPropertyCountIsOutOfLimits(DataModelValidator):
83
83
  code = f"{BASE_CODE}-VIEW-001"
84
84
  issue_type = ConsistencyError
85
85
 
86
- def run(self) -> list[ConsistencyError]:
86
+ def validate(self) -> list[ConsistencyError]:
87
87
  errors: list[ConsistencyError] = []
88
88
 
89
89
  for view_ref in self.validation_resources.merged_data_model.views or []:
@@ -117,7 +117,7 @@ class ViewPropertyCountIsOutOfLimits(DataModelValidator):
117
117
  return errors
118
118
 
119
119
 
120
- class ViewContainerCountIsOutOfLimits(DataModelValidator):
120
+ class ViewContainerCountIsOutOfLimits(DataModelRule):
121
121
  """Validates that a view does not reference too many containers.
122
122
 
123
123
  ## What it does
@@ -135,7 +135,7 @@ class ViewContainerCountIsOutOfLimits(DataModelValidator):
135
135
  code = f"{BASE_CODE}-VIEW-002"
136
136
  issue_type = Recommendation
137
137
 
138
- def run(self) -> list[Recommendation]:
138
+ def validate(self) -> list[Recommendation]:
139
139
  recommendations: list[Recommendation] = []
140
140
 
141
141
  # Single loop over all views
@@ -166,7 +166,7 @@ class ViewContainerCountIsOutOfLimits(DataModelValidator):
166
166
  return recommendations
167
167
 
168
168
 
169
- class ViewImplementsCountIsOutOfLimits(DataModelValidator):
169
+ class ViewImplementsCountIsOutOfLimits(DataModelRule):
170
170
  """Validates that a view does not implement too many other views.
171
171
 
172
172
  ## What it does
@@ -183,7 +183,7 @@ class ViewImplementsCountIsOutOfLimits(DataModelValidator):
183
183
  code = f"{BASE_CODE}-VIEW-003"
184
184
  issue_type = ConsistencyError
185
185
 
186
- def run(self) -> list[ConsistencyError]:
186
+ def validate(self) -> list[ConsistencyError]:
187
187
  errors: list[ConsistencyError] = []
188
188
 
189
189
  # Single loop over all views
@@ -206,7 +206,7 @@ class ViewImplementsCountIsOutOfLimits(DataModelValidator):
206
206
  ### Container level limits
207
207
 
208
208
 
209
- class ContainerPropertyCountIsOutOfLimits(DataModelValidator):
209
+ class ContainerPropertyCountIsOutOfLimits(DataModelRule):
210
210
  """Validates that a container does not exceed the maximum number of properties.
211
211
 
212
212
  ## What it does
@@ -224,7 +224,7 @@ class ContainerPropertyCountIsOutOfLimits(DataModelValidator):
224
224
  code = f"{BASE_CODE}-CONTAINER-001"
225
225
  issue_type = ConsistencyError
226
226
 
227
- def run(self) -> list[ConsistencyError]:
227
+ def validate(self) -> list[ConsistencyError]:
228
228
  errors: list[ConsistencyError] = []
229
229
  # Single loop over all containers
230
230
  for container_ref in self.validation_resources.merged.containers:
@@ -263,7 +263,7 @@ class ContainerPropertyCountIsOutOfLimits(DataModelValidator):
263
263
  return errors
264
264
 
265
265
 
266
- class ContainerPropertyListSizeIsOutOfLimits(DataModelValidator):
266
+ class ContainerPropertyListSizeIsOutOfLimits(DataModelRule):
267
267
  """Validates that container property list sizes do not exceed CDF limits.
268
268
 
269
269
  ## What it does
@@ -288,7 +288,7 @@ class ContainerPropertyListSizeIsOutOfLimits(DataModelValidator):
288
288
  code = f"{BASE_CODE}-CONTAINER-002"
289
289
  issue_type = ConsistencyError
290
290
 
291
- def run(self) -> list[ConsistencyError]:
291
+ def validate(self) -> list[ConsistencyError]:
292
292
  errors: list[ConsistencyError] = []
293
293
 
294
294
  # Single loop over all containers
@@ -6,14 +6,14 @@ from cognite.neat._data_model._shared import OnSuccessIssuesChecker
6
6
  from cognite.neat._data_model._snapshot import SchemaSnapshot
7
7
  from cognite.neat._data_model.models.dms._limits import SchemaLimits
8
8
  from cognite.neat._data_model.models.dms._schema import RequestSchema
9
+ from cognite.neat._data_model.rules.dms._base import DataModelRule
9
10
  from cognite.neat._utils.auxiliary import get_concrete_subclasses
10
11
  from cognite.neat._utils.useful_types import ModusOperandi
11
12
 
12
- from ._base import DataModelValidator
13
13
 
14
-
15
- class DmsDataModelValidation(OnSuccessIssuesChecker):
16
- """Placeholder for DMS Quality Assessment functionality."""
14
+ class DmsDataModelRulesOrchestrator(OnSuccessIssuesChecker):
15
+ """DMS Data Model rules orchestrator, used to execute DMS data model rules on a single data model represented
16
+ as RequestSchema."""
17
17
 
18
18
  def __init__(
19
19
  self,
@@ -37,8 +37,8 @@ class DmsDataModelValidation(OnSuccessIssuesChecker):
37
37
  validation_resources = self._gather_validation_resources(request_schema)
38
38
 
39
39
  # Initialize all validators
40
- validators: list[DataModelValidator] = [
41
- validator(validation_resources) for validator in get_concrete_subclasses(DataModelValidator)
40
+ validators: list[DataModelRule] = [
41
+ validator(validation_resources) for validator in get_concrete_subclasses(DataModelRule)
42
42
  ]
43
43
 
44
44
  # Run validators
@@ -46,7 +46,7 @@ class DmsDataModelValidation(OnSuccessIssuesChecker):
46
46
  if validator.alpha and not self._enable_alpha_validators:
47
47
  continue
48
48
  if self._can_run_validator(validator.code, validator.issue_type):
49
- self._issues.extend(validator.run())
49
+ self._issues.extend(validator.validate())
50
50
 
51
51
  self._has_run = True
52
52
 
@@ -2,13 +2,13 @@
2
2
 
3
3
  from cognite.neat._data_model._analysis import RequiresChangeStatus
4
4
  from cognite.neat._data_model._constants import COGNITE_SPACES
5
- from cognite.neat._data_model.validation.dms._base import DataModelValidator
5
+ from cognite.neat._data_model.rules.dms._base import DataModelRule
6
6
  from cognite.neat._issues import Recommendation
7
7
 
8
8
  BASE_CODE = "NEAT-DMS-PERFORMANCE"
9
9
 
10
10
 
11
- class MissingRequiresConstraint(DataModelValidator):
11
+ class MissingRequiresConstraint(DataModelRule):
12
12
  """
13
13
  Recommends adding requires constraints to optimize query performance.
14
14
 
@@ -31,7 +31,7 @@ class MissingRequiresConstraint(DataModelValidator):
31
31
  issue_type = Recommendation
32
32
  alpha = True
33
33
 
34
- def run(self) -> list[Recommendation]:
34
+ def validate(self) -> list[Recommendation]:
35
35
  recommendations: list[Recommendation] = []
36
36
 
37
37
  for view_ref in self.validation_resources.merged.views:
@@ -75,7 +75,7 @@ class MissingRequiresConstraint(DataModelValidator):
75
75
  return recommendations
76
76
 
77
77
 
78
- class SuboptimalRequiresConstraint(DataModelValidator):
78
+ class SuboptimalRequiresConstraint(DataModelRule):
79
79
  """
80
80
  Recommends removing requires constraints that are not optimal.
81
81
 
@@ -100,7 +100,7 @@ class SuboptimalRequiresConstraint(DataModelValidator):
100
100
  issue_type = Recommendation
101
101
  alpha = True
102
102
 
103
- def run(self) -> list[Recommendation]:
103
+ def validate(self) -> list[Recommendation]:
104
104
  recommendations: list[Recommendation] = []
105
105
 
106
106
  for view_ref in self.validation_resources.merged.views:
@@ -125,7 +125,7 @@ class SuboptimalRequiresConstraint(DataModelValidator):
125
125
  return recommendations
126
126
 
127
127
 
128
- class UnresolvableQueryPerformance(DataModelValidator):
128
+ class UnresolvableQueryPerformance(DataModelRule):
129
129
  """
130
130
  Identifies views with query performance issues that cannot be resolved.
131
131
  This is likely to be caused by unintended modeling choices.
@@ -158,7 +158,7 @@ class UnresolvableQueryPerformance(DataModelValidator):
158
158
  issue_type = Recommendation
159
159
  alpha = True
160
160
 
161
- def run(self) -> list[Recommendation]:
161
+ def validate(self) -> list[Recommendation]:
162
162
  recommendations: list[Recommendation] = []
163
163
 
164
164
  for view_ref in self.validation_resources.merged.views:
@@ -1,13 +1,13 @@
1
1
  """Validators for checking containers in the data model."""
2
2
 
3
3
  from cognite.neat._data_model.models.dms._view_property import ViewCorePropertyRequest
4
- from cognite.neat._data_model.validation.dms._base import DataModelValidator
4
+ from cognite.neat._data_model.rules.dms._base import DataModelRule
5
5
  from cognite.neat._issues import ConsistencyError
6
6
 
7
7
  BASE_CODE = "NEAT-DMS-VIEW"
8
8
 
9
9
 
10
- class ViewToContainerMappingNotPossible(DataModelValidator):
10
+ class ViewToContainerMappingNotPossible(DataModelRule):
11
11
  """Validates that container and container property referenced by view property exist.
12
12
 
13
13
  ## What it does
@@ -26,7 +26,7 @@ class ViewToContainerMappingNotPossible(DataModelValidator):
26
26
  code = f"{BASE_CODE}-001"
27
27
  issue_type = ConsistencyError
28
28
 
29
- def run(self) -> list[ConsistencyError]:
29
+ def validate(self) -> list[ConsistencyError]:
30
30
  errors: list[ConsistencyError] = []
31
31
 
32
32
  if not self.validation_resources.merged_data_model.views:
@@ -79,7 +79,7 @@ class ViewToContainerMappingNotPossible(DataModelValidator):
79
79
  return errors
80
80
 
81
81
 
82
- class ImplementedViewNotExisting(DataModelValidator):
82
+ class ImplementedViewNotExisting(DataModelRule):
83
83
  """Validates that implemented (inherited) view exists.
84
84
 
85
85
  ## What it does
@@ -97,7 +97,7 @@ class ImplementedViewNotExisting(DataModelValidator):
97
97
  code = f"{BASE_CODE}-002"
98
98
  issue_type = ConsistencyError
99
99
 
100
- def run(self) -> list[ConsistencyError]:
100
+ def validate(self) -> list[ConsistencyError]:
101
101
  errors: list[ConsistencyError] = []
102
102
 
103
103
  if not self.validation_resources.merged_data_model.views:
@@ -126,7 +126,7 @@ class ImplementedViewNotExisting(DataModelValidator):
126
126
  return errors
127
127
 
128
128
 
129
- class CyclicImplements(DataModelValidator):
129
+ class CyclicImplements(DataModelRule):
130
130
  """Validates that view implements are not forming a cycle (i.e. cyclic graph of implements)
131
131
 
132
132
  ## What it does
@@ -146,7 +146,7 @@ class CyclicImplements(DataModelValidator):
146
146
  issue_type = ConsistencyError
147
147
  alpha = True
148
148
 
149
- def run(self) -> list[ConsistencyError]:
149
+ def validate(self) -> list[ConsistencyError]:
150
150
  errors: list[ConsistencyError] = []
151
151
 
152
152
  for cycle in self.validation_resources.implements_cycles:
@@ -1,13 +1,15 @@
1
- # /Users/nikola/repos/neat/cognite/neat/_session/_cdf.py
2
1
  import uuid
3
2
 
4
3
  from cognite.neat._client import NeatClient
5
4
  from cognite.neat._config import NeatConfig
5
+ from cognite.neat._data_model.rules.cdf._orchestrator import CDFRulesOrchestrator
6
+ from cognite.neat._session._wrappers import session_wrapper
6
7
  from cognite.neat._store._store import NeatStore
7
8
 
8
9
  from ._html._render import render
9
10
 
10
11
 
12
+ @session_wrapper
11
13
  class CDF:
12
14
  """Read from a data source into NeatSession graph store."""
13
15
 
@@ -34,3 +36,15 @@ class CDF:
34
36
  "data_models_limit": self._store.cdf_limits.data_models.limit,
35
37
  },
36
38
  )
39
+
40
+ def analyze(self) -> None:
41
+ """Analyze the entity of CDF data models."""
42
+
43
+ on_success = CDFRulesOrchestrator(
44
+ limits=self._store.cdf_limits,
45
+ space_statistics=self._store.cdf_space_statistics,
46
+ can_run_validator=self._config.validation.can_run_validator,
47
+ enable_alpha_validators=self._config.alpha.enable_experimental_validators,
48
+ )
49
+
50
+ return self._store.cdf_analyze(on_success)
@@ -16,7 +16,7 @@ from cognite.neat._data_model.exporters import (
16
16
  from cognite.neat._data_model.exporters._table_exporter.workbook import WorkbookOptions
17
17
  from cognite.neat._data_model.importers import DMSAPICreator, DMSAPIImporter, DMSImporter, DMSTableImporter
18
18
  from cognite.neat._data_model.models.dms import DataModelReference
19
- from cognite.neat._data_model.validation.dms import DmsDataModelValidation
19
+ from cognite.neat._data_model.rules.dms import DmsDataModelRulesOrchestrator
20
20
  from cognite.neat._exceptions import UserInputError
21
21
  from cognite.neat._state_machine import PhysicalState
22
22
  from cognite.neat._store._store import NeatStore
@@ -109,7 +109,7 @@ class ReadPhysicalDataModel:
109
109
  else:
110
110
  raise UserInputError(f"Unsupported format: {format}. Supported formats are 'neat' and 'toolkit'.")
111
111
 
112
- on_success = DmsDataModelValidation(
112
+ on_success = DmsDataModelRulesOrchestrator(
113
113
  modus_operandi=self._config.modeling.mode,
114
114
  cdf_snapshot=self._store.cdf_snapshot,
115
115
  limits=self._store.cdf_limits,
@@ -138,7 +138,7 @@ class ReadPhysicalDataModel:
138
138
  else:
139
139
  raise UserInputError(f"Unsupported format: {format}. Supported formats are 'neat' and 'toolkit'.")
140
140
 
141
- on_success = DmsDataModelValidation(
141
+ on_success = DmsDataModelRulesOrchestrator(
142
142
  modus_operandi=self._config.modeling.mode,
143
143
  cdf_snapshot=self._store.cdf_snapshot,
144
144
  limits=self._store.cdf_limits,
@@ -158,7 +158,7 @@ class ReadPhysicalDataModel:
158
158
  path = NeatReader.create(io).materialize_path()
159
159
  reader = DMSTableImporter.from_excel(path)
160
160
 
161
- on_success = DmsDataModelValidation(
161
+ on_success = DmsDataModelRulesOrchestrator(
162
162
  modus_operandi=self._config.modeling.mode,
163
163
  cdf_snapshot=self._store.cdf_snapshot,
164
164
  limits=self._store.cdf_limits,
@@ -181,7 +181,7 @@ class ReadPhysicalDataModel:
181
181
  DataModelReference(space=space, external_id=external_id, version=version), self._client
182
182
  )
183
183
 
184
- on_success = DmsDataModelValidation(
184
+ on_success = DmsDataModelRulesOrchestrator(
185
185
  modus_operandi=self._config.modeling.mode,
186
186
  cdf_snapshot=self._store.cdf_snapshot,
187
187
  limits=self._store.cdf_limits,
@@ -337,7 +337,7 @@ def create(
337
337
  cdf_snapshot=self._store.cdf_snapshot,
338
338
  )
339
339
 
340
- on_success = DmsDataModelValidation(
340
+ on_success = DmsDataModelRulesOrchestrator(
341
341
  modus_operandi=self._config.modeling.mode,
342
342
  cdf_snapshot=self._store.cdf_snapshot,
343
343
  limits=self._store.cdf_limits,
@@ -28,7 +28,7 @@ def session_wrapper(cls: type[T_Class]) -> type[T_Class]:
28
28
  identifier = f"{cls.__name__}.{func.__name__}"
29
29
  try:
30
30
  res = func(self, *args, **kwargs)
31
- if not self._store.provenance or "DataModel" not in identifier:
31
+ if not self._store.provenance or ("DataModel" not in identifier and "CDF" not in identifier):
32
32
  print(f"{display_name} ✅")
33
33
  if _COLLECTOR.can_collect:
34
34
  _COLLECTOR.collect("action", {"action": identifier, "success": True})
@@ -34,7 +34,7 @@ class EmptyState(State):
34
34
  The initial state with empty NEAT store.
35
35
  """
36
36
 
37
- def transition(self, event: Any) -> State:
37
+ def transition(self, event: Any | None) -> State:
38
38
  if isinstance(event, DMSImporter):
39
39
  return PhysicalState()
40
40
  return ForbiddenState(self)
@@ -4,6 +4,7 @@ from datetime import datetime, timezone
4
4
  from typing import Any, cast
5
5
 
6
6
  from cognite.neat._client.client import NeatClient
7
+ from cognite.neat._client.data_classes import SpaceStatisticsResponse
7
8
  from cognite.neat._config import NeatConfig
8
9
  from cognite.neat._data_model._shared import OnSuccess, OnSuccessIssuesChecker, OnSuccessResultProducer
9
10
  from cognite.neat._data_model._snapshot import SchemaSnapshot
@@ -36,6 +37,15 @@ class NeatStore:
36
37
  # Placeholder for CDF schema and limit snapshot
37
38
  self._cdf_snapshot: SchemaSnapshot | None = None
38
39
  self._cdf_limits: SchemaLimits | None = None
40
+ self._cdf_space_statistics: SpaceStatisticsResponse | None = None
41
+
42
+ @property
43
+ def cdf_space_statistics(self) -> SpaceStatisticsResponse:
44
+ if self._cdf_space_statistics is None:
45
+ self._cdf_space_statistics = self._client.statistics.space_statistics(
46
+ [space.space for space in self.cdf_snapshot.spaces.keys()]
47
+ )
48
+ return self._cdf_space_statistics
39
49
 
40
50
  @property
41
51
  def cdf_limits(self) -> SchemaLimits:
@@ -91,8 +101,16 @@ class NeatStore:
91
101
  and isinstance(on_success, SchemaDeployer)
92
102
  and not on_success.options.dry_run
93
103
  ):
94
- # Update CDF snapshot after successful deployment
104
+ # Update CDF snapshot and space statistics after deployment
95
105
  self._cdf_snapshot = SchemaSnapshot.fetch_entire_cdf(self._client)
106
+ self._cdf_space_statistics = self._client.statistics.space_statistics(
107
+ [space.space for space in self.cdf_snapshot.spaces.keys()]
108
+ )
109
+
110
+ def cdf_analyze(self, on_success: OnSuccess) -> None:
111
+ """Analyze the entity of CDF data models"""
112
+ change, _ = self._do_activity(lambda: self.cdf_snapshot, on_success)
113
+ self.provenance.append(change)
96
114
 
97
115
  def _gather_data_model(self, writer: DMSExporter) -> PhysicalDataModel:
98
116
  """Gather the current physical data model from the store
cognite/neat/_version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "1.0.31"
1
+ __version__ = "1.0.32"
2
2
  __engine__ = "^2.0.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite-neat
3
- Version: 1.0.31
3
+ Version: 1.0.32
4
4
  Summary: Knowledge graph transformation
5
5
  Author: Nikola Vasiljevic, Anders Albert
6
6
  Author-email: Nikola Vasiljevic <nikola.vasiljevic@cognite.com>, Anders Albert <anders.albert@cognite.com>
@@ -4,7 +4,7 @@ cognite/neat/_client/api.py,sha256=VOtXyr9-Ouxkl3nWUj6fffr-9VG6wzVRGWSr_QqR5d8,6
4
4
  cognite/neat/_client/client.py,sha256=h0HELAHiBFxMNInkDu4AzbgfEIXqeM0BqqnMBmXjgi0,903
5
5
  cognite/neat/_client/config.py,sha256=eIIdWaA13yncRP6X7vTYsTpmXmVcmkhZPv5oPnLUEVc,1484
6
6
  cognite/neat/_client/containers_api.py,sha256=zFHb9SwfwqAxUkrEStLBV8BDSvRWvBBOY8mVuCIOWQU,3116
7
- cognite/neat/_client/data_classes.py,sha256=HYPsrAJGVCUmlWTSIxJgAnIHAOzcyDveMM6Z-cuA92M,1404
7
+ cognite/neat/_client/data_classes.py,sha256=C1GNg5MmWaZFwtdV39Mcza7T3dt_cyXVtK6RF0aIHgM,2324
8
8
  cognite/neat/_client/data_model_api.py,sha256=fxJ77RbKd8UAsm4jfDH3P16Jp-GwKWPrxx2jyA_xCnk,3518
9
9
  cognite/neat/_client/filters.py,sha256=1tPpbp_GFAh7Jq5tdwUvZz6nOoWB36zIxa_ZO-1UER0,1138
10
10
  cognite/neat/_client/init/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -13,12 +13,12 @@ cognite/neat/_client/init/env_vars.py,sha256=9nOEVABp4rI2TtFHCMItLouQ5MXFL0zzL4P
13
13
  cognite/neat/_client/init/interactive.py,sha256=YVnsvRblQJPojf24dA050gVlrrqADK8afSQ6hkXn7Cs,4801
14
14
  cognite/neat/_client/init/main.py,sha256=D-9bsor07T84iFnTZLnhIFA1Xey9zsooHaDhXVeNdos,2508
15
15
  cognite/neat/_client/spaces_api.py,sha256=yb26ju3sKbVgiduMEbN4LDGan6vsC3z_JaW3p4FUdr0,2929
16
- cognite/neat/_client/statistics_api.py,sha256=5meeh0v5mxC2SMB7xGdOwMh4KkaX3DtpUjbGEPhNBJo,913
16
+ cognite/neat/_client/statistics_api.py,sha256=3KNVsD2OV-EDFb1eqIrCXfYwjvyCDO80bPEpu_aHieI,1813
17
17
  cognite/neat/_client/views_api.py,sha256=YMaw7IaxU4gmixpd_t1u9JK9BHfNerf5DMNinGPCAa0,3692
18
18
  cognite/neat/_config.py,sha256=IJS_R-86M4SLxdo644LZ0dE9h0jg2XBL1A4QKWJj0TQ,10160
19
19
  cognite/neat/_data_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- cognite/neat/_data_model/_analysis.py,sha256=y-U2ko4uIGu4bgnL6HIZnZWrEZSZFH0Kf3NdQ5870ns,43595
21
- cognite/neat/_data_model/_constants.py,sha256=h6FaREqE2KG7hy2ZQVDq-3_yjVjlpSG6Usz2kadIUIs,1722
20
+ cognite/neat/_data_model/_analysis.py,sha256=sZO2NATkyuSzlo3uRgXJ6B3btKWkwblNos7SXT6LHLc,43779
21
+ cognite/neat/_data_model/_constants.py,sha256=pPDtRwBsOq80IkYXRJ0XaRfFOb7CPvxz81IQzcPgAuc,1889
22
22
  cognite/neat/_data_model/_identifiers.py,sha256=lDLvMvYDgRNFgk5GmxWzOUunG7M3synAciNjzJI0m_o,1913
23
23
  cognite/neat/_data_model/_shared.py,sha256=H0gFqa8tKFNWuvdat5jL6OwySjCw3aQkLPY3wtb9Wrw,1302
24
24
  cognite/neat/_data_model/_snapshot.py,sha256=JBaKmL0Tmprz59SZ1JeB49BPMB8Hqa-OAOt0Bai8cw4,6305
@@ -75,21 +75,26 @@ cognite/neat/_data_model/models/entities/_constants.py,sha256=EK9Bus8UgFgxK5cVFM
75
75
  cognite/neat/_data_model/models/entities/_data_types.py,sha256=DfdEWGek7gODro-_0SiiInhPGwul4zn-ASACQfn8HUY,2838
76
76
  cognite/neat/_data_model/models/entities/_identifiers.py,sha256=a7ojJKY1ErZgUANHscEwkctX4RJ7bWEEWOQt5g5Tsdk,1915
77
77
  cognite/neat/_data_model/models/entities/_parser.py,sha256=zef_pSDZYMZrJl4IKreFDR577KutfhtN1xpH3Ayjt2o,7669
78
- cognite/neat/_data_model/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- cognite/neat/_data_model/validation/dms/__init__.py,sha256=Z6P8TTXZR1KIJreDieRVTcJVvovdZXCLXRbzm86UojI,2936
80
- cognite/neat/_data_model/validation/dms/_ai_readiness.py,sha256=bffMQJ5pqumU5P3KaEdQP67OO5eMKqzN2BAWbUjG6KE,16143
81
- cognite/neat/_data_model/validation/dms/_base.py,sha256=G_gMPTgKwyBW62UcCkKIBVHWp9ufAZPJ2p7o69_dJI0,820
82
- cognite/neat/_data_model/validation/dms/_connections.py,sha256=-kUXf2_3V50ckxwXRwJoTHsKkS5zxiBKkkkHg8Dm4WI,30353
83
- cognite/neat/_data_model/validation/dms/_consistency.py,sha256=IKSUoRQfQQcsymviESW9VuTFX7jsZMXfsObeZHPdov4,2435
84
- cognite/neat/_data_model/validation/dms/_containers.py,sha256=n2L8HiJLylHIkzGi1veGb2QLVEFZuLlOwws77mxm0Fw,10552
85
- cognite/neat/_data_model/validation/dms/_limits.py,sha256=rAIh54DJBPi3J7d7eD-jMdldZS8R2vlkQ5MD9RxNsrI,14830
86
- cognite/neat/_data_model/validation/dms/_orchestrator.py,sha256=qiuUSUmNhekFyBARUUO2yhG-X9AeU_LL49UrJ65JXFA,2964
87
- cognite/neat/_data_model/validation/dms/_performance.py,sha256=LvSQpmoYblSVqnSX5EOqCXnwPfMTGSndVCkX3ogoOSc,8611
88
- cognite/neat/_data_model/validation/dms/_views.py,sha256=pRdnj5ZBnHNnbLKleXGbipteGma8_l5AYsDIfqgAil4,6345
78
+ cognite/neat/_data_model/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ cognite/neat/_data_model/rules/_base.py,sha256=W5VHNQipinWkXnaI0CfFvqhPar0OuauhG5ixa4XnTLo,1032
80
+ cognite/neat/_data_model/rules/cdf/__init__.py,sha256=Bn9_DkkO4OPUYh0CsM3Pf1fD_UkhfhWqATOzB6iLquk,60
81
+ cognite/neat/_data_model/rules/cdf/_base.py,sha256=59fqmFi_Gvzx3swLsIyc2ACkHAzKAKiqNlwwGnW5bDg,128
82
+ cognite/neat/_data_model/rules/cdf/_orchestrator.py,sha256=egzcYUuFDd8Vm7neBpZFofqZBfYjuElAjYwJWAScutc,2250
83
+ cognite/neat/_data_model/rules/cdf/_spaces.py,sha256=Lsfrp2e7yzgRimkD0qynJ5M2S7Zwzplfg_4Pim1voHk,1605
84
+ cognite/neat/_data_model/rules/dms/__init__.py,sha256=ThCvtSCPzEhciJNnzBKDoTWMimw5U74MbfUwoF6e7F8,2950
85
+ cognite/neat/_data_model/rules/dms/_ai_readiness.py,sha256=1KvOk3Q8aQkE8G6oHml7O-SHiTeIBNmyKPWr3hPcCCw,16133
86
+ cognite/neat/_data_model/rules/dms/_base.py,sha256=BnzBELon389lEXJi7dlb9t3SPjiXgVquiI445I7-APU,134
87
+ cognite/neat/_data_model/rules/dms/_connections.py,sha256=vi_cJp5S4MpfX-jA1eqZClnHdKznkQMDvZk9iIj42mM,30343
88
+ cognite/neat/_data_model/rules/dms/_consistency.py,sha256=7u-EDQk08eV4CJoY5nRbrYXs2cbkQkH6TQCcPOyUGI8,2425
89
+ cognite/neat/_data_model/rules/dms/_containers.py,sha256=eb0eLy13n7OozKp2vrE_oXqD6m2uyX-9fhoCqU_gJqc,10542
90
+ cognite/neat/_data_model/rules/dms/_limits.py,sha256=L6dAsLWVBEpfVFZgw3SvJk1PnEGf4lhJ3SOXjDUsY2Q,14820
91
+ cognite/neat/_data_model/rules/dms/_orchestrator.py,sha256=tTXxLH1yThAeTW_GdDeD-to19faK72c_z8QL9kzgGJc,3069
92
+ cognite/neat/_data_model/rules/dms/_performance.py,sha256=7LTs1E86xA-hvL4fqiIhAHcgIeohwb1pODzh3o6tuzQ,8601
93
+ cognite/neat/_data_model/rules/dms/_views.py,sha256=Tp4VW2512eGSGgeMRoUFh7hqK2vsZD8ryN_EJ7QJoEg,6335
89
94
  cognite/neat/_exceptions.py,sha256=hOjPL1vFNNAZzqAHFB9l9ek-XJEBKcqiaPk0onwLPns,2540
90
95
  cognite/neat/_issues.py,sha256=wH1mnkrpBsHUkQMGUHFLUIQWQlfJ_qMfdF7q0d9wNhY,1871
91
96
  cognite/neat/_session/__init__.py,sha256=owqW5Mml2DSZx1AvPvwNRTBngfhBNrQ6EH-7CKL7Jp0,61
92
- cognite/neat/_session/_cdf.py,sha256=Ps49pc2tKriImpDkcIABnCgrfoX-L3QGmnXK8ceJ1Lc,1365
97
+ cognite/neat/_session/_cdf.py,sha256=-Z1mTCd2no25zWEADS9LwqC7ycLdR6__7Hf9Tok_QYw,1924
93
98
  cognite/neat/_session/_html/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
99
  cognite/neat/_session/_html/_render.py,sha256=ksauN5-lW9GFakPILfaql3CGXpVMwIuvaY8XaEjhFnE,1520
95
100
  cognite/neat/_session/_html/static/__init__.py,sha256=VLqgkeITPLrR_WAbVkc_BtGOaHCHbreTHewkoCdgPgQ,427
@@ -105,7 +110,7 @@ cognite/neat/_session/_html/templates/deployment.html,sha256=aLDXMbF3pcSqnCpUYVG
105
110
  cognite/neat/_session/_html/templates/issues.html,sha256=zjhkJcPK0hMp_ZKJ9RCf88tuZxQyTYRPxzpqx33Nkt0,1661
106
111
  cognite/neat/_session/_html/templates/statistics.html,sha256=C-ghoT8xzBehAJLOonNzCB418LW-FA60MaZBHlW1D5c,968
107
112
  cognite/neat/_session/_issues.py,sha256=E8UQeSJURg2dm4MF1pfD9dp-heSRT7pgQZgKlD1-FGs,2723
108
- cognite/neat/_session/_physical.py,sha256=uzgyNfchv5axhDMjdGB6hnpbvT_QfXKmI6zhwbsFW-o,14448
113
+ cognite/neat/_session/_physical.py,sha256=k4O-qXDekiC4ZvRRMRdSyKaplLqADbFTMmLk6Hvlq2I,14485
109
114
  cognite/neat/_session/_result/__init__.py,sha256=8A0BKgsqnjxkiHUlCpHBNl3mrFWtyjaWYnh0jssE6QU,50
110
115
  cognite/neat/_session/_result/_deployment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
116
  cognite/neat/_session/_result/_deployment/_physical/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -118,13 +123,13 @@ cognite/neat/_session/_usage_analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
118
123
  cognite/neat/_session/_usage_analytics/_collector.py,sha256=8yVfzt8KFfZ-ldkVjDWazuQbs45Q3r6vWKcZEwU8i18,4734
119
124
  cognite/neat/_session/_usage_analytics/_constants.py,sha256=-tVdYrCTMKfuMlbO7AlzC29Nug41ug6uuX9DFuihpJg,561
120
125
  cognite/neat/_session/_usage_analytics/_storage.py,sha256=w3mUvmPysww6vM3PZBjg6jzNEsDISl7FJ1j19LNs26E,7779
121
- cognite/neat/_session/_wrappers.py,sha256=3GADffOVyGryXknnN88hKhwTHvtZfeFBYpCROuXyGXY,5447
126
+ cognite/neat/_session/_wrappers.py,sha256=hTk2AI9-CWe1sfx3WveP3yKvYxTIE9P6awaP3SV4YhE,5477
122
127
  cognite/neat/_state_machine/__init__.py,sha256=wrtQUHETiLzYM0pFo7JC6pJCiXetHADQbyMu8pU8rQU,195
123
128
  cognite/neat/_state_machine/_base.py,sha256=-ZpeAhM6l6N6W70dET25tAzOxaaK5aa474eabwZVzjA,1112
124
- cognite/neat/_state_machine/_states.py,sha256=nmj4SmunpDYcBsNx8A284xnXGS43wuUuWpMMORha2DE,1170
129
+ cognite/neat/_state_machine/_states.py,sha256=cE1WzYZCJygaT1rieTp4aFsI7t2CiISK-slRs_t414k,1177
125
130
  cognite/neat/_store/__init__.py,sha256=TvM9CcFbtOSrxydPAuJi6Bv_iiGard1Mxfx42ZFoTl0,55
126
131
  cognite/neat/_store/_provenance.py,sha256=1zzRDWjR9twZu2jVyIG3UdYdIXtQKJ7uF8a0hV7LEuA,3368
127
- cognite/neat/_store/_store.py,sha256=3mfw5zFL2nLad57gHbriDnwd5WMy4qoUKKinK5k3xwA,9738
132
+ cognite/neat/_store/_store.py,sha256=Obx6s4vVjBhZZoUclj4On4bxW3Y8_v3fKileQLrI0VI,10630
128
133
  cognite/neat/_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
134
  cognite/neat/_utils/_reader.py,sha256=pBAwGK_UMd-mGnAP3cXXj3SrORocR3lFKxn-WaVjqsY,5367
130
135
  cognite/neat/_utils/auxiliary.py,sha256=YQMpqCxccex_slmLYrR5icVX9aeLbD793ou7IrbNTFs,1654
@@ -328,9 +333,9 @@ cognite/neat/_v0/session/_template.py,sha256=BNcvrW5y7LWzRM1XFxZkfR1Nc7e8UgjBClH
328
333
  cognite/neat/_v0/session/_to.py,sha256=AnsRSDDdfFyYwSgi0Z-904X7WdLtPfLlR0x1xsu_jAo,19447
329
334
  cognite/neat/_v0/session/_wizard.py,sha256=baPJgXAAF3d1bn4nbIzon1gWfJOeS5T43UXRDJEnD3c,1490
330
335
  cognite/neat/_v0/session/exceptions.py,sha256=jv52D-SjxGfgqaHR8vnpzo0SOJETIuwbyffSWAxSDJw,3495
331
- cognite/neat/_version.py,sha256=q5vmOs-FCuZ31umumKHe6GbNV8ckfBN8mfbY89LmFps,45
336
+ cognite/neat/_version.py,sha256=yW-UQpMiFBxk9CkqtMOupox-RheZyNu-70iZhHFcuEI,45
332
337
  cognite/neat/legacy.py,sha256=DMFeLCSBLT2enk-nm1KfX1rKR2DQDpxY-w6ThY0y9c8,421
333
338
  cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
334
- cognite_neat-1.0.31.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
335
- cognite_neat-1.0.31.dist-info/METADATA,sha256=ME2bvIHfAazZH8FezWe5bURIdXAqIvoKCTl8pHpsobA,6872
336
- cognite_neat-1.0.31.dist-info/RECORD,,
339
+ cognite_neat-1.0.32.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
340
+ cognite_neat-1.0.32.dist-info/METADATA,sha256=7ZoBFgcFA7TUMrocwakJBvfuWt1Amux3_mqWNtqEMAE,6872
341
+ cognite_neat-1.0.32.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.26
2
+ Generator: uv 0.9.27
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any