cognite-toolkit 0.7.30__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 (121) hide show
  1. cognite_toolkit/_cdf.py +5 -6
  2. cognite_toolkit/_cdf_tk/apps/__init__.py +2 -0
  3. cognite_toolkit/_cdf_tk/apps/_core_app.py +7 -1
  4. cognite_toolkit/_cdf_tk/apps/_download_app.py +2 -2
  5. cognite_toolkit/_cdf_tk/apps/_dump_app.py +1 -1
  6. cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
  7. cognite_toolkit/_cdf_tk/apps/_migrate_app.py +177 -2
  8. cognite_toolkit/_cdf_tk/builders/_raw.py +1 -1
  9. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +9 -9
  10. cognite_toolkit/_cdf_tk/client/api/infield.py +38 -33
  11. cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
  12. cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
  13. cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
  14. cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
  15. cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +9 -9
  16. cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
  17. cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
  18. cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
  19. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
  20. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
  21. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
  22. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
  23. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
  24. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
  25. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
  26. cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
  27. cognite_toolkit/_cdf_tk/client/api/migration.py +2 -3
  28. cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
  29. cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
  30. cognite_toolkit/_cdf_tk/client/api/streams.py +21 -17
  31. cognite_toolkit/_cdf_tk/client/api/three_d.py +343 -9
  32. cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
  33. cognite_toolkit/_cdf_tk/client/data_classes/base.py +12 -32
  34. cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +18 -13
  35. cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
  36. cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +1 -1
  37. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +65 -0
  38. cognite_toolkit/_cdf_tk/client/testing.py +24 -16
  39. cognite_toolkit/_cdf_tk/commands/__init__.py +1 -0
  40. cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +8 -2
  41. cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
  42. cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +35 -4
  43. cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +149 -14
  44. cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
  45. cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +1 -1
  46. cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +19 -1
  47. cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +220 -3
  48. cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
  49. cognite_toolkit/_cdf_tk/commands/_purge.py +9 -11
  50. cognite_toolkit/_cdf_tk/commands/build_cmd.py +1 -1
  51. cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
  52. cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
  53. cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
  54. cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
  55. cognite_toolkit/_cdf_tk/commands/dump_resource.py +4 -4
  56. cognite_toolkit/_cdf_tk/commands/run.py +1 -1
  57. cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +2 -2
  58. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +1 -1
  59. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +1 -1
  60. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +1 -1
  61. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +1 -1
  62. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +1 -1
  63. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +22 -20
  64. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +1 -1
  65. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +14 -2
  66. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +1 -1
  67. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +1 -1
  68. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +1 -1
  69. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +1 -1
  70. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +1 -1
  71. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +49 -14
  72. cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
  73. cognite_toolkit/_cdf_tk/resource_classes/search_config.py +1 -1
  74. cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
  75. cognite_toolkit/_cdf_tk/storageio/_applications.py +2 -2
  76. cognite_toolkit/_cdf_tk/storageio/_file_content.py +1 -2
  77. cognite_toolkit/_cdf_tk/storageio/_instances.py +1 -1
  78. cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +10 -1
  79. cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py +34 -0
  80. cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
  81. cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
  82. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +3 -2
  83. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +6 -0
  84. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +67 -7
  85. cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
  86. cognite_toolkit/_cdf_tk/utils/interactive_select.py +51 -4
  87. cognite_toolkit/_cdf_tk/validation.py +4 -0
  88. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  89. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  90. cognite_toolkit/_resources/cdf.toml +1 -1
  91. cognite_toolkit/_version.py +1 -1
  92. {cognite_toolkit-0.7.30.dist-info → cognite_toolkit-0.7.39.dist-info}/METADATA +1 -1
  93. {cognite_toolkit-0.7.30.dist-info → cognite_toolkit-0.7.39.dist-info}/RECORD +119 -113
  94. {cognite_toolkit-0.7.30.dist-info → cognite_toolkit-0.7.39.dist-info}/WHEEL +1 -1
  95. cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
  96. cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
  97. /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
  98. /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
  99. /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
  100. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
  101. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
  102. /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
  103. /cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +0 -0
  104. /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
  105. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
  106. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
  107. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
  108. /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
  109. /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
  110. /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
  111. /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
  112. /cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/migration.py} +0 -0
  113. /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
  114. /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
  115. /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
  116. /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
  117. /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
  118. /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
  119. /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
  120. /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
  121. {cognite_toolkit-0.7.30.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +0 -0
cognite_toolkit/_cdf.py CHANGED
@@ -27,6 +27,7 @@ from cognite_toolkit._cdf_tk.apps import (
27
27
  DataApp,
28
28
  DevApp,
29
29
  DumpApp,
30
+ ImportApp,
30
31
  LandingApp,
31
32
  MigrateApp,
32
33
  ModulesApp,
@@ -42,7 +43,7 @@ from cognite_toolkit._cdf_tk.constants import HINT_LEAD_TEXT, URL, USE_SENTRY
42
43
  from cognite_toolkit._cdf_tk.exceptions import (
43
44
  ToolkitError,
44
45
  )
45
- from cognite_toolkit._cdf_tk.feature_flags import FeatureFlag, Flags
46
+ from cognite_toolkit._cdf_tk.feature_flags import Flags
46
47
  from cognite_toolkit._cdf_tk.plugins import Plugins
47
48
  from cognite_toolkit._cdf_tk.tracker import Tracker
48
49
  from cognite_toolkit._cdf_tk.utils import (
@@ -108,6 +109,9 @@ if Flags.PROFILE.is_enabled():
108
109
  if Flags.MIGRATE.is_enabled():
109
110
  _app.add_typer(MigrateApp(**default_typer_kws), name="migrate")
110
111
 
112
+ if Flags.IMPORT_CMD.is_enabled():
113
+ _app.add_typer(ImportApp(**default_typer_kws), name="import")
114
+
111
115
  if Plugins.data.value.is_enabled():
112
116
  _app.add_typer(DataApp(**default_typer_kws), name="data")
113
117
 
@@ -126,11 +130,6 @@ def app() -> NoReturn:
126
130
  # --- Main entry point ---
127
131
  # Users run 'app()' directly, but that doesn't allow us to control excepton handling:
128
132
  try:
129
- if FeatureFlag.is_enabled(Flags.IMPORT_CMD):
130
- from cognite_toolkit._cdf_tk.prototypes.import_app import import_app
131
-
132
- _app.add_typer(import_app, name="import")
133
-
134
133
  _app()
135
134
  except ToolkitError as err:
136
135
  if "--verbose" in sys.argv:
@@ -4,6 +4,7 @@ from ._data_app import DataApp
4
4
  from ._dev_app import DevApp
5
5
  from ._download_app import DownloadApp
6
6
  from ._dump_app import DumpApp
7
+ from ._import_app import ImportApp
7
8
  from ._landing_app import LandingApp
8
9
  from ._migrate_app import MigrateApp
9
10
  from ._modules_app import ModulesApp
@@ -20,6 +21,7 @@ __all__ = [
20
21
  "DevApp",
21
22
  "DownloadApp",
22
23
  "DumpApp",
24
+ "ImportApp",
23
25
  "LandingApp",
24
26
  "MigrateApp",
25
27
  "ModulesApp",
@@ -13,8 +13,10 @@ from rich.panel import Panel
13
13
  from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
14
14
  from cognite_toolkit._cdf_tk.client import ToolkitClient
15
15
  from cognite_toolkit._cdf_tk.commands import BuildCommand, CleanCommand, DeployCommand
16
+ from cognite_toolkit._cdf_tk.commands.build_v2.build_cmd import BuildCommand as BuildCommandV2
16
17
  from cognite_toolkit._cdf_tk.commands.clean import AVAILABLE_DATA_TYPES
17
18
  from cognite_toolkit._cdf_tk.exceptions import ToolkitFileNotFoundError
19
+ from cognite_toolkit._cdf_tk.feature_flags import Flags
18
20
  from cognite_toolkit._cdf_tk.utils import get_cicd_environment
19
21
  from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
20
22
  from cognite_toolkit._version import __version__ as current_version
@@ -207,7 +209,11 @@ class CoreApp(typer.Typer):
207
209
  if exit_on_warning:
208
210
  print_warning = False
209
211
 
210
- cmd = BuildCommand(print_warning=print_warning)
212
+ cmd = (
213
+ BuildCommandV2(print_warning=print_warning)
214
+ if Flags.v08.is_enabled()
215
+ else BuildCommand(print_warning=print_warning)
216
+ )
211
217
  cmd.run(
212
218
  lambda: cmd.execute(
213
219
  verbose,
@@ -7,7 +7,7 @@ import typer
7
7
  from questionary import Choice
8
8
  from rich import print
9
9
 
10
- from cognite_toolkit._cdf_tk.client.data_classes.raw import RawTable
10
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.raw import RawTable
11
11
  from cognite_toolkit._cdf_tk.commands import DownloadCommand
12
12
  from cognite_toolkit._cdf_tk.constants import DATA_DEFAULT_DIR
13
13
  from cognite_toolkit._cdf_tk.feature_flags import Flags
@@ -616,7 +616,7 @@ class DownloadApp(typer.Typer):
616
616
  file_format = AssetCentricFormats.ndjson
617
617
  files = client.files.list(data_set_external_ids=data_sets, limit=limit)
618
618
  selector = FileIdentifierSelector(
619
- identifiers=tuple([FileInternalID(internal_id=file.id) for file in files]) # type: ignore[call-arg]
619
+ identifiers=tuple([FileInternalID(internal_id=file.id) for file in files])
620
620
  )
621
621
  selectors = [selector]
622
622
  io = FileContentIO(client, output_dir / sanitize_filename(selector.group))
@@ -6,7 +6,7 @@ from cognite.client.data_classes import WorkflowVersionId
6
6
  from cognite.client.data_classes.data_modeling import DataModelId, ViewId
7
7
  from rich import print
8
8
 
9
- from cognite_toolkit._cdf_tk.client.data_classes.search_config import ViewId as SearchConfigViewId
9
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.search_config import ViewId as SearchConfigViewId
10
10
  from cognite_toolkit._cdf_tk.commands import DumpResourceCommand
11
11
  from cognite_toolkit._cdf_tk.commands.dump_resource import (
12
12
  AgentFinder,
@@ -0,0 +1,41 @@
1
+ from pathlib import Path
2
+ from typing import Any
3
+
4
+ import typer
5
+
6
+ from cognite_toolkit._cdf_tk.client import ToolkitClient
7
+ from cognite_toolkit._cdf_tk.commands._import_cmd import ImportTransformationCLI
8
+ from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
9
+
10
+
11
+ class ImportApp(typer.Typer):
12
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
13
+ super().__init__(*args, **kwargs)
14
+ self.callback(invoke_without_command=True)(self.main)
15
+ self.command("transformation-cli")(self.transformation_cli)
16
+
17
+ def main(self, ctx: typer.Context) -> None:
18
+ """PREVIEW FEATURE Import resources into Cognite-Toolkit."""
19
+ if ctx.invoked_subcommand is None:
20
+ print("Use [bold yellow]cdf-tk import --help[/] for more information.")
21
+ return None
22
+
23
+ @staticmethod
24
+ def transformation_cli(
25
+ source: Path = typer.Argument(..., help="Path to the transformation CLI manifest directory or files."),
26
+ destination: Path = typer.Argument(..., help="Path to the destination directory."),
27
+ overwrite: bool = typer.Option(False, help="Overwrite destination if it already exists."),
28
+ flatten: bool = typer.Option(False, help="Flatten the directory structure."),
29
+ clean: bool = typer.Option(False, help="Remove the source directory after import."),
30
+ verbose: bool = typer.Option(False, help="Turn on to get more verbose output when running the command"),
31
+ ) -> None:
32
+ """Import transformation CLI manifests into Cognite-Toolkit modules."""
33
+
34
+ # We are lazy loading the client as we only need it if we need to look up dataset ids.
35
+ # This is to ensure the command can be executed without a client if the user does not need to look up dataset ids.
36
+ # (which is likely 99% of the time)
37
+ def get_client() -> ToolkitClient:
38
+ return EnvironmentVariables.create_from_environment().get_client()
39
+
40
+ cmd = ImportTransformationCLI(print_warning=True, get_client=get_client)
41
+ cmd.execute(source, destination, overwrite, flatten, clean, verbose=verbose)
@@ -15,10 +15,18 @@ from cognite_toolkit._cdf_tk.commands._migrate.creators import (
15
15
  InstanceSpaceCreator,
16
16
  SourceSystemCreator,
17
17
  )
18
- from cognite_toolkit._cdf_tk.commands._migrate.data_mapper import AssetCentricMapper, CanvasMapper, ChartMapper
18
+ from cognite_toolkit._cdf_tk.commands._migrate.data_mapper import (
19
+ AssetCentricMapper,
20
+ CanvasMapper,
21
+ ChartMapper,
22
+ ThreeDAssetMapper,
23
+ ThreeDMapper,
24
+ )
19
25
  from cognite_toolkit._cdf_tk.commands._migrate.migration_io import (
20
26
  AnnotationMigrationIO,
21
27
  AssetCentricMigrationIO,
28
+ ThreeDAssetMappingMigrationIO,
29
+ ThreeDMigrationIO,
22
30
  )
23
31
  from cognite_toolkit._cdf_tk.commands._migrate.selectors import (
24
32
  AssetCentricMigrationSelector,
@@ -26,7 +34,11 @@ from cognite_toolkit._cdf_tk.commands._migrate.selectors import (
26
34
  MigrationCSVFileSelector,
27
35
  )
28
36
  from cognite_toolkit._cdf_tk.storageio import CanvasIO, ChartIO
29
- from cognite_toolkit._cdf_tk.storageio.selectors import CanvasExternalIdSelector, ChartExternalIdSelector
37
+ from cognite_toolkit._cdf_tk.storageio.selectors import (
38
+ CanvasExternalIdSelector,
39
+ ChartExternalIdSelector,
40
+ ThreeDModelIdSelector,
41
+ )
30
42
  from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
31
43
  from cognite_toolkit._cdf_tk.utils.cli_args import parse_view_str
32
44
  from cognite_toolkit._cdf_tk.utils.interactive_select import (
@@ -36,6 +48,7 @@ from cognite_toolkit._cdf_tk.utils.interactive_select import (
36
48
  InteractiveCanvasSelect,
37
49
  InteractiveChartSelect,
38
50
  ResourceViewMappingInteractiveSelect,
51
+ ThreeDInteractiveSelect,
39
52
  )
40
53
  from cognite_toolkit._cdf_tk.utils.useful_types import AssetCentricKind
41
54
 
@@ -56,6 +69,8 @@ class MigrateApp(typer.Typer):
56
69
  self.command("annotations")(self.annotations)
57
70
  self.command("canvas")(self.canvas)
58
71
  self.command("charts")(self.charts)
72
+ self.command("3d")(self.three_d)
73
+ self.command("3d-mappings")(self.three_d_asset_mapping)
59
74
  # Uncomment when infield v2 config migration is ready
60
75
  # self.command("infield-configs")(self.infield_configs)
61
76
 
@@ -980,6 +995,166 @@ class MigrateApp(typer.Typer):
980
995
  )
981
996
  )
982
997
 
998
+ @staticmethod
999
+ def three_d(
1000
+ ctx: typer.Context,
1001
+ id: Annotated[
1002
+ list[int] | None,
1003
+ typer.Argument(
1004
+ help="The ID of the 3D Model to migrate. If not provided, an interactive selection will be "
1005
+ "performed to select the 3D Models to migrate."
1006
+ ),
1007
+ ] = None,
1008
+ log_dir: Annotated[
1009
+ Path,
1010
+ typer.Option(
1011
+ "--log-dir",
1012
+ "-l",
1013
+ help="Path to the directory where migration logs will be stored.",
1014
+ ),
1015
+ ] = Path(f"migration_logs_{TODAY}"),
1016
+ dry_run: Annotated[
1017
+ bool,
1018
+ typer.Option(
1019
+ "--dry-run",
1020
+ "-d",
1021
+ help="If set, the migration will not be executed, but only a report of "
1022
+ "what would be done is printed. This is useful for checking that all resources referenced by the 3D Models "
1023
+ "have been migrated to the new data modeling resources in CDF.",
1024
+ ),
1025
+ ] = False,
1026
+ verbose: Annotated[
1027
+ bool,
1028
+ typer.Option(
1029
+ "--verbose",
1030
+ "-v",
1031
+ help="Turn on to get more verbose output when running the command",
1032
+ ),
1033
+ ] = False,
1034
+ ) -> None:
1035
+ """Migrate 3D Models from Asset-Centric to data modeling in CDF.
1036
+
1037
+ This command expects that the CogniteMigration data model is already deployed, and that the Mapping view
1038
+ is populated with the mapping from Asset-Centric resources to the new data modeling resources.
1039
+ """
1040
+ client = EnvironmentVariables.create_from_environment().get_client()
1041
+ selected_ids: list[int]
1042
+ if id:
1043
+ selected_ids = id
1044
+ else:
1045
+ selected_models = ThreeDInteractiveSelect(client, "migrate").select_three_d_models("classic")
1046
+ selected_ids = [model.id for model in selected_models]
1047
+
1048
+ cmd = MigrationCommand()
1049
+ cmd.run(
1050
+ lambda: cmd.migrate(
1051
+ selected=ThreeDModelIdSelector(ids=tuple(selected_ids)),
1052
+ data=ThreeDMigrationIO(client),
1053
+ mapper=ThreeDMapper(client),
1054
+ log_dir=log_dir,
1055
+ dry_run=dry_run,
1056
+ verbose=verbose,
1057
+ )
1058
+ )
1059
+
1060
+ @staticmethod
1061
+ def three_d_asset_mapping(
1062
+ ctx: typer.Context,
1063
+ model_id: Annotated[
1064
+ list[int] | None,
1065
+ typer.Argument(
1066
+ help="The IDs of the 3D model to migrate asset mappings for. If not provided, an interactive selection will be "
1067
+ "performed to select the."
1068
+ ),
1069
+ ] = None,
1070
+ object_3D_space: Annotated[
1071
+ str | None,
1072
+ typer.Option(
1073
+ "--object-3d-space",
1074
+ "-o",
1075
+ help="The instance space to ceate the 3D object nodes in.",
1076
+ ),
1077
+ ] = None,
1078
+ cad_node_space: Annotated[
1079
+ str | None,
1080
+ typer.Option(
1081
+ "--cad-node-space",
1082
+ "-c",
1083
+ help="The instance space to create the CAD node nodes in.",
1084
+ ),
1085
+ ] = None,
1086
+ log_dir: Annotated[
1087
+ Path,
1088
+ typer.Option(
1089
+ "--log-dir",
1090
+ "-l",
1091
+ help="Path to the directory where migration logs will be stored.",
1092
+ ),
1093
+ ] = Path(f"migration_logs_{TODAY}"),
1094
+ dry_run: Annotated[
1095
+ bool,
1096
+ typer.Option(
1097
+ "--dry-run",
1098
+ "-d",
1099
+ help="If set, the migration will not be executed, but only a report of what would be done is printed.",
1100
+ ),
1101
+ ] = False,
1102
+ verbose: Annotated[
1103
+ bool,
1104
+ typer.Option(
1105
+ "--verbose",
1106
+ "-v",
1107
+ help="Turn on to get more verbose output when running the command",
1108
+ ),
1109
+ ] = False,
1110
+ ) -> None:
1111
+ """Migrate 3D Model Asset Mappings from Asset-Centric to data modeling in CDF.
1112
+
1113
+ This command expects that the selected 3D model has already been migrated to data modeling.
1114
+ """
1115
+ client = EnvironmentVariables.create_from_environment().get_client()
1116
+ selected_ids: list[int]
1117
+ if model_id is not None:
1118
+ selected_ids = model_id
1119
+ else:
1120
+ # Interactive selection
1121
+ selected_models = ThreeDInteractiveSelect(client, "migrate").select_three_d_models("dm")
1122
+ selected_ids = [model.id for model in selected_models]
1123
+ space_selector = DataModelingSelect(client, "migrate")
1124
+ object_3D_space = space_selector.select_instance_space(
1125
+ multiselect=False,
1126
+ message="In which instance space do you want to create the 3D Object nodes?",
1127
+ include_empty=False,
1128
+ )
1129
+ cad_node_space = space_selector.select_instance_space(
1130
+ multiselect=False,
1131
+ message="In which instance space do you want to create the CAD Node nodes?",
1132
+ include_empty=False,
1133
+ )
1134
+ dry_run = questionary.confirm("Do you want to perform a dry run?", default=dry_run).ask()
1135
+ verbose = questionary.confirm("Do you want verbose output?", default=verbose).ask()
1136
+ if any(res is None for res in [dry_run, verbose]):
1137
+ raise typer.Abort()
1138
+
1139
+ if object_3D_space is None or cad_node_space is None:
1140
+ raise typer.BadParameter(
1141
+ "--object-3d-space and --cad-node-space are required when specifying IDs directly."
1142
+ )
1143
+
1144
+ cmd = MigrationCommand()
1145
+ cmd.run(
1146
+ lambda: cmd.migrate(
1147
+ selected=ThreeDModelIdSelector(ids=tuple(selected_ids)),
1148
+ data=ThreeDAssetMappingMigrationIO(
1149
+ client, object_3D_space=object_3D_space, cad_node_space=cad_node_space
1150
+ ),
1151
+ mapper=ThreeDAssetMapper(client),
1152
+ log_dir=log_dir,
1153
+ dry_run=dry_run,
1154
+ verbose=verbose,
1155
+ )
1156
+ )
1157
+
983
1158
  @staticmethod
984
1159
  def infield_configs(
985
1160
  ctx: typer.Context,
@@ -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,
@@ -3,21 +3,21 @@ 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
22
  from .api.streams import StreamsAPI
23
23
  from .api.three_d import ThreeDAPI
@@ -1,9 +1,10 @@
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.api_classes import QueryResponse
7
8
  from cognite_toolkit._cdf_tk.client.data_classes.infield import (
8
9
  DataExplorationConfig,
9
10
  InFieldCDMLocationConfig,
@@ -12,10 +13,14 @@ from cognite_toolkit._cdf_tk.client.data_classes.infield import (
12
13
  from cognite_toolkit._cdf_tk.client.data_classes.instance_api import (
13
14
  InstanceResponseItem,
14
15
  InstanceResult,
15
- NodeIdentifier,
16
+ TypedNodeIdentifier,
16
17
  )
17
18
  from cognite_toolkit._cdf_tk.tk_warnings import HighSeverityWarning
18
- 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
+ )
19
24
 
20
25
 
21
26
  class InfieldConfigAPI:
@@ -40,34 +45,34 @@ class InfieldConfigAPI:
40
45
  else [item.as_request_item(), item.data_exploration_config.as_request_item()]
41
46
  for item in items
42
47
  )
43
- responses = self._http_client.request_with_retries(
44
- ItemsRequest(
48
+ responses = self._http_client.request_items_retries(
49
+ ItemsRequest2(
45
50
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
46
51
  method="POST",
47
52
  items=[item for sublist in request_items for item in sublist],
48
53
  )
49
54
  )
50
55
  responses.raise_for_status()
51
- return PagedResponse[InstanceResult].model_validate(responses.get_first_body()).items
56
+ return TypeAdapter(list[InstanceResult]).validate_python(responses.get_items())
52
57
 
53
- def retrieve(self, items: Sequence[NodeIdentifier]) -> list[InfieldLocationConfig]:
58
+ def retrieve(self, items: Sequence[TypedNodeIdentifier]) -> list[InfieldLocationConfig]:
54
59
  if len(items) > 100:
55
60
  raise ValueError("Cannot retrieve more than 100 InfieldLocationConfig items at once.")
56
61
  if not items:
57
62
  return []
58
- responses = self._http_client.request_with_retries(
59
- SimpleBodyRequest(
63
+ response = self._http_client.request_single_retries(
64
+ RequestMessage2(
60
65
  # We use the query endpoint to be able to retrieve linked DataExplorationConfig items
61
66
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
62
67
  method="POST",
63
68
  body_content=self._retrieve_query(items),
64
69
  )
65
70
  )
66
- responses.raise_for_status()
67
- 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)
68
73
  return self._parse_retrieve_response(parsed_response)
69
74
 
70
- def delete(self, items: Sequence[InfieldLocationConfig]) -> list[NodeIdentifier]:
75
+ def delete(self, items: Sequence[InfieldLocationConfig]) -> list[TypedNodeIdentifier]:
71
76
  if len(items) > 500:
72
77
  raise ValueError("Cannot delete more than 500 InfieldLocationConfig items at once.")
73
78
 
@@ -77,18 +82,18 @@ class InfieldConfigAPI:
77
82
  else [item.as_id(), item.data_exploration_config.as_id()]
78
83
  for item in items
79
84
  )
80
- responses = self._http_client.request_with_retries(
81
- ItemsRequest(
85
+ responses = self._http_client.request_items_retries(
86
+ ItemsRequest2(
82
87
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
83
88
  method="POST",
84
89
  items=[identifier for sublist in identifiers for identifier in sublist],
85
90
  )
86
91
  )
87
92
  responses.raise_for_status()
88
- return PagedResponse[NodeIdentifier].model_validate(responses.get_first_body()).items
93
+ return TypeAdapter(list[TypedNodeIdentifier]).validate_python(responses.get_items())
89
94
 
90
95
  @classmethod
91
- def _retrieve_query(cls, items: Sequence[NodeIdentifier]) -> dict[str, Any]:
96
+ def _retrieve_query(cls, items: Sequence[TypedNodeIdentifier]) -> dict[str, Any]:
92
97
  return {
93
98
  "with": {
94
99
  cls.LOCATION_REF: {
@@ -168,49 +173,49 @@ class InFieldCDMConfigAPI:
168
173
  raise ValueError("Cannot apply more than 500 InFieldCDMLocationConfig items at once.")
169
174
 
170
175
  request_items = [item.as_request_item() for item in items]
171
- responses = self._http_client.request_with_retries(
172
- ItemsRequest(
176
+ results = self._http_client.request_items_retries(
177
+ ItemsRequest2(
173
178
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
174
179
  method="POST",
175
- items=request_items, # type: ignore[arg-type]
180
+ items=request_items,
176
181
  )
177
182
  )
178
- responses.raise_for_status()
179
- return PagedResponse[InstanceResult].model_validate(responses.get_first_body()).items
183
+ results.raise_for_status()
184
+ return TypeAdapter(list[InstanceResult]).validate_python(results.get_items())
180
185
 
181
- def retrieve(self, items: Sequence[NodeIdentifier]) -> list[InFieldCDMLocationConfig]:
186
+ def retrieve(self, items: Sequence[TypedNodeIdentifier]) -> list[InFieldCDMLocationConfig]:
182
187
  if len(items) > 100:
183
188
  raise ValueError("Cannot retrieve more than 100 InFieldCDMLocationConfig items at once.")
184
189
  if not items:
185
190
  return []
186
- responses = self._http_client.request_with_retries(
187
- SimpleBodyRequest(
191
+ result = self._http_client.request_single_retries(
192
+ RequestMessage2(
188
193
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
189
194
  method="POST",
190
195
  body_content=self._retrieve_query(items),
191
196
  )
192
197
  )
193
- responses.raise_for_status()
194
- parsed_response = QueryResponse[InstanceResponseItem].model_validate(responses.get_first_body())
198
+ success = result.get_success_or_raise()
199
+ parsed_response = QueryResponse[InstanceResponseItem].model_validate(success.body_json)
195
200
  return self._parse_retrieve_response(parsed_response)
196
201
 
197
- def delete(self, items: Sequence[InFieldCDMLocationConfig]) -> list[NodeIdentifier]:
202
+ def delete(self, items: Sequence[InFieldCDMLocationConfig]) -> list[TypedNodeIdentifier]:
198
203
  if len(items) > 500:
199
204
  raise ValueError("Cannot delete more than 500 InFieldCDMLocationConfig items at once.")
200
205
 
201
- identifiers: Sequence = [item.as_id() for item in items]
202
- responses = self._http_client.request_with_retries(
203
- ItemsRequest(
206
+ identifiers = [item.as_id() for item in items]
207
+ responses = self._http_client.request_items_retries(
208
+ ItemsRequest2(
204
209
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
205
210
  method="POST",
206
- items=identifiers, # type: ignore[arg-type]
211
+ items=identifiers,
207
212
  )
208
213
  )
209
214
  responses.raise_for_status()
210
- return PagedResponse[NodeIdentifier].model_validate(responses.get_first_body()).items
215
+ return TypeAdapter(list[TypedNodeIdentifier]).validate_python(responses.get_items())
211
216
 
212
217
  @classmethod
213
- def _retrieve_query(cls, items: Sequence[NodeIdentifier]) -> dict[str, Any]:
218
+ def _retrieve_query(cls, items: Sequence[TypedNodeIdentifier]) -> dict[str, Any]:
214
219
  return {
215
220
  "with": {
216
221
  cls.LOCATION_REF: {
@@ -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={
@@ -6,7 +6,7 @@ from cognite.client._api_client import APIClient
6
6
  from cognite.client.utils._identifier import IdentifierSequence
7
7
  from cognite.client.utils.useful_types import SequenceNotStr
8
8
 
9
- from cognite_toolkit._cdf_tk.client.data_classes.charts import (
9
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.charts import (
10
10
  Chart,
11
11
  ChartList,
12
12
  ChartWrite,
@@ -16,7 +16,7 @@ from cognite.client.utils._concurrency import execute_tasks
16
16
  from requests import Response
17
17
 
18
18
  from cognite_toolkit._cdf_tk.client._constants import DATA_MODELING_MAX_DELETE_WORKERS, DATA_MODELING_MAX_WRITE_WORKERS
19
- from cognite_toolkit._cdf_tk.client.data_classes.instances import InstancesApplyResultList
19
+ from cognite_toolkit._cdf_tk.client.data_classes.legacy.instances import InstancesApplyResultList
20
20
  from cognite_toolkit._cdf_tk.client.utils._concurrency import ToolkitConcurrencySettings
21
21
  from cognite_toolkit._cdf_tk.client.utils._http_client import ToolkitRetryTracker
22
22