cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.39__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 (198) hide show
  1. cognite_toolkit/_cdf.py +21 -23
  2. cognite_toolkit/_cdf_tk/apps/__init__.py +4 -0
  3. cognite_toolkit/_cdf_tk/apps/_core_app.py +19 -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 +693 -25
  7. cognite_toolkit/_cdf_tk/apps/_dump_app.py +44 -102
  8. cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
  9. cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
  10. cognite_toolkit/_cdf_tk/apps/_migrate_app.py +424 -9
  11. cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
  12. cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
  13. cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
  14. cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
  15. cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
  16. cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
  17. cognite_toolkit/_cdf_tk/builders/_raw.py +1 -1
  18. cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
  19. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +32 -12
  20. cognite_toolkit/_cdf_tk/client/api/infield.py +114 -17
  21. cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
  22. cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
  23. cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
  24. cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
  25. cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +15 -18
  26. cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
  27. cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
  28. cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
  29. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
  30. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
  31. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
  32. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
  33. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
  34. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
  35. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
  36. cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
  37. cognite_toolkit/_cdf_tk/client/api/migration.py +177 -4
  38. cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
  39. cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
  40. cognite_toolkit/_cdf_tk/client/api/streams.py +88 -0
  41. cognite_toolkit/_cdf_tk/client/api/three_d.py +384 -0
  42. cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
  43. cognite_toolkit/_cdf_tk/client/data_classes/base.py +37 -33
  44. cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
  45. cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
  46. cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +18 -13
  47. cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
  48. cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +47 -4
  49. cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +3 -3
  50. cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/migration.py} +10 -2
  51. cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
  52. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +112 -0
  53. cognite_toolkit/_cdf_tk/client/testing.py +42 -18
  54. cognite_toolkit/_cdf_tk/commands/__init__.py +7 -6
  55. cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
  56. cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
  57. cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
  58. cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
  59. cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +140 -92
  60. cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
  61. cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +108 -26
  62. cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +448 -45
  63. cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
  64. cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +6 -6
  65. cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +52 -1
  66. cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +377 -11
  67. cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
  68. cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
  69. cognite_toolkit/_cdf_tk/commands/_purge.py +36 -39
  70. cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
  71. cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
  72. cognite_toolkit/_cdf_tk/commands/about.py +221 -0
  73. cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
  74. cognite_toolkit/_cdf_tk/commands/build_cmd.py +16 -62
  75. cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
  76. cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
  77. cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
  78. cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
  79. cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
  80. cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
  81. cognite_toolkit/_cdf_tk/commands/dump_resource.py +10 -8
  82. cognite_toolkit/_cdf_tk/commands/init.py +225 -3
  83. cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
  84. cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
  85. cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
  86. cognite_toolkit/_cdf_tk/commands/run.py +1 -1
  87. cognite_toolkit/_cdf_tk/constants.py +20 -1
  88. cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
  89. cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
  90. cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +10 -19
  91. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
  92. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
  93. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +5 -15
  94. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +45 -44
  95. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +5 -12
  96. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
  97. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +206 -67
  98. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +6 -18
  99. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +126 -35
  100. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +7 -28
  101. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -30
  102. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
  103. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +4 -8
  104. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +4 -16
  105. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +5 -13
  106. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +5 -11
  107. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
  108. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +16 -45
  109. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
  110. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
  111. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
  112. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +75 -32
  113. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
  114. cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
  115. cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
  116. cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
  117. cognite_toolkit/_cdf_tk/plugins.py +2 -1
  118. cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
  119. cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
  120. cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
  121. cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
  122. cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
  123. cognite_toolkit/_cdf_tk/resource_classes/search_config.py +1 -1
  124. cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
  125. cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
  126. cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
  127. cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
  128. cognite_toolkit/_cdf_tk/storageio/_applications.py +340 -28
  129. cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
  130. cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
  131. cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
  132. cognite_toolkit/_cdf_tk/storageio/_file_content.py +435 -0
  133. cognite_toolkit/_cdf_tk/storageio/_instances.py +35 -3
  134. cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
  135. cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +71 -4
  136. cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
  137. cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
  138. cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
  139. cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
  140. cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
  141. cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py +34 -0
  142. cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
  143. cognite_toolkit/_cdf_tk/tracker.py +2 -2
  144. cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
  145. cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
  146. cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
  147. cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
  148. cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
  149. cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
  150. cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
  151. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +285 -18
  152. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +56 -4
  153. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +247 -0
  154. cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
  155. cognite_toolkit/_cdf_tk/utils/interactive_select.py +60 -18
  156. cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
  157. cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
  158. cognite_toolkit/_cdf_tk/validation.py +83 -1
  159. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  160. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  161. cognite_toolkit/_resources/cdf.toml +5 -4
  162. cognite_toolkit/_version.py +1 -1
  163. cognite_toolkit/config.dev.yaml +13 -0
  164. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/METADATA +24 -24
  165. cognite_toolkit-0.7.39.dist-info/RECORD +322 -0
  166. cognite_toolkit-0.7.39.dist-info/WHEEL +4 -0
  167. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +1 -0
  168. cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
  169. cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
  170. cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
  171. cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
  172. cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
  173. cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
  174. cognite_toolkit-0.6.97.dist-info/RECORD +0 -306
  175. cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
  176. cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
  177. /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
  178. /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
  179. /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
  180. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
  181. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
  182. /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
  183. /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
  184. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
  185. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
  186. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
  187. /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
  188. /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
  189. /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
  190. /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
  191. /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
  192. /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
  193. /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
  194. /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
  195. /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
  196. /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
  197. /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
  198. /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
@@ -0,0 +1,241 @@
1
+ from pathlib import Path
2
+ from typing import Any, Literal, TypedDict
3
+
4
+ from rich import print
5
+ from rich.panel import Panel
6
+
7
+ from cognite_toolkit._cdf_tk.client import ToolkitClient
8
+ from cognite_toolkit._cdf_tk.commands._base import ToolkitCommand
9
+ from cognite_toolkit._cdf_tk.commands.build_cmd import BuildCommand as OldBuildCommand
10
+ from cognite_toolkit._cdf_tk.commands.build_v2.build_input import BuildInput
11
+ from cognite_toolkit._cdf_tk.commands.build_v2.build_issues import BuildIssue, BuildIssueList
12
+ from cognite_toolkit._cdf_tk.data_classes import (
13
+ BuildConfigYAML,
14
+ BuildVariables,
15
+ BuiltModuleList,
16
+ ModuleDirectories,
17
+ )
18
+ from cognite_toolkit._cdf_tk.exceptions import ToolkitError
19
+ from cognite_toolkit._cdf_tk.hints import verify_module_directory
20
+ from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning, WarningList
21
+ from cognite_toolkit._cdf_tk.utils.file import safe_rmtree
22
+ from cognite_toolkit._cdf_tk.validation import validate_module_selection, validate_modules_variables
23
+ from cognite_toolkit._version import __version__
24
+
25
+
26
+ class BuildWarnings(TypedDict):
27
+ warning: ToolkitWarning
28
+ location: list[Path]
29
+
30
+
31
+ class BuildCommand(ToolkitCommand):
32
+ def __init__(self, print_warning: bool = True, skip_tracking: bool = False, silent: bool = False) -> None:
33
+ super().__init__(print_warning, skip_tracking, silent)
34
+ self.issues = BuildIssueList()
35
+
36
+ def execute(
37
+ self,
38
+ verbose: bool,
39
+ organization_dir: Path,
40
+ build_dir: Path,
41
+ selected: list[str | Path] | None,
42
+ build_env_name: str | None,
43
+ no_clean: bool,
44
+ client: ToolkitClient | None = None,
45
+ on_error: Literal["continue", "raise"] = "continue",
46
+ ) -> BuiltModuleList:
47
+ """
48
+ Build the resources into deployable artifacts in the build directory.
49
+ """
50
+
51
+ self.verbose = verbose
52
+ self.on_error = on_error
53
+
54
+ # Tracking the project and cluster for the build.
55
+ if client:
56
+ self._additional_tracking_info.project = client.config.project
57
+ self._additional_tracking_info.cluster = client.config.cdf_cluster
58
+
59
+ # Setting the parameters for the build.
60
+ input = BuildInput.load(organization_dir, build_dir, build_env_name, client, selected)
61
+
62
+ # Print the build input.
63
+ if self.verbose:
64
+ self._print_build_input(input)
65
+
66
+ # Capture warnings from module structure integrity
67
+ if module_selection_issues := self._validate_modules(input):
68
+ self.issues.extend(module_selection_issues)
69
+
70
+ # Logistics: clean and create build directory
71
+ if prepare_issues := self._prepare_target_directory(input, not no_clean):
72
+ self.issues.extend(prepare_issues)
73
+
74
+ # Compile the configuration and variables,
75
+ # check syntax on module and resource level
76
+ # for any "compilation errors and warnings"
77
+ built_modules, build_integrity_issues = self._build_configuration(input)
78
+ if build_integrity_issues:
79
+ self.issues.extend(build_integrity_issues)
80
+
81
+ # This is where we would add any recommendations for the user to improve the build.
82
+ if build_quality_issues := self._verify_build_quality(built_modules):
83
+ self.issues.extend(build_quality_issues)
84
+
85
+ # Finally, print warnings grouped by category/code and location.
86
+ self._print_or_log_warnings_by_category(self.issues)
87
+
88
+ return built_modules
89
+
90
+ def _print_build_input(self, input: BuildInput) -> None:
91
+ print(
92
+ Panel(
93
+ f"Building {input.organization_dir!s}:\n - Toolkit Version '{__version__!s}'\n"
94
+ f" - Environment name {input.build_env_name!r}, validation-type {input.config.environment.validation_type!r}.\n"
95
+ f" - Config '{input.config.filepath!s}'",
96
+ expand=False,
97
+ )
98
+ )
99
+
100
+ def _prepare_target_directory(self, input: BuildInput, clean: bool = False) -> BuildIssueList:
101
+ """
102
+ Directory logistics
103
+ """
104
+ issues = BuildIssueList()
105
+ if input.build_dir.exists() and any(input.build_dir.iterdir()):
106
+ if not clean:
107
+ raise ToolkitError("Build directory is not empty. Run without --no-clean to remove existing files.")
108
+
109
+ if self.verbose:
110
+ issues.append(BuildIssue(description=f"Build directory {input.build_dir!s} is not empty. Clearing."))
111
+ safe_rmtree(input.build_dir)
112
+ input.build_dir.mkdir(parents=True, exist_ok=True)
113
+ return issues
114
+
115
+ def _validate_modules(self, input: BuildInput) -> BuildIssueList:
116
+ issues = BuildIssueList()
117
+ # Verify that the modules exists, are not duplicates,
118
+ # and at least one is selected
119
+ verify_module_directory(input.organization_dir, input.build_env_name)
120
+
121
+ # Validate module selection
122
+ user_selected_modules = input.config.environment.get_selected_modules({})
123
+ module_warnings = validate_module_selection(
124
+ modules=input.modules,
125
+ config=input.config,
126
+ packages={},
127
+ selected_modules=user_selected_modules,
128
+ organization_dir=input.organization_dir,
129
+ )
130
+ if module_warnings:
131
+ issues.extend(BuildIssueList.from_warning_list(module_warnings))
132
+
133
+ # Validate variables. Note: this looks for non-replaced template
134
+ # variables <.*?> and can be improved in the future.
135
+ # Keeping for reference.
136
+ variables_warnings = validate_modules_variables(input.variables, input.config.filepath)
137
+ if variables_warnings:
138
+ issues.extend(BuildIssueList.from_warning_list(variables_warnings))
139
+
140
+ # Track LOC of managed configuration
141
+ # Note: _track is not implemented yet, so we skip it for now
142
+ # self._track(input)
143
+
144
+ return issues
145
+
146
+ def _build_configuration(self, input: BuildInput) -> tuple[BuiltModuleList, BuildIssueList]:
147
+ issues = BuildIssueList()
148
+ # Use input.modules.selected directly (it's already a ModuleDirectories)
149
+ if not input.modules.selected:
150
+ return BuiltModuleList(), issues
151
+
152
+ # first collect variables into practical lookup
153
+ # TODO: parallelism is not implemented yet. I'm sure there are optimizations to be had here, but we'll focus on process parallelism since we believe loading yaml and file i/O are the biggest bottlenecks.
154
+
155
+ old_build_command = OldBuildCommand(print_warning=False, skip_tracking=False)
156
+ built_modules = old_build_command.build_config(
157
+ build_dir=input.build_dir,
158
+ organization_dir=input.organization_dir,
159
+ config=input.config,
160
+ packages={},
161
+ clean=False,
162
+ verbose=self.verbose,
163
+ client=input.client,
164
+ progress_bar=False,
165
+ on_error=self.on_error,
166
+ )
167
+ # Copy tracking info from old command to self
168
+ self._additional_tracking_info.package_ids.update(old_build_command._additional_tracking_info.package_ids)
169
+ self._additional_tracking_info.module_ids.update(old_build_command._additional_tracking_info.module_ids)
170
+
171
+ # Collect warnings from the old build command and convert to issues
172
+ # Always convert warnings to issues, even if the list appears empty
173
+ # (WarningList might have custom __bool__ behavior)
174
+ if old_build_command.warning_list:
175
+ converted_issues = BuildIssueList.from_warning_list(old_build_command.warning_list)
176
+ issues.extend(converted_issues)
177
+ return built_modules, issues
178
+
179
+ def _verify_build_quality(self, built_modules: BuiltModuleList) -> BuildIssueList:
180
+ issues = BuildIssueList()
181
+ return issues
182
+
183
+ def _write(self, input: BuildInput) -> None:
184
+ # Write the build to the build directory.
185
+ # Track lines of code built.
186
+ raise NotImplementedError()
187
+
188
+ def _track(self, input: BuildInput) -> None:
189
+ raise NotImplementedError()
190
+
191
+ def _print_or_log_warnings_by_category(self, issues: BuildIssueList) -> None:
192
+ pass
193
+
194
+ # Delegate to old BuildCommand for backward compatibility with tests
195
+ def build_modules(
196
+ self,
197
+ modules: ModuleDirectories,
198
+ build_dir: Path,
199
+ variables: BuildVariables,
200
+ verbose: bool = False,
201
+ progress_bar: bool = False,
202
+ on_error: Literal["continue", "raise"] = "continue",
203
+ ) -> BuiltModuleList:
204
+ """Delegate to old BuildCommand for backward compatibility."""
205
+ old_cmd = OldBuildCommand()
206
+
207
+ built_modules = old_cmd.build_modules(modules, build_dir, variables, verbose, progress_bar, on_error)
208
+ self._additional_tracking_info.package_ids.update(old_cmd._additional_tracking_info.package_ids)
209
+ self._additional_tracking_info.module_ids.update(old_cmd._additional_tracking_info.module_ids)
210
+ self.issues.extend(BuildIssueList.from_warning_list(old_cmd.warning_list or WarningList[ToolkitWarning]()))
211
+ return built_modules
212
+
213
+ def build_config(
214
+ self,
215
+ build_dir: Path,
216
+ organization_dir: Path,
217
+ config: BuildConfigYAML,
218
+ packages: dict[str, list[str]],
219
+ clean: bool = False,
220
+ verbose: bool = False,
221
+ client: ToolkitClient | None = None,
222
+ progress_bar: bool = False,
223
+ on_error: Literal["continue", "raise"] = "continue",
224
+ ) -> BuiltModuleList:
225
+ """Delegate to old BuildCommand for backward compatibility."""
226
+ old_cmd = OldBuildCommand()
227
+ return old_cmd.build_config(
228
+ build_dir, organization_dir, config, packages, clean, verbose, client, progress_bar, on_error
229
+ )
230
+
231
+ def _replace_variables(
232
+ self,
233
+ resource_files: list[Path],
234
+ variables: BuildVariables,
235
+ resource_name: str,
236
+ module_dir: Path,
237
+ verbose: bool = False,
238
+ ) -> list[Any]:
239
+ """Delegate to old BuildCommand for backward compatibility."""
240
+ old_cmd = OldBuildCommand()
241
+ return old_cmd._replace_variables(resource_files, variables, resource_name, module_dir, verbose)
@@ -0,0 +1,85 @@
1
+ import sys
2
+ from functools import cached_property
3
+ from pathlib import Path
4
+
5
+ if sys.version_info >= (3, 11):
6
+ from typing import Self
7
+ else:
8
+ from typing_extensions import Self
9
+
10
+ from pydantic import BaseModel, ConfigDict
11
+
12
+ from cognite_toolkit._cdf_tk.client import ToolkitClient
13
+ from cognite_toolkit._cdf_tk.constants import DEFAULT_ENV
14
+ from cognite_toolkit._cdf_tk.data_classes import (
15
+ BuildConfigYAML,
16
+ BuildVariables,
17
+ ModuleDirectories,
18
+ )
19
+ from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning, WarningList
20
+ from cognite_toolkit._cdf_tk.utils.modules import parse_user_selected_modules
21
+
22
+
23
+ class BuildInput(BaseModel):
24
+ """Input to the build process."""
25
+
26
+ # need this until we turn BuildConfigYaml and ToolkitClient into Pydantic models
27
+ model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)
28
+
29
+ organization_dir: Path
30
+ build_dir: Path
31
+ build_env_name: str
32
+ config: BuildConfigYAML
33
+ client: ToolkitClient | None = None
34
+ selected: list[str | Path] | None = None
35
+ warnings: WarningList[ToolkitWarning] | None = None
36
+
37
+ @classmethod
38
+ def load(
39
+ cls,
40
+ organization_dir: Path,
41
+ build_dir: Path,
42
+ build_env_name: str | None,
43
+ client: ToolkitClient | None,
44
+ selected: list[str | Path] | None = None,
45
+ ) -> Self:
46
+ resolved_org_dir = Path.cwd() if organization_dir in {Path("."), Path("./")} else organization_dir
47
+ resolved_env = build_env_name or DEFAULT_ENV
48
+ config, warnings = cls._load_config(resolved_org_dir, resolved_env, selected)
49
+ return cls(
50
+ organization_dir=resolved_org_dir,
51
+ build_dir=build_dir,
52
+ build_env_name=resolved_env,
53
+ config=config,
54
+ client=client,
55
+ selected=selected,
56
+ warnings=warnings,
57
+ )
58
+
59
+ @classmethod
60
+ def _load_config(
61
+ cls, organization_dir: Path, build_env_name: str, selected: list[str | Path] | None
62
+ ) -> tuple[BuildConfigYAML, WarningList[ToolkitWarning]]:
63
+ warnings: WarningList[ToolkitWarning] = WarningList[ToolkitWarning]()
64
+ if (organization_dir / BuildConfigYAML.get_filename(build_env_name or DEFAULT_ENV)).exists():
65
+ config = BuildConfigYAML.load_from_directory(organization_dir, build_env_name or DEFAULT_ENV)
66
+ else:
67
+ # Loads the default environment
68
+ config = BuildConfigYAML.load_default(organization_dir)
69
+ if selected:
70
+ config.environment.selected = parse_user_selected_modules(selected, organization_dir)
71
+ config.set_environment_variables()
72
+ if environment_warning := config.validate_environment():
73
+ warnings.append(environment_warning)
74
+ return config, warnings
75
+
76
+ @cached_property
77
+ def modules(self) -> ModuleDirectories:
78
+ user_selected_modules = self.config.environment.get_selected_modules({})
79
+ return ModuleDirectories.load(self.organization_dir, user_selected_modules)
80
+
81
+ @cached_property
82
+ def variables(self) -> BuildVariables:
83
+ return BuildVariables.load_raw(
84
+ self.config.variables, self.modules.available_paths, self.modules.selected.available_paths
85
+ )
@@ -0,0 +1,27 @@
1
+ import sys
2
+
3
+ if sys.version_info >= (3, 11):
4
+ from typing import Self
5
+ else:
6
+ from typing_extensions import Self
7
+
8
+ from collections import UserList
9
+
10
+ from pydantic import BaseModel
11
+
12
+ from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning, WarningList
13
+
14
+
15
+ class BuildIssue(BaseModel):
16
+ """Issue with the build. Can have a recommendation for the user to improve the build."""
17
+
18
+ description: str
19
+
20
+
21
+ class BuildIssueList(UserList[BuildIssue]):
22
+ """List of build issues."""
23
+
24
+ @classmethod
25
+ def from_warning_list(cls, warning_list: WarningList[ToolkitWarning]) -> Self:
26
+ """Create a BuildIssueList from a WarningList."""
27
+ return cls([BuildIssue(description=warning.get_message()) for warning in warning_list])
@@ -1,7 +1,9 @@
1
1
  import traceback
2
+ from collections.abc import Sequence
2
3
  from graphlib import TopologicalSorter
3
4
  from pathlib import Path
4
5
 
6
+ import questionary
5
7
  from cognite.client.exceptions import CogniteAPIError, CogniteNotFoundError
6
8
  from cognite.client.utils.useful_types import SequenceNotStr
7
9
  from rich import print
@@ -23,14 +25,7 @@ from cognite_toolkit._cdf_tk.cruds import (
23
25
  ResourceCRUD,
24
26
  ResourceWorker,
25
27
  )
26
- from cognite_toolkit._cdf_tk.cruds._base_cruds import (
27
- T_ID,
28
- Loader,
29
- T_ResourceRequest,
30
- T_ResourceRequestList,
31
- T_ResourceResponse,
32
- T_ResourceResponseList,
33
- )
28
+ from cognite_toolkit._cdf_tk.cruds._base_cruds import Loader
34
29
  from cognite_toolkit._cdf_tk.data_classes import (
35
30
  BuildEnvironment,
36
31
  DeployResults,
@@ -40,9 +35,12 @@ from cognite_toolkit._cdf_tk.data_classes import (
40
35
  from cognite_toolkit._cdf_tk.data_classes._module_directories import ReadModule
41
36
  from cognite_toolkit._cdf_tk.exceptions import (
42
37
  ToolkitCleanResourceError,
38
+ ToolkitMissingModuleError,
43
39
  ToolkitNotADirectoryError,
44
40
  ToolkitValidationError,
41
+ ToolkitValueError,
45
42
  )
43
+ from cognite_toolkit._cdf_tk.protocols import T_ResourceRequest, T_ResourceResponse
46
44
  from cognite_toolkit._cdf_tk.tk_warnings import (
47
45
  LowSeverityWarning,
48
46
  MediumSeverityWarning,
@@ -54,6 +52,7 @@ from cognite_toolkit._cdf_tk.utils import (
54
52
  read_yaml_file,
55
53
  )
56
54
  from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
55
+ from cognite_toolkit._cdf_tk.utils.useful_types import T_ID
57
56
 
58
57
  from ._utils import _print_ids_or_length
59
58
 
@@ -63,9 +62,7 @@ AVAILABLE_DATA_TYPES: tuple[str, ...] = tuple(CRUDS_BY_FOLDER_NAME)
63
62
  class CleanCommand(ToolkitCommand):
64
63
  def clean_resources(
65
64
  self,
66
- loader: ResourceCRUD[
67
- T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList
68
- ],
65
+ loader: ResourceCRUD[T_ID, T_ResourceRequest, T_ResourceResponse],
69
66
  env_vars: EnvironmentVariables,
70
67
  read_modules: list[ReadModule],
71
68
  dry_run: bool = False,
@@ -136,7 +133,7 @@ class CleanCommand(ToolkitCommand):
136
133
  return ResourceDeployResult(name=loader.display_name)
137
134
 
138
135
  def _delete_resources(
139
- self, loaded_resources: T_ResourceResponseList, loader: ResourceCRUD, dry_run: bool, verbose: bool
136
+ self, loaded_resources: Sequence[T_ResourceResponse], loader: ResourceCRUD, dry_run: bool, verbose: bool
140
137
  ) -> int:
141
138
  nr_of_deleted = 0
142
139
  resource_ids = loader.get_ids(loaded_resources)
@@ -161,7 +158,11 @@ class CleanCommand(ToolkitCommand):
161
158
  return nr_of_deleted
162
159
 
163
160
  def _drop_data(
164
- self, loaded_resources: T_ResourceResponseList, loader: ResourceContainerCRUD, dry_run: bool, verbose: bool
161
+ self,
162
+ loaded_resources: Sequence[T_ResourceResponse],
163
+ loader: ResourceContainerCRUD,
164
+ dry_run: bool,
165
+ verbose: bool,
165
166
  ) -> int:
166
167
  nr_of_dropped = 0
167
168
  resource_ids = loader.get_ids(loaded_resources)
@@ -185,6 +186,23 @@ class CleanCommand(ToolkitCommand):
185
186
  self._verbose_print_drop(resource_drop_count, resource_ids, loader, dry_run)
186
187
  return nr_of_dropped
187
188
 
189
+ def _interactive_module_selection(self, built_modules: list[ReadModule] | None) -> list[ReadModule] | None:
190
+ if not built_modules:
191
+ return None
192
+ choices = [
193
+ questionary.Choice(title=built_module.dir.name, value=built_module) for built_module in built_modules
194
+ ]
195
+
196
+ selected_modules = questionary.checkbox(
197
+ "Which modules would you like to clean?",
198
+ instruction="Use arrow up/down, press space to select item(s) and enter to save",
199
+ choices=choices,
200
+ ).ask()
201
+
202
+ if not selected_modules:
203
+ return None
204
+ return selected_modules
205
+
188
206
  def _verbose_print_drop(
189
207
  self, drop_count: int, resource_ids: SequenceNotStr[T_ID], loader: ResourceContainerCRUD, dry_run: bool
190
208
  ) -> None:
@@ -204,6 +222,11 @@ class CleanCommand(ToolkitCommand):
204
222
  # Count is not supported
205
223
  print(f" {prefix} all {loader.item_name} from {loader.display_name}: {_print_ids_or_length(resource_ids)}.")
206
224
 
225
+ def _select_modules(self, clean_state: BuildEnvironment, module_str: str | None) -> list[ReadModule] | None:
226
+ if module_str:
227
+ return [module for module in clean_state.read_modules if module.dir.name == module_str]
228
+ return self._interactive_module_selection(clean_state.read_modules)
229
+
207
230
  def execute(
208
231
  self,
209
232
  env_vars: EnvironmentVariables,
@@ -211,7 +234,9 @@ class CleanCommand(ToolkitCommand):
211
234
  build_env_name: str | None,
212
235
  dry_run: bool,
213
236
  include: list[str] | None,
237
+ module_str: str | None,
214
238
  verbose: bool,
239
+ all_modules: bool = False,
215
240
  ) -> None:
216
241
  if not build_dir.exists():
217
242
  raise ToolkitNotADirectoryError(
@@ -245,9 +270,31 @@ class CleanCommand(ToolkitCommand):
245
270
  )
246
271
 
247
272
  if not build_dir.is_dir():
248
- raise ToolkitNotADirectoryError(f"'{build_dir}'. Did you forget to run `cdf-tk build` first?")
273
+ raise ToolkitNotADirectoryError(f"'{build_dir}'. Did you forget to run `cdf build` first?")
274
+
275
+ selected_modules: list[ReadModule]
276
+ if all_modules:
277
+ selected_modules = clean_state.read_modules or []
278
+ if not selected_modules:
279
+ raise ToolkitValueError("No modules available to clean.")
280
+ elif module_str:
281
+ selected_modules = [module for module in clean_state.read_modules if module.dir.name == module_str]
282
+ if not selected_modules:
283
+ available_module_names = {module.dir.name for module in clean_state.read_modules}
284
+ raise ToolkitMissingModuleError(
285
+ f"No modules matched the selection: {module_str}. Available modules: {sorted(available_module_names)}"
286
+ )
287
+ else:
288
+ selected_modules = self._interactive_module_selection(clean_state.read_modules) or []
289
+ if not selected_modules:
290
+ raise ToolkitValueError(
291
+ "No module specified with the --module option and no modules selected interactively."
292
+ )
249
293
 
250
- selected_loaders = self.get_selected_loaders(build_dir, clean_state.read_resource_folders, include)
294
+ selected_resource_folders = {
295
+ resource_folder for module in selected_modules for resource_folder in module.resource_directories
296
+ }
297
+ selected_loaders = self.get_selected_loaders(build_dir, selected_resource_folders, include)
251
298
 
252
299
  results = DeployResults([], "clean", dry_run=dry_run)
253
300
 
@@ -274,7 +321,7 @@ class CleanCommand(ToolkitCommand):
274
321
  result = self.clean_resources(
275
322
  loader,
276
323
  env_vars=env_vars,
277
- read_modules=clean_state.read_modules,
324
+ read_modules=selected_modules,
278
325
  drop=True,
279
326
  dry_run=dry_run,
280
327
  drop_data=True,
@@ -1,4 +1,4 @@
1
- from collections.abc import Hashable
1
+ from collections.abc import Hashable, Sequence
2
2
  from graphlib import TopologicalSorter
3
3
  from pathlib import Path
4
4
  from typing import overload
@@ -15,6 +15,7 @@ from cognite_toolkit._cdf_tk.commands.clean import CleanCommand
15
15
  from cognite_toolkit._cdf_tk.constants import (
16
16
  _RUNNING_IN_BROWSER,
17
17
  BUILD_ENVIRONMENT_FILE,
18
+ DATA_UPLOAD_URL,
18
19
  HINT_LEAD_TEXT,
19
20
  )
20
21
  from cognite_toolkit._cdf_tk.cruds import (
@@ -45,13 +46,12 @@ from cognite_toolkit._cdf_tk.exceptions import (
45
46
  )
46
47
  from cognite_toolkit._cdf_tk.protocols import (
47
48
  T_ResourceRequest,
48
- T_ResourceRequestList,
49
49
  T_ResourceResponse,
50
- T_ResourceResponseList,
51
50
  )
52
51
  from cognite_toolkit._cdf_tk.tk_warnings import EnvironmentVariableMissingWarning
53
52
  from cognite_toolkit._cdf_tk.tk_warnings.base import WarningList, catch_warnings
54
53
  from cognite_toolkit._cdf_tk.tk_warnings.other import (
54
+ HighSeverityWarning,
55
55
  LowSeverityWarning,
56
56
  ToolkitDependenciesIncludedWarning,
57
57
  )
@@ -292,6 +292,15 @@ class DeployCommand(ToolkitCommand):
292
292
  read_modules = build.read_modules
293
293
  output_results = DeployResults([], "deploy", dry_run=dry_run) if results is None else results
294
294
  for loader_cls in ordered_loaders:
295
+ if issubclass(loader_cls, DataCRUD):
296
+ self.warn(
297
+ HighSeverityWarning(
298
+ f"Uploading {loader_cls.kind} data is deprecated and will be removed in v0.8. "
299
+ f"Use the `cdf data upload dir` command instead. See [{DATA_UPLOAD_URL}]({DATA_UPLOAD_URL}) for more information about "
300
+ "the upload command."
301
+ )
302
+ )
303
+
295
304
  loader = loader_cls.create_loader(client, build_dir)
296
305
  resource_result: DeployResult | None
297
306
  if isinstance(loader, ResourceCRUD):
@@ -327,9 +336,7 @@ class DeployCommand(ToolkitCommand):
327
336
 
328
337
  def deploy_resource_type(
329
338
  self,
330
- loader: ResourceCRUD[
331
- T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList
332
- ],
339
+ loader: ResourceCRUD[T_ID, T_ResourceRequest, T_ResourceResponse],
333
340
  env_vars: EnvironmentVariables,
334
341
  read_modules: list[ReadModule] | None = None,
335
342
  dry_run: bool = False,
@@ -391,10 +398,8 @@ class DeployCommand(ToolkitCommand):
391
398
 
392
399
  def actual_deploy(
393
400
  self,
394
- resources: CategorizedResources[T_ID, T_ResourceResponseList],
395
- loader: ResourceCRUD[
396
- T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList
397
- ],
401
+ resources: CategorizedResources[T_ID, T_ResourceRequest],
402
+ loader: ResourceCRUD[T_ID, T_ResourceRequest, T_ResourceResponse],
398
403
  env_var_warnings: WarningList | None = None,
399
404
  ) -> ResourceDeployResult:
400
405
  environment_variable_warning_by_id = {
@@ -425,10 +430,8 @@ class DeployCommand(ToolkitCommand):
425
430
 
426
431
  @staticmethod
427
432
  def dry_run_deploy(
428
- resources: CategorizedResources[T_ID, T_ResourceResponseList],
429
- loader: ResourceCRUD[
430
- T_ID, T_ResourceRequest, T_ResourceResponse, T_ResourceRequestList, T_ResourceResponseList
431
- ],
433
+ resources: CategorizedResources[T_ID, T_ResourceRequest],
434
+ loader: ResourceCRUD[T_ID, T_ResourceRequest, T_ResourceResponse],
432
435
  has_done_drop: bool,
433
436
  has_dropped_data: bool,
434
437
  ) -> ResourceDeployResult:
@@ -459,7 +462,7 @@ class DeployCommand(ToolkitCommand):
459
462
 
460
463
  @staticmethod
461
464
  def _verbose_print(
462
- resources: CategorizedResources[T_ID, T_ResourceResponseList],
465
+ resources: CategorizedResources[T_ID, T_ResourceRequest],
463
466
  loader: ResourceCRUD,
464
467
  dry_run: bool,
465
468
  ) -> None:
@@ -483,7 +486,7 @@ class DeployCommand(ToolkitCommand):
483
486
 
484
487
  def _create_resources(
485
488
  self,
486
- resources: T_ResourceResponseList,
489
+ resources: Sequence[T_ResourceRequest],
487
490
  loader: ResourceCRUD,
488
491
  environment_variable_warning_by_id: dict[Hashable, EnvironmentVariableMissingWarning],
489
492
  ) -> int:
@@ -506,7 +509,7 @@ class DeployCommand(ToolkitCommand):
506
509
 
507
510
  def _update_resources(
508
511
  self,
509
- resources: T_ResourceResponseList,
512
+ resources: Sequence[T_ResourceRequest],
510
513
  loader: ResourceCRUD,
511
514
  environment_variable_warning_by_id: dict[Hashable, EnvironmentVariableMissingWarning],
512
515
  ) -> int:
@@ -3,7 +3,7 @@ import json
3
3
  import zipfile
4
4
  from abc import ABC, abstractmethod
5
5
  from collections import defaultdict
6
- from collections.abc import Hashable, Iterable, Iterator
6
+ from collections.abc import Hashable, Iterable, Iterator, Sequence
7
7
  from functools import cached_property
8
8
  from pathlib import Path
9
9
  from typing import Generic, cast
@@ -22,6 +22,7 @@ from cognite.client.data_classes import (
22
22
  filters,
23
23
  )
24
24
  from cognite.client.data_classes._base import (
25
+ CogniteResource,
25
26
  CogniteResourceList,
26
27
  )
27
28
  from cognite.client.data_classes.agents import (
@@ -51,10 +52,10 @@ from rich.console import Console
51
52
  from rich.panel import Panel
52
53
 
53
54
  from cognite_toolkit._cdf_tk.client import ToolkitClient
54
- from cognite_toolkit._cdf_tk.client.data_classes.location_filters import LocationFilterList
55
- from cognite_toolkit._cdf_tk.client.data_classes.search_config import SearchConfigList
56
- from cognite_toolkit._cdf_tk.client.data_classes.search_config import ViewId as SearchConfigViewId
57
- from cognite_toolkit._cdf_tk.client.data_classes.streamlit_ import Streamlit, StreamlitList
55
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.location_filters import LocationFilterList
56
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.search_config import SearchConfigList
57
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.search_config import ViewId as SearchConfigViewId
58
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.streamlit_ import Streamlit, StreamlitList
58
59
  from cognite_toolkit._cdf_tk.cruds import (
59
60
  AgentCRUD,
60
61
  ContainerCRUD,
@@ -113,7 +114,7 @@ class ResourceFinder(Iterable, ABC, Generic[T_ID]):
113
114
  raise NotImplementedError
114
115
 
115
116
  # Can be implemented in subclasses
116
- def update(self, resources: CogniteResourceList) -> None: ...
117
+ def update(self, resources: Sequence[CogniteResource]) -> None: ...
117
118
 
118
119
 
119
120
  class DataModelFinder(ResourceFinder[DataModelId]):
@@ -178,7 +179,7 @@ class DataModelFinder(ResourceFinder[DataModelId]):
178
179
  self.data_model = models_by_version[selected_model]
179
180
  return self.data_model.as_id()
180
181
 
181
- def update(self, resources: CogniteResourceList) -> None:
182
+ def update(self, resources: Sequence[CogniteResource]) -> None:
182
183
  if isinstance(resources, dm.DataModelList):
183
184
  self.view_ids |= {
184
185
  view.as_id() if isinstance(view, dm.View) else view for item in resources for view in item.views
@@ -187,7 +188,7 @@ class DataModelFinder(ResourceFinder[DataModelId]):
187
188
  self.container_ids |= resources.referenced_containers()
188
189
  elif isinstance(resources, dm.SpaceList):
189
190
  return
190
- self.space_ids |= {item.space for item in resources}
191
+ self.space_ids |= {item.space for item in resources if hasattr(item, "space")}
191
192
 
192
193
  def __iter__(self) -> Iterator[tuple[list[Hashable], CogniteResourceList | None, ResourceCRUD, None | str]]:
193
194
  self.identifier = self._selected()
@@ -804,6 +805,7 @@ class DumpResourceCommand(ToolkitCommand):
804
805
  output_dir.mkdir(exist_ok=True)
805
806
 
806
807
  dumped_ids: list[Hashable] = []
808
+ resources: Sequence[CogniteResource] | None = None
807
809
  for identifiers, resources, loader, subfolder in finder:
808
810
  if not identifiers and not resources:
809
811
  # No resources to dump