cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.30__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 (136) hide show
  1. cognite_toolkit/_cdf.py +16 -17
  2. cognite_toolkit/_cdf_tk/apps/__init__.py +2 -0
  3. cognite_toolkit/_cdf_tk/apps/_core_app.py +13 -5
  4. cognite_toolkit/_cdf_tk/apps/_data_app.py +1 -1
  5. cognite_toolkit/_cdf_tk/apps/_dev_app.py +86 -0
  6. cognite_toolkit/_cdf_tk/apps/_download_app.py +692 -24
  7. cognite_toolkit/_cdf_tk/apps/_dump_app.py +43 -101
  8. cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
  9. cognite_toolkit/_cdf_tk/apps/_migrate_app.py +249 -9
  10. cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
  11. cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
  12. cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
  13. cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
  14. cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
  15. cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
  16. cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
  17. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +23 -3
  18. cognite_toolkit/_cdf_tk/client/api/extended_functions.py +6 -9
  19. cognite_toolkit/_cdf_tk/client/api/infield.py +93 -1
  20. cognite_toolkit/_cdf_tk/client/api/migration.py +175 -1
  21. cognite_toolkit/_cdf_tk/client/api/streams.py +84 -0
  22. cognite_toolkit/_cdf_tk/client/api/three_d.py +50 -0
  23. cognite_toolkit/_cdf_tk/client/data_classes/base.py +25 -1
  24. cognite_toolkit/_cdf_tk/client/data_classes/canvas.py +46 -3
  25. cognite_toolkit/_cdf_tk/client/data_classes/charts.py +3 -3
  26. cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
  27. cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
  28. cognite_toolkit/_cdf_tk/client/data_classes/migration.py +10 -2
  29. cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
  30. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +47 -0
  31. cognite_toolkit/_cdf_tk/client/testing.py +18 -2
  32. cognite_toolkit/_cdf_tk/commands/__init__.py +6 -6
  33. cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
  34. cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
  35. cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
  36. cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
  37. cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +133 -91
  38. cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +73 -22
  39. cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +311 -43
  40. cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +5 -5
  41. cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +33 -0
  42. cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +157 -8
  43. cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
  44. cognite_toolkit/_cdf_tk/commands/_purge.py +27 -28
  45. cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
  46. cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
  47. cognite_toolkit/_cdf_tk/commands/about.py +221 -0
  48. cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
  49. cognite_toolkit/_cdf_tk/commands/build_cmd.py +15 -61
  50. cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
  51. cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
  52. cognite_toolkit/_cdf_tk/commands/dump_resource.py +6 -4
  53. cognite_toolkit/_cdf_tk/commands/init.py +225 -3
  54. cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
  55. cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
  56. cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
  57. cognite_toolkit/_cdf_tk/constants.py +20 -1
  58. cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
  59. cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
  60. cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +8 -17
  61. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
  62. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
  63. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +4 -14
  64. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +44 -43
  65. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +4 -11
  66. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
  67. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +205 -66
  68. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +5 -17
  69. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +116 -27
  70. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +6 -27
  71. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +9 -28
  72. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
  73. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +3 -7
  74. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +3 -15
  75. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +4 -12
  76. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +4 -10
  77. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
  78. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +15 -44
  79. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
  80. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
  81. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
  82. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +39 -31
  83. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
  84. cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
  85. cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
  86. cognite_toolkit/_cdf_tk/plugins.py +2 -1
  87. cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
  88. cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
  89. cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
  90. cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
  91. cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
  92. cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
  93. cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
  94. cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
  95. cognite_toolkit/_cdf_tk/storageio/_applications.py +338 -26
  96. cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
  97. cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
  98. cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
  99. cognite_toolkit/_cdf_tk/storageio/_file_content.py +436 -0
  100. cognite_toolkit/_cdf_tk/storageio/_instances.py +34 -2
  101. cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
  102. cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +62 -4
  103. cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
  104. cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
  105. cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
  106. cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
  107. cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
  108. cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
  109. cognite_toolkit/_cdf_tk/tracker.py +2 -2
  110. cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
  111. cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
  112. cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
  113. cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
  114. cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
  115. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +284 -18
  116. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +50 -4
  117. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +187 -0
  118. cognite_toolkit/_cdf_tk/utils/interactive_select.py +9 -14
  119. cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
  120. cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
  121. cognite_toolkit/_cdf_tk/validation.py +79 -1
  122. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  123. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  124. cognite_toolkit/_resources/cdf.toml +5 -4
  125. cognite_toolkit/_version.py +1 -1
  126. cognite_toolkit/config.dev.yaml +13 -0
  127. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/METADATA +24 -24
  128. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/RECORD +153 -143
  129. cognite_toolkit-0.7.30.dist-info/WHEEL +4 -0
  130. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/entry_points.txt +1 -0
  131. cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
  132. cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
  133. cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
  134. cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
  135. cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
  136. cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
@@ -0,0 +1,187 @@
1
+ import gzip
2
+ import sys
3
+ from abc import ABC, abstractmethod
4
+ from collections.abc import Hashable
5
+ from typing import Any, Literal
6
+
7
+ import httpx
8
+ from cognite.client import global_config
9
+ from pydantic import BaseModel, ConfigDict, Field, JsonValue, TypeAdapter, model_validator
10
+ from pydantic.alias_generators import to_camel
11
+
12
+ from cognite_toolkit._cdf_tk.utils.http_client._tracker import ItemsRequestTracker
13
+ from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
14
+
15
+ if sys.version_info >= (3, 11):
16
+ from typing import Self
17
+ else:
18
+ from typing_extensions import Self
19
+
20
+
21
+ class HTTPResult2(BaseModel): ...
22
+
23
+
24
+ class FailedRequest2(HTTPResult2):
25
+ error: str
26
+
27
+
28
+ class SuccessResponse2(HTTPResult2):
29
+ status_code: int
30
+ body: str
31
+ content: bytes
32
+
33
+
34
+ class ErrorDetails2(BaseModel):
35
+ """This is the expected structure of error details in the CDF API"""
36
+
37
+ code: int
38
+ message: str
39
+ missing: list[JsonValue] | None = None
40
+ duplicated: list[JsonValue] | None = None
41
+ is_auto_retryable: bool | None = None
42
+
43
+ @classmethod
44
+ def from_response(cls, response: httpx.Response) -> "ErrorDetails2":
45
+ """Populate the error details from a httpx response."""
46
+ try:
47
+ res = TypeAdapter(dict[Literal["error"], ErrorDetails2]).validate_json(response.text)
48
+ except ValueError:
49
+ return cls(code=response.status_code, message=response.text)
50
+ return res["error"]
51
+
52
+
53
+ class FailedResponse2(HTTPResult2):
54
+ status_code: int
55
+ body: str
56
+ error: ErrorDetails2
57
+
58
+
59
+ class BaseRequestMessage(BaseModel, ABC):
60
+ endpoint_url: str
61
+ method: Literal["GET", "POST", "PATCH", "DELETE", "PUT"]
62
+ connect_attempt: int = 0
63
+ read_attempt: int = 0
64
+ status_attempt: int = 0
65
+ api_version: str | None = None
66
+ content_type: str = "application/json"
67
+ accept: str = "application/json"
68
+
69
+ parameters: dict[str, PrimitiveType] | None = None
70
+
71
+ @property
72
+ def total_attempts(self) -> int:
73
+ return self.connect_attempt + self.read_attempt + self.status_attempt
74
+
75
+ @property
76
+ @abstractmethod
77
+ def content(self) -> str | bytes | None: ...
78
+
79
+
80
+ class RequestMessage2(BaseRequestMessage):
81
+ data_content: bytes | None = None
82
+ body_content: dict[str, JsonValue] | None = None
83
+
84
+ @model_validator(mode="before")
85
+ def check_data_or_body(cls, values: dict[str, Any]) -> dict[str, Any]:
86
+ if values.get("data_content") is not None and values.get("body_content") is not None:
87
+ raise ValueError("Only one of data_content or body_content can be set.")
88
+ return values
89
+
90
+ @property
91
+ def content(self) -> str | bytes | None:
92
+ data: str | bytes | None = None
93
+ if self.data_content is not None:
94
+ data = self.data_content
95
+ if not global_config.disable_gzip:
96
+ data = gzip.compress(data)
97
+ elif self.body_content is not None:
98
+ # We serialize using pydantic instead of json.dumps. This is because pydantic is faster
99
+ # and handles more complex types such as datetime, float('nan'), etc.
100
+ data = _BODY_SERIALIZER.dump_json(self.body_content)
101
+ if not global_config.disable_gzip and isinstance(data, str):
102
+ data = gzip.compress(data.encode("utf-8"))
103
+ return data
104
+
105
+
106
+ _BODY_SERIALIZER = TypeAdapter(dict[str, JsonValue])
107
+
108
+
109
+ class ItemsResultMessage2(BaseModel):
110
+ ids: list[Hashable]
111
+
112
+
113
+ class ItemsFailedRequest2(ItemsResultMessage2):
114
+ error_message: str
115
+
116
+
117
+ class ItemsSuccessResponse2(ItemsResultMessage2):
118
+ status_code: int
119
+ body: str
120
+ content: bytes
121
+
122
+
123
+ class ItemsFailedResponse2(ItemsResultMessage2):
124
+ status_code: int
125
+ error: ErrorDetails2
126
+ body: str
127
+
128
+
129
+ class BaseModelObject(BaseModel):
130
+ """Base class for all object. This includes resources and nested objects."""
131
+
132
+ # We allow extra fields to support forward compatibility.
133
+ model_config = ConfigDict(alias_generator=to_camel, extra="allow")
134
+
135
+ def dump(self, camel_case: bool = True) -> dict[str, Any]:
136
+ """Dump the resource to a dictionary.
137
+
138
+ This is the default serialization method for request resources.
139
+ """
140
+ return self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True)
141
+
142
+ @classmethod
143
+ def _load(cls, resource: dict[str, Any]) -> "Self":
144
+ """Load method to match CogniteResource signature."""
145
+ return cls.model_validate(resource)
146
+
147
+
148
+ class RequestResource(BaseModelObject, ABC):
149
+ @abstractmethod
150
+ def as_id(self) -> Hashable: ...
151
+
152
+
153
+ def _set_default_tracker(data: dict[str, Any]) -> ItemsRequestTracker:
154
+ if "tracker" not in data or data["tracker"] is None:
155
+ return ItemsRequestTracker(data.get("max_failures_before_abort", 50))
156
+ return data["tracker"]
157
+
158
+
159
+ class ItemsRequest2(BaseRequestMessage):
160
+ model_config = ConfigDict(arbitrary_types_allowed=True)
161
+ items: list[RequestResource]
162
+ extra_body_fields: dict[str, JsonValue] | None = None
163
+ max_failures_before_abort: int = 50
164
+ tracker: ItemsRequestTracker = Field(init=False, default_factory=_set_default_tracker, exclude=True)
165
+
166
+ @property
167
+ def content(self) -> str | bytes | None:
168
+ body: dict[str, JsonValue] = {"items": [item.dump() for item in self.items]}
169
+ if self.extra_body_fields:
170
+ body.update(self.extra_body_fields)
171
+ res = _BODY_SERIALIZER.dump_json(body)
172
+ if not global_config.disable_gzip and isinstance(res, str):
173
+ return gzip.compress(res.encode("utf-8"))
174
+ return res
175
+
176
+ def split(self, status_attempts: int) -> list["ItemsRequest2"]:
177
+ """Split the request into multiple requests with a single item each."""
178
+ mid = len(self.items) // 2
179
+ if mid == 0:
180
+ return [self]
181
+ self.tracker.register_failure()
182
+ messages: list[ItemsRequest2] = []
183
+ for part in (self.items[:mid], self.items[mid:]):
184
+ new_request = self.model_copy(update={"items": part, "status_attempt": status_attempts})
185
+ new_request.tracker = self.tracker
186
+ messages.append(new_request)
187
+ return messages
@@ -14,9 +14,6 @@ from cognite.client.data_classes import (
14
14
  filters,
15
15
  )
16
16
  from cognite.client.data_classes.aggregations import Count
17
- from cognite.client.data_classes.capabilities import (
18
- UserProfilesAcl,
19
- )
20
17
  from cognite.client.data_classes.data_modeling import ContainerId, NodeList, Space, SpaceList, View, ViewId, ViewList
21
18
  from cognite.client.data_classes.data_modeling.statistics import SpaceStatistics
22
19
  from cognite.client.utils import ms_to_datetime
@@ -28,7 +25,7 @@ from cognite_toolkit._cdf_tk.client.data_classes.canvas import Canvas
28
25
  from cognite_toolkit._cdf_tk.client.data_classes.charts import Chart, ChartList, Visibility
29
26
  from cognite_toolkit._cdf_tk.client.data_classes.migration import ResourceViewMapping
30
27
  from cognite_toolkit._cdf_tk.client.data_classes.raw import RawTable
31
- from cognite_toolkit._cdf_tk.exceptions import AuthorizationError, ToolkitMissingResourceError, ToolkitValueError
28
+ from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitValueError
32
29
 
33
30
  from . import humanize_collection
34
31
  from .aggregators import (
@@ -309,9 +306,14 @@ class InteractiveCanvasSelect:
309
306
  opening_choices: ClassVar[list[questionary.Choice]] = [
310
307
  questionary.Choice(title="All public Canvases", value=CanvasFilter(visibility="public", select_all=True)),
311
308
  questionary.Choice(title="Selected public Canvases", value=CanvasFilter(visibility="public", select_all=False)),
312
- questionary.Choice(title="All by given user", value=CanvasFilter(created_by="user", select_all=True)),
313
- questionary.Choice(title="Selected by given user", value=CanvasFilter(created_by="user", select_all=False)),
314
- questionary.Choice(title="All Canvases", value=CanvasFilter(visibility=None, select_all=True)),
309
+ questionary.Choice(
310
+ title="All public Canvases by given user",
311
+ value=CanvasFilter(created_by="user", select_all=True, visibility="public"),
312
+ ),
313
+ questionary.Choice(
314
+ title="Selected public Canvases by given user",
315
+ value=CanvasFilter(created_by="user", select_all=False, visibility="public"),
316
+ ),
315
317
  ]
316
318
 
317
319
  def __init__(self, client: ToolkitClient) -> None:
@@ -406,13 +408,6 @@ class InteractiveChartSelect:
406
408
  return user_response
407
409
 
408
410
  def _select_external_ids(self, select_filter: ChartFilter) -> list[str]:
409
- if not self.client.iam.verify_capabilities(
410
- UserProfilesAcl([UserProfilesAcl.Action.Read], scope=UserProfilesAcl.Scope.All())
411
- ):
412
- raise AuthorizationError(
413
- "The current user does not have permission to list user profiles, "
414
- "which is required to select Charts owned by a specific user."
415
- )
416
411
  available_charts = self.client.charts.list(visibility=(select_filter.visibility or "PUBLIC"))
417
412
  if select_filter.select_all and select_filter.owned_by is None:
418
413
  return [chart.external_id for chart in available_charts]
@@ -1,12 +1,11 @@
1
1
  import importlib.util
2
+ from dataclasses import dataclass
2
3
  from typing import TYPE_CHECKING
3
4
 
4
5
  from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingDependencyError
5
6
 
6
7
  if TYPE_CHECKING:
7
- from sqlparse.sql import Identifier
8
- from sqlparse.tokens import Token
9
- from dataclasses import dataclass
8
+ from sqlparse.sql import Identifier, Token
10
9
 
11
10
 
12
11
  @dataclass(frozen=True)
@@ -8,10 +8,13 @@ from cognite.client.data_classes._base import CogniteObject, WriteableCogniteRes
8
8
  JsonVal: TypeAlias = None | str | int | float | bool | dict[str, "JsonVal"] | list["JsonVal"]
9
9
 
10
10
  AssetCentricDestinationType: TypeAlias = Literal["assets", "files", "events", "timeseries", "sequences"]
11
- AssetCentricType: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence", "fileAnnotation"]
11
+ AssetCentricType: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence"]
12
+ AssetCentricTypeExtended: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence", "annotation"]
12
13
  AssetCentricResource: TypeAlias = Asset | FileMetadata | Event | TimeSeries
13
14
  AssetCentricResourceExtended: TypeAlias = Asset | FileMetadata | Event | TimeSeries | Annotation
14
- AssetCentricKind: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata", "FileAnnotations"]
15
+ AssetCentricKind: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata"]
16
+ AssetCentricKindExtended: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata", "Annotations"]
17
+
15
18
 
16
19
  DataType: TypeAlias = Literal["string", "integer", "float", "boolean", "json", "date", "timestamp", "epoch"]
17
20
  PythonTypes: TypeAlias = str | int | float | bool | datetime | date | dict[str, Any] | list[Any]
@@ -25,3 +28,4 @@ PrimitiveType: TypeAlias = str | int | float | bool
25
28
 
26
29
  T_WriteCogniteResource = TypeVar("T_WriteCogniteResource", bound=CogniteObject)
27
30
  T_AssetCentricResource = TypeVar("T_AssetCentricResource", bound=AssetCentricResource)
31
+ T_AssetCentricResourceExtended = TypeVar("T_AssetCentricResourceExtended", bound=AssetCentricResourceExtended)
@@ -8,18 +8,29 @@ from cognite.client.utils._text import to_snake_case
8
8
  from pydantic import BaseModel, TypeAdapter, ValidationError
9
9
  from pydantic_core import ErrorDetails
10
10
 
11
- from cognite_toolkit._cdf_tk.data_classes import BuildVariables
11
+ from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
12
+ from cognite_toolkit._cdf_tk.constants import DEV_ONLY_MODULES
13
+ from cognite_toolkit._cdf_tk.data_classes import BuildConfigYAML, BuildVariables, ModuleDirectories
14
+ from cognite_toolkit._cdf_tk.exceptions import (
15
+ ToolkitDuplicatedModuleError,
16
+ ToolkitEnvError,
17
+ ToolkitMissingModuleError,
18
+ )
19
+ from cognite_toolkit._cdf_tk.hints import ModuleDefinition
12
20
  from cognite_toolkit._cdf_tk.resource_classes import BaseModelResource
13
21
  from cognite_toolkit._cdf_tk.tk_warnings import (
14
22
  DataSetMissingWarning,
23
+ MediumSeverityWarning,
15
24
  TemplateVariableWarning,
16
25
  WarningList,
17
26
  )
18
27
  from cognite_toolkit._cdf_tk.tk_warnings.fileread import ResourceFormatWarning
28
+ from cognite_toolkit._cdf_tk.utils import humanize_collection
19
29
 
20
30
  __all__ = [
21
31
  "humanize_validation_error",
22
32
  "validate_data_set_is_set",
33
+ "validate_module_selection",
23
34
  "validate_modules_variables",
24
35
  ]
25
36
 
@@ -210,3 +221,70 @@ def as_json_path(loc: tuple[str | int, ...]) -> str:
210
221
 
211
222
  suffix = ".".join([str(x) if isinstance(x, str) else f"[{x + 1}]" for x in loc]).replace(".[", "[")
212
223
  return f"{prefix}{suffix}"
224
+
225
+
226
+ def validate_module_selection(
227
+ modules: ModuleDirectories,
228
+ config: BuildConfigYAML,
229
+ packages: dict[str, list[str]],
230
+ selected_modules: set[str | Path],
231
+ organization_dir: Path,
232
+ ) -> WarningList:
233
+ """Validates module selection and returns warnings for non-critical issues.
234
+
235
+ Critical errors (duplicate modules, missing modules, no modules selected) are still raised
236
+ as exceptions as they prevent the build from proceeding.
237
+ """
238
+ warnings: WarningList = WarningList()
239
+
240
+ # Validations: Ambiguous selection.
241
+ selected_names = {s for s in config.environment.selected if isinstance(s, str)}
242
+ if duplicate_modules := {
243
+ module_name: paths
244
+ for module_name, paths in modules.as_path_by_name().items()
245
+ if len(paths) > 1 and module_name in selected_names
246
+ }:
247
+ # If the user has selected a module by name, and there are multiple modules with that name, raise an error.
248
+ # Note, if the user uses a path to select a module, this error will not be raised.
249
+ raise ToolkitDuplicatedModuleError(
250
+ f"Ambiguous module selected in config.{config.environment.name}.yaml:", duplicate_modules
251
+ )
252
+
253
+ # Package Referenced Modules Exists
254
+ for package, package_modules in packages.items():
255
+ if package not in selected_names:
256
+ # We do not check packages that are not selected.
257
+ # Typically, the user will delete the modules that are irrelevant for them;
258
+ # thus we only check the selected packages.
259
+ continue
260
+ if missing_packages := set(package_modules) - modules.available_names:
261
+ raise ToolkitMissingModuleError(
262
+ f"Package {package} defined in {CDFToml.file_name!s} is referring "
263
+ f"the following missing modules {missing_packages}."
264
+ )
265
+
266
+ # Selected modules does not exists
267
+ if missing_modules := set(selected_modules) - modules.available:
268
+ hint = ModuleDefinition.long(missing_modules, organization_dir)
269
+ raise ToolkitMissingModuleError(
270
+ f"The following selected modules are missing, please check path: {missing_modules}.\n{hint}"
271
+ )
272
+
273
+ # Nothing is Selected
274
+ if not modules.selected:
275
+ raise ToolkitEnvError(
276
+ f"No selected modules specified in {config.filepath!s}, have you configured "
277
+ f"the environment ({config.environment.name})?"
278
+ )
279
+
280
+ # Dev modules warning (non-critical)
281
+ dev_modules = modules.available_names & DEV_ONLY_MODULES
282
+ if dev_modules and config.environment.validation_type != "dev":
283
+ warnings.append(
284
+ MediumSeverityWarning(
285
+ "The following modules should [bold]only[/bold] be used a in CDF Projects designated as dev (development): "
286
+ f"{humanize_collection(dev_modules)!r}",
287
+ )
288
+ )
289
+
290
+ return warnings
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.6.97
15
+ image: cognite/toolkit:0.7.30
16
16
  env:
17
17
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
18
18
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -10,7 +10,7 @@ jobs:
10
10
  environment: dev
11
11
  name: Deploy Dry Run
12
12
  container:
13
- image: cognite/toolkit:0.6.97
13
+ image: cognite/toolkit:0.7.30
14
14
  env:
15
15
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
16
16
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -4,13 +4,14 @@ default_env = "<DEFAULT_ENV_PLACEHOLDER>"
4
4
  [modules]
5
5
  # This is the version of the modules. It should not be changed manually.
6
6
  # It will be updated by the 'cdf modules upgrade' command.
7
- version = "0.6.97"
7
+ version = "0.7.30"
8
8
 
9
- [alpha_flags]
10
- external-libraries = true
11
9
 
12
10
  [plugins]
13
- run = true
11
+ dump = false
12
+ dev = false
13
+ data = false
14
+
14
15
 
15
16
  [library.toolkit-data]
16
17
  url = "https://github.com/cognitedata/toolkit-data/releases/download/latest/packages.zip"
@@ -1 +1 @@
1
- __version__ = "0.6.97"
1
+ __version__ = "0.7.30"
@@ -0,0 +1,13 @@
1
+ environment:
2
+ name: dev
3
+ project: infield-experimental-test-aws
4
+ validation-type: dev
5
+ selected:
6
+ - modules/eriks-location
7
+
8
+ variables:
9
+ modules:
10
+ eriks-location:
11
+ - location: erik-infield-cdm2
12
+ location_name: Oslo CDM - Erik tookit
13
+ location_description: Used to test toolkit ingestion for InField cdm
@@ -1,38 +1,38 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.6.97
3
+ Version: 0.7.30
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
- Project-URL: Homepage, https://docs.cognite.com/cdf/deploy/cdf_toolkit/
6
- Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
7
- Project-URL: GitHub, https://github.com/cognitedata/toolkit
8
- Project-URL: Documentation, https://docs.cognite.com/cdf/deploy/cdf_toolkit/references/resource_library
5
+ Author: Cognite AS
9
6
  Author-email: Cognite AS <support@cognite.com>
10
7
  License-Expression: Apache-2.0
11
- License-File: LICENSE
12
- Requires-Python: >=3.10
13
- Requires-Dist: cognite-sdk<8.0.0,>=7.83.0
14
- Requires-Dist: filelock>=3.18.0
15
- Requires-Dist: httpx>=0.28.1
16
- Requires-Dist: mixpanel>=4.10.1
17
- Requires-Dist: packaging>=25
18
- Requires-Dist: pandas<3.0.0,>=1.5.3
19
- Requires-Dist: pip>=25.0.1
20
- Requires-Dist: pydantic>=2.11.0
21
- Requires-Dist: python-dateutil>=2.9.0
22
8
  Requires-Dist: python-dotenv>=1.0.0
9
+ Requires-Dist: cognite-sdk>=7.87.0,<8.0.0
10
+ Requires-Dist: httpx>=0.28.1
11
+ Requires-Dist: pandas>=1.5.3,<3.0.0
23
12
  Requires-Dist: pyyaml>=6.0.1
24
- Requires-Dist: questionary>=2.0.1
13
+ Requires-Dist: typer>=0.12.0,<1.0.0
25
14
  Requires-Dist: rich>=13.9.4
26
- Requires-Dist: sentry-sdk>=2.1.0
27
- Requires-Dist: toml>=0.10.2
28
- Requires-Dist: tomli<3.0.0,>=2.0.1; python_version < '3.11'
29
- Requires-Dist: typer<1.0.0,>=0.12.0
15
+ Requires-Dist: questionary>=2.0.1
16
+ Requires-Dist: tomli>=2.0.1,<3.0.0 ; python_full_version < '3.11'
17
+ Requires-Dist: packaging>=25
30
18
  Requires-Dist: typing-extensions>=4.0.0
19
+ Requires-Dist: toml>=0.10.2
20
+ Requires-Dist: sentry-sdk>=2.1.0
21
+ Requires-Dist: mixpanel>=4.10.1
22
+ Requires-Dist: pydantic>=2.11.0
23
+ Requires-Dist: python-dateutil>=2.9.0
24
+ Requires-Dist: pip>=25.0.1
25
+ Requires-Dist: filelock>=3.18.0
26
+ Requires-Dist: sqlparse>=0.5.3 ; extra == 'sql'
27
+ Requires-Dist: pyarrow>=20.0.0 ; extra == 'table'
28
+ Requires-Dist: openpyxl>=3.1.5 ; extra == 'table'
29
+ Requires-Python: >=3.10
30
+ Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
31
+ Project-URL: Documentation, https://docs.cognite.com/cdf/deploy/cdf_toolkit/references/resource_library
32
+ Project-URL: GitHub, https://github.com/cognitedata/toolkit
33
+ Project-URL: Homepage, https://docs.cognite.com/cdf/deploy/cdf_toolkit/
31
34
  Provides-Extra: sql
32
- Requires-Dist: sqlparse>=0.5.3; extra == 'sql'
33
35
  Provides-Extra: table
34
- Requires-Dist: openpyxl>=3.1.5; extra == 'table'
35
- Requires-Dist: pyarrow>=20.0.0; extra == 'table'
36
36
  Description-Content-Type: text/markdown
37
37
 
38
38
  # Cognite Data Fusion Toolkit