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
@@ -43,9 +43,7 @@ from cognite.client.data_classes import (
43
43
  TransformationSchedule,
44
44
  TransformationScheduleList,
45
45
  TransformationScheduleWrite,
46
- TransformationScheduleWriteList,
47
46
  TransformationWrite,
48
- TransformationWriteList,
49
47
  )
50
48
  from cognite.client.data_classes.capabilities import (
51
49
  Capability,
@@ -58,7 +56,6 @@ from cognite.client.data_classes.data_modeling.ids import (
58
56
  from cognite.client.data_classes.transformations import NonceCredentials
59
57
  from cognite.client.data_classes.transformations.notifications import (
60
58
  TransformationNotificationWrite,
61
- TransformationNotificationWriteList,
62
59
  )
63
60
  from cognite.client.exceptions import CogniteAPIError, CogniteAuthError, CogniteDuplicatedError, CogniteNotFoundError
64
61
  from cognite.client.utils.useful_types import SequenceNotStr
@@ -82,7 +79,7 @@ from cognite_toolkit._cdf_tk.resource_classes import (
82
79
  TransformationScheduleYAML,
83
80
  TransformationYAML,
84
81
  )
85
- from cognite_toolkit._cdf_tk.tk_warnings import HighSeverityWarning
82
+ from cognite_toolkit._cdf_tk.tk_warnings import HighSeverityWarning, MediumSeverityWarning
86
83
  from cognite_toolkit._cdf_tk.utils import (
87
84
  calculate_secure_hash,
88
85
  humanize_collection,
@@ -103,18 +100,10 @@ from .raw import RawDatabaseCRUD, RawTableCRUD
103
100
 
104
101
 
105
102
  @final
106
- class TransformationCRUD(
107
- ResourceCRUD[str, TransformationWrite, Transformation, TransformationWriteList, TransformationList]
108
- ):
103
+ class TransformationCRUD(ResourceCRUD[str, TransformationWrite, Transformation]):
109
104
  folder_name = "transformations"
110
- filename_pattern = (
111
- # Matches all yaml files except file names whose stem contain *.schedule. or .Notification
112
- r"^(?!.*schedule.*|.*\.notification$).*$"
113
- )
114
105
  resource_cls = Transformation
115
106
  resource_write_cls = TransformationWrite
116
- list_cls = TransformationList
117
- list_write_cls = TransformationWriteList
118
107
  kind = "Transformation"
119
108
  yaml_cls = TransformationYAML
120
109
  dependencies = frozenset(
@@ -354,6 +343,16 @@ class TransformationCRUD(
354
343
  if "authentication" in local:
355
344
  # The hash added to the beginning of the query detects the change in the authentication
356
345
  dumped["authentication"] = local["authentication"]
346
+ cdf_destination = dumped.get("destination", {})
347
+ local_destination = local.get("destination", {})
348
+ if isinstance(cdf_destination, dict) and isinstance(local_destination, dict):
349
+ if cdf_destination.get("instanceSpace") is None and "instanceSpace" not in local_destination:
350
+ cdf_destination.pop("instanceSpace", None)
351
+ if not dumped.get("query") and "query" not in local:
352
+ dumped.pop("query", None)
353
+ if dumped.get("conflictMode") == "upsert" and "conflictMode" not in local:
354
+ # Default set from server side.
355
+ dumped.pop("conflictMode", None)
357
356
  return dumped
358
357
 
359
358
  def split_resource(
@@ -427,16 +426,37 @@ class TransformationCRUD(
427
426
  if error := self._create_auth_creation_error(chunk):
428
427
  raise error from e
429
428
  raise e
430
- results.extend(chunk_results)
429
+ except CogniteAPIError as e:
430
+ if "Failed to bind session using nonce for" in e.message and len(chunk) > 1:
431
+ MediumSeverityWarning(
432
+ f"Failed to create {len(chunk)} transformations in a batch due to nonce binding error. "
433
+ "Trying to recover by creating them one by one."
434
+ ).print_warning(console=self.console)
435
+ # Retry one by one
436
+ for item in chunk:
437
+ recovered = self._execute_in_batches(items=[item], api_call=api_call)
438
+ results.extend(recovered)
439
+ if self.console:
440
+ self.console.print(
441
+ f" [bold green]RECOVERED:[/] Successfully created {len(chunk)} transformations one by one."
442
+ )
443
+ else:
444
+ raise
445
+ else:
446
+ results.extend(chunk_results)
431
447
  return results
432
448
 
433
449
  def _update_nonce(self, items: Sequence[TransformationWrite]) -> None:
434
450
  for item in items:
435
451
  if not item.external_id:
436
452
  raise ToolkitRequiredValueError("Transformation must have external_id set.")
437
- if read_credentials := self._authentication_by_id_operation.get((item.external_id, "read")):
453
+ if item.source_nonce is None and (
454
+ read_credentials := self._authentication_by_id_operation.get((item.external_id, "read"))
455
+ ):
438
456
  item.source_nonce = self._create_nonce(read_credentials)
439
- if write_credentials := self._authentication_by_id_operation.get((item.external_id, "write")):
457
+ if item.destination_nonce is None and (
458
+ write_credentials := self._authentication_by_id_operation.get((item.external_id, "write"))
459
+ ):
440
460
  item.destination_nonce = self._create_nonce(write_credentials)
441
461
 
442
462
  def _create_nonce(self, credentials: OidcCredentials | ClientCredentials) -> NonceCredentials:
@@ -483,17 +503,11 @@ class TransformationScheduleCRUD(
483
503
  str,
484
504
  TransformationScheduleWrite,
485
505
  TransformationSchedule,
486
- TransformationScheduleWriteList,
487
- TransformationScheduleList,
488
506
  ]
489
507
  ):
490
508
  folder_name = "transformations"
491
- # Matches all yaml files whose stem contains *schedule or *TransformationSchedule.
492
- filename_pattern = r"^.*schedule$"
493
509
  resource_cls = TransformationSchedule
494
510
  resource_write_cls = TransformationScheduleWrite
495
- list_cls = TransformationScheduleList
496
- list_write_cls = TransformationScheduleWriteList
497
511
  kind = "Schedule"
498
512
  yaml_cls = TransformationScheduleYAML
499
513
  dependencies = frozenset({TransformationCRUD})
@@ -543,7 +557,7 @@ class TransformationScheduleCRUD(
543
557
  def retrieve(self, ids: SequenceNotStr[str]) -> TransformationScheduleList:
544
558
  return self.client.transformations.schedules.retrieve_multiple(external_ids=ids, ignore_unknown_ids=True)
545
559
 
546
- def update(self, items: TransformationScheduleWriteList) -> TransformationScheduleList:
560
+ def update(self, items: Sequence[TransformationScheduleWrite]) -> TransformationScheduleList:
547
561
  return self.client.transformations.schedules.update(items, mode="replace")
548
562
 
549
563
  def delete(self, ids: str | SequenceNotStr[str] | None) -> int:
@@ -581,17 +595,11 @@ class TransformationNotificationCRUD(
581
595
  str,
582
596
  TransformationNotificationWrite,
583
597
  TransformationNotification,
584
- TransformationNotificationWriteList,
585
- TransformationNotificationList,
586
598
  ]
587
599
  ):
588
600
  folder_name = "transformations"
589
- # Matches all yaml files whose stem ends with *Notification.
590
- filename_pattern = r"^.*Notification$"
591
601
  resource_cls = TransformationNotification
592
602
  resource_write_cls = TransformationNotificationWrite
593
- list_cls = TransformationNotificationList
594
- list_write_cls = TransformationNotificationWriteList
595
603
  kind = "Notification"
596
604
  dependencies = frozenset({TransformationCRUD})
597
605
  _doc_url = "Transformation-Notifications/operation/createTransformationNotifications"
@@ -638,7 +646,7 @@ class TransformationNotificationCRUD(
638
646
  dumped["transformationExternalId"] = local["transformationExternalId"]
639
647
  return dumped
640
648
 
641
- def create(self, items: TransformationNotificationWriteList) -> TransformationNotificationList:
649
+ def create(self, items: Sequence[TransformationNotificationWrite]) -> TransformationNotificationList:
642
650
  return self.client.transformations.notifications.create(items)
643
651
 
644
652
  def retrieve(self, ids: SequenceNotStr[str]) -> TransformationNotificationList:
@@ -669,7 +677,7 @@ class TransformationNotificationCRUD(
669
677
 
670
678
  return retrieved
671
679
 
672
- def update(self, items: TransformationNotificationWriteList) -> TransformationNotificationList:
680
+ def update(self, items: Sequence[TransformationNotificationWrite]) -> TransformationNotificationList:
673
681
  # Note that since a notification is identified by the combination of transformationExternalId and destination,
674
682
  # which is the entire object, an update should never happen. However, implementing just in case.
675
683
  item_by_id = {self.get_id(item): item for item in items}
@@ -22,24 +22,23 @@ from typing import Any, final
22
22
  from cognite.client.data_classes import (
23
23
  ClientCredentials,
24
24
  Workflow,
25
- WorkflowList,
26
25
  WorkflowTrigger,
27
- WorkflowTriggerList,
28
26
  WorkflowTriggerUpsert,
29
- WorkflowTriggerUpsertList,
30
27
  WorkflowUpsert,
31
- WorkflowUpsertList,
32
28
  WorkflowVersion,
33
29
  WorkflowVersionId,
34
- WorkflowVersionList,
35
30
  WorkflowVersionUpsert,
36
- WorkflowVersionUpsertList,
37
31
  )
38
32
  from cognite.client.data_classes.capabilities import (
39
33
  Capability,
40
34
  WorkflowOrchestrationAcl,
41
35
  )
42
- from cognite.client.data_classes.workflows import SubworkflowReferenceParameters
36
+ from cognite.client.data_classes.workflows import (
37
+ SubworkflowReferenceParameters,
38
+ WorkflowList,
39
+ WorkflowTriggerList,
40
+ WorkflowVersionList,
41
+ )
43
42
  from cognite.client.exceptions import CogniteAuthError, CogniteNotFoundError
44
43
  from cognite.client.utils.useful_types import SequenceNotStr
45
44
  from rich import print
@@ -75,13 +74,10 @@ from .transformation import TransformationCRUD
75
74
 
76
75
 
77
76
  @final
78
- class WorkflowCRUD(ResourceCRUD[str, WorkflowUpsert, Workflow, WorkflowUpsertList, WorkflowList]):
77
+ class WorkflowCRUD(ResourceCRUD[str, WorkflowUpsert, Workflow]):
79
78
  folder_name = "workflows"
80
- filename_pattern = r"^.*Workflow$"
81
79
  resource_cls = Workflow
82
80
  resource_write_cls = WorkflowUpsert
83
- list_cls = WorkflowList
84
- list_write_cls = WorkflowUpsertList
85
81
  kind = "Workflow"
86
82
  dependencies = frozenset(
87
83
  {
@@ -140,18 +136,14 @@ class WorkflowCRUD(ResourceCRUD[str, WorkflowUpsert, Workflow, WorkflowUpsertLis
140
136
  dumped["dataSetExternalId"] = self.client.lookup.data_sets.external_id(data_set_id)
141
137
  return dumped
142
138
 
143
- def retrieve(self, ids: SequenceNotStr[str]) -> WorkflowList:
139
+ def retrieve(self, ids: SequenceNotStr[str]) -> Sequence[Workflow]:
144
140
  return self.client.workflows.retrieve(external_id=ids, ignore_unknown_ids=True)
145
141
 
146
- def _upsert(self, items: WorkflowUpsert | WorkflowUpsertList) -> WorkflowList:
147
- upserts = [items] if isinstance(items, WorkflowUpsert) else items
148
- return self.client.workflows.upsert(upserts)
142
+ def create(self, items: Sequence[WorkflowUpsert]) -> WorkflowList:
143
+ return self.client.workflows.upsert(items)
149
144
 
150
- def create(self, items: WorkflowUpsert | WorkflowUpsertList) -> WorkflowList:
151
- return self._upsert(items)
152
-
153
- def update(self, items: WorkflowUpsertList) -> WorkflowList:
154
- return self._upsert(items)
145
+ def update(self, items: Sequence[WorkflowUpsert]) -> WorkflowList:
146
+ return self.client.workflows.upsert(items)
155
147
 
156
148
  def delete(self, ids: SequenceNotStr[str]) -> int:
157
149
  successes = 0
@@ -192,17 +184,10 @@ class WorkflowCRUD(ResourceCRUD[str, WorkflowUpsert, Workflow, WorkflowUpsertLis
192
184
 
193
185
 
194
186
  @final
195
- class WorkflowVersionCRUD(
196
- ResourceCRUD[
197
- WorkflowVersionId, WorkflowVersionUpsert, WorkflowVersion, WorkflowVersionUpsertList, WorkflowVersionList
198
- ]
199
- ):
187
+ class WorkflowVersionCRUD(ResourceCRUD[WorkflowVersionId, WorkflowVersionUpsert, WorkflowVersion]):
200
188
  folder_name = "workflows"
201
- filename_pattern = r"^.*WorkflowVersion$"
202
189
  resource_cls = WorkflowVersion
203
190
  resource_write_cls = WorkflowVersionUpsert
204
- list_cls = WorkflowVersionList
205
- list_write_cls = WorkflowVersionUpsertList
206
191
  kind = "WorkflowVersion"
207
192
  dependencies = frozenset({WorkflowCRUD})
208
193
  parent_resource = frozenset({WorkflowCRUD})
@@ -398,16 +383,16 @@ class WorkflowVersionCRUD(
398
383
  return WorkflowVersionList([])
399
384
  return self.client.workflows.versions.retrieve(workflow_external_id=list(ids), ignore_unknown_ids=True)
400
385
 
401
- def _upsert(self, items: WorkflowVersionUpsertList) -> WorkflowVersionList:
386
+ def _upsert(self, items: Sequence[WorkflowVersionUpsert]) -> WorkflowVersionList:
402
387
  return self.client.workflows.versions.upsert(items)
403
388
 
404
- def create(self, items: WorkflowVersionUpsertList) -> WorkflowVersionList:
389
+ def create(self, items: Sequence[WorkflowVersionUpsert]) -> WorkflowVersionList:
405
390
  upserted: list[WorkflowVersion] = []
406
391
  for item in self.topological_sort(items):
407
392
  upserted.extend(self.client.workflows.versions.upsert([item]))
408
393
  return WorkflowVersionList(upserted)
409
394
 
410
- def update(self, items: WorkflowVersionUpsertList) -> WorkflowVersionList:
395
+ def update(self, items: Sequence[WorkflowVersionUpsert]) -> WorkflowVersionList:
411
396
  return self._upsert(items)
412
397
 
413
398
  def delete(self, ids: SequenceNotStr[WorkflowVersionId]) -> int:
@@ -467,15 +452,10 @@ class WorkflowVersionCRUD(
467
452
 
468
453
 
469
454
  @final
470
- class WorkflowTriggerCRUD(
471
- ResourceCRUD[str, WorkflowTriggerUpsert, WorkflowTrigger, WorkflowTriggerUpsertList, WorkflowTriggerList]
472
- ):
455
+ class WorkflowTriggerCRUD(ResourceCRUD[str, WorkflowTriggerUpsert, WorkflowTrigger]):
473
456
  folder_name = "workflows"
474
- filename_pattern = r"^.*WorkflowTrigger$"
475
457
  resource_cls = WorkflowTrigger
476
458
  resource_write_cls = WorkflowTriggerUpsert
477
- list_cls = WorkflowTriggerList
478
- list_write_cls = WorkflowTriggerUpsertList
479
459
  kind = "WorkflowTrigger"
480
460
  dependencies = frozenset({WorkflowCRUD, WorkflowVersionCRUD, GroupResourceScopedCRUD, GroupAllScopedCRUD})
481
461
  parent_resource = frozenset({WorkflowCRUD})
@@ -522,10 +502,10 @@ class WorkflowTriggerCRUD(
522
502
  WorkflowOrchestrationAcl.Scope.All(),
523
503
  )
524
504
 
525
- def create(self, items: WorkflowTriggerUpsertList) -> WorkflowTriggerList:
505
+ def create(self, items: Sequence[WorkflowTriggerUpsert]) -> WorkflowTriggerList:
526
506
  return self._upsert(items)
527
507
 
528
- def _upsert(self, items: WorkflowTriggerUpsertList) -> WorkflowTriggerList:
508
+ def _upsert(self, items: Sequence[WorkflowTriggerUpsert]) -> WorkflowTriggerList:
529
509
  created = WorkflowTriggerList([])
530
510
  for item in items:
531
511
  created.append(self._upsert_item(item))
@@ -545,7 +525,7 @@ class WorkflowTriggerCRUD(
545
525
  lookup = set(ids)
546
526
  return WorkflowTriggerList([trigger for trigger in all_triggers if trigger.external_id in lookup])
547
527
 
548
- def update(self, items: WorkflowTriggerUpsertList) -> WorkflowTriggerList:
528
+ def update(self, items: Sequence[WorkflowTriggerUpsert]) -> WorkflowTriggerList:
549
529
  return self._upsert(items)
550
530
 
551
531
  def delete(self, ids: SequenceNotStr[str]) -> int:
@@ -1,8 +1,8 @@
1
1
  import re
2
2
  import warnings
3
- from collections.abc import Hashable
3
+ from collections.abc import Hashable, Sequence
4
4
  from copy import deepcopy
5
- from dataclasses import dataclass
5
+ from dataclasses import dataclass, field
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING, Any, Generic, cast
8
8
 
@@ -14,39 +14,29 @@ from yaml import YAMLError
14
14
 
15
15
  from cognite_toolkit._cdf_tk.constants import TABLE_FORMATS
16
16
  from cognite_toolkit._cdf_tk.exceptions import ToolkitWrongResourceError, ToolkitYAMLFormatError
17
+ from cognite_toolkit._cdf_tk.feature_flags import Flags
17
18
  from cognite_toolkit._cdf_tk.tk_warnings import EnvironmentVariableMissingWarning, catch_warnings
18
19
  from cognite_toolkit._cdf_tk.utils import to_diff
19
20
 
20
21
  from . import FunctionCRUD
21
- from ._base_cruds import (
22
- T_ID,
23
- ResourceCRUD,
24
- T_ResourceRequest,
25
- T_ResourceRequestList,
26
- T_ResourceResponse,
27
- T_ResourceResponseList,
28
- )
22
+ from ._base_cruds import T_ID, ResourceCRUD, T_ResourceRequest, T_ResourceResponse
29
23
 
30
24
  if TYPE_CHECKING:
31
25
  from cognite_toolkit._cdf_tk.data_classes._module_directories import ReadModule
32
26
 
33
27
 
34
28
  @dataclass
35
- class CategorizedResources(Generic[T_ID, T_ResourceRequestList]):
36
- to_create: T_ResourceRequestList
37
- to_update: T_ResourceRequestList
38
- to_delete: list[T_ID]
39
- unchanged: T_ResourceRequestList
29
+ class CategorizedResources(Generic[T_ID, T_ResourceRequest]):
30
+ to_create: list[T_ResourceRequest] = field(default_factory=list)
31
+ to_update: list[T_ResourceRequest] = field(default_factory=list)
32
+ to_delete: list[T_ID] = field(default_factory=list)
33
+ unchanged: list[T_ResourceRequest] = field(default_factory=list)
40
34
 
41
35
 
42
- class ResourceWorker(
43
- Generic[T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList]
44
- ):
36
+ class ResourceWorker(Generic[T_ID, T_ResourceRequest, T_ResourceResponse]):
45
37
  def __init__(
46
38
  self,
47
- loader: ResourceCRUD[
48
- T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList
49
- ],
39
+ loader: ResourceCRUD[T_ID, T_ResourceRequest, T_ResourceResponse],
50
40
  action: str,
51
41
  ):
52
42
  self.loader = loader
@@ -58,12 +48,16 @@ class ResourceWorker(
58
48
  ) -> list[Path]:
59
49
  filepaths = self.loader.find_files(directory)
60
50
 
61
- for read_module in read_modules or []:
62
- if resource_dir := read_module.resource_dir_path(self.loader.folder_name):
63
- # As of 05/11/24, Asset support csv and parquet files in addition to YAML.
64
- # These table formats are not built, i.e., no variable replacement is done,
65
- # so we load them directly from the source module.
66
- filepaths.extend(self.loader.find_files(resource_dir, include_formats=TABLE_FORMATS))
51
+ if not Flags.v08.is_enabled():
52
+ for read_module in read_modules or []:
53
+ if resource_dir := read_module.resource_dir_path(self.loader.folder_name):
54
+ # As of 05/11/24, Asset support csv and parquet files in addition to YAML.
55
+ # These table formats are not built, i.e., no variable replacement is done,
56
+ # so we load them directly from the source module.
57
+ table_files = [
58
+ file for file in self.loader.find_files(resource_dir) if file.suffix in TABLE_FORMATS
59
+ ]
60
+ filepaths.extend(table_files)
67
61
 
68
62
  if not sort:
69
63
  return filepaths
@@ -104,7 +98,6 @@ class ResourceWorker(
104
98
  self.validate_access(local_by_id, is_dry_run)
105
99
 
106
100
  # Lookup the existing resources in CDF
107
- cdf_resources: T_ResourceResponseList
108
101
  cdf_resources = self.loader.retrieve(list(local_by_id.keys()))
109
102
  return self.categorize_resources(local_by_id, cdf_resources, force_update, verbose)
110
103
 
@@ -165,16 +158,11 @@ class ResourceWorker(
165
158
  def categorize_resources(
166
159
  self,
167
160
  local_by_id: dict[T_ID, tuple[dict[str, Any], T_ResourceRequest]],
168
- cdf_resources: T_ResourceResponseList,
161
+ cdf_resources: Sequence[T_ResourceResponse],
169
162
  force_update: bool,
170
163
  verbose: bool,
171
- ) -> CategorizedResources[T_ID, T_ResourceRequestList]:
172
- resources: CategorizedResources[T_ID, T_ResourceRequestList] = CategorizedResources(
173
- to_create=self.loader.list_write_cls([]),
174
- to_update=self.loader.list_write_cls([]),
175
- to_delete=[],
176
- unchanged=self.loader.list_write_cls([]),
177
- )
164
+ ) -> CategorizedResources[T_ID, T_ResourceRequest]:
165
+ resources: CategorizedResources[T_ID, T_ResourceRequest] = CategorizedResources()
178
166
  cdf_resource_by_id = {self.loader.get_id(resource): resource for resource in cdf_resources}
179
167
  for identifier, (local_dict, local_resource) in local_by_id.items():
180
168
  cdf_resource = cdf_resource_by_id.get(identifier)
@@ -22,21 +22,13 @@ class Flags(Enum):
22
22
  description="Enables the import sub application",
23
23
  )
24
24
  GRAPHQL = FlagMetadata(
25
- visible=True,
25
+ visible=False,
26
26
  description="Enables the support for deploying data models as GraphQL schemas",
27
27
  )
28
28
  MODULE_REPEAT = FlagMetadata(
29
29
  visible=True,
30
30
  description="Enables the support for repeating modules in the config file",
31
31
  )
32
- AGENTS = FlagMetadata(
33
- visible=True,
34
- description="Enables support for Atlas Agents and Agent Tools",
35
- )
36
- DUMP_EXTENDED = FlagMetadata(
37
- visible=True,
38
- description="Enables support for the dumping Location Filters.",
39
- )
40
32
  PROFILE = FlagMetadata(
41
33
  visible=True,
42
34
  description="Enables support for the profile command",
@@ -45,45 +37,29 @@ class Flags(Enum):
45
37
  visible=True,
46
38
  description="Enables support for Infield configs",
47
39
  )
48
- DUMP_DATA = FlagMetadata(
49
- visible=True,
50
- description="Splits the dump command in dump data and dump config",
51
- )
52
- EXIT_ON_WARNING = FlagMetadata(
53
- visible=True,
54
- description="Enables the exit on warning feature during the build command",
55
- )
56
40
  MIGRATE = FlagMetadata(
57
41
  visible=True,
58
42
  description="Enables the migrate command",
59
43
  )
60
- EXTERNAL_LIBRARIES = FlagMetadata(
61
- visible=True,
62
- description="Enables the support for external libraries in the config file",
63
- )
64
- PURGE_INSTANCES = FlagMetadata(
44
+ STREAMS = FlagMetadata(
65
45
  visible=True,
66
- description="Enables the cdf purge instances command",
46
+ description="Enables the support for the streams resources",
67
47
  )
68
- DOWNLOAD = FlagMetadata(
69
- visible=True,
70
- description="Enables the support for the download command",
48
+ v08 = FlagMetadata(
49
+ visible=False,
50
+ description="Enables features planned for Cognite Toolkit version 0.8.0",
71
51
  )
72
- UPLOAD = FlagMetadata(
52
+ CREATE = FlagMetadata(
73
53
  visible=True,
74
- description="Enables the cdf upload command",
54
+ description="Enables the support for the resources create command under dev plugin",
75
55
  )
76
- SEARCH_CONFIG = FlagMetadata(
56
+ EXTEND_DOWNLOAD = FlagMetadata(
77
57
  visible=True,
78
- description="Enables the support for the search config command",
58
+ description="Enables extended download to support downloading file content and datapoints",
79
59
  )
80
- FUNCTION_COGNITE_FILE = FlagMetadata(
60
+ EXTEND_UPLOAD = FlagMetadata(
81
61
  visible=True,
82
- description="Enables support for using Cognite Files to store function code",
83
- )
84
- v07 = FlagMetadata(
85
- visible=False,
86
- description="Enables features planned for Cognite Toolkit version 0.7.0",
62
+ description="Enables extended upload to support uploading individual files",
87
63
  )
88
64
 
89
65
  def is_enabled(self) -> bool:
@@ -95,3 +71,7 @@ class FeatureFlag:
95
71
  @lru_cache(typed=True)
96
72
  def is_enabled(flag: Flags) -> bool:
97
73
  return CDFToml.load().alpha_flags.get(clean_name(flag.name), False)
74
+
75
+ @staticmethod
76
+ def flush() -> None:
77
+ FeatureFlag.is_enabled.cache_clear()
@@ -17,7 +17,8 @@ class Plugin:
17
17
  class Plugins(Enum):
18
18
  run = Plugin("run", "plugin for Run command to execute Python scripts in CDF")
19
19
  dump = Plugin("dump", "plugin for Dump command to retrieve Asset resources from CDF")
20
- purge = Plugin("purge", "plugin for Purge command to remove datasets and spaces from CDF")
20
+ dev = Plugin("dev", "plugin for commands to develop modules in CDF")
21
+ data = Plugin("data", "plugin for Data command to manage data in CDF")
21
22
 
22
23
  @staticmethod
23
24
  def list() -> dict[str, bool]:
@@ -27,6 +27,7 @@ from .hosted_extractor_destination import HostedExtractorDestinationYAML
27
27
  from .hosted_extractor_job import HostedExtractorJobYAML
28
28
  from .hosted_extractor_mapping import HostedExtractorMappingYAML
29
29
  from .hosted_extractor_source import HostedExtractorSourceYAML
30
+ from .infield_cdm_location_config import InFieldCDMLocationConfigYAML
30
31
  from .infield_location_config import InfieldLocationConfigYAML
31
32
  from .infield_v1 import InfieldV1YAML
32
33
  from .instance import EdgeYAML, NodeYAML
@@ -41,6 +42,7 @@ from .securitycategories import SecurityCategoriesYAML
41
42
  from .sequence import SequenceRowYAML, SequenceYAML
42
43
  from .space import SpaceYAML
43
44
  from .streamlit_ import StreamlitYAML
45
+ from .streams import StreamYAML
44
46
  from .threedmodels import ThreeDModelYAML
45
47
  from .timeseries import TimeSeriesYAML
46
48
  from .transformation_notification import TransformationNotificationYAML
@@ -75,6 +77,7 @@ __all__ = [
75
77
  "HostedExtractorJobYAML",
76
78
  "HostedExtractorMappingYAML",
77
79
  "HostedExtractorSourceYAML",
80
+ "InFieldCDMLocationConfigYAML",
78
81
  "InfieldLocationConfigYAML",
79
82
  "InfieldV1YAML",
80
83
  "LabelsYAML",
@@ -92,6 +95,7 @@ __all__ = [
92
95
  "SequenceRowYAML",
93
96
  "SequenceYAML",
94
97
  "SpaceYAML",
98
+ "StreamYAML",
95
99
  "StreamlitYAML",
96
100
  "TableYAML",
97
101
  "ThreeDModelYAML",
@@ -510,6 +510,18 @@ class LegacyGenericsAcl(Capability):
510
510
  scope: AllScope
511
511
 
512
512
 
513
+ class StreamsAcl(Capability):
514
+ _capability_name = "streamsAcl"
515
+ actions: list[Literal["READ", "CREATE", "DELETE"]]
516
+ scope: AllScope
517
+
518
+
519
+ class StreamRecordsAcl(Capability):
520
+ _capability_name = "streamRecordsAcl"
521
+ actions: list[Literal["READ", "WRITE"]]
522
+ scope: AllScope | SpaceIDScope
523
+
524
+
513
525
  _CAPABILITY_CLASS_BY_NAME: MappingProxyType[str, type[Capability]] = MappingProxyType(
514
526
  {c._capability_name: c for c in Capability.__subclasses__()}
515
527
  )
@@ -44,7 +44,9 @@ class FunctionsYAML(ToolkitResource):
44
44
  )
45
45
  cpu: float | None = Field(default=None, description="Number of CPU cores per function.")
46
46
  memory: float | None = Field(default=None, description="Memory per function measured in GB.")
47
- runtime: Literal["py39", "py310", "py311"] | None = Field(default="py311", description="Runtime of the function.")
47
+ runtime: Literal["py39", "py310", "py311", "py312"] | None = Field(
48
+ default="py311", description="Runtime of the function."
49
+ )
48
50
  metadata: dict[str, str] | None = Field(
49
51
  default=None, description="Custom, application-specific metadata.", max_length=16
50
52
  )