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
@@ -23,9 +23,15 @@ class RunApp(typer.Typer):
23
23
  self.command("workflow")(self.run_workflow)
24
24
  self.add_typer(RunFunctionApp(*args, **kwargs), name="function")
25
25
 
26
+ @staticmethod
27
+ def _print_deprecation_warning() -> None:
28
+ """Print deprecation warning for the run plugin."""
29
+ print("The run plugin is deprecated and will be replaced by the dev plugin in v0.8.0.")
30
+
26
31
  @staticmethod
27
32
  def main(ctx: typer.Context) -> None:
28
33
  """Commands to execute processes in CDF."""
34
+ RunApp._print_deprecation_warning()
29
35
  if ctx.invoked_subcommand is None:
30
36
  print("Use [bold yellow]cdf run --help[/] for more information.")
31
37
 
@@ -51,6 +57,7 @@ class RunApp(typer.Typer):
51
57
  ] = False,
52
58
  ) -> None:
53
59
  """This command will run the specified transformation using a one-time session."""
60
+ RunApp._print_deprecation_warning()
54
61
  cmd = RunTransformationCommand()
55
62
  client = EnvironmentVariables.create_from_environment().get_client()
56
63
  cmd.run(lambda: cmd.run_transformation(client, external_id))
@@ -108,6 +115,7 @@ class RunApp(typer.Typer):
108
115
  ] = False,
109
116
  ) -> None:
110
117
  """This command will run the specified workflow."""
118
+ RunApp._print_deprecation_warning()
111
119
  cmd = RunWorkflowCommand()
112
120
  env_vars = EnvironmentVariables.create_from_environment()
113
121
  cmd.run(lambda: cmd.run_workflow(env_vars, organization_dir, env_name, external_id, version, wait))
@@ -123,6 +131,7 @@ class RunFunctionApp(typer.Typer):
123
131
  @staticmethod
124
132
  def main(ctx: typer.Context) -> None:
125
133
  """Commands to execute function."""
134
+ RunApp._print_deprecation_warning()
126
135
  if ctx.invoked_subcommand is None:
127
136
  print("Use [bold yellow]cdf run function --help[/] for more information.")
128
137
 
@@ -178,6 +187,7 @@ class RunFunctionApp(typer.Typer):
178
187
  ] = False,
179
188
  ) -> None:
180
189
  """This command will run the specified function locally."""
190
+ RunApp._print_deprecation_warning()
181
191
  cmd = RunFunctionCommand()
182
192
  env_vars = EnvironmentVariables.create_from_environment()
183
193
  cmd.run(
@@ -243,6 +253,7 @@ class RunFunctionApp(typer.Typer):
243
253
  ] = False,
244
254
  ) -> None:
245
255
  """This command will run the specified function (assuming it is deployed) in CDF."""
256
+ RunApp._print_deprecation_warning()
246
257
  cmd = RunFunctionCommand()
247
258
  env_vars = EnvironmentVariables.create_from_environment()
248
259
  cmd.run(lambda: cmd.run_cdf(env_vars, organization_dir, env_name, external_id, schedule, wait))
@@ -1,10 +1,12 @@
1
1
  from pathlib import Path
2
2
  from typing import Annotated, Any
3
3
 
4
+ import questionary
4
5
  import typer
6
+ from questionary import Choice
5
7
 
6
8
  from cognite_toolkit._cdf_tk.commands import UploadCommand
7
- from cognite_toolkit._cdf_tk.constants import DATA_DEFAULT_DIR
9
+ from cognite_toolkit._cdf_tk.constants import DATA_DEFAULT_DIR, DATA_MANIFEST_SUFFIX, DATA_RESOURCE_DIR
8
10
  from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
9
11
 
10
12
  DEFAULT_INPUT_DIR = Path.cwd() / DATA_DEFAULT_DIR
@@ -14,20 +16,28 @@ class UploadApp(typer.Typer):
14
16
  def __init__(self, *args: Any, **kwargs: Any) -> None:
15
17
  super().__init__(*args, **kwargs)
16
18
  self.callback(invoke_without_command=True)(self.upload_main)
19
+ self.command("dir")(self.upload_dir)
17
20
 
18
21
  @staticmethod
19
- def upload_main(
22
+ def upload_main(ctx: typer.Context) -> None:
23
+ """Commands to upload data to CDF."""
24
+ if ctx.invoked_subcommand is None:
25
+ print("Use [bold yellow]cdf upload --help[/] for more information.")
26
+ return None
27
+
28
+ @staticmethod
29
+ def upload_dir(
20
30
  ctx: typer.Context,
21
31
  input_dir: Annotated[
22
- Path,
32
+ Path | None,
23
33
  typer.Argument(
24
- help="The directory containing the data to upload.",
34
+ help="The directory containing the data to upload. If not specified, an interactive prompt will ask for the directory.",
25
35
  exists=True,
26
36
  file_okay=False,
27
37
  dir_okay=True,
28
38
  resolve_path=True,
29
39
  ),
30
- ],
40
+ ] = None,
31
41
  dry_run: Annotated[
32
42
  bool,
33
43
  typer.Option(
@@ -43,7 +53,7 @@ class UploadApp(typer.Typer):
43
53
  "-r",
44
54
  help="If set, the command will look for resource configuration files in adjacent folders and create them if they do not exist.",
45
55
  ),
46
- ] = True,
56
+ ] = False,
47
57
  verbose: Annotated[
48
58
  bool,
49
59
  typer.Option(
@@ -55,6 +65,35 @@ class UploadApp(typer.Typer):
55
65
  ) -> None:
56
66
  """Commands to upload data to CDF."""
57
67
  cmd = UploadCommand()
68
+ if input_dir is None:
69
+ input_candidate = sorted({p.parent for p in DEFAULT_INPUT_DIR.rglob(f"**/*{DATA_MANIFEST_SUFFIX}")})
70
+ if not input_candidate:
71
+ typer.echo(f"No data manifests found in default directory: {DEFAULT_INPUT_DIR}")
72
+ raise typer.Exit(code=1)
73
+ input_dir = questionary.select(
74
+ "Select the input directory containing the data to upload:",
75
+ choices=[Choice(str(option.name), value=option) for option in input_candidate],
76
+ ).ask()
77
+ if input_dir is None:
78
+ typer.echo("No input directory selected. Exiting.")
79
+ raise typer.Exit(code=1)
80
+ dry_run = questionary.confirm("Proceed with dry run?", default=dry_run).ask()
81
+ if dry_run is None:
82
+ typer.echo("No selection made for dry run. Exiting.")
83
+ raise typer.Exit(code=1)
84
+ resource_dir = Path(input_dir) / DATA_RESOURCE_DIR
85
+ if resource_dir.exists():
86
+ if resource_dir.is_relative_to(Path.cwd()):
87
+ display_name = resource_dir.relative_to(Path.cwd()).as_posix()
88
+ else:
89
+ display_name = resource_dir.as_posix()
90
+
91
+ deploy_resources = questionary.confirm(
92
+ f"Deploy resources found in {display_name!r}?", default=deploy_resources
93
+ ).ask()
94
+ if deploy_resources is None:
95
+ typer.echo("No selection made for deploying resources. Exiting.")
96
+ raise typer.Exit(code=1)
58
97
 
59
98
  client = EnvironmentVariables.create_from_environment().get_client()
60
99
  cmd.run(
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
 
4
4
  from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning
5
5
 
6
- from ._base import Builder, DefaultBuilder, get_loader
6
+ from ._base import Builder, DefaultBuilder, get_resource_crud
7
7
  from ._datamodels import DataModelBuilder
8
8
  from ._file import FileBuilder
9
9
  from ._function import FunctionBuilder
@@ -36,5 +36,5 @@ __all__ = [
36
36
  "StreamlitBuilder",
37
37
  "TransformationBuilder",
38
38
  "create_builder",
39
- "get_loader",
39
+ "get_resource_crud",
40
40
  ]
@@ -2,14 +2,12 @@ import difflib
2
2
  from abc import ABC, abstractmethod
3
3
  from collections.abc import Callable, Iterable, Sequence
4
4
  from pathlib import Path
5
- from typing import Any, ClassVar, cast
5
+ from typing import Any, ClassVar
6
6
 
7
7
  from cognite_toolkit._cdf_tk.constants import INDEX_PATTERN
8
8
  from cognite_toolkit._cdf_tk.cruds import (
9
- CRUDS_BY_FOLDER_NAME,
9
+ RESOURCE_CRUD_BY_FOLDER_NAME,
10
10
  GroupCRUD,
11
- RawDatabaseCRUD,
12
- RawTableCRUD,
13
11
  ResourceCRUD,
14
12
  )
15
13
  from cognite_toolkit._cdf_tk.data_classes import (
@@ -31,7 +29,6 @@ from cognite_toolkit._cdf_tk.tk_warnings.fileread import (
31
29
  )
32
30
  from cognite_toolkit._cdf_tk.utils import (
33
31
  humanize_collection,
34
- safe_read,
35
32
  )
36
33
 
37
34
 
@@ -103,34 +100,31 @@ class Builder(ABC):
103
100
  return destination_path
104
101
 
105
102
  def _get_loader(self, source_path: Path) -> tuple[None, ToolkitWarning] | tuple[type[ResourceCRUD], None]:
106
- return get_loader(source_path, self.resource_folder)
103
+ return get_resource_crud(source_path, self.resource_folder)
107
104
 
108
105
 
109
- def get_loader(
110
- source_path: Path,
111
- resource_folder: str,
112
- force_pattern: bool = False,
106
+ def get_resource_crud(
107
+ source_path: Path, resource_folder: str
113
108
  ) -> tuple[None, ToolkitWarning] | tuple[type[ResourceCRUD], None]:
114
- folder_loaders = CRUDS_BY_FOLDER_NAME.get(resource_folder, [])
115
- if not folder_loaders:
109
+ """Get the appropriate CRUD class for the given source file and resource folder."""
110
+ folder_cruds = RESOURCE_CRUD_BY_FOLDER_NAME.get(resource_folder, [])
111
+ if not folder_cruds:
116
112
  return None, ToolkitNotSupportedWarning(
117
113
  f"resource of type {resource_folder!r} in {source_path.name}.",
118
- details=f"Available resources are: {', '.join(CRUDS_BY_FOLDER_NAME.keys())}",
114
+ details=f"Available resources are: {humanize_collection(RESOURCE_CRUD_BY_FOLDER_NAME.keys())}",
119
115
  )
120
116
 
121
- loaders = [
122
- loader for loader in folder_loaders if loader.is_supported_file(source_path, force_pattern=force_pattern)
123
- ]
124
- if len(loaders) == 0:
117
+ crud_candidates = [crud_cls for crud_cls in folder_cruds if crud_cls.is_supported_file(source_path)]
118
+ if len(crud_candidates) == 0:
125
119
  suggestion: str | None = None
126
120
  if "." in source_path.stem:
127
121
  core, kind = source_path.stem.rsplit(".", 1)
128
- match = difflib.get_close_matches(kind, [loader.kind for loader in folder_loaders])
122
+ match = difflib.get_close_matches(kind, [crud_cls.kind for crud_cls in folder_cruds])
129
123
  if match:
130
124
  suggested_name = f"{core}.{match[0]}{source_path.suffix}"
131
125
  suggestion = f"Did you mean to call the file {suggested_name!r}?"
132
126
  else:
133
- kinds = [loader.kind for loader in folder_loaders]
127
+ kinds = [crud.kind for crud in folder_cruds]
134
128
  if len(kinds) == 1:
135
129
  suggestion = f"Did you mean to call the file '{source_path.stem}.{kinds[0]}{source_path.suffix}'?"
136
130
  else:
@@ -139,30 +133,22 @@ def get_loader(
139
133
  f"the resource type. Supported types are: {humanize_collection(kinds)}."
140
134
  )
141
135
  return None, UnknownResourceTypeWarning(source_path, suggestion)
142
- elif len(loaders) > 1 and all(loader.folder_name == "raw" for loader in loaders):
143
- # Raw files can be ambiguous, so we need to check the content.
144
- # If there is a tableName field, it is a table, otherwise it is a database.
145
- if any(
146
- line.strip().startswith("tableName:") or line.strip().startswith("- tableName:")
147
- for line in safe_read(source_path).splitlines()
148
- ):
149
- return RawTableCRUD, None
150
- else:
151
- return RawDatabaseCRUD, None
152
- elif len(loaders) > 1 and all(issubclass(loader, GroupCRUD) for loader in loaders):
153
- # There are two group loaders, one for resource scoped and one for all scoped.
136
+ elif len(crud_candidates) > 1 and all(issubclass(loader, GroupCRUD) for loader in crud_candidates):
137
+ # There are two group cruds, one for resource scoped and one for all scoped.
154
138
  return GroupCRUD, None
155
- elif len(loaders) > 1:
156
- names = humanize_collection(
157
- [f"'{source_path.stem}.{loader.kind}{source_path.suffix}'" for loader in loaders], bind_word="or"
158
- )
159
- raise AmbiguousResourceFileError(
160
- f"Ambiguous resource file {source_path.name} in {resource_folder} folder. "
161
- f"Unclear whether it is {humanize_collection([loader.kind for loader in loaders], bind_word='or')}."
162
- f"\nPlease name the file {names}."
163
- )
164
-
165
- return cast(type[ResourceCRUD], loaders[0]), None
139
+ elif len(crud_candidates) == 1:
140
+ return crud_candidates[0], None
141
+
142
+ # This is unreachable with our current ResourceCRUD classes. We have tests that is exhaustive over
143
+ # all ResourceCRUDs to ensure this.
144
+ names = humanize_collection(
145
+ [f"'{source_path.stem}.{loader.kind}{source_path.suffix}'" for loader in crud_candidates], bind_word="or"
146
+ )
147
+ raise AmbiguousResourceFileError(
148
+ f"Ambiguous resource file {source_path.name} in {resource_folder} folder. "
149
+ f"Unclear whether it is {humanize_collection([crud_cls.kind for crud_cls in crud_candidates], bind_word='or')}."
150
+ f"\nPlease name the file {names}."
151
+ )
166
152
 
167
153
 
168
154
  class DefaultBuilder(Builder):
@@ -3,7 +3,7 @@ from collections.abc import Callable, Iterable, Sequence
3
3
  from typing import Any
4
4
 
5
5
  from cognite_toolkit._cdf_tk.builders import Builder
6
- from cognite_toolkit._cdf_tk.client.data_classes.raw import RawDatabase
6
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.raw import RawDatabase
7
7
  from cognite_toolkit._cdf_tk.cruds import RawDatabaseCRUD, RawTableCRUD, ResourceCRUD
8
8
  from cognite_toolkit._cdf_tk.data_classes import (
9
9
  BuildDestinationFile,
@@ -9,7 +9,7 @@ from typing import Any, ClassVar
9
9
  from rich import print
10
10
 
11
11
  from cognite_toolkit import _version
12
- from cognite_toolkit._cdf_tk.constants import clean_name
12
+ from cognite_toolkit._cdf_tk.constants import RESOURCES_PATH, EnvType, clean_name
13
13
  from cognite_toolkit._cdf_tk.exceptions import (
14
14
  ToolkitRequiredValueError,
15
15
  ToolkitTOMLFormatError,
@@ -176,6 +176,25 @@ class CDFToml:
176
176
  is_loaded_from_file=False,
177
177
  )
178
178
 
179
+ @classmethod
180
+ def write(cls, organization_dir: Path, env: EnvType = "dev", version: str = _version.__version__) -> None:
181
+ destination = Path.cwd() / CDFToml.file_name
182
+ if destination.exists():
183
+ print("cdf.toml file already exists. Skipping creation.")
184
+ return
185
+ cdf_toml_content = (RESOURCES_PATH / CDFToml.file_name).read_text(encoding="utf-8")
186
+ cdf_toml_content = cdf_toml_content.replace("0.0.0", version)
187
+ if organization_dir != Path.cwd():
188
+ cdf_toml_content = cdf_toml_content.replace(
189
+ "#<PLACEHOLDER>",
190
+ f'''
191
+ default_organization_dir = "{organization_dir.name}"''',
192
+ )
193
+ else:
194
+ cdf_toml_content = cdf_toml_content.replace("#<PLACEHOLDER>", "")
195
+ cdf_toml_content = cdf_toml_content.replace("<DEFAULT_ENV_PLACEHOLDER>", env)
196
+ destination.write_text(cdf_toml_content, encoding="utf-8")
197
+
179
198
 
180
199
  def _read_toml(file_path: Path) -> dict[str, Any]:
181
200
  # TOML files are required to be UTF-8 encoded
@@ -3,39 +3,58 @@ from typing import cast
3
3
  from cognite.client import CogniteClient
4
4
  from rich.console import Console
5
5
 
6
+ from cognite_toolkit._cdf_tk.client.api.legacy.canvas import CanvasAPI
7
+ from cognite_toolkit._cdf_tk.client.api.legacy.charts import ChartsAPI
8
+ from cognite_toolkit._cdf_tk.client.api.legacy.dml import DMLAPI
9
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_data_modeling import ExtendedDataModelingAPI
10
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_files import ExtendedFileMetadataAPI
11
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_functions import ExtendedFunctionsAPI
12
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_raw import ExtendedRawAPI
13
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_timeseries import ExtendedTimeSeriesAPI
14
+ from cognite_toolkit._cdf_tk.client.api.legacy.robotics import RoboticsAPI
6
15
  from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient
7
16
 
8
- from .api.canvas import CanvasAPI
9
- from .api.charts import ChartsAPI
10
- from .api.dml import DMLAPI
11
- from .api.extended_data_modeling import ExtendedDataModelingAPI
12
- from .api.extended_files import ExtendedFileMetadataAPI
13
- from .api.extended_functions import ExtendedFunctionsAPI
14
- from .api.extended_raw import ExtendedRawAPI
15
- from .api.extended_timeseries import ExtendedTimeSeriesAPI
16
17
  from .api.infield import InfieldAPI
17
18
  from .api.lookup import LookUpGroup
18
19
  from .api.migration import MigrationAPI
19
20
  from .api.project import ProjectAPI
20
- from .api.robotics import RoboticsAPI
21
21
  from .api.search import SearchAPI
22
+ from .api.streams import StreamsAPI
23
+ from .api.three_d import ThreeDAPI
22
24
  from .api.token import TokenAPI
23
25
  from .api.verify import VerifyAPI
24
26
  from .config import ToolkitClientConfig
25
27
 
26
28
 
29
+ class ToolAPI:
30
+ """This is reimplemented CogniteAPIs in Toolkit"""
31
+
32
+ def __init__(self, http_client: HTTPClient, console: Console) -> None:
33
+ self.http_client = http_client
34
+ self.three_d = ThreeDAPI(http_client, console)
35
+
36
+
27
37
  class ToolkitClient(CogniteClient):
28
- def __init__(self, config: ToolkitClientConfig | None = None, enable_set_pending_ids: bool = False) -> None:
38
+ def __init__(
39
+ self,
40
+ config: ToolkitClientConfig | None = None,
41
+ enable_set_pending_ids: bool = False,
42
+ console: Console | None = None,
43
+ ) -> None:
29
44
  super().__init__(config=config)
30
45
  http_client = HTTPClient(self.config)
46
+ self.http_client = http_client
31
47
  toolkit_config = ToolkitClientConfig.from_client_config(self.config)
32
- self.console = Console()
48
+ self.console = console or Console()
49
+ self.tool = ToolAPI(http_client, self.console)
33
50
  self.search = SearchAPI(self._config, self._API_VERSION, self)
34
51
  self.robotics = RoboticsAPI(self._config, self._API_VERSION, self)
35
52
  self.dml = DMLAPI(self._config, self._API_VERSION, self)
36
53
  self.verify = VerifyAPI(self._config, self._API_VERSION, self)
37
54
  self.lookup = LookUpGroup(self._config, self._API_VERSION, self, self.console)
38
- self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(toolkit_config, self._API_VERSION, self)
55
+ self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(
56
+ toolkit_config, self._API_VERSION, self, self.console
57
+ )
39
58
  self.data_modeling: ExtendedDataModelingAPI = ExtendedDataModelingAPI(self._config, self._API_VERSION, self)
40
59
  if enable_set_pending_ids:
41
60
  self.time_series: ExtendedTimeSeriesAPI = ExtendedTimeSeriesAPI(self._config, self._API_VERSION, self)
@@ -47,6 +66,7 @@ class ToolkitClient(CogniteClient):
47
66
  self.charts = ChartsAPI(self._config, self._API_VERSION, self)
48
67
  self.project = ProjectAPI(config=toolkit_config, cognite_client=self)
49
68
  self.infield = InfieldAPI(http_client, self.console)
69
+ self.streams = StreamsAPI(http_client, self.console)
50
70
 
51
71
  @property
52
72
  def config(self) -> ToolkitClientConfig:
@@ -1,17 +1,26 @@
1
1
  from collections.abc import Sequence
2
2
  from typing import Any, cast
3
3
 
4
+ from pydantic import TypeAdapter
4
5
  from rich.console import Console
5
6
 
6
- from cognite_toolkit._cdf_tk.client.data_classes.api_classes import PagedResponse, QueryResponse
7
- from cognite_toolkit._cdf_tk.client.data_classes.infield import DataExplorationConfig, InfieldLocationConfig
7
+ from cognite_toolkit._cdf_tk.client.data_classes.api_classes import QueryResponse
8
+ from cognite_toolkit._cdf_tk.client.data_classes.infield import (
9
+ DataExplorationConfig,
10
+ InFieldCDMLocationConfig,
11
+ InfieldLocationConfig,
12
+ )
8
13
  from cognite_toolkit._cdf_tk.client.data_classes.instance_api import (
9
14
  InstanceResponseItem,
10
15
  InstanceResult,
11
- NodeIdentifier,
16
+ TypedNodeIdentifier,
12
17
  )
13
18
  from cognite_toolkit._cdf_tk.tk_warnings import HighSeverityWarning
14
- from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, ItemsRequest, SimpleBodyRequest
19
+ from cognite_toolkit._cdf_tk.utils.http_client import (
20
+ HTTPClient,
21
+ ItemsRequest2,
22
+ RequestMessage2,
23
+ )
15
24
 
16
25
 
17
26
  class InfieldConfigAPI:
@@ -36,34 +45,34 @@ class InfieldConfigAPI:
36
45
  else [item.as_request_item(), item.data_exploration_config.as_request_item()]
37
46
  for item in items
38
47
  )
39
- responses = self._http_client.request_with_retries(
40
- ItemsRequest(
48
+ responses = self._http_client.request_items_retries(
49
+ ItemsRequest2(
41
50
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
42
51
  method="POST",
43
52
  items=[item for sublist in request_items for item in sublist],
44
53
  )
45
54
  )
46
55
  responses.raise_for_status()
47
- return PagedResponse[InstanceResult].model_validate(responses.get_first_body()).items
56
+ return TypeAdapter(list[InstanceResult]).validate_python(responses.get_items())
48
57
 
49
- def retrieve(self, items: Sequence[NodeIdentifier]) -> list[InfieldLocationConfig]:
58
+ def retrieve(self, items: Sequence[TypedNodeIdentifier]) -> list[InfieldLocationConfig]:
50
59
  if len(items) > 100:
51
60
  raise ValueError("Cannot retrieve more than 100 InfieldLocationConfig items at once.")
52
61
  if not items:
53
62
  return []
54
- responses = self._http_client.request_with_retries(
55
- SimpleBodyRequest(
63
+ response = self._http_client.request_single_retries(
64
+ RequestMessage2(
56
65
  # We use the query endpoint to be able to retrieve linked DataExplorationConfig items
57
66
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
58
67
  method="POST",
59
68
  body_content=self._retrieve_query(items),
60
69
  )
61
70
  )
62
- responses.raise_for_status()
63
- parsed_response = QueryResponse[InstanceResponseItem].model_validate(responses.get_first_body())
71
+ success = response.get_success_or_raise()
72
+ parsed_response = QueryResponse[InstanceResponseItem].model_validate(success.body_json)
64
73
  return self._parse_retrieve_response(parsed_response)
65
74
 
66
- def delete(self, items: Sequence[InfieldLocationConfig]) -> list[NodeIdentifier]:
75
+ def delete(self, items: Sequence[InfieldLocationConfig]) -> list[TypedNodeIdentifier]:
67
76
  if len(items) > 500:
68
77
  raise ValueError("Cannot delete more than 500 InfieldLocationConfig items at once.")
69
78
 
@@ -73,18 +82,18 @@ class InfieldConfigAPI:
73
82
  else [item.as_id(), item.data_exploration_config.as_id()]
74
83
  for item in items
75
84
  )
76
- responses = self._http_client.request_with_retries(
77
- ItemsRequest(
85
+ responses = self._http_client.request_items_retries(
86
+ ItemsRequest2(
78
87
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
79
88
  method="POST",
80
89
  items=[identifier for sublist in identifiers for identifier in sublist],
81
90
  )
82
91
  )
83
92
  responses.raise_for_status()
84
- return PagedResponse[NodeIdentifier].model_validate(responses.get_first_body()).items
93
+ return TypeAdapter(list[TypedNodeIdentifier]).validate_python(responses.get_items())
85
94
 
86
95
  @classmethod
87
- def _retrieve_query(cls, items: Sequence[NodeIdentifier]) -> dict[str, Any]:
96
+ def _retrieve_query(cls, items: Sequence[TypedNodeIdentifier]) -> dict[str, Any]:
88
97
  return {
89
98
  "with": {
90
99
  cls.LOCATION_REF: {
@@ -150,7 +159,95 @@ class InfieldConfigAPI:
150
159
  return result
151
160
 
152
161
 
162
+ class InFieldCDMConfigAPI:
163
+ ENDPOINT = "/models/instances"
164
+ LOCATION_REF = "cdmLocationConfig"
165
+
166
+ def __init__(self, http_client: HTTPClient, console: Console) -> None:
167
+ self._http_client = http_client
168
+ self._console = console
169
+ self._config = http_client.config
170
+
171
+ def apply(self, items: Sequence[InFieldCDMLocationConfig]) -> list[InstanceResult]:
172
+ if len(items) > 500:
173
+ raise ValueError("Cannot apply more than 500 InFieldCDMLocationConfig items at once.")
174
+
175
+ request_items = [item.as_request_item() for item in items]
176
+ results = self._http_client.request_items_retries(
177
+ ItemsRequest2(
178
+ endpoint_url=self._config.create_api_url(self.ENDPOINT),
179
+ method="POST",
180
+ items=request_items,
181
+ )
182
+ )
183
+ results.raise_for_status()
184
+ return TypeAdapter(list[InstanceResult]).validate_python(results.get_items())
185
+
186
+ def retrieve(self, items: Sequence[TypedNodeIdentifier]) -> list[InFieldCDMLocationConfig]:
187
+ if len(items) > 100:
188
+ raise ValueError("Cannot retrieve more than 100 InFieldCDMLocationConfig items at once.")
189
+ if not items:
190
+ return []
191
+ result = self._http_client.request_single_retries(
192
+ RequestMessage2(
193
+ endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
194
+ method="POST",
195
+ body_content=self._retrieve_query(items),
196
+ )
197
+ )
198
+ success = result.get_success_or_raise()
199
+ parsed_response = QueryResponse[InstanceResponseItem].model_validate(success.body_json)
200
+ return self._parse_retrieve_response(parsed_response)
201
+
202
+ def delete(self, items: Sequence[InFieldCDMLocationConfig]) -> list[TypedNodeIdentifier]:
203
+ if len(items) > 500:
204
+ raise ValueError("Cannot delete more than 500 InFieldCDMLocationConfig items at once.")
205
+
206
+ identifiers = [item.as_id() for item in items]
207
+ responses = self._http_client.request_items_retries(
208
+ ItemsRequest2(
209
+ endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
210
+ method="POST",
211
+ items=identifiers,
212
+ )
213
+ )
214
+ responses.raise_for_status()
215
+ return TypeAdapter(list[TypedNodeIdentifier]).validate_python(responses.get_items())
216
+
217
+ @classmethod
218
+ def _retrieve_query(cls, items: Sequence[TypedNodeIdentifier]) -> dict[str, Any]:
219
+ return {
220
+ "with": {
221
+ cls.LOCATION_REF: {
222
+ "limit": len(items),
223
+ "nodes": {
224
+ "filter": {
225
+ "instanceReferences": [
226
+ {"space": item.space, "externalId": item.external_id} for item in items
227
+ ]
228
+ },
229
+ },
230
+ },
231
+ },
232
+ "select": {
233
+ cls.LOCATION_REF: {
234
+ "sources": [{"source": InFieldCDMLocationConfig.VIEW_ID.dump(), "properties": ["*"]}],
235
+ },
236
+ },
237
+ }
238
+
239
+ def _parse_retrieve_response(
240
+ self, parsed_response: QueryResponse[InstanceResponseItem]
241
+ ) -> list[InFieldCDMLocationConfig]:
242
+ result: list[InFieldCDMLocationConfig] = []
243
+ for item in parsed_response.items[self.LOCATION_REF]:
244
+ properties = item.get_properties_for_source(InFieldCDMLocationConfig.VIEW_ID, include_identifier=True)
245
+ result.append(InFieldCDMLocationConfig.model_validate(properties))
246
+ return result
247
+
248
+
153
249
  class InfieldAPI:
154
250
  def __init__(self, http_client: HTTPClient, console: Console) -> None:
155
251
  self._http_client = http_client
156
252
  self.config = InfieldConfigAPI(http_client, console)
253
+ self.cdm_config = InFieldCDMConfigAPI(http_client, console)
@@ -15,7 +15,8 @@ from cognite.client.data_classes.filters import Filter
15
15
  from cognite.client.exceptions import CogniteDuplicatedError
16
16
  from cognite.client.utils.useful_types import SequenceNotStr
17
17
 
18
- from cognite_toolkit._cdf_tk.client.data_classes.canvas import (
18
+ from cognite_toolkit._cdf_tk.client.api.legacy.extended_data_modeling import ExtendedInstancesAPI
19
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.canvas import (
19
20
  ANNOTATION_EDGE_TYPE,
20
21
  CANVAS_INSTANCE_SPACE,
21
22
  CONTAINER_REFERENCE_EDGE_TYPE,
@@ -29,11 +30,9 @@ from cognite_toolkit._cdf_tk.client.data_classes.canvas import (
29
30
  IndustrialCanvas,
30
31
  IndustrialCanvasApply,
31
32
  )
32
- from cognite_toolkit._cdf_tk.client.data_classes.instances import InstancesApplyResultList
33
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.instances import InstancesApplyResultList
33
34
  from cognite_toolkit._cdf_tk.exceptions import ToolkitValueError
34
35
 
35
- from .extended_data_modeling import ExtendedInstancesAPI
36
-
37
36
 
38
37
  class CanvasAPI:
39
38
  def __init__(self, instance_api: ExtendedInstancesAPI) -> None:
@@ -134,6 +133,9 @@ class IndustrialCanvasAPI:
134
133
 
135
134
  @classmethod
136
135
  def _retrieve_query(cls, external_id: str) -> query.Query:
136
+ # The limit for canvas components must be high enough to cover all annotations/references in a canvas.
137
+ # Using 1000 as a safe upper bound (same as _APPLY_LIMIT).
138
+ query_limit = 1000
137
139
  return query.Query(
138
140
  with_={
139
141
  "canvas": query.NodeResultSetExpression(
@@ -143,18 +145,21 @@ class IndustrialCanvasAPI:
143
145
  "solutionTags": query.NodeResultSetExpression(
144
146
  from_="canvas",
145
147
  through=Canvas.get_source().as_property_ref("solutionTags"),
148
+ limit=query_limit,
146
149
  ),
147
150
  "annotationEdges": query.EdgeResultSetExpression(
148
151
  from_="canvas",
149
152
  filter=filters.Equals(["edge", "type"], ANNOTATION_EDGE_TYPE.dump()),
150
153
  node_filter=filters.HasData(views=[CanvasAnnotation.get_source()]),
151
154
  direction="outwards",
155
+ limit=query_limit,
152
156
  ),
153
157
  "containerReferenceEdges": query.EdgeResultSetExpression(
154
158
  from_="canvas",
155
159
  filter=filters.Equals(["edge", "type"], CONTAINER_REFERENCE_EDGE_TYPE.dump()),
156
160
  node_filter=filters.HasData(views=[ContainerReference.get_source()]),
157
161
  direction="outwards",
162
+ limit=query_limit,
158
163
  ),
159
164
  "fdmInstanceContainerReferenceEdges": query.EdgeResultSetExpression(
160
165
  from_="canvas",
@@ -164,11 +169,14 @@ class IndustrialCanvasAPI:
164
169
  ),
165
170
  node_filter=filters.HasData(views=[FdmInstanceContainerReference.get_source()]),
166
171
  direction="outwards",
172
+ limit=query_limit,
173
+ ),
174
+ "annotations": query.NodeResultSetExpression(from_="annotationEdges", limit=query_limit),
175
+ "containerReferences": query.NodeResultSetExpression(
176
+ from_="containerReferenceEdges", limit=query_limit
167
177
  ),
168
- "annotations": query.NodeResultSetExpression(from_="annotationEdges"),
169
- "containerReferences": query.NodeResultSetExpression(from_="containerReferenceEdges"),
170
178
  "fdmInstanceContainerReferences": query.NodeResultSetExpression(
171
- from_="fdmInstanceContainerReferenceEdges"
179
+ from_="fdmInstanceContainerReferenceEdges", limit=query_limit
172
180
  ),
173
181
  },
174
182
  select={