cognite-toolkit 0.5.60__py3-none-any.whl → 0.5.62__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.
@@ -4,7 +4,7 @@ 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.5.60"
7
+ version = "0.5.62"
8
8
 
9
9
 
10
10
  [plugins]
@@ -62,14 +62,14 @@ class ModulesApp(typer.Typer):
62
62
  ) -> None:
63
63
  """Initialize or upgrade a new CDF project with templates interactively."""
64
64
 
65
- cmd = ModulesCommand()
66
- cmd.run(
67
- lambda: cmd.init(
68
- organization_dir=organization_dir,
69
- select_all=all,
70
- clean=clean,
65
+ with ModulesCommand() as cmd:
66
+ cmd.run(
67
+ lambda: cmd.init(
68
+ organization_dir=organization_dir,
69
+ select_all=all,
70
+ clean=clean,
71
+ )
71
72
  )
72
- )
73
73
 
74
74
  def upgrade(
75
75
  self,
@@ -116,8 +116,8 @@ class ModulesApp(typer.Typer):
116
116
  ] = False,
117
117
  ) -> None:
118
118
  """Add one or more new module(s) to the project."""
119
- cmd = ModulesCommand()
120
- cmd.run(lambda: cmd.add(organization_dir=organization_dir))
119
+ with ModulesCommand() as cmd:
120
+ cmd.run(lambda: cmd.add(organization_dir=organization_dir))
121
121
 
122
122
  def pull(
123
123
  self,
@@ -3,7 +3,7 @@ from typing import Any
3
3
  import typer
4
4
  from rich import print
5
5
 
6
- from cognite_toolkit._cdf_tk.commands import ProfileCommand
6
+ from cognite_toolkit._cdf_tk.commands import ProfileAssetCentricCommand
7
7
  from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
8
8
 
9
9
 
@@ -27,7 +27,7 @@ class ProfileApp(typer.Typer):
27
27
  This shows an approximation of unstructured data count. This can, for example, be used to estimate the
28
28
  effort to model this data in data modeling."""
29
29
  client = EnvironmentVariables.create_from_environment().get_client()
30
- cmd = ProfileCommand()
30
+ cmd = ProfileAssetCentricCommand()
31
31
  cmd.run(
32
32
  lambda: cmd.asset_centric(
33
33
  client,
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
  import sys
5
+ import urllib
5
6
  from contextlib import suppress
6
7
  from dataclasses import dataclass, field
7
8
  from pathlib import Path
@@ -64,12 +65,39 @@ class ModulesConfig:
64
65
  ):
65
66
  raise ToolkitVersionError(
66
67
  f"The version of the modules ({version}) does not match the version of the installed CLI "
67
- f"({_version.__version__}). Please either run `cdf-tk modules upgrade` to upgrade the modules OR "
68
- f"run `pip install cognite-toolkit=={version}` to downgrade cdf-tk CLI."
68
+ f"({_version.__version__}). Please run `cdf modules upgrade` to upgrade the modules OR "
69
+ f"run `pip install cognite-toolkit=={version}` to downgrade cdf CLI."
69
70
  )
70
71
  return cls(version=version, packages=packages)
71
72
 
72
73
 
74
+ @dataclass
75
+ class Library:
76
+ url: str
77
+ checksum: str
78
+
79
+ @classmethod
80
+ def load(cls, raw: dict[str, Any]) -> Library:
81
+ if "url" not in raw:
82
+ raise ValueError("Library configuration must contain 'url' field.")
83
+
84
+ if "checksum" not in raw:
85
+ raise ValueError("Library configuration must contain 'checksum' field.")
86
+
87
+ parsed_url = urllib.parse.urlparse(raw["url"])
88
+
89
+ if not all([parsed_url.scheme, parsed_url.netloc]):
90
+ raise ValueError("URL is missing scheme or network location (e.g., 'https://domain.com')")
91
+
92
+ if parsed_url.scheme != "https":
93
+ raise ValueError("URL must start with 'https'")
94
+
95
+ if not parsed_url.path.casefold().endswith(".zip"):
96
+ raise ValueError("URL must point to a .zip file.")
97
+
98
+ return cls(**raw)
99
+
100
+
73
101
  @dataclass
74
102
  class CDFToml:
75
103
  """This is the configuration for the CLI and Modules"""
@@ -80,6 +108,7 @@ class CDFToml:
80
108
  modules: ModulesConfig
81
109
  alpha_flags: dict[str, bool] = field(default_factory=dict)
82
110
  plugins: dict[str, bool] = field(default_factory=dict)
111
+ libraries: dict[str, Library] = field(default_factory=dict)
83
112
 
84
113
  is_loaded_from_file: bool = False
85
114
 
@@ -114,7 +143,21 @@ class CDFToml:
114
143
  if "plugins" in raw:
115
144
  plugins = {clean_name(k): v for k, v in raw["plugins"].items()}
116
145
 
117
- instance = cls(cdf=cdf, modules=modules, alpha_flags=alpha_flags, plugins=plugins, is_loaded_from_file=True)
146
+ libraries = {}
147
+ for k, v in raw.get("library", {}).items():
148
+ try:
149
+ libraries[k] = Library.load(v)
150
+ except Exception as e:
151
+ raise ToolkitTOMLFormatError(f"Invalid library configuration for '{k}': {e.args[0]}") from e
152
+
153
+ instance = cls(
154
+ cdf=cdf,
155
+ modules=modules,
156
+ alpha_flags=alpha_flags,
157
+ plugins=plugins,
158
+ libraries=libraries,
159
+ is_loaded_from_file=True,
160
+ )
118
161
  if use_singleton:
119
162
  _CDF_TOML = instance
120
163
  return instance
@@ -0,0 +1,395 @@
1
+ from datetime import datetime
2
+
3
+ from cognite.client.data_classes.data_modeling import DirectRelationReference
4
+ from cognite.client.data_classes.data_modeling.ids import ViewId
5
+ from cognite.client.data_classes.data_modeling.instances import (
6
+ PropertyOptions,
7
+ TypedNode,
8
+ TypedNodeApply,
9
+ )
10
+
11
+
12
+ class _CanvasProperties:
13
+ created_by = PropertyOptions("createdBy")
14
+ updated_at = PropertyOptions("updatedAt")
15
+ updated_by = PropertyOptions("updatedBy")
16
+ is_locked = PropertyOptions("isLocked")
17
+ source_canvas_id = PropertyOptions("sourceCanvasId")
18
+ is_archived = PropertyOptions("isArchived")
19
+ solution_tags = PropertyOptions("solutionTags")
20
+
21
+ @classmethod
22
+ def get_source(cls) -> ViewId:
23
+ return ViewId("cdf_industrial_canvas", "Canvas", "v7")
24
+
25
+
26
+ class CanvasApply(_CanvasProperties, TypedNodeApply):
27
+ """This represents the writing format of canvas.
28
+
29
+ It is used to when data is written to CDF.
30
+
31
+ Args:
32
+ space: The space where the node is located.
33
+ external_id: The external id of the canva.
34
+ name: The name or title of the canvas.
35
+ created_by: The user identifier of the user that created the canvas.
36
+ updated_at: The timestamp when the canvas was last updated.
37
+ updated_by: The user identifier of the user that last updated the canvas.
38
+ is_locked: The boolean state for handling canvas locking which is one-way operation from the user perspective
39
+ visibility: The application-level visibility of the canvas. Must be either 'public' or 'private' and, if not
40
+ set, the canvas is expected to be public.
41
+ source_canvas_id: The property for handling versioning. Example sourceCanvasId === selectedCanvas -> query all
42
+ versions of such canvas
43
+ is_archived: Boolean that indicates whether the canvas is archived.
44
+ context: Stores contextual data attached to the canvas, such as rules and pinned values.
45
+ solution_tags: The list of solution tags associated with the canvas.
46
+ existing_version: Fail the ingestion request if the node's version is greater than or equal to this value.
47
+ If no existingVersion is specified, the ingestion will always overwrite any existing data for the node
48
+ (for the specified container or node). If existingVersion is set to 0, the upsert will behave as an insert,
49
+ so it will fail the bulk if the item already exists. If skipOnVersionConflict is set on the ingestion
50
+ request, then the item will be skipped instead of failing the ingestion request.
51
+ type: Direct relation pointing to the type node.
52
+ """
53
+
54
+ def __init__(
55
+ self,
56
+ space: str,
57
+ external_id: str,
58
+ *,
59
+ name: str,
60
+ created_by: str,
61
+ updated_at: datetime,
62
+ updated_by: str,
63
+ is_locked: bool | None = None,
64
+ visibility: str | None = None,
65
+ source_canvas_id: str | None = None,
66
+ is_archived: bool | None = None,
67
+ context: list[dict] | None = None,
68
+ solution_tags: list[DirectRelationReference | tuple[str, str]] | None = None,
69
+ existing_version: int | None = None,
70
+ type: DirectRelationReference | tuple[str, str] | None = None,
71
+ ) -> None:
72
+ TypedNodeApply.__init__(self, space, external_id, existing_version, type)
73
+ self.name = name
74
+ self.created_by = created_by
75
+ self.updated_at = updated_at
76
+ self.updated_by = updated_by
77
+ self.is_locked = is_locked
78
+ self.visibility = visibility
79
+ self.source_canvas_id = source_canvas_id
80
+ self.is_archived = is_archived
81
+ self.context = context
82
+ self.solution_tags = (
83
+ [DirectRelationReference.load(solution_tag) for solution_tag in solution_tags] if solution_tags else None
84
+ )
85
+
86
+
87
+ class Canvas(_CanvasProperties, TypedNode):
88
+ """This represents the reading format of canva.
89
+
90
+ It is used to when data is read from CDF.
91
+
92
+ Args:
93
+ space: The space where the node is located.
94
+ external_id: The external id of the canva.
95
+ version (int): DMS version.
96
+ last_updated_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
97
+ Coordinated Universal Time (UTC), minus leap seconds.
98
+ created_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
99
+ Coordinated Universal Time (UTC), minus leap seconds.
100
+ name: The name or title of the canvas.
101
+ created_by: The user identifier of the user that created the canvas.
102
+ updated_at: The timestamp when the canvas was last updated.
103
+ updated_by: The user identifier of the user that last updated the canvas.
104
+ is_locked: The boolean state for handling canvas locking which is one-way operation from the user perspective
105
+ visibility: The application-level visibility of the canvas. Must be either 'public' or 'private' and, if not
106
+ set, the canvas is expected to be public.
107
+ source_canvas_id: The property for handling versioning. Example sourceCanvasId === selectedCanvas -> query all
108
+ versions of such canvas
109
+ is_archived: Boolean that indicates whether the canvas is archived.
110
+ context: Stores contextual data attached to the canvas, such as rules and pinned values.
111
+ solution_tags: The list of solution tags associated with the canvas.
112
+ type: Direct relation pointing to the type node.
113
+ deleted_time: The number of milliseconds since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time
114
+ (UTC), minus leap seconds. Timestamp when the instance was soft deleted. Note that deleted instances
115
+ are filtered out of query results, but present in sync results
116
+ """
117
+
118
+ def __init__(
119
+ self,
120
+ space: str,
121
+ external_id: str,
122
+ version: int,
123
+ last_updated_time: int,
124
+ created_time: int,
125
+ *,
126
+ name: str,
127
+ created_by: str,
128
+ updated_at: datetime,
129
+ updated_by: str,
130
+ is_locked: bool | None = None,
131
+ visibility: str | None = None,
132
+ source_canvas_id: str | None = None,
133
+ is_archived: bool | None = None,
134
+ context: list[dict] | None = None,
135
+ solution_tags: list[DirectRelationReference] | None = None,
136
+ type: DirectRelationReference | None = None,
137
+ deleted_time: int | None = None,
138
+ ) -> None:
139
+ TypedNode.__init__(self, space, external_id, version, last_updated_time, created_time, deleted_time, type)
140
+ self.name = name
141
+ self.created_by = created_by
142
+ self.updated_at = updated_at
143
+ self.updated_by = updated_by
144
+ self.is_locked = is_locked
145
+ self.visibility = visibility
146
+ self.source_canvas_id = source_canvas_id
147
+ self.is_archived = is_archived
148
+ self.context = context
149
+ self.solution_tags = (
150
+ [DirectRelationReference.load(solution_tag) for solution_tag in solution_tags] if solution_tags else None
151
+ )
152
+
153
+ def as_write(self) -> CanvasApply:
154
+ return CanvasApply(
155
+ self.space,
156
+ self.external_id,
157
+ name=self.name,
158
+ created_by=self.created_by,
159
+ updated_at=self.updated_at,
160
+ updated_by=self.updated_by,
161
+ is_locked=self.is_locked,
162
+ visibility=self.visibility,
163
+ source_canvas_id=self.source_canvas_id,
164
+ is_archived=self.is_archived,
165
+ context=self.context,
166
+ solution_tags=self.solution_tags, # type: ignore[arg-type]
167
+ existing_version=self.version,
168
+ type=self.type,
169
+ )
170
+
171
+
172
+ class _CanvasAnnotationProperties:
173
+ id_ = PropertyOptions("id")
174
+ annotation_type = PropertyOptions("annotationType")
175
+ container_id = PropertyOptions("containerId")
176
+ is_selectable = PropertyOptions("isSelectable")
177
+ is_draggable = PropertyOptions("isDraggable")
178
+ is_resizable = PropertyOptions("isResizable")
179
+ properties_ = PropertyOptions("properties")
180
+
181
+ @classmethod
182
+ def get_source(cls) -> ViewId:
183
+ return ViewId("cdf_industrial_canvas", "CanvasAnnotation", "v1")
184
+
185
+
186
+ class CanvasAnnotationApply(_CanvasAnnotationProperties, TypedNodeApply):
187
+ """This represents the writing format of canvas annotation.
188
+
189
+ It is used to when data is written to CDF.
190
+
191
+ Args:
192
+ space: The space where the node is located.
193
+ external_id: The external id of the canvas annotation.
194
+ id_: The unique identifier of the canvas annotation.
195
+ annotation_type: The type of the annotation. Must be one of rectangle, ellipse, polyline, text or sticky.
196
+ container_id: The optional ID of the container that the annotation is contained in.
197
+ is_selectable: Boolean that indicates whether the annotation is selectable.
198
+ is_draggable: Boolean that indicates whether the annotation is draggable.
199
+ is_resizable: Boolean that indicates whether the annotation is resizable.
200
+ properties_: Additional properties or configuration for the annotation.
201
+ existing_version: Fail the ingestion request if the node's version is greater than or equal to this value.
202
+ If no existingVersion is specified, the ingestion will always overwrite any existing data for the node
203
+ (for the specified container or node). If existingVersion is set to 0, the upsert will behave as an insert,
204
+ so it will fail the bulk if the item already exists. If skipOnVersionConflict is set on the ingestion
205
+ request, then the item will be skipped instead of failing the ingestion request.
206
+ type: Direct relation pointing to the type node.
207
+ """
208
+
209
+ def __init__(
210
+ self,
211
+ space: str,
212
+ external_id: str,
213
+ *,
214
+ id_: str,
215
+ annotation_type: str,
216
+ container_id: str | None = None,
217
+ is_selectable: bool | None = None,
218
+ is_draggable: bool | None = None,
219
+ is_resizable: bool | None = None,
220
+ properties_: dict | None = None,
221
+ existing_version: int | None = None,
222
+ type: DirectRelationReference | tuple[str, str] | None = None,
223
+ ) -> None:
224
+ TypedNodeApply.__init__(self, space, external_id, existing_version, type)
225
+ self.id_ = id_
226
+ self.annotation_type = annotation_type
227
+ self.container_id = container_id
228
+ self.is_selectable = is_selectable
229
+ self.is_draggable = is_draggable
230
+ self.is_resizable = is_resizable
231
+ self.properties_ = properties_
232
+
233
+
234
+ class CanvasAnnotation(_CanvasAnnotationProperties, TypedNode):
235
+ """This represents the reading format of canvas annotation.
236
+
237
+ It is used to when data is read from CDF.
238
+
239
+ Args:
240
+ space: The space where the node is located.
241
+ external_id: The external id of the canvas annotation.
242
+ version (int): DMS version.
243
+ last_updated_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
244
+ Coordinated Universal Time (UTC), minus leap seconds.
245
+ created_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
246
+ Coordinated Universal Time (UTC), minus leap seconds.
247
+ id_: The unique identifier of the canvas annotation.
248
+ annotation_type: The type of the annotation. Must be one of rectangle, ellipse, polyline, text or sticky.
249
+ container_id: The optional ID of the container that the annotation is contained in.
250
+ is_selectable: Boolean that indicates whether the annotation is selectable.
251
+ is_draggable: Boolean that indicates whether the annotation is draggable.
252
+ is_resizable: Boolean that indicates whether the annotation is resizable.
253
+ properties_: Additional properties or configuration for the annotation.
254
+ type: Direct relation pointing to the type node.
255
+ deleted_time: The number of milliseconds since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time
256
+ (UTC), minus leap seconds. Timestamp when the instance was soft deleted. Note that deleted instances
257
+ are filtered out of query results, but present in sync results
258
+ """
259
+
260
+ def __init__(
261
+ self,
262
+ space: str,
263
+ external_id: str,
264
+ version: int,
265
+ last_updated_time: int,
266
+ created_time: int,
267
+ *,
268
+ id_: str,
269
+ annotation_type: str,
270
+ container_id: str | None = None,
271
+ is_selectable: bool | None = None,
272
+ is_draggable: bool | None = None,
273
+ is_resizable: bool | None = None,
274
+ properties_: dict | None = None,
275
+ type: DirectRelationReference | None = None,
276
+ deleted_time: int | None = None,
277
+ ) -> None:
278
+ TypedNode.__init__(self, space, external_id, version, last_updated_time, created_time, deleted_time, type)
279
+ self.id_ = id_
280
+ self.annotation_type = annotation_type
281
+ self.container_id = container_id
282
+ self.is_selectable = is_selectable
283
+ self.is_draggable = is_draggable
284
+ self.is_resizable = is_resizable
285
+ self.properties_ = properties_
286
+
287
+ def as_write(self) -> CanvasAnnotationApply:
288
+ return CanvasAnnotationApply(
289
+ self.space,
290
+ self.external_id,
291
+ id_=self.id_,
292
+ annotation_type=self.annotation_type,
293
+ container_id=self.container_id,
294
+ is_selectable=self.is_selectable,
295
+ is_draggable=self.is_draggable,
296
+ is_resizable=self.is_resizable,
297
+ properties_=self.properties_,
298
+ existing_version=self.version,
299
+ type=self.type,
300
+ )
301
+
302
+
303
+ class _CogniteSolutionTagProperties:
304
+ @classmethod
305
+ def get_source(cls) -> ViewId:
306
+ return ViewId("cdf_apps_shared", "CogniteSolutionTag", "v1")
307
+
308
+
309
+ class CogniteSolutionTagApply(_CogniteSolutionTagProperties, TypedNodeApply):
310
+ """This represents the writing format of Cognite solution tag.
311
+
312
+ It is used to when data is written to CDF.
313
+
314
+ Args:
315
+ space: The space where the node is located.
316
+ external_id: The external id of the Cognite solution tag.
317
+ name: Name of the solution tag/label
318
+ description: Description of the solution tag/label
319
+ color: Color of the solution tag/label
320
+ existing_version: Fail the ingestion request if the node's version is greater than or equal to this value.
321
+ If no existingVersion is specified, the ingestion will always overwrite any existing data for the node
322
+ (for the specified container or node). If existingVersion is set to 0, the upsert will behave as an insert,
323
+ so it will fail the bulk if the item already exists. If skipOnVersionConflict is set on the ingestion
324
+ request, then the item will be skipped instead of failing the ingestion request.
325
+ type: Direct relation pointing to the type node.
326
+ """
327
+
328
+ def __init__(
329
+ self,
330
+ space: str,
331
+ external_id: str,
332
+ *,
333
+ name: str,
334
+ description: str | None = None,
335
+ color: str | None = None,
336
+ existing_version: int | None = None,
337
+ type: DirectRelationReference | tuple[str, str] | None = None,
338
+ ) -> None:
339
+ TypedNodeApply.__init__(self, space, external_id, existing_version, type)
340
+ self.name = name
341
+ self.description = description
342
+ self.color = color
343
+
344
+
345
+ class CogniteSolutionTag(_CogniteSolutionTagProperties, TypedNode):
346
+ """This represents the reading format of Cognite solution tag.
347
+
348
+ It is used to when data is read from CDF.
349
+
350
+ Args:
351
+ space: The space where the node is located.
352
+ external_id: The external id of the Cognite solution tag.
353
+ version (int): DMS version.
354
+ last_updated_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
355
+ Coordinated Universal Time (UTC), minus leap seconds.
356
+ created_time (int): The number of milliseconds since 00:00:00 Thursday, 1 January 1970,
357
+ Coordinated Universal Time (UTC), minus leap seconds.
358
+ name: Name of the solution tag/label
359
+ description: Description of the solution tag/label
360
+ color: Color of the solution tag/label
361
+ type: Direct relation pointing to the type node.
362
+ deleted_time: The number of milliseconds since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time
363
+ (UTC), minus leap seconds. Timestamp when the instance was soft deleted. Note that deleted instances
364
+ are filtered out of query results, but present in sync results
365
+ """
366
+
367
+ def __init__(
368
+ self,
369
+ space: str,
370
+ external_id: str,
371
+ version: int,
372
+ last_updated_time: int,
373
+ created_time: int,
374
+ *,
375
+ name: str,
376
+ description: str | None = None,
377
+ color: str | None = None,
378
+ type: DirectRelationReference | None = None,
379
+ deleted_time: int | None = None,
380
+ ) -> None:
381
+ TypedNode.__init__(self, space, external_id, version, last_updated_time, created_time, deleted_time, type)
382
+ self.name = name
383
+ self.description = description
384
+ self.color = color
385
+
386
+ def as_write(self) -> CogniteSolutionTagApply:
387
+ return CogniteSolutionTagApply(
388
+ self.space,
389
+ self.external_id,
390
+ name=self.name,
391
+ description=self.description,
392
+ color=self.color,
393
+ existing_version=self.version,
394
+ type=self.type,
395
+ )
@@ -1,6 +1,6 @@
1
1
  from ._migrate import MigrateTimeseriesCommand, MigrationPrepareCommand
2
2
  from ._populate import PopulateCommand
3
- from ._profile import ProfileCommand
3
+ from ._profile import ProfileAssetCentricCommand
4
4
  from ._purge import PurgeCommand
5
5
  from .auth import AuthCommand
6
6
  from .build_cmd import BuildCommand
@@ -30,7 +30,7 @@ __all__ = [
30
30
  "MigrationPrepareCommand",
31
31
  "ModulesCommand",
32
32
  "PopulateCommand",
33
- "ProfileCommand",
33
+ "ProfileAssetCentricCommand",
34
34
  "PullCommand",
35
35
  "PurgeCommand",
36
36
  "RepoCommand",