cognite-toolkit 0.7.31__py3-none-any.whl → 0.7.32__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 (27) 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/_import_app.py +41 -0
  4. cognite_toolkit/_cdf_tk/client/api/extended_functions.py +9 -9
  5. cognite_toolkit/_cdf_tk/client/api/infield.py +23 -17
  6. cognite_toolkit/_cdf_tk/client/api/project.py +8 -7
  7. cognite_toolkit/_cdf_tk/client/api/streams.py +19 -14
  8. cognite_toolkit/_cdf_tk/client/api/three_d.py +5 -5
  9. cognite_toolkit/_cdf_tk/client/data_classes/base.py +2 -22
  10. cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +1 -1
  11. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +3 -0
  12. cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
  13. cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
  14. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +3 -2
  15. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +69 -7
  16. cognite_toolkit/_cdf_tk/validation.py +4 -0
  17. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  18. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  19. cognite_toolkit/_resources/cdf.toml +1 -1
  20. cognite_toolkit/_version.py +1 -1
  21. {cognite_toolkit-0.7.31.dist-info → cognite_toolkit-0.7.32.dist-info}/METADATA +1 -1
  22. {cognite_toolkit-0.7.31.dist-info → cognite_toolkit-0.7.32.dist-info}/RECORD +25 -26
  23. {cognite_toolkit-0.7.31.dist-info → cognite_toolkit-0.7.32.dist-info}/WHEEL +1 -1
  24. cognite_toolkit/_cdf_tk/prototypes/commands/__init__.py +0 -0
  25. cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
  26. /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
  27. {cognite_toolkit-0.7.31.dist-info → cognite_toolkit-0.7.32.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",
@@ -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)
@@ -7,7 +7,7 @@ from rich.console import Console
7
7
 
8
8
  from cognite_toolkit._cdf_tk.client.config import ToolkitClientConfig
9
9
  from cognite_toolkit._cdf_tk.utils.collection import chunker
10
- from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, SimpleBodyRequest
10
+ from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, RequestMessage2
11
11
  from cognite_toolkit._cdf_tk.utils.useful_types import JsonVal
12
12
 
13
13
 
@@ -34,21 +34,20 @@ class ExtendedFunctionsAPI(FunctionsAPI):
34
34
 
35
35
  Args:
36
36
  function (FunctionWrite): The function to create.
37
- console (Console | None): The rich console to use for printing warnings.
38
37
 
39
38
  Returns:
40
39
  Function: The created function object.
41
40
  """
42
- result = self._toolkit_http_client.request_with_retries(
43
- message=SimpleBodyRequest(
41
+ result = self._toolkit_http_client.request_single_retries(
42
+ message=RequestMessage2(
44
43
  endpoint_url=self._toolkit_config.create_api_url("/functions"),
45
44
  method="POST",
46
45
  body_content={"items": [function.dump(camel_case=True)]},
47
46
  )
48
47
  )
49
- result.raise_for_status()
48
+ success = result.get_success_or_raise()
50
49
  # We assume the API response is one item on a successful creation
51
- return Function._load(result.get_first_body()["items"][0], cognite_client=self._cognite_client) # type: ignore[arg-type,index]
50
+ return Function._load(success.body_json["items"][0], cognite_client=self._cognite_client)
52
51
 
53
52
  def delete_with_429_retry(self, external_id: SequenceNotStr[str], ignore_unknown_ids: bool = False) -> None:
54
53
  """Delete one or more functions with retry handling for 429 Too Many Requests responses.
@@ -70,11 +69,12 @@ class ExtendedFunctionsAPI(FunctionsAPI):
70
69
  }
71
70
  if ignore_unknown_ids:
72
71
  body_content["ignoreUnknownIds"] = True
73
- self._toolkit_http_client.request_with_retries(
74
- message=SimpleBodyRequest(
72
+ result = self._toolkit_http_client.request_single_retries(
73
+ message=RequestMessage2(
75
74
  endpoint_url=self._toolkit_config.create_api_url("/functions/delete"),
76
75
  method="POST",
77
76
  body_content=body_content,
78
77
  )
79
- ).raise_for_status()
78
+ )
79
+ result.get_success_or_raise()
80
80
  return None
@@ -1,6 +1,7 @@
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
7
  from cognite_toolkit._cdf_tk.client.data_classes.api_classes import PagedResponse, QueryResponse
@@ -15,7 +16,12 @@ from cognite_toolkit._cdf_tk.client.data_classes.instance_api import (
15
16
  NodeIdentifier,
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
+ ItemsRequest,
22
+ ItemsRequest2,
23
+ RequestMessage2,
24
+ )
19
25
 
20
26
 
21
27
  class InfieldConfigAPI:
@@ -40,31 +46,31 @@ class InfieldConfigAPI:
40
46
  else [item.as_request_item(), item.data_exploration_config.as_request_item()]
41
47
  for item in items
42
48
  )
43
- responses = self._http_client.request_with_retries(
44
- ItemsRequest(
49
+ responses = self._http_client.request_items_retries(
50
+ ItemsRequest2(
45
51
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
46
52
  method="POST",
47
53
  items=[item for sublist in request_items for item in sublist],
48
54
  )
49
55
  )
50
56
  responses.raise_for_status()
51
- return PagedResponse[InstanceResult].model_validate(responses.get_first_body()).items
57
+ return TypeAdapter(list[InstanceResult]).validate_python(responses.get_items())
52
58
 
53
59
  def retrieve(self, items: Sequence[NodeIdentifier]) -> list[InfieldLocationConfig]:
54
60
  if len(items) > 100:
55
61
  raise ValueError("Cannot retrieve more than 100 InfieldLocationConfig items at once.")
56
62
  if not items:
57
63
  return []
58
- responses = self._http_client.request_with_retries(
59
- SimpleBodyRequest(
64
+ response = self._http_client.request_single_retries(
65
+ RequestMessage2(
60
66
  # We use the query endpoint to be able to retrieve linked DataExplorationConfig items
61
67
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
62
68
  method="POST",
63
69
  body_content=self._retrieve_query(items),
64
70
  )
65
71
  )
66
- responses.raise_for_status()
67
- parsed_response = QueryResponse[InstanceResponseItem].model_validate(responses.get_first_body())
72
+ success = response.get_success_or_raise()
73
+ parsed_response = QueryResponse[InstanceResponseItem].model_validate(success.body_json)
68
74
  return self._parse_retrieve_response(parsed_response)
69
75
 
70
76
  def delete(self, items: Sequence[InfieldLocationConfig]) -> list[NodeIdentifier]:
@@ -168,30 +174,30 @@ class InFieldCDMConfigAPI:
168
174
  raise ValueError("Cannot apply more than 500 InFieldCDMLocationConfig items at once.")
169
175
 
170
176
  request_items = [item.as_request_item() for item in items]
171
- responses = self._http_client.request_with_retries(
172
- ItemsRequest(
177
+ results = self._http_client.request_items_retries(
178
+ ItemsRequest2(
173
179
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
174
180
  method="POST",
175
- items=request_items, # type: ignore[arg-type]
181
+ items=request_items,
176
182
  )
177
183
  )
178
- responses.raise_for_status()
179
- return PagedResponse[InstanceResult].model_validate(responses.get_first_body()).items
184
+ results.raise_for_status()
185
+ return TypeAdapter(list[InstanceResult]).validate_python(results.get_items())
180
186
 
181
187
  def retrieve(self, items: Sequence[NodeIdentifier]) -> list[InFieldCDMLocationConfig]:
182
188
  if len(items) > 100:
183
189
  raise ValueError("Cannot retrieve more than 100 InFieldCDMLocationConfig items at once.")
184
190
  if not items:
185
191
  return []
186
- responses = self._http_client.request_with_retries(
187
- SimpleBodyRequest(
192
+ result = self._http_client.request_single_retries(
193
+ RequestMessage2(
188
194
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/query"),
189
195
  method="POST",
190
196
  body_content=self._retrieve_query(items),
191
197
  )
192
198
  )
193
- responses.raise_for_status()
194
- parsed_response = QueryResponse[InstanceResponseItem].model_validate(responses.get_first_body())
199
+ success = result.get_success_or_raise()
200
+ parsed_response = QueryResponse[InstanceResponseItem].model_validate(success.body_json)
195
201
  return self._parse_retrieve_response(parsed_response)
196
202
 
197
203
  def delete(self, items: Sequence[InFieldCDMLocationConfig]) -> list[NodeIdentifier]:
@@ -2,7 +2,7 @@ from cognite.client import CogniteClient
2
2
 
3
3
  from cognite_toolkit._cdf_tk.client.config import ToolkitClientConfig
4
4
  from cognite_toolkit._cdf_tk.client.data_classes.project import ProjectStatusList
5
- from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, ParamRequest
5
+ from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, RequestMessage2
6
6
 
7
7
 
8
8
  class ProjectAPI:
@@ -13,11 +13,12 @@ class ProjectAPI:
13
13
 
14
14
  def status(self) -> ProjectStatusList:
15
15
  """Retrieve information about the current project."""
16
- response = self._http_client.request_with_retries(
17
- ParamRequest(
18
- endpoint_url=f"{self._config.base_url}/api/v1/projects?withDataModelingStatus=true", method="GET"
16
+ response = self._http_client.request_single_retries(
17
+ RequestMessage2(
18
+ endpoint_url=f"{self._config.base_url}/api/v1/projects",
19
+ method="GET",
20
+ parameters={"withDataModelingStatus": True},
19
21
  )
20
22
  )
21
- response.raise_for_status()
22
- body = response.get_first_body()
23
- return ProjectStatusList._load(body["items"], cognite_client=self._cognite_client) # type: ignore[arg-type]
23
+ success = response.get_success_or_raise()
24
+ return ProjectStatusList._load(success.body_json["items"], cognite_client=self._cognite_client)
@@ -1,10 +1,16 @@
1
1
  from collections.abc import Sequence
2
2
 
3
+ from pydantic import TypeAdapter
3
4
  from rich.console import Console
4
5
 
5
6
  from cognite_toolkit._cdf_tk.client.data_classes.api_classes import PagedResponse
6
7
  from cognite_toolkit._cdf_tk.client.data_classes.streams import StreamRequest, StreamResponse
7
- from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, ItemsRequest, ParamRequest
8
+ from cognite_toolkit._cdf_tk.utils.http_client import (
9
+ HTTPClient,
10
+ ItemsRequest2,
11
+ ParamRequest,
12
+ RequestMessage2,
13
+ )
8
14
 
9
15
 
10
16
  class StreamsAPI:
@@ -24,15 +30,15 @@ class StreamsAPI:
24
30
  Returns:
25
31
  List of created StreamResponse items.
26
32
  """
27
- responses = self._http_client.request_with_retries(
28
- ItemsRequest(
33
+ responses = self._http_client.request_items_retries(
34
+ ItemsRequest2(
29
35
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
30
36
  method="POST",
31
- items=list(items),
37
+ items=items,
32
38
  )
33
39
  )
34
40
  responses.raise_for_status()
35
- return PagedResponse[StreamResponse].model_validate(responses.get_first_body()).items
41
+ return TypeAdapter(list[StreamResponse]).validate_python(responses.get_items())
36
42
 
37
43
  def delete(self, external_id: str) -> None:
38
44
  """Delete stream using its external ID.
@@ -54,14 +60,14 @@ class StreamsAPI:
54
60
  Returns:
55
61
  StreamResponseList containing the listed streams.
56
62
  """
57
- responses = self._http_client.request_with_retries(
58
- ParamRequest(
63
+ response = self._http_client.request_single_retries(
64
+ RequestMessage2(
59
65
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
60
66
  method="GET",
61
67
  )
62
68
  )
63
- responses.raise_for_status()
64
- return PagedResponse[StreamResponse].model_validate(responses.get_first_body()).items
69
+ success = response.get_success_or_raise()
70
+ return PagedResponse[StreamResponse].model_validate(success.body_json).items
65
71
 
66
72
  def retrieve(self, external_id: str, include_statistics: bool = True) -> StreamResponse:
67
73
  """Retrieve a stream by its external ID.
@@ -72,13 +78,12 @@ class StreamsAPI:
72
78
  Returns:
73
79
  StreamResponse item.
74
80
  """
75
- responses = self._http_client.request_with_retries(
76
- ParamRequest(
81
+ response = self._http_client.request_single_retries(
82
+ RequestMessage2(
77
83
  endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/{external_id}"),
78
84
  method="GET",
79
85
  parameters={"includeStatistics": include_statistics},
80
86
  )
81
87
  )
82
- responses.raise_for_status()
83
- response_body = responses.get_first_body()
84
- return StreamResponse.model_validate(response_body)
88
+ success = response.get_success_or_raise()
89
+ return StreamResponse.model_validate(success.body_json)
@@ -2,7 +2,7 @@ from rich.console import Console
2
2
 
3
3
  from cognite_toolkit._cdf_tk.client.data_classes.api_classes import PagedResponse
4
4
  from cognite_toolkit._cdf_tk.client.data_classes.three_d import ThreeDModelResponse
5
- from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, ParamRequest
5
+ from cognite_toolkit._cdf_tk.utils.http_client import HTTPClient, RequestMessage2
6
6
  from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
7
7
 
8
8
 
@@ -34,15 +34,15 @@ class ThreeDModelAPI:
34
34
  parameters["published"] = published
35
35
  if cursor is not None:
36
36
  parameters["cursor"] = cursor
37
- responses = self._http_client.request_with_retries(
38
- ParamRequest(
37
+ responses = self._http_client.request_single_retries(
38
+ RequestMessage2(
39
39
  endpoint_url=self._config.create_api_url(self.ENDPOINT),
40
40
  method="GET",
41
41
  parameters=parameters,
42
42
  )
43
43
  )
44
- responses.raise_for_status()
45
- return PagedResponse[ThreeDModelResponse].model_validate(responses.get_first_body())
44
+ success_response = responses.get_success_or_raise()
45
+ return PagedResponse[ThreeDModelResponse].model_validate(success_response.body_json)
46
46
 
47
47
 
48
48
  class ThreeDAPI:
@@ -6,6 +6,8 @@ from typing import TYPE_CHECKING, Any, Generic, TypeVar
6
6
  from pydantic import BaseModel, ConfigDict
7
7
  from pydantic.alias_generators import to_camel
8
8
 
9
+ from cognite_toolkit._cdf_tk.utils.http_client._data_classes2 import BaseModelObject, RequestResource
10
+
9
11
  if TYPE_CHECKING:
10
12
  from cognite.client import CogniteClient
11
13
 
@@ -15,28 +17,6 @@ else:
15
17
  from typing_extensions import Self
16
18
 
17
19
 
18
- class BaseModelObject(BaseModel):
19
- """Base class for all object. This includes resources and nested objects."""
20
-
21
- # We allow extra fields to support forward compatibility.
22
- model_config = ConfigDict(alias_generator=to_camel, extra="allow")
23
-
24
- def dump(self, camel_case: bool = True) -> dict[str, Any]:
25
- """Dump the resource to a dictionary.
26
-
27
- This is the default serialization method for request resources.
28
- """
29
- return self.model_dump(mode="json", by_alias=camel_case)
30
-
31
- @classmethod
32
- def _load(cls, resource: dict[str, Any]) -> "Self":
33
- """Load method to match CogniteResource signature."""
34
- return cls.model_validate(resource)
35
-
36
-
37
- class RequestResource(BaseModelObject): ...
38
-
39
-
40
20
  T_RequestResource = TypeVar("T_RequestResource", bound=RequestResource)
41
21
 
42
22
 
@@ -107,7 +107,7 @@ class InstanceSource(BaseModelObject):
107
107
  return value
108
108
 
109
109
 
110
- class InstanceRequestItem(BaseModelObject):
110
+ class InstanceRequestItem(RequestResource):
111
111
  model_config = ConfigDict(populate_by_name=True)
112
112
  instance_type: InstanceType
113
113
  space: str
@@ -19,6 +19,9 @@ class RevisionStatus(BaseModelObject):
19
19
  class ThreeDModelRequest(RequestResource):
20
20
  name: str
21
21
 
22
+ def as_id(self) -> str:
23
+ return self.name
24
+
22
25
 
23
26
  class ThreeDModelClassicRequest(ThreeDModelRequest):
24
27
  data_set_id: int | None = None
@@ -1,4 +1,5 @@
1
- from typing import Literal
1
+ from abc import ABC
2
+ from typing import Annotated, Literal
2
3
 
3
4
  from cognite.client.data_classes import WorkflowVersionUpsert
4
5
  from pydantic import Field, JsonValue
@@ -6,18 +7,141 @@ from pydantic import Field, JsonValue
6
7
  from .base import BaseModelResource, ToolkitResource
7
8
 
8
9
 
10
+ class WorkflowVersionId(BaseModelResource):
11
+ workflow_external_id: str = Field(
12
+ max_length=255,
13
+ description="Identifier for a workflow. Must be unique for the project. No trailing or leading whitespace and no null characters allowed.",
14
+ )
15
+ version: str = Field(
16
+ max_length=255,
17
+ description="Identifier for a version. Must be unique for the workflow. No trailing or leading whitespace and no null characters allowed.",
18
+ )
19
+
20
+
21
+ class CogniteFunctionRef(BaseModelResource):
22
+ external_id: str = Field(
23
+ description="The external id of the Cognite Function in the project. This can be either a function external ID or a reference like ${myTaskExternalId.output.someKey}"
24
+ )
25
+ data: str | JsonValue | None = Field(
26
+ None, description="Input data that will be passed to the Cognite Function. Limited to 100KB in size."
27
+ )
28
+
29
+
30
+ class FunctionTaskParameters(BaseModelResource):
31
+ function: CogniteFunctionRef
32
+ is_async_complete: bool = Field(
33
+ False, description="Defines if the execution of the task should be completed asynchronously."
34
+ )
35
+
36
+
37
+ class TransformationRef(BaseModelResource):
38
+ external_id: str = Field(
39
+ description="The external id of the Transformation in the project. This can be either a transformation external ID or a reference like ${myTaskExternalId.output.someKey}"
40
+ )
41
+ concurrency_policy: Literal["fail", "waitForCurrent", "restartAfterCurrent"] = Field(
42
+ "fail",
43
+ description="""Determines the behavior of the task if the Transformation is already running.
44
+
45
+ fail: The task fails if another instance of the Transformation is currently running.
46
+ waitForCurrent: The task will pause and wait for the already running Transformation to complete. Once completed, the task is completed. This mode is useful for preventing redundant Transformation runs.
47
+ restartAfterCurrent: The task waits for the ongoing Transformation to finish. After completion, the task restarts the Transformation. This mode ensures that the most recent data can be used by following tasks.""",
48
+ )
49
+ use_transformation_credentials: bool = Field(
50
+ False,
51
+ description="If set to true, the transformation will run using the client credentials configured on the transformation. If set to false, the transformation will run using the client credentials used to trigger the workflow.",
52
+ )
53
+
54
+
55
+ class TransformationTaskParameters(BaseModelResource):
56
+ transformation: TransformationRef
57
+
58
+
59
+ class CDFRequest(BaseModelResource):
60
+ resource_path: str = Field(
61
+ description="The path of the request. The path should be prefixed by {cluster}.cognitedata.com/api/v1/project/{project} based on the relevant cluster and project. It can also contain references like ${myTaskExternalId.output.someKey}"
62
+ )
63
+ method: Literal["POST", "GET", "PUT"] | str = Field(
64
+ description="The HTTP method of the request. It can also be a reference like ${myTaskExternalId.output.someKey}"
65
+ )
66
+ query_parameters: dict[str, JsonValue] | str | None = Field(
67
+ None,
68
+ description="The query parameters of the request. It can also be a reference like ${myTaskExternalId.output.someKey}",
69
+ )
70
+ body: JsonValue | str | None = Field(
71
+ None, description="The body of the request. It can also be a reference like ${myTaskExternalId.output.someKey}"
72
+ )
73
+ request_timeout_in_millis: float | str | None = Field(
74
+ None,
75
+ description="The timeout for the request in milliseconds. It can also be a reference like ${myTaskExternalId.output.someKey}",
76
+ )
77
+ cdf_version_header: Literal["alpha", "beta"] | str | None = Field(
78
+ None, description="The Cognite Data Fusion version header to use for the request."
79
+ )
80
+
81
+
82
+ class CDFTaskParameters(BaseModelResource):
83
+ cdf_request: CDFRequest
84
+
85
+
86
+ class DynamicRef(BaseModelResource):
87
+ tasks: str = Field(
88
+ description="A Reference is an expression that allows dynamically injecting input to a task during execution. References can be used to reference the input of the Workflow, the output of a previous task in the Workflow, or the input of a previous task in the Workflow. Note that the injected value must be valid in the context of the property it is injected into. Example Task reference: ${myTaskExternalId.output.someKey} Example Workflow input reference: ${workflow.input.myKey}"
89
+ )
90
+
91
+
92
+ class DynamicTaskParameters(BaseModelResource):
93
+ dynamic: DynamicRef = Field(description="Reference to another task to use as the definition for this task.")
94
+
95
+
96
+ class SubworkflowRef(BaseModelResource):
97
+ tasks: "WorkflowVersionId | list[Task]" = Field(
98
+ description="Reference to the subworkflow to execute. This can be either a reference to an existing workflow version or an inline definition of tasks."
99
+ )
100
+
101
+
102
+ class SubworkflowTaskParameters(BaseModelResource):
103
+ subworkflow: SubworkflowRef = Field(description="Reference to the subworkflow to execute.")
104
+
105
+
106
+ class SimulatorInputUnit(BaseModelResource):
107
+ name: str = Field(description="Name of the unit.")
108
+
109
+
110
+ class SimulatorInput(BaseModelResource):
111
+ reference_id: str = Field(description="Reference id of the value to override.")
112
+ value: str | int | float | list[str] | list[int] | list[float] = Field(
113
+ description="Override the value used for a simulation run."
114
+ )
115
+ unit: SimulatorInputUnit | None = Field(None, description="Override the unit of the value")
116
+
117
+
118
+ class SimulationRef(BaseModelResource):
119
+ routine_external_id: str = Field(description="The external id of the routine to be executed.")
120
+ run_time: int | None = Field(
121
+ None,
122
+ description="Run time in milliseconds. Reference timestamp used for data pre-processing and data sampling.",
123
+ )
124
+ inputs: list[SimulatorInput] | None = Field(
125
+ None, description="List of inputs to be provided to the simulation.", max_length=200
126
+ )
127
+
128
+
129
+ class SimulationTaskParameters(BaseModelResource):
130
+ simulation: SimulationRef = Field(description="Reference to the simulation to execute.")
131
+
132
+
9
133
  class TaskId(BaseModelResource):
10
134
  external_id: str = Field(
11
135
  max_length=255, description="The external ID provided by the client. Must be unique for the resource type."
12
136
  )
13
137
 
14
138
 
15
- class TaskDefinition(BaseModelResource):
139
+ class TaskDefinition(BaseModelResource, ABC):
16
140
  external_id: str = Field(
17
141
  max_length=255,
18
142
  description="Identifier for the task. Must be unique within the version. No trailing or leading whitespace and no null characters allowed.",
19
143
  )
20
- type: Literal["function", "transformation", "cdf", "dynamic", "subworkflow", "simulation"]
144
+ type: str
21
145
  name: str | None = Field(
22
146
  default=None,
23
147
  max_length=255,
@@ -28,7 +152,6 @@ class TaskDefinition(BaseModelResource):
28
152
  max_length=500,
29
153
  description="Description of the intention of the task",
30
154
  )
31
- parameters: JsonValue = Field()
32
155
  retries: int = Field(
33
156
  3,
34
157
  ge=0,
@@ -52,13 +175,49 @@ class TaskDefinition(BaseModelResource):
52
175
  )
53
176
 
54
177
 
178
+ class FunctionTask(TaskDefinition):
179
+ type: Literal["function"] = "function"
180
+ parameters: FunctionTaskParameters
181
+
182
+
183
+ class TransformationTask(TaskDefinition):
184
+ type: Literal["transformation"] = "transformation"
185
+ parameters: TransformationTaskParameters
186
+
187
+
188
+ class CDFTask(TaskDefinition):
189
+ type: Literal["cdfRequest"] = "cdfRequest"
190
+ parameters: CDFTaskParameters
191
+
192
+
193
+ class DynamicTask(TaskDefinition):
194
+ type: Literal["dynamic"] = "dynamic"
195
+ parameters: DynamicTaskParameters
196
+
197
+
198
+ class SubworkflowTask(TaskDefinition):
199
+ type: Literal["subworkflow"] = "subworkflow"
200
+ parameters: SubworkflowTaskParameters
201
+
202
+
203
+ class SimulationTask(TaskDefinition):
204
+ type: Literal["simulation"] = "simulation"
205
+ parameters: SimulationTaskParameters
206
+
207
+
208
+ Task = Annotated[
209
+ FunctionTask | TransformationTask | CDFTask | DynamicTask | SubworkflowTask | SimulationTask,
210
+ Field(discriminator="type"),
211
+ ]
212
+
213
+
55
214
  class WorkflowDefinition(BaseModelResource):
56
215
  description: str | None = Field(
57
216
  default=None,
58
217
  max_length=500,
59
218
  description="The description of the workflow version.",
60
219
  )
61
- tasks: list[TaskDefinition]
220
+ tasks: list[Task]
62
221
 
63
222
 
64
223
  class WorkflowVersionYAML(ToolkitResource):
@@ -17,25 +17,53 @@ from ._data_classes import (
17
17
  SuccessResponse,
18
18
  SuccessResponseItems,
19
19
  )
20
+ from ._data_classes2 import (
21
+ BaseModelObject,
22
+ ErrorDetails2,
23
+ FailedRequest2,
24
+ FailedResponse2,
25
+ HTTPResult2,
26
+ ItemsFailedRequest2,
27
+ ItemsFailedResponse2,
28
+ ItemsRequest2,
29
+ ItemsResultMessage2,
30
+ ItemsSuccessResponse2,
31
+ RequestMessage2,
32
+ RequestResource,
33
+ SuccessResponse2,
34
+ )
20
35
  from ._exception import ToolkitAPIError
21
36
 
22
37
  __all__ = [
38
+ "BaseModelObject",
23
39
  "DataBodyRequest",
24
40
  "ErrorDetails",
41
+ "ErrorDetails2",
42
+ "FailedRequest2",
25
43
  "FailedRequestItems",
26
44
  "FailedRequestMessage",
27
45
  "FailedResponse",
46
+ "FailedResponse2",
28
47
  "FailedResponseItems",
29
48
  "HTTPClient",
30
49
  "HTTPMessage",
50
+ "HTTPResult2",
31
51
  "ItemMessage",
52
+ "ItemsFailedRequest2",
53
+ "ItemsFailedResponse2",
32
54
  "ItemsRequest",
55
+ "ItemsRequest2",
56
+ "ItemsResultMessage2",
57
+ "ItemsSuccessResponse2",
33
58
  "ParamRequest",
34
59
  "RequestMessage",
60
+ "RequestMessage2",
61
+ "RequestResource",
35
62
  "ResponseList",
36
63
  "ResponseMessage",
37
64
  "SimpleBodyRequest",
38
65
  "SuccessResponse",
66
+ "SuccessResponse2",
39
67
  "SuccessResponseItems",
40
68
  "ToolkitAPIError",
41
69
  ]
@@ -32,6 +32,7 @@ from cognite_toolkit._cdf_tk.utils.http_client._data_classes2 import (
32
32
  ItemsFailedRequest2,
33
33
  ItemsFailedResponse2,
34
34
  ItemsRequest2,
35
+ ItemsResultList,
35
36
  ItemsResultMessage2,
36
37
  ItemsSuccessResponse2,
37
38
  RequestMessage2,
@@ -424,7 +425,7 @@ class HTTPClient:
424
425
  results = self._handle_items_error(e, message)
425
426
  return results
426
427
 
427
- def request_items_retries(self, message: ItemsRequest2) -> Sequence[ItemsResultMessage2]:
428
+ def request_items_retries(self, message: ItemsRequest2) -> ItemsResultList:
428
429
  """Send an HTTP request with multiple items and handle retries.
429
430
 
430
431
  This method will keep retrying the request until it either succeeds or
@@ -442,7 +443,7 @@ class HTTPClient:
442
443
  raise RuntimeError(f"ItemsRequest2 has already been attempted {message.total_attempts} times.")
443
444
  pending_requests: deque[ItemsRequest2] = deque()
444
445
  pending_requests.append(message)
445
- final_responses: list[ItemsResultMessage2] = []
446
+ final_responses = ItemsResultList([])
446
447
  while pending_requests:
447
448
  current_request = pending_requests.popleft()
448
449
  results = self.request_items(current_request)
@@ -1,7 +1,8 @@
1
1
  import gzip
2
2
  import sys
3
3
  from abc import ABC, abstractmethod
4
- from collections.abc import Hashable
4
+ from collections import UserList
5
+ from collections.abc import Hashable, Sequence
5
6
  from typing import Any, Literal
6
7
 
7
8
  import httpx
@@ -9,6 +10,7 @@ from cognite.client import global_config
9
10
  from pydantic import BaseModel, ConfigDict, Field, JsonValue, TypeAdapter, model_validator
10
11
  from pydantic.alias_generators import to_camel
11
12
 
13
+ from cognite_toolkit._cdf_tk.utils.http_client._exception import ToolkitAPIError
12
14
  from cognite_toolkit._cdf_tk.utils.http_client._tracker import ItemsRequestTracker
13
15
  from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
14
16
 
@@ -18,7 +20,19 @@ else:
18
20
  from typing_extensions import Self
19
21
 
20
22
 
21
- class HTTPResult2(BaseModel): ...
23
+ class HTTPResult2(BaseModel):
24
+ def get_success_or_raise(self) -> "SuccessResponse2":
25
+ """Raises an exception if any response in the list indicates a failure."""
26
+ if isinstance(self, SuccessResponse2):
27
+ return self
28
+ elif isinstance(self, FailedResponse2):
29
+ raise ToolkitAPIError(
30
+ f"Request failed with status code {self.status_code}: {self.error.code} - {self.error.message}"
31
+ )
32
+ elif isinstance(self, FailedRequest2):
33
+ raise ToolkitAPIError(f"Request failed with error: {self.error}")
34
+ else:
35
+ raise ToolkitAPIError("Unknown HTTPResult2 type")
22
36
 
23
37
 
24
38
  class FailedRequest2(HTTPResult2):
@@ -30,6 +44,11 @@ class SuccessResponse2(HTTPResult2):
30
44
  body: str
31
45
  content: bytes
32
46
 
47
+ @property
48
+ def body_json(self) -> dict[str, Any]:
49
+ """Parse the response body as JSON."""
50
+ return TypeAdapter(dict[str, JsonValue]).validate_json(self.body)
51
+
33
52
 
34
53
  class ErrorDetails2(BaseModel):
35
54
  """This is the expected structure of error details in the CDF API"""
@@ -98,8 +117,8 @@ class RequestMessage2(BaseRequestMessage):
98
117
  # We serialize using pydantic instead of json.dumps. This is because pydantic is faster
99
118
  # and handles more complex types such as datetime, float('nan'), etc.
100
119
  data = _BODY_SERIALIZER.dump_json(self.body_content)
101
- if not global_config.disable_gzip and isinstance(data, str):
102
- data = gzip.compress(data.encode("utf-8"))
120
+ if not global_config.disable_gzip and isinstance(data, bytes):
121
+ data = gzip.compress(data)
103
122
  return data
104
123
 
105
124
 
@@ -158,7 +177,7 @@ def _set_default_tracker(data: dict[str, Any]) -> ItemsRequestTracker:
158
177
 
159
178
  class ItemsRequest2(BaseRequestMessage):
160
179
  model_config = ConfigDict(arbitrary_types_allowed=True)
161
- items: list[RequestResource]
180
+ items: Sequence[RequestResource]
162
181
  extra_body_fields: dict[str, JsonValue] | None = None
163
182
  max_failures_before_abort: int = 50
164
183
  tracker: ItemsRequestTracker = Field(init=False, default_factory=_set_default_tracker, exclude=True)
@@ -169,8 +188,8 @@ class ItemsRequest2(BaseRequestMessage):
169
188
  if self.extra_body_fields:
170
189
  body.update(self.extra_body_fields)
171
190
  res = _BODY_SERIALIZER.dump_json(body)
172
- if not global_config.disable_gzip and isinstance(res, str):
173
- return gzip.compress(res.encode("utf-8"))
191
+ if not global_config.disable_gzip and isinstance(res, bytes):
192
+ return gzip.compress(res)
174
193
  return res
175
194
 
176
195
  def split(self, status_attempts: int) -> list["ItemsRequest2"]:
@@ -185,3 +204,46 @@ class ItemsRequest2(BaseRequestMessage):
185
204
  new_request.tracker = self.tracker
186
205
  messages.append(new_request)
187
206
  return messages
207
+
208
+
209
+ class ItemResponse(BaseModel):
210
+ items: list[dict[str, JsonValue]]
211
+
212
+
213
+ class ItemsResultList(UserList[ItemsResultMessage2]):
214
+ def __init__(self, collection: Sequence[ItemsResultMessage2] | None = None) -> None:
215
+ super().__init__(collection or [])
216
+
217
+ def raise_for_status(self) -> None:
218
+ """Raises an exception if any response in the list indicates a failure."""
219
+ failed_responses = [resp for resp in self.data if isinstance(resp, ItemsFailedResponse2)]
220
+ failed_requests = [resp for resp in self.data if isinstance(resp, ItemsFailedRequest2)]
221
+ if not failed_responses and not failed_requests:
222
+ return
223
+ error_messages = "; ".join(f"Status {err.status_code}: {err.error.message}" for err in failed_responses)
224
+ if failed_requests:
225
+ if error_messages:
226
+ error_messages += "; "
227
+ error_messages += "; ".join(f"Request error: {err.error_message}" for err in failed_requests)
228
+ raise ToolkitAPIError(f"One or more requests failed: {error_messages}")
229
+
230
+ @property
231
+ def has_failed(self) -> bool:
232
+ """Indicates whether any response in the list indicates a failure.
233
+
234
+ Returns:
235
+ bool: True if there are any failed responses or requests, False otherwise.
236
+ """
237
+ for resp in self.data:
238
+ if isinstance(resp, ItemsFailedResponse2 | ItemsFailedRequest2):
239
+ return True
240
+ return False
241
+
242
+ def get_items(self) -> list[dict[str, JsonValue]]:
243
+ """Get the items from all successful responses."""
244
+ items: list[dict[str, JsonValue]] = []
245
+ for resp in self.data:
246
+ if isinstance(resp, ItemsSuccessResponse2):
247
+ body_json = ItemResponse.model_validate_json(resp.body)
248
+ items.extend(body_json.items)
249
+ return items
@@ -182,6 +182,10 @@ def humanize_validation_error(error: ValidationError) -> list[str]:
182
182
  "dict_type",
183
183
  }:
184
184
  msg = f"{item['msg']}. Got {item['input']!r} of type {type(item['input']).__name__}."
185
+ elif error_type == "union_tag_not_found" and "ctx" in item and "discriminator" in item["ctx"]:
186
+ # This is when we use a discriminator field to determine the type in a union. For the user, this means they
187
+ # are missing a required field.
188
+ msg = f"Missing required field: {item['ctx']['discriminator']}"
185
189
  else:
186
190
  # Default to the Pydantic error message
187
191
  msg = item["msg"]
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.7.31
15
+ image: cognite/toolkit:0.7.32
16
16
  env:
17
17
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
18
18
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -10,7 +10,7 @@ jobs:
10
10
  environment: dev
11
11
  name: Deploy Dry Run
12
12
  container:
13
- image: cognite/toolkit:0.7.31
13
+ image: cognite/toolkit:0.7.32
14
14
  env:
15
15
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
16
16
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -4,7 +4,7 @@ default_env = "<DEFAULT_ENV_PLACEHOLDER>"
4
4
  [modules]
5
5
  # This is the version of the modules. It should not be changed manually.
6
6
  # It will be updated by the 'cdf modules upgrade' command.
7
- version = "0.7.31"
7
+ version = "0.7.32"
8
8
 
9
9
 
10
10
  [plugins]
@@ -1 +1 @@
1
- __version__ = "0.7.31"
1
+ __version__ = "0.7.32"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.7.31
3
+ Version: 0.7.32
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Author: Cognite AS
6
6
  Author-email: Cognite AS <support@cognite.com>
@@ -1,13 +1,14 @@
1
1
  cognite_toolkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cognite_toolkit/_cdf.py,sha256=sefGD2JQuOTBZhEqSj_ECbNZ7nTRN4AwGwX1pSUhoow,5636
2
+ cognite_toolkit/_cdf.py,sha256=W3VpmgXn3fUtXErTk45Y34qpGbO-nbirsWin_WA4Xe4,5549
3
3
  cognite_toolkit/_cdf_tk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- cognite_toolkit/_cdf_tk/apps/__init__.py,sha256=KKmhbpvPKTwqQS2g_XqAC2yvtPsvdl8wV5TgJA3zqhs,702
4
+ cognite_toolkit/_cdf_tk/apps/__init__.py,sha256=80XM_8Tx7nIav2weV7Ni03Oqy84jDtyDPUtDeSaPk5E,754
5
5
  cognite_toolkit/_cdf_tk/apps/_auth_app.py,sha256=ER7uYb3ViwsHMXiQEZpyhwU6TIjKaB9aEy32VI4MPpg,3397
6
6
  cognite_toolkit/_cdf_tk/apps/_core_app.py,sha256=BiY7GWInq0INa7uCiGQyt4cBs1Eguyr5BBCW14JHo3I,14018
7
7
  cognite_toolkit/_cdf_tk/apps/_data_app.py,sha256=LeplXlxXtyIymRPgbatQrRFodU4VZBFxI0bqDutLSbg,806
8
8
  cognite_toolkit/_cdf_tk/apps/_dev_app.py,sha256=FaY67PFdKwdiMKgJbTcjHT1X2Xfbog2PKL6T-kcawyc,2818
9
9
  cognite_toolkit/_cdf_tk/apps/_download_app.py,sha256=2nPn9P_9br9poynSpKKSZF7WYTYT--BfxlxXkSEeH-8,41156
10
10
  cognite_toolkit/_cdf_tk/apps/_dump_app.py,sha256=EPq6fWSaScj9ncKfRY253rRJ37er47PIM60IFgkQK_k,37127
11
+ cognite_toolkit/_cdf_tk/apps/_import_app.py,sha256=5n5AF40HJ0Q_3LENCknG0MxH4pMUS8OwsqvtCYj_t7w,2086
11
12
  cognite_toolkit/_cdf_tk/apps/_landing_app.py,sha256=YR9z83OY7PhhgBVC5gmRLgo9iTXoGoZfRhOU3gd_r2o,888
12
13
  cognite_toolkit/_cdf_tk/apps/_migrate_app.py,sha256=_woM0D2j6VzuYC0LJKteALbQ4U8vGj0B1LSBj_WszKQ,41198
13
14
  cognite_toolkit/_cdf_tk/apps/_modules_app.py,sha256=t0SPvulgbgkF_OO2E68mQ_ZUcJ6HoaurYe0IkmXie0o,7449
@@ -35,15 +36,15 @@ cognite_toolkit/_cdf_tk/client/api/charts.py,sha256=t-VOrRGwpjmYUtUqGObQWYwGb5gO
35
36
  cognite_toolkit/_cdf_tk/client/api/dml.py,sha256=8b1lo86JdvfEsz9mP2rx0Mp9fyWsU6mbXHqLBtvSidU,3546
36
37
  cognite_toolkit/_cdf_tk/client/api/extended_data_modeling.py,sha256=T08lXIrgDRGKhF-44FYoBMd4oJRYiWRzYhHsNkLyLAo,12967
37
38
  cognite_toolkit/_cdf_tk/client/api/extended_files.py,sha256=azdPnCqXUVuPLTuiV9WZ97VJTJ6mN2hOEtD9LklLw8M,9191
38
- cognite_toolkit/_cdf_tk/client/api/extended_functions.py,sha256=_MbkztZskZAt43ZERddhmeZYKHeQSDteFlnaCLL5J6k,3523
39
+ cognite_toolkit/_cdf_tk/client/api/extended_functions.py,sha256=_AAA_p4uVCgMx5_aYuhpv-nWxlj__6qMPc3z3c2Z9n4,3444
39
40
  cognite_toolkit/_cdf_tk/client/api/extended_raw.py,sha256=9DVbM2aWmIyzbaW-lh10_pzVYJUEQFnIKnxvt413Bjk,2118
40
41
  cognite_toolkit/_cdf_tk/client/api/extended_timeseries.py,sha256=xK7XhTfe4W9FvaueUIfR7Q64JOIDwq_svHRjORM76Q4,17774
41
42
  cognite_toolkit/_cdf_tk/client/api/fixed_transformations.py,sha256=m66cqbx4oCtjv5TBQOWLNFrz475qVTCXBu_pTxbdCD4,5589
42
- cognite_toolkit/_cdf_tk/client/api/infield.py,sha256=rtWbt1emyluZwRHKOisMXC6A44QDONHCBIQ9-nxl7Wk,11042
43
+ cognite_toolkit/_cdf_tk/client/api/infield.py,sha256=r_KeHEFs9slr6Zw3N6Ka3-_JBhU8yVW4KcjQ3u5OSFw,11071
43
44
  cognite_toolkit/_cdf_tk/client/api/location_filters.py,sha256=TIbomUbpUNDxOON_a3pwBmCBdltxL1jMQBXKcIjRx44,3759
44
45
  cognite_toolkit/_cdf_tk/client/api/lookup.py,sha256=c-cvtgfGGGYyk8ROcJu44qlo1ocqbk0o1zafCql79fU,17652
45
46
  cognite_toolkit/_cdf_tk/client/api/migration.py,sha256=jjQ-3HyBgEPWO8RB8mI1sp8ZWHrUmtaYsufuUGp_3ew,23055
46
- cognite_toolkit/_cdf_tk/client/api/project.py,sha256=Hj0uDCLyPofG-T4626EdeoRRtBaovhU-SMAQ7VWJ1M4,1063
47
+ cognite_toolkit/_cdf_tk/client/api/project.py,sha256=Fb3ag9-Q5L4c2YyIwO_Rg9RJSX1HvQBjUrSAnmmoHZA,1081
47
48
  cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py,sha256=6xDSr24_IkLRx_kAKU0_e6_sqnxVWcQChnML_NJqnIQ,56
48
49
  cognite_toolkit/_cdf_tk/client/api/robotics/api.py,sha256=o_wQLlctAY4pkwJhcXcPnox3YC_kQmUFezQhjR76jrU,981
49
50
  cognite_toolkit/_cdf_tk/client/api/robotics/capabilities.py,sha256=YXorz89ELxuSDyMAx31p3ROaCFrbutLkwGaayP5CQkM,4429
@@ -55,8 +56,8 @@ cognite_toolkit/_cdf_tk/client/api/robotics/robots.py,sha256=J0GN8FjfZ9iUO_rcc6e
55
56
  cognite_toolkit/_cdf_tk/client/api/robotics/utlis.py,sha256=EMwyrIb9CfM1q6HAfPe6qqfmE1Gdm_UiM8XicsbEAzE,329
56
57
  cognite_toolkit/_cdf_tk/client/api/search.py,sha256=L4cDPip7pJVP7bEgAiSOjqINIHg8AULNBtR29G5khEQ,612
57
58
  cognite_toolkit/_cdf_tk/client/api/search_config.py,sha256=31rPCSOnzfiLv8FKU6F3tF9ZesEV8moSlbnkFPNh13g,1824
58
- cognite_toolkit/_cdf_tk/client/api/streams.py,sha256=4u5jRdbhxKbVR8OLURyVwehHgoejFxArjUAGni78PNY,3015
59
- cognite_toolkit/_cdf_tk/client/api/three_d.py,sha256=2jMBrdHBERcXn7qIRHZjRtlfXXIIDGoMyfkSGPrl8jE,2022
59
+ cognite_toolkit/_cdf_tk/client/api/streams.py,sha256=qOUFHdpz75PSlfImIizVCtschLLHttR8AUV0Jw3DTRM,3055
60
+ cognite_toolkit/_cdf_tk/client/api/three_d.py,sha256=zY71RGEBkH5b8R8WOb2CKHUsxFcDWTb5kPaxBa8wuAY,2053
60
61
  cognite_toolkit/_cdf_tk/client/api/token.py,sha256=8SiA44Dwsx0j_X8lgIxl2rdNCQSdEiSfoD_4ybxMtFA,5131
61
62
  cognite_toolkit/_cdf_tk/client/api/verify.py,sha256=-x6z6lMaOZG91adi0m9NtJ4wIQgoZURbzluPALXM-ps,3730
62
63
  cognite_toolkit/_cdf_tk/client/api_client.py,sha256=CQdD_gfDqQkz5OYHrTnKvBvEvzHPdHDB1BkZPWRoahg,440
@@ -64,7 +65,7 @@ cognite_toolkit/_cdf_tk/client/config.py,sha256=weMR43z-gqHMn-Jqvfmh_nJ0HbgEdyeC
64
65
  cognite_toolkit/_cdf_tk/client/data_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
66
  cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py,sha256=X-aGFnYzSxXYDxlFP2rqJ8P10Um7bcRRUZxVVzblYBw,477
66
67
  cognite_toolkit/_cdf_tk/client/data_classes/apm_config_v1.py,sha256=0bPq7R0qvdf8SMFS06kX7TXHIClDcJNHwdTBweQB-GU,20150
67
- cognite_toolkit/_cdf_tk/client/data_classes/base.py,sha256=QG4S0HlByMB6zwxUXWaVHwP-DrA2Y97XGN_o6QsL6FY,2776
68
+ cognite_toolkit/_cdf_tk/client/data_classes/base.py,sha256=CQ64XroKpH7pODOZ3NPZ_GBkdsH7evFAxYKQ8-ywmYI,2142
68
69
  cognite_toolkit/_cdf_tk/client/data_classes/canvas.py,sha256=DrE-7HOLnk1ELhydySsEhw-VOjriUqB_zzon5qb7CDk,50721
69
70
  cognite_toolkit/_cdf_tk/client/data_classes/capabilities.py,sha256=muqpAC2JLCFcEpRPzuh_3sS3o_q42WFyfsGzl-LfB_U,8773
70
71
  cognite_toolkit/_cdf_tk/client/data_classes/charts.py,sha256=4ZSZDJhDP8uNubXfzphuLJzKJhL1F01grB4UesxtSbQ,3745
@@ -76,7 +77,7 @@ cognite_toolkit/_cdf_tk/client/data_classes/extended_timeseries.py,sha256=yAvJCH
76
77
  cognite_toolkit/_cdf_tk/client/data_classes/functions.py,sha256=r9vhkS7sJ-wCiwvtD9CDKKthAktDMS6FJWDsLzq6iJ8,378
77
78
  cognite_toolkit/_cdf_tk/client/data_classes/graphql_data_models.py,sha256=N_1dfXSdsLlhw5uXreNfmSCo5bA4XeiZneMdnHWDgJI,4313
78
79
  cognite_toolkit/_cdf_tk/client/data_classes/infield.py,sha256=xZDpHw190FgX2vK6zk_r8dUJA7J6UzdS8227VOu74ms,4298
79
- cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py,sha256=dCgCYqvQHiuFhe8CRb1_lYderkVHoHWki1vcf07F8tw,4929
80
+ cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py,sha256=Ihi2Q1GKL3uBDReudtMI-T8XL8wxuNYmvrY3PD0feQs,4929
80
81
  cognite_toolkit/_cdf_tk/client/data_classes/instances.py,sha256=aGV3XtBGwG1ELks3kqFkScO-MGC5zvcSZtYXOVWL2BE,2501
81
82
  cognite_toolkit/_cdf_tk/client/data_classes/location_filters.py,sha256=IgHU7Hto0Zz3Bk_QW17JC3vUw0yN1oaTeJ3ZPKOGFAE,12112
82
83
  cognite_toolkit/_cdf_tk/client/data_classes/migration.py,sha256=AoYgqwSoYn1ok_ksG9Lljb270J4zPF_qyJSu5ZHtD_Q,18632
@@ -88,7 +89,7 @@ cognite_toolkit/_cdf_tk/client/data_classes/search_config.py,sha256=Reo_rcFrwk_s
88
89
  cognite_toolkit/_cdf_tk/client/data_classes/sequences.py,sha256=02d34fPcJ1H7U5ZnCCfOi36z5WJ4WnRfCWwkp99mW2E,6234
89
90
  cognite_toolkit/_cdf_tk/client/data_classes/streamlit_.py,sha256=nEk00FH3i-px2r6ql4kk1VVL4sytjUn0_sTkEdDSHVc,6746
90
91
  cognite_toolkit/_cdf_tk/client/data_classes/streams.py,sha256=DHSDrBax81fUzneIikn9hUMVgQVbdaiQ9aY-bRaTK38,2459
91
- cognite_toolkit/_cdf_tk/client/data_classes/three_d.py,sha256=X5BCOZC1B_WOcaC2RbmEscHJ0J9BrY_0oGbB17kpS90,1298
92
+ cognite_toolkit/_cdf_tk/client/data_classes/three_d.py,sha256=afPfgZtsYs7OhBo7lJXb-7xInTdYK8wWg1a_hQJNOcE,1352
92
93
  cognite_toolkit/_cdf_tk/client/testing.py,sha256=mXqEXPMZcbETrXBn6D-SiAcjD7xAkuuxCNYJMW0IO0Y,6815
93
94
  cognite_toolkit/_cdf_tk/client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
95
  cognite_toolkit/_cdf_tk/client/utils/_concurrency.py,sha256=3GtQbKDaosyKHEt-KzxKK9Yie4TvZPdoou2vUk6dUa8,2298
@@ -98,6 +99,7 @@ cognite_toolkit/_cdf_tk/commands/_base.py,sha256=1gl8Y-yqfedRMfdbwM3iPTIUIZriX1U
98
99
  cognite_toolkit/_cdf_tk/commands/_changes.py,sha256=sU0KaTtPVSJgAZcaZ1Tkcajj36pmhd13kh7V8QbIED8,22987
99
100
  cognite_toolkit/_cdf_tk/commands/_cli_commands.py,sha256=TK6U_rm6VZT_V941kTyHMoulWgJzbDC8YIIQDPJ5x3w,1011
100
101
  cognite_toolkit/_cdf_tk/commands/_download.py,sha256=dVddH9t7oGx1kdQ3CCYYQb96Uxxy-xC8Opph98lo46U,6869
102
+ cognite_toolkit/_cdf_tk/commands/_import_cmd.py,sha256=RkJ7RZI6zxe0_1xrPB-iJhCVchurmIAChilx0_XMR6k,11141
101
103
  cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py,sha256=8ki04tJGH1dHdF2NtVF4HyhaC0XDDS7onrH_nvd9KtE,153
102
104
  cognite_toolkit/_cdf_tk/commands/_migrate/command.py,sha256=l2P0Em05aEJvNZH4WkEIm-QfO3TAjG1rc_YxELuQIQM,14214
103
105
  cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py,sha256=Ew9JRYrd-Ol9G9csTzpnhXAgCFnX67MwDYOTsdJLP3E,16803
@@ -181,9 +183,6 @@ cognite_toolkit/_cdf_tk/feature_flags.py,sha256=X2-penlGM4RlFcX3UXTxXeb85eDrV0Ni
181
183
  cognite_toolkit/_cdf_tk/hints.py,sha256=UI1ymi2T5wCcYOpEbKbVaDnlyFReFy8TDtMVt-5E1h8,6493
182
184
  cognite_toolkit/_cdf_tk/plugins.py,sha256=0V14rceAWLZQF8iWdyL5QmK7xB796YaDEtb9RIj5AOc,836
183
185
  cognite_toolkit/_cdf_tk/protocols.py,sha256=Lc8XnBfmDZN6dwmSopmK7cFE9a9jZ2zdUryEeCXn27I,3052
184
- cognite_toolkit/_cdf_tk/prototypes/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
- cognite_toolkit/_cdf_tk/prototypes/commands/import_.py,sha256=RkJ7RZI6zxe0_1xrPB-iJhCVchurmIAChilx0_XMR6k,11141
186
- cognite_toolkit/_cdf_tk/prototypes/import_app.py,sha256=7dy852cBlHI2RQF1MidSmxl0jPBxekGWXnd2VtI7QFI,1899
187
186
  cognite_toolkit/_cdf_tk/resource_classes/__init__.py,sha256=IR9Qh4p46v_zHpq6VUYzfNuu9L3aSZgOYw5yy7XXiuk,4006
188
187
  cognite_toolkit/_cdf_tk/resource_classes/agent.py,sha256=5rglrj551Z-0eT53S_UmSA3wz4m4Y494QxleWVs0ECE,1786
189
188
  cognite_toolkit/_cdf_tk/resource_classes/agent_tools.py,sha256=oNkpPCQF3CyV9zcD6NTuEAnATLXzslw2GOyFz58ZGZg,2891
@@ -240,7 +239,7 @@ cognite_toolkit/_cdf_tk/resource_classes/view_field_definitions.py,sha256=2fIrIs
240
239
  cognite_toolkit/_cdf_tk/resource_classes/views.py,sha256=X3uC0E0CsvYHWZQZjXh0PhjpDgLrnmwq-r0GMmZACnI,3518
241
240
  cognite_toolkit/_cdf_tk/resource_classes/workflow.py,sha256=fMNfW93D8tdVwO7YgEYYiYvpktSMx4i0viIFg0gD2VY,512
242
241
  cognite_toolkit/_cdf_tk/resource_classes/workflow_trigger.py,sha256=aSN0WFPupQ383A7RT-0Monw-inkVdYYSsK3UwHXW1HA,5216
243
- cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py,sha256=ui724EaM9Nlm3wTnm7Givgv6GLQ-xbsfZgidyRKv09U,2991
242
+ cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py,sha256=anoDnl8lk8Xa9T2FwpjQ5TrrCMnR4QDjdDxo2OAcKTs,9850
244
243
  cognite_toolkit/_cdf_tk/storageio/__init__.py,sha256=h5Wr4i7zNIgsslrsRJxmp7ls4bNRKl0uZzQ7GLRMP7g,1920
245
244
  cognite_toolkit/_cdf_tk/storageio/_annotations.py,sha256=QcFrikDgz-9VjNy4Xq7wchM4VOQh-z2JaHcWR2C1sEs,4879
246
245
  cognite_toolkit/_cdf_tk/storageio/_applications.py,sha256=M7FEK4xC0BjP2i6FyYs1589zEA3afJiOKCzY56RV6NU,19685
@@ -284,10 +283,10 @@ cognite_toolkit/_cdf_tk/utils/fileio/_readers.py,sha256=IjOSHyW0GiID_lKdgAwQZao9
284
283
  cognite_toolkit/_cdf_tk/utils/fileio/_writers.py,sha256=mc23m0kJgl57FUDvwLmS7yR3xVZWQguPJa_63-qQ_L0,17731
285
284
  cognite_toolkit/_cdf_tk/utils/graphql_parser.py,sha256=2i2wDjg_Uw3hJ-pHtPK8hczIuCj5atrK8HZbgWJB-Pk,11532
286
285
  cognite_toolkit/_cdf_tk/utils/hashing.py,sha256=3NyNfljyYNTqAyAFBd6XlyWaj43jRzENxIuPdOY6nqo,2116
287
- cognite_toolkit/_cdf_tk/utils/http_client/__init__.py,sha256=G8b7Bg4yIet5R4Igh3dS2SntWzE6I0iTGBeNlNsSxkQ,857
288
- cognite_toolkit/_cdf_tk/utils/http_client/_client.py,sha256=WQFqzjWobjUYEcO1YV9uOMaoRrfi4APuDFrZakD86BQ,22496
286
+ cognite_toolkit/_cdf_tk/utils/http_client/__init__.py,sha256=MG3rAi5IiLxqlCMyVvzyfsKXMb_3fVxwAZ7uyPXrMvs,1483
287
+ cognite_toolkit/_cdf_tk/utils/http_client/_client.py,sha256=1nKMop_ORrGXybG-KDmC3rlcKs8cseLWSkPkMTFWRyw,22493
289
288
  cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py,sha256=8KEDyRRaOLhwN2eA2vaBAzZ__JDUicUDyir6x_PE5lk,14817
290
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py,sha256=mg0BfP7Te5TSgljPFWI0atLtIGa9OPb50jEAXpkzVXE,6078
289
+ cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py,sha256=Qqy7OEg8MGF9EksDUcn39fq6GpC_SrbWbyt-UGqD80Q,8811
291
290
  cognite_toolkit/_cdf_tk/utils/http_client/_exception.py,sha256=fC9oW6BN0HbUe2AkYABMP7Kj0-9dNYXVFBY5RQztq2c,126
292
291
  cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py,sha256=EBBnd-JZ7nc_jYNFJokCHN2UZ9sx0McFLZvlceUYYic,1215
293
292
  cognite_toolkit/_cdf_tk/utils/interactive_select.py,sha256=dP_ZFHvzQRPQxRt6EzURY3Z3Ld_otJtCz-nGqUNtt1k,35725
@@ -301,20 +300,20 @@ cognite_toolkit/_cdf_tk/utils/text.py,sha256=1-LQMo633_hEhNhishQo7Buj-7np5Pe4qKk
301
300
  cognite_toolkit/_cdf_tk/utils/thread_safe_dict.py,sha256=NbRHcZvWpF9xHP5OkOMGFpxrPNbi0Q3Eea6PUNbGlt4,3426
302
301
  cognite_toolkit/_cdf_tk/utils/useful_types.py,sha256=oK88W6G_aK3hebORSQKZjWrq7jG-pO2lkLWSWYMlngM,1872
303
302
  cognite_toolkit/_cdf_tk/utils/validate_access.py,sha256=1puswcpgEDNCwdk91dhLqCBSu_aaUAd3Hsw21d-YVFs,21955
304
- cognite_toolkit/_cdf_tk/validation.py,sha256=ixxYJA96EYZwFeo3vHjGfuHsFbbPgAJ3RQ-Sh0-PMok,11790
303
+ cognite_toolkit/_cdf_tk/validation.py,sha256=9v0ucMnt8YK0SZtbzEjtp8nMstehmKVHnuwyPf5kQI8,12133
305
304
  cognite_toolkit/_repo_files/.env.tmpl,sha256=UmgKZVvIp-OzD8oOcYuwb_6c7vSJsqkLhuFaiVgK7RI,972
306
305
  cognite_toolkit/_repo_files/.gitignore,sha256=ip9kf9tcC5OguF4YF4JFEApnKYw0nG0vPi6urlpTZ3k,5274
307
306
  cognite_toolkit/_repo_files/AzureDevOps/.devops/README.md,sha256=OLA0D7yCX2tACpzvkA0IfkgQ4_swSd-OlJ1tYcTBpsA,240
308
307
  cognite_toolkit/_repo_files/AzureDevOps/.devops/deploy-pipeline.yml,sha256=brULcs8joAeBC_w_aoWjDDUHs3JheLMIR9ajPUK96nc,693
309
308
  cognite_toolkit/_repo_files/AzureDevOps/.devops/dry-run-pipeline.yml,sha256=OBFDhFWK1mlT4Dc6mDUE2Es834l8sAlYG50-5RxRtHk,723
310
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=Ft9lViXmay2AajHAwOiFbP1BYBIlVHvxu56qFQlN9Zk,667
311
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=_gR9FBSVup2h_P2iTlKRvnxV5kdRMZFvHLo-fK6o_Zc,2430
312
- cognite_toolkit/_resources/cdf.toml,sha256=3YM8T2ivUqrfocBzLTYRWCWyeYXyXfM7wRSY1Zxa7k8,475
313
- cognite_toolkit/_version.py,sha256=CtvyqFRtdJwNvYSDVmaT9l1R18bsaIwflR8r696jttk,23
309
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=SJrUHATry3OVNdwVmG33hrleUAMRoGWh39OwuxJEAt8,667
310
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=WvlVo-pbKtDRwAk9gZwD4aQxRKhd10OI3dY1AVgXbvc,2430
311
+ cognite_toolkit/_resources/cdf.toml,sha256=hmcpZvF4m-Ii4jhmVnuxrTp5Juk0kV4LQQHRpO_Dp9g,475
312
+ cognite_toolkit/_version.py,sha256=1XUohj6Z0TqUfrazUNkieWrPdQbTTSPaX1bSiD_w2V0,23
314
313
  cognite_toolkit/config.dev.yaml,sha256=M33FiIKdS3XKif-9vXniQ444GTZ-bLXV8aFH86u9iUQ,332
315
314
  cognite_toolkit/demo/__init__.py,sha256=-m1JoUiwRhNCL18eJ6t7fZOL7RPfowhCuqhYFtLgrss,72
316
315
  cognite_toolkit/demo/_base.py,sha256=6xKBUQpXZXGQ3fJ5f7nj7oT0s2n7OTAGIa17ZlKHZ5U,8052
317
- cognite_toolkit-0.7.31.dist-info/WHEEL,sha256=93kfTGt3a0Dykt_T-gsjtyS5_p8F_d6CE1NwmBOirzo,79
318
- cognite_toolkit-0.7.31.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
319
- cognite_toolkit-0.7.31.dist-info/METADATA,sha256=lOFzBCcUEoVSZjcxZh685Mb3FTEhTlrZTN6XXlrlJ4A,4507
320
- cognite_toolkit-0.7.31.dist-info/RECORD,,
316
+ cognite_toolkit-0.7.32.dist-info/WHEEL,sha256=xDCZ-UyfvkGuEHPeI7BcJzYKIZzdqN8A8o1M5Om8IyA,79
317
+ cognite_toolkit-0.7.32.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
318
+ cognite_toolkit-0.7.32.dist-info/METADATA,sha256=AINvh-AoKJNaRlhP7RO_AaPoBItlW2tt4cxrDhFNxvc,4507
319
+ cognite_toolkit-0.7.32.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.16
2
+ Generator: uv 0.9.17
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
File without changes
@@ -1,41 +0,0 @@
1
- from pathlib import Path
2
-
3
- import typer
4
-
5
- from cognite_toolkit._cdf_tk.client import ToolkitClient
6
- from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
7
-
8
- from .commands.import_ import ImportTransformationCLI
9
-
10
- import_app = typer.Typer(
11
- pretty_exceptions_short=False, pretty_exceptions_show_locals=False, pretty_exceptions_enable=False
12
- )
13
-
14
-
15
- @import_app.callback(invoke_without_command=True)
16
- def import_main(ctx: typer.Context) -> None:
17
- """PREVIEW FEATURE Import resources into Cognite-Toolkit."""
18
- if ctx.invoked_subcommand is None:
19
- print("Use [bold yellow]cdf-tk import --help[/] for more information.")
20
- return None
21
-
22
-
23
- @import_app.command("transformation-cli")
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)