cognite-toolkit 0.6.83__py3-none-any.whl → 0.6.85__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.
Potentially problematic release.
This version of cognite-toolkit might be problematic. Click here for more details.
- cognite_toolkit/_cdf_tk/apps/_purge.py +84 -4
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py +3 -1
- cognite_toolkit/_cdf_tk/client/api/lookup.py +128 -73
- cognite_toolkit/_cdf_tk/client/testing.py +2 -0
- cognite_toolkit/_cdf_tk/commands/_download.py +1 -2
- cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +5 -4
- cognite_toolkit/_cdf_tk/commands/_purge.py +173 -348
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +1 -1
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -17
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +105 -37
- cognite_toolkit/_cdf_tk/utils/aggregators.py +47 -9
- cognite_toolkit/_cdf_tk/utils/validate_access.py +205 -43
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
- cognite_toolkit/_resources/cdf.toml +1 -1
- cognite_toolkit/_version.py +1 -1
- {cognite_toolkit-0.6.83.dist-info → cognite_toolkit-0.6.85.dist-info}/METADATA +1 -1
- {cognite_toolkit-0.6.83.dist-info → cognite_toolkit-0.6.85.dist-info}/RECORD +21 -21
- {cognite_toolkit-0.6.83.dist-info → cognite_toolkit-0.6.85.dist-info}/WHEEL +0 -0
- {cognite_toolkit-0.6.83.dist-info → cognite_toolkit-0.6.85.dist-info}/entry_points.txt +0 -0
- {cognite_toolkit-0.6.83.dist-info → cognite_toolkit-0.6.85.dist-info}/licenses/LICENSE +0 -0
|
@@ -17,7 +17,7 @@ from cognite_toolkit._cdf_tk.storageio.selectors import (
|
|
|
17
17
|
)
|
|
18
18
|
from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
|
|
19
19
|
from cognite_toolkit._cdf_tk.utils.cli_args import parse_view_str
|
|
20
|
-
from cognite_toolkit._cdf_tk.utils.interactive_select import DataModelingSelect
|
|
20
|
+
from cognite_toolkit._cdf_tk.utils.interactive_select import AssetInteractiveSelect, DataModelingSelect
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class InstanceTypeEnum(str, Enum):
|
|
@@ -39,8 +39,8 @@ class PurgeApp(typer.Typer):
|
|
|
39
39
|
if ctx.invoked_subcommand is None:
|
|
40
40
|
print("Use [bold yellow]cdf purge --help[/] for more information.")
|
|
41
41
|
|
|
42
|
+
@staticmethod
|
|
42
43
|
def purge_dataset(
|
|
43
|
-
self,
|
|
44
44
|
ctx: typer.Context,
|
|
45
45
|
external_id: Annotated[
|
|
46
46
|
str | None,
|
|
@@ -53,7 +53,46 @@ class PurgeApp(typer.Typer):
|
|
|
53
53
|
typer.Option(
|
|
54
54
|
"--include-dataset",
|
|
55
55
|
"-i",
|
|
56
|
-
help="
|
|
56
|
+
help="Whether to archive the dataset itself after purging its contents.",
|
|
57
|
+
hidden=Flags.v07.is_enabled(),
|
|
58
|
+
),
|
|
59
|
+
] = False,
|
|
60
|
+
archive_dataset: Annotated[
|
|
61
|
+
bool,
|
|
62
|
+
typer.Option(
|
|
63
|
+
"--archive-dataset",
|
|
64
|
+
help="Whether to archive the dataset itself after purging its contents.",
|
|
65
|
+
hidden=not Flags.v07.is_enabled(),
|
|
66
|
+
),
|
|
67
|
+
] = False,
|
|
68
|
+
skip_data: Annotated[
|
|
69
|
+
bool,
|
|
70
|
+
typer.Option(
|
|
71
|
+
"--skip-data",
|
|
72
|
+
"-s",
|
|
73
|
+
help="Skip deleting the data in the dataset, only delete configurations. The resources that are "
|
|
74
|
+
"considered data are: time series, event, files, assets, sequences, relationships, "
|
|
75
|
+
"labels, and 3D Models",
|
|
76
|
+
hidden=not Flags.v07.is_enabled(),
|
|
77
|
+
),
|
|
78
|
+
] = False,
|
|
79
|
+
include_configurations: Annotated[
|
|
80
|
+
bool,
|
|
81
|
+
typer.Option(
|
|
82
|
+
"--include-configurations",
|
|
83
|
+
"-c",
|
|
84
|
+
help="Include configurations, workflows, extraction pipelines and transformations in the purge.",
|
|
85
|
+
hidden=not Flags.v07.is_enabled(),
|
|
86
|
+
),
|
|
87
|
+
] = False,
|
|
88
|
+
asset_recursive: Annotated[
|
|
89
|
+
bool,
|
|
90
|
+
typer.Option(
|
|
91
|
+
"--asset-recursive",
|
|
92
|
+
"-a",
|
|
93
|
+
help="When deleting assets, delete all child assets recursively. CAVEAT: This can lead to assets"
|
|
94
|
+
" not in the selected dataset being deleted if they are children of assets in the dataset.",
|
|
95
|
+
hidden=not Flags.v07.is_enabled(),
|
|
57
96
|
),
|
|
58
97
|
] = False,
|
|
59
98
|
dry_run: Annotated[
|
|
@@ -84,11 +123,52 @@ class PurgeApp(typer.Typer):
|
|
|
84
123
|
"""This command will delete the contents of the specified dataset"""
|
|
85
124
|
cmd = PurgeCommand()
|
|
86
125
|
client = EnvironmentVariables.create_from_environment().get_client()
|
|
126
|
+
|
|
127
|
+
if external_id is None:
|
|
128
|
+
# Is Interactive
|
|
129
|
+
interactive = AssetInteractiveSelect(client, operation="purge")
|
|
130
|
+
external_id = interactive.select_data_set(allow_empty=False)
|
|
131
|
+
if Flags.v07.is_enabled():
|
|
132
|
+
skip_data = not questionary.confirm(
|
|
133
|
+
"Delete data in the dataset (time series, events, files, assets, sequences, relationships, labels, 3D models)?",
|
|
134
|
+
default=True,
|
|
135
|
+
).ask()
|
|
136
|
+
include_configurations = questionary.confirm(
|
|
137
|
+
"Delete configurations (workflows, extraction pipelines and transformations) in the dataset?",
|
|
138
|
+
default=False,
|
|
139
|
+
).ask()
|
|
140
|
+
asset_recursive = questionary.confirm(
|
|
141
|
+
"When deleting assets, delete all child assets recursively? (WARNING: This can lead "
|
|
142
|
+
"to assets not in the selected dataset being deleted if they are children of assets in the dataset.)",
|
|
143
|
+
default=False,
|
|
144
|
+
).ask()
|
|
145
|
+
archive_dataset = questionary.confirm("Archive the dataset itself after purging?", default=False).ask()
|
|
146
|
+
dry_run = questionary.confirm("Dry run?", default=True).ask()
|
|
147
|
+
verbose = questionary.confirm("Verbose?", default=True).ask()
|
|
148
|
+
|
|
149
|
+
user_options = [archive_dataset, dry_run, verbose]
|
|
150
|
+
if Flags.v07.is_enabled():
|
|
151
|
+
user_options.extend([skip_data, include_configurations, asset_recursive])
|
|
152
|
+
|
|
153
|
+
if any(selected is None for selected in user_options):
|
|
154
|
+
raise typer.Abort("Aborted by user.")
|
|
155
|
+
|
|
156
|
+
else:
|
|
157
|
+
archive_dataset = archive_dataset if Flags.v07.is_enabled() else include_dataset
|
|
158
|
+
|
|
159
|
+
if not Flags.v07.is_enabled():
|
|
160
|
+
skip_data = False
|
|
161
|
+
include_configurations = True
|
|
162
|
+
asset_recursive = False
|
|
163
|
+
|
|
87
164
|
cmd.run(
|
|
88
165
|
lambda: cmd.dataset(
|
|
89
166
|
client,
|
|
90
167
|
external_id,
|
|
91
|
-
|
|
168
|
+
archive_dataset,
|
|
169
|
+
not skip_data,
|
|
170
|
+
include_configurations,
|
|
171
|
+
asset_recursive,
|
|
92
172
|
dry_run,
|
|
93
173
|
auto_yes,
|
|
94
174
|
verbose,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import cast
|
|
2
2
|
|
|
3
3
|
from cognite.client import CogniteClient
|
|
4
|
+
from rich.console import Console
|
|
4
5
|
|
|
5
6
|
from .api.canvas import CanvasAPI
|
|
6
7
|
from .api.charts import ChartsAPI
|
|
@@ -24,11 +25,12 @@ class ToolkitClient(CogniteClient):
|
|
|
24
25
|
def __init__(self, config: ToolkitClientConfig | None = None, enable_set_pending_ids: bool = False) -> None:
|
|
25
26
|
super().__init__(config=config)
|
|
26
27
|
toolkit_config = ToolkitClientConfig.from_client_config(self.config)
|
|
28
|
+
self.console = Console()
|
|
27
29
|
self.search = SearchAPI(self._config, self._API_VERSION, self)
|
|
28
30
|
self.robotics = RoboticsAPI(self._config, self._API_VERSION, self)
|
|
29
31
|
self.dml = DMLAPI(self._config, self._API_VERSION, self)
|
|
30
32
|
self.verify = VerifyAPI(self._config, self._API_VERSION, self)
|
|
31
|
-
self.lookup = LookUpGroup(self._config, self._API_VERSION, self)
|
|
33
|
+
self.lookup = LookUpGroup(self._config, self._API_VERSION, self, self.console)
|
|
32
34
|
self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(toolkit_config, self._API_VERSION, self)
|
|
33
35
|
self.data_modeling: ExtendedDataModelingAPI = ExtendedDataModelingAPI(self._config, self._API_VERSION, self)
|
|
34
36
|
if enable_set_pending_ids:
|
|
@@ -17,11 +17,12 @@ from cognite.client.data_classes.capabilities import (
|
|
|
17
17
|
)
|
|
18
18
|
from cognite.client.exceptions import CogniteAPIError
|
|
19
19
|
from cognite.client.utils.useful_types import SequenceNotStr
|
|
20
|
+
from rich.console import Console
|
|
20
21
|
|
|
21
22
|
from cognite_toolkit._cdf_tk.client.api_client import ToolkitAPI
|
|
22
23
|
from cognite_toolkit._cdf_tk.constants import DRY_RUN_ID
|
|
23
|
-
from cognite_toolkit._cdf_tk.exceptions import ResourceRetrievalError
|
|
24
24
|
from cognite_toolkit._cdf_tk.tk_warnings import MediumSeverityWarning
|
|
25
|
+
from cognite_toolkit._cdf_tk.utils import humanize_collection
|
|
25
26
|
|
|
26
27
|
if TYPE_CHECKING:
|
|
27
28
|
from cognite_toolkit._cdf_tk.client._toolkit_client import ToolkitClient
|
|
@@ -30,17 +31,20 @@ if TYPE_CHECKING:
|
|
|
30
31
|
class LookUpAPI(ToolkitAPI, ABC):
|
|
31
32
|
dry_run_id: int = DRY_RUN_ID
|
|
32
33
|
|
|
33
|
-
def __init__(
|
|
34
|
+
def __init__(
|
|
35
|
+
self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
|
|
36
|
+
) -> None:
|
|
34
37
|
super().__init__(config, api_version, cognite_client)
|
|
35
|
-
self.
|
|
36
|
-
self.
|
|
38
|
+
self._console = console
|
|
39
|
+
self._cache: dict[str, int | None] = {}
|
|
40
|
+
self._reverse_cache: dict[int, str | None] = {}
|
|
37
41
|
|
|
38
42
|
@property
|
|
39
43
|
def resource_name(self) -> str:
|
|
40
44
|
return type(self).__name__.removesuffix("LookUpAPI")
|
|
41
45
|
|
|
42
46
|
@overload
|
|
43
|
-
def id(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int: ...
|
|
47
|
+
def id(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int | None: ...
|
|
44
48
|
|
|
45
49
|
@overload
|
|
46
50
|
def id(
|
|
@@ -49,39 +53,61 @@ class LookUpAPI(ToolkitAPI, ABC):
|
|
|
49
53
|
|
|
50
54
|
def id(
|
|
51
55
|
self, external_id: str | SequenceNotStr[str], is_dry_run: bool = False, allow_empty: bool = False
|
|
52
|
-
) -> int | list[int]:
|
|
56
|
+
) -> int | None | list[int]:
|
|
57
|
+
"""Lookup internal IDs for given external IDs.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
external_id: A string external ID or a sequence of string external IDs to look up.
|
|
61
|
+
is_dry_run: If True, return a predefined dry run ID for missing external IDs instead of raising an error.
|
|
62
|
+
allow_empty: If True, allow empty string external IDs and return 0 for them.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
The corresponding internal ID as an integer if a single external ID is provided,
|
|
66
|
+
or a list of internal IDs if a sequence of external IDs is provided.
|
|
67
|
+
"""
|
|
53
68
|
ids = [external_id] if isinstance(external_id, str) else external_id
|
|
54
|
-
|
|
55
|
-
if allow_empty and "" in
|
|
69
|
+
need_lookup = [id for id in ids if id not in self._cache]
|
|
70
|
+
if allow_empty and "" in need_lookup:
|
|
56
71
|
# Note we do not want to put empty string in the cache. It is a special case that
|
|
57
72
|
# as of 01/02/2025 only applies to LocationFilters
|
|
58
|
-
|
|
59
|
-
if
|
|
60
|
-
|
|
61
|
-
lookup = self._id(missing)
|
|
62
|
-
except CogniteAPIError as e:
|
|
63
|
-
if 400 <= e.code < 500:
|
|
64
|
-
missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
|
|
65
|
-
if missing_capabilities:
|
|
66
|
-
raise self._toolkit_client.verify.create_error(
|
|
67
|
-
missing_capabilities,
|
|
68
|
-
f"lookup {self.resource_name} with external_id {missing}",
|
|
69
|
-
)
|
|
70
|
-
# Raise the original error if it's not a 400 or the user has access to read the resource.from
|
|
71
|
-
raise
|
|
72
|
-
self._cache.update(lookup)
|
|
73
|
-
self._reverse_cache.update({v: k for k, v in lookup.items()})
|
|
74
|
-
if len(missing) != len(lookup) and not is_dry_run:
|
|
75
|
-
raise ResourceRetrievalError(
|
|
76
|
-
f"Failed to retrieve {self.resource_name} with external_id {missing}. Have you created it?", missing
|
|
77
|
-
)
|
|
78
|
-
return (
|
|
79
|
-
self._get_id_from_cache(external_id, is_dry_run, allow_empty)
|
|
80
|
-
if isinstance(external_id, str)
|
|
81
|
-
else [self._get_id_from_cache(id, is_dry_run, allow_empty) for id in ids]
|
|
82
|
-
)
|
|
73
|
+
need_lookup.remove("")
|
|
74
|
+
if need_lookup:
|
|
75
|
+
self._do_lookup_external_ids(need_lookup, is_dry_run)
|
|
83
76
|
|
|
84
|
-
|
|
77
|
+
if isinstance(external_id, str):
|
|
78
|
+
return self._get_id_from_cache(external_id, is_dry_run, allow_empty)
|
|
79
|
+
else:
|
|
80
|
+
internal_ids = (
|
|
81
|
+
self._get_id_from_cache(external_id, is_dry_run, allow_empty) for external_id in external_id
|
|
82
|
+
)
|
|
83
|
+
return [id_ for id_ in internal_ids if id_ is not None]
|
|
84
|
+
|
|
85
|
+
def _do_lookup_external_ids(self, external_ids: list[str], is_dry_run: bool) -> None:
|
|
86
|
+
try:
|
|
87
|
+
ids_by_external_id = self._id(external_ids)
|
|
88
|
+
except CogniteAPIError as e:
|
|
89
|
+
if 400 <= e.code < 500:
|
|
90
|
+
missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
|
|
91
|
+
if missing_capabilities:
|
|
92
|
+
raise self._toolkit_client.verify.create_error(
|
|
93
|
+
missing_capabilities,
|
|
94
|
+
f"lookup {self.resource_name} with external_id {external_ids}",
|
|
95
|
+
)
|
|
96
|
+
# Raise the original error if it's not a 400 or the user has access to read the resource.from
|
|
97
|
+
raise
|
|
98
|
+
self._cache.update(ids_by_external_id)
|
|
99
|
+
self._reverse_cache.update({v: k for k, v in ids_by_external_id.items()})
|
|
100
|
+
missing_external_ids = [ext_id for ext_id in external_ids if ext_id not in ids_by_external_id]
|
|
101
|
+
if missing_external_ids and not is_dry_run:
|
|
102
|
+
plural = "s" if len(missing_external_ids) > 1 else ""
|
|
103
|
+
plural2 = "They do" if len(missing_external_ids) > 1 else "It does"
|
|
104
|
+
MediumSeverityWarning(
|
|
105
|
+
f"Failed to retrieve {self.resource_name} with external_id{plural} "
|
|
106
|
+
f"{humanize_collection(missing_external_ids)}. {plural2} not exist in CDF"
|
|
107
|
+
).print_warning(console=self._console)
|
|
108
|
+
self._cache.update({ext_id: None for ext_id in missing_external_ids})
|
|
109
|
+
|
|
110
|
+
def _get_id_from_cache(self, external_id: str, is_dry_run: bool = False, allow_empty: bool = False) -> int | None:
|
|
85
111
|
if allow_empty and external_id == "":
|
|
86
112
|
return 0
|
|
87
113
|
elif is_dry_run:
|
|
@@ -96,34 +122,56 @@ class LookUpAPI(ToolkitAPI, ABC):
|
|
|
96
122
|
def external_id(self, id: Sequence[int]) -> list[str]: ...
|
|
97
123
|
|
|
98
124
|
def external_id(self, id: int | Sequence[int]) -> str | None | list[str]:
|
|
125
|
+
"""Lookup external IDs for given internal IDs.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
id: An integer ID or a sequence of integer IDs to look up. Note that an ID of 0 corresponds
|
|
129
|
+
to an empty string external ID.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
The corresponding external ID as a string if a single ID is provided,
|
|
133
|
+
or a list of external IDs if a sequence of IDs is provided.
|
|
134
|
+
If an ID does not exist, None is returned for that ID.
|
|
135
|
+
|
|
136
|
+
"""
|
|
99
137
|
ids = [id] if isinstance(id, int) else id
|
|
100
|
-
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
try:
|
|
105
|
-
lookup = self._external_id(missing)
|
|
106
|
-
except CogniteAPIError as e:
|
|
107
|
-
if 400 <= e.code < 500:
|
|
108
|
-
missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
|
|
109
|
-
if missing_capabilities:
|
|
110
|
-
raise self._toolkit_client.verify.create_error(
|
|
111
|
-
missing_capabilities,
|
|
112
|
-
f"lookup {self.resource_name} with id {missing}",
|
|
113
|
-
)
|
|
114
|
-
# Raise the original error if it's not a 400 or the user has access to read the resource.from
|
|
115
|
-
raise
|
|
116
|
-
self._reverse_cache.update(lookup)
|
|
117
|
-
self._cache.update({v: k for k, v in lookup.items()})
|
|
118
|
-
if len(missing) != len(lookup):
|
|
119
|
-
MediumSeverityWarning(
|
|
120
|
-
f"Failed to retrieve {self.resource_name} with id {missing}. It does not exist in CDF"
|
|
121
|
-
).print_warning()
|
|
138
|
+
need_lookup = [id_ for id_ in ids if id_ not in self._reverse_cache if id_ != 0]
|
|
139
|
+
if need_lookup:
|
|
140
|
+
self._do_lookup_internal_ids(need_lookup)
|
|
141
|
+
|
|
122
142
|
if isinstance(id, int):
|
|
123
143
|
return self._get_external_id_from_cache(id)
|
|
124
144
|
else:
|
|
125
|
-
external_ids = (self._get_external_id_from_cache(
|
|
126
|
-
return [
|
|
145
|
+
external_ids = (self._get_external_id_from_cache(id_) for id_ in ids)
|
|
146
|
+
return [id_ for id_ in external_ids if id_ is not None]
|
|
147
|
+
|
|
148
|
+
def _do_lookup_internal_ids(self, ids: list[int]) -> None:
|
|
149
|
+
try:
|
|
150
|
+
found_by_id = self._external_id(ids)
|
|
151
|
+
except CogniteAPIError as e:
|
|
152
|
+
if 400 <= e.code < 500:
|
|
153
|
+
missing_capabilities = self._toolkit_client.verify.authorization(self._read_acl())
|
|
154
|
+
if missing_capabilities:
|
|
155
|
+
raise self._toolkit_client.verify.create_error(
|
|
156
|
+
missing_capabilities,
|
|
157
|
+
f"lookup {self.resource_name} with id {ids}",
|
|
158
|
+
)
|
|
159
|
+
# Raise the original error if it's not a 400 or the user has access to read the resource.from
|
|
160
|
+
raise
|
|
161
|
+
self._reverse_cache.update(found_by_id)
|
|
162
|
+
self._cache.update({v: k for k, v in found_by_id.items()})
|
|
163
|
+
missing_ids = [id for id in ids if id not in found_by_id]
|
|
164
|
+
if not missing_ids:
|
|
165
|
+
return None
|
|
166
|
+
plural = "s" if len(missing_ids) > 1 else ""
|
|
167
|
+
plural2 = "They do" if len(missing_ids) > 1 else "It does"
|
|
168
|
+
MediumSeverityWarning(
|
|
169
|
+
f"Failed to retrieve {self.resource_name} with id{plural} "
|
|
170
|
+
f"{humanize_collection(missing_ids)}. {plural2} not exist in CDF"
|
|
171
|
+
).print_warning(console=self._console)
|
|
172
|
+
# Cache the missing IDs with None to avoid repeated lookups
|
|
173
|
+
self._reverse_cache.update({missing_id: None for missing_id in missing_ids})
|
|
174
|
+
return None
|
|
127
175
|
|
|
128
176
|
def _get_external_id_from_cache(self, id: int) -> str | None:
|
|
129
177
|
if id == 0:
|
|
@@ -311,8 +359,10 @@ class FunctionLookUpAPI(LookUpAPI):
|
|
|
311
359
|
|
|
312
360
|
|
|
313
361
|
class AllLookUpAPI(LookUpAPI, ABC):
|
|
314
|
-
def __init__(
|
|
315
|
-
|
|
362
|
+
def __init__(
|
|
363
|
+
self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
|
|
364
|
+
) -> None:
|
|
365
|
+
super().__init__(config, api_version, cognite_client, console)
|
|
316
366
|
self._has_looked_up = False
|
|
317
367
|
|
|
318
368
|
@abstractmethod
|
|
@@ -322,13 +372,15 @@ class AllLookUpAPI(LookUpAPI, ABC):
|
|
|
322
372
|
def _id(self, external_id: SequenceNotStr[str]) -> dict[str, int]:
|
|
323
373
|
if not self._has_looked_up:
|
|
324
374
|
self._lookup()
|
|
325
|
-
|
|
375
|
+
found_pairs = ((ext_id, self._cache[ext_id]) for ext_id in external_id if ext_id in self._cache)
|
|
376
|
+
return {k: v for k, v in found_pairs if v is not None}
|
|
326
377
|
|
|
327
378
|
def _external_id(self, id: Sequence[int]) -> dict[int, str]:
|
|
328
379
|
if not self._has_looked_up:
|
|
329
380
|
self._lookup()
|
|
330
381
|
self._has_looked_up = True
|
|
331
|
-
|
|
382
|
+
found_pairs = ((id_, self._reverse_cache[id_]) for id_ in id if id_ in self._reverse_cache)
|
|
383
|
+
return {k: v for k, v in found_pairs if v is not None}
|
|
332
384
|
|
|
333
385
|
|
|
334
386
|
class SecurityCategoriesLookUpAPI(AllLookUpAPI):
|
|
@@ -363,18 +415,21 @@ class LocationFiltersLookUpAPI(AllLookUpAPI):
|
|
|
363
415
|
def _id(self, external_id: SequenceNotStr[str]) -> dict[str, int]:
|
|
364
416
|
if not self._has_looked_up:
|
|
365
417
|
self._lookup()
|
|
366
|
-
|
|
418
|
+
found_pairs = ((ext_id, self._cache[ext_id]) for ext_id in external_id if ext_id in self._cache)
|
|
419
|
+
return {k: v for k, v in found_pairs if v is not None}
|
|
367
420
|
|
|
368
421
|
|
|
369
422
|
class LookUpGroup(ToolkitAPI):
|
|
370
|
-
def __init__(
|
|
423
|
+
def __init__(
|
|
424
|
+
self, config: ClientConfig, api_version: str | None, cognite_client: "ToolkitClient", console: Console
|
|
425
|
+
) -> None:
|
|
371
426
|
super().__init__(config, api_version, cognite_client)
|
|
372
|
-
self.data_sets = DataSetLookUpAPI(config, api_version, cognite_client)
|
|
373
|
-
self.assets = AssetLookUpAPI(config, api_version, cognite_client)
|
|
374
|
-
self.time_series = TimeSeriesLookUpAPI(config, api_version, cognite_client)
|
|
375
|
-
self.files = FileMetadataLookUpAPI(config, api_version, cognite_client)
|
|
376
|
-
self.events = EventLookUpAPI(config, api_version, cognite_client)
|
|
377
|
-
self.security_categories = SecurityCategoriesLookUpAPI(config, api_version, cognite_client)
|
|
378
|
-
self.location_filters = LocationFiltersLookUpAPI(config, api_version, cognite_client)
|
|
379
|
-
self.extraction_pipelines = ExtractionPipelineLookUpAPI(config, api_version, cognite_client)
|
|
380
|
-
self.functions = FunctionLookUpAPI(config, api_version, cognite_client)
|
|
427
|
+
self.data_sets = DataSetLookUpAPI(config, api_version, cognite_client, console)
|
|
428
|
+
self.assets = AssetLookUpAPI(config, api_version, cognite_client, console)
|
|
429
|
+
self.time_series = TimeSeriesLookUpAPI(config, api_version, cognite_client, console)
|
|
430
|
+
self.files = FileMetadataLookUpAPI(config, api_version, cognite_client, console)
|
|
431
|
+
self.events = EventLookUpAPI(config, api_version, cognite_client, console)
|
|
432
|
+
self.security_categories = SecurityCategoriesLookUpAPI(config, api_version, cognite_client, console)
|
|
433
|
+
self.location_filters = LocationFiltersLookUpAPI(config, api_version, cognite_client, console)
|
|
434
|
+
self.extraction_pipelines = ExtractionPipelineLookUpAPI(config, api_version, cognite_client, console)
|
|
435
|
+
self.functions = FunctionLookUpAPI(config, api_version, cognite_client, console)
|
|
@@ -9,6 +9,7 @@ from cognite.client._api.functions import FunctionCallsAPI, FunctionSchedulesAPI
|
|
|
9
9
|
from cognite.client._api.raw import RawDatabasesAPI, RawRowsAPI, RawTablesAPI
|
|
10
10
|
from cognite.client._api.synthetic_time_series import SyntheticDatapointsAPI
|
|
11
11
|
from cognite.client.testing import CogniteClientMock
|
|
12
|
+
from rich.console import Console
|
|
12
13
|
|
|
13
14
|
from cognite_toolkit._cdf_tk.client._toolkit_client import ToolkitClient
|
|
14
15
|
|
|
@@ -58,6 +59,7 @@ class ToolkitClientMock(CogniteClientMock):
|
|
|
58
59
|
super().__init__(*args, **kwargs)
|
|
59
60
|
return None
|
|
60
61
|
super().__init__(*args, **kwargs)
|
|
62
|
+
self.console = Console()
|
|
61
63
|
# Developer note:
|
|
62
64
|
# - Please add your mocked APIs in chronological order
|
|
63
65
|
# - For nested APIs:
|
|
@@ -3,7 +3,6 @@ from functools import partial
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
from cognite.client.data_classes._base import T_CogniteResource
|
|
6
|
-
from rich.console import Console
|
|
7
6
|
|
|
8
7
|
from cognite_toolkit._cdf_tk.constants import DATA_MANIFEST_STEM, DATA_RESOURCE_DIR
|
|
9
8
|
from cognite_toolkit._cdf_tk.exceptions import ToolkitValueError
|
|
@@ -41,7 +40,7 @@ class DownloadCommand(ToolkitCommand):
|
|
|
41
40
|
"""
|
|
42
41
|
compression_cls = Compression.from_name(compression)
|
|
43
42
|
|
|
44
|
-
console =
|
|
43
|
+
console = io.client.console
|
|
45
44
|
for selector in selectors:
|
|
46
45
|
target_dir = output_dir / selector.group
|
|
47
46
|
if verbose:
|
|
@@ -22,7 +22,7 @@ from cognite.client.data_classes.events import EventProperty
|
|
|
22
22
|
from cognite_toolkit._cdf_tk.client import ToolkitClient
|
|
23
23
|
from cognite_toolkit._cdf_tk.client.data_classes.apm_config_v1 import APMConfig, APMConfigList
|
|
24
24
|
from cognite_toolkit._cdf_tk.cruds import NodeCRUD, ResourceCRUD, SpaceCRUD
|
|
25
|
-
from cognite_toolkit._cdf_tk.exceptions import ToolkitRequiredValueError
|
|
25
|
+
from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitRequiredValueError
|
|
26
26
|
from cognite_toolkit._cdf_tk.utils import humanize_collection
|
|
27
27
|
|
|
28
28
|
from .data_model import CREATED_SOURCE_SYSTEM_VIEW_ID, SPACE, SPACE_SOURCE_VIEW_ID
|
|
@@ -196,9 +196,10 @@ class SourceSystemCreator(MigrationCreator[NodeApplyList]):
|
|
|
196
196
|
@cached_property
|
|
197
197
|
def _advanced_filter(self) -> filters.Filter:
|
|
198
198
|
if self.data_set_external_id is not None:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
data_set_id = self.client.lookup.data_sets.id(self.data_set_external_id)
|
|
200
|
+
if data_set_id is None:
|
|
201
|
+
raise ToolkitMissingResourceError(f"Data set with external ID '{self.data_set_external_id}' not found.")
|
|
202
|
+
return filters.Equals(SourceFileProperty.data_set_id, data_set_id)
|
|
202
203
|
if self.hierarchy is not None:
|
|
203
204
|
return filters.InAssetSubtree(SourceFileProperty.asset_external_ids, [self.hierarchy])
|
|
204
205
|
else:
|