cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.30__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.
- cognite_toolkit/_cdf.py +16 -17
- cognite_toolkit/_cdf_tk/apps/__init__.py +2 -0
- cognite_toolkit/_cdf_tk/apps/_core_app.py +13 -5
- cognite_toolkit/_cdf_tk/apps/_data_app.py +1 -1
- cognite_toolkit/_cdf_tk/apps/_dev_app.py +86 -0
- cognite_toolkit/_cdf_tk/apps/_download_app.py +692 -24
- cognite_toolkit/_cdf_tk/apps/_dump_app.py +43 -101
- cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
- cognite_toolkit/_cdf_tk/apps/_migrate_app.py +249 -9
- cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
- cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
- cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
- cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
- cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
- cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
- cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py +23 -3
- cognite_toolkit/_cdf_tk/client/api/extended_functions.py +6 -9
- cognite_toolkit/_cdf_tk/client/api/infield.py +93 -1
- cognite_toolkit/_cdf_tk/client/api/migration.py +175 -1
- cognite_toolkit/_cdf_tk/client/api/streams.py +84 -0
- cognite_toolkit/_cdf_tk/client/api/three_d.py +50 -0
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +25 -1
- cognite_toolkit/_cdf_tk/client/data_classes/canvas.py +46 -3
- cognite_toolkit/_cdf_tk/client/data_classes/charts.py +3 -3
- cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
- cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
- cognite_toolkit/_cdf_tk/client/data_classes/migration.py +10 -2
- cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
- cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +47 -0
- cognite_toolkit/_cdf_tk/client/testing.py +18 -2
- cognite_toolkit/_cdf_tk/commands/__init__.py +6 -6
- cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
- cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
- cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
- cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +133 -91
- cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +73 -22
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +311 -43
- cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +5 -5
- cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +33 -0
- cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +157 -8
- cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
- cognite_toolkit/_cdf_tk/commands/_purge.py +27 -28
- cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
- cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
- cognite_toolkit/_cdf_tk/commands/about.py +221 -0
- cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
- cognite_toolkit/_cdf_tk/commands/build_cmd.py +15 -61
- cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
- cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
- cognite_toolkit/_cdf_tk/commands/dump_resource.py +6 -4
- cognite_toolkit/_cdf_tk/commands/init.py +225 -3
- cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
- cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
- cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
- cognite_toolkit/_cdf_tk/constants.py +20 -1
- cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
- cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
- cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +8 -17
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +4 -14
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +44 -43
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +4 -11
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +205 -66
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +5 -17
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +116 -27
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +6 -27
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +9 -28
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +3 -7
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +3 -15
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +4 -12
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +4 -10
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +15 -44
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +39 -31
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
- cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
- cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
- cognite_toolkit/_cdf_tk/plugins.py +2 -1
- cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
- cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
- cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
- cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
- cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
- cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
- cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
- cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
- cognite_toolkit/_cdf_tk/storageio/_applications.py +338 -26
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
- cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
- cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
- cognite_toolkit/_cdf_tk/storageio/_file_content.py +436 -0
- cognite_toolkit/_cdf_tk/storageio/_instances.py +34 -2
- cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +62 -4
- cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
- cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
- cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
- cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
- cognite_toolkit/_cdf_tk/tracker.py +2 -2
- cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
- cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
- cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
- cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
- cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
- cognite_toolkit/_cdf_tk/utils/http_client/_client.py +284 -18
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +50 -4
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +187 -0
- cognite_toolkit/_cdf_tk/utils/interactive_select.py +9 -14
- cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
- cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
- cognite_toolkit/_cdf_tk/validation.py +79 -1
- 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 +5 -4
- cognite_toolkit/_version.py +1 -1
- cognite_toolkit/config.dev.yaml +13 -0
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/METADATA +24 -24
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/RECORD +153 -143
- cognite_toolkit-0.7.30.dist-info/WHEEL +4 -0
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.30.dist-info}/entry_points.txt +1 -0
- cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
- cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
- cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
- cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
- cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
- cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import gzip
|
|
2
|
+
import sys
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import Hashable
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
from cognite.client import global_config
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field, JsonValue, TypeAdapter, model_validator
|
|
10
|
+
from pydantic.alias_generators import to_camel
|
|
11
|
+
|
|
12
|
+
from cognite_toolkit._cdf_tk.utils.http_client._tracker import ItemsRequestTracker
|
|
13
|
+
from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
|
|
14
|
+
|
|
15
|
+
if sys.version_info >= (3, 11):
|
|
16
|
+
from typing import Self
|
|
17
|
+
else:
|
|
18
|
+
from typing_extensions import Self
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HTTPResult2(BaseModel): ...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class FailedRequest2(HTTPResult2):
|
|
25
|
+
error: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SuccessResponse2(HTTPResult2):
|
|
29
|
+
status_code: int
|
|
30
|
+
body: str
|
|
31
|
+
content: bytes
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ErrorDetails2(BaseModel):
|
|
35
|
+
"""This is the expected structure of error details in the CDF API"""
|
|
36
|
+
|
|
37
|
+
code: int
|
|
38
|
+
message: str
|
|
39
|
+
missing: list[JsonValue] | None = None
|
|
40
|
+
duplicated: list[JsonValue] | None = None
|
|
41
|
+
is_auto_retryable: bool | None = None
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def from_response(cls, response: httpx.Response) -> "ErrorDetails2":
|
|
45
|
+
"""Populate the error details from a httpx response."""
|
|
46
|
+
try:
|
|
47
|
+
res = TypeAdapter(dict[Literal["error"], ErrorDetails2]).validate_json(response.text)
|
|
48
|
+
except ValueError:
|
|
49
|
+
return cls(code=response.status_code, message=response.text)
|
|
50
|
+
return res["error"]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class FailedResponse2(HTTPResult2):
|
|
54
|
+
status_code: int
|
|
55
|
+
body: str
|
|
56
|
+
error: ErrorDetails2
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class BaseRequestMessage(BaseModel, ABC):
|
|
60
|
+
endpoint_url: str
|
|
61
|
+
method: Literal["GET", "POST", "PATCH", "DELETE", "PUT"]
|
|
62
|
+
connect_attempt: int = 0
|
|
63
|
+
read_attempt: int = 0
|
|
64
|
+
status_attempt: int = 0
|
|
65
|
+
api_version: str | None = None
|
|
66
|
+
content_type: str = "application/json"
|
|
67
|
+
accept: str = "application/json"
|
|
68
|
+
|
|
69
|
+
parameters: dict[str, PrimitiveType] | None = None
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def total_attempts(self) -> int:
|
|
73
|
+
return self.connect_attempt + self.read_attempt + self.status_attempt
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
@abstractmethod
|
|
77
|
+
def content(self) -> str | bytes | None: ...
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class RequestMessage2(BaseRequestMessage):
|
|
81
|
+
data_content: bytes | None = None
|
|
82
|
+
body_content: dict[str, JsonValue] | None = None
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="before")
|
|
85
|
+
def check_data_or_body(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
86
|
+
if values.get("data_content") is not None and values.get("body_content") is not None:
|
|
87
|
+
raise ValueError("Only one of data_content or body_content can be set.")
|
|
88
|
+
return values
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def content(self) -> str | bytes | None:
|
|
92
|
+
data: str | bytes | None = None
|
|
93
|
+
if self.data_content is not None:
|
|
94
|
+
data = self.data_content
|
|
95
|
+
if not global_config.disable_gzip:
|
|
96
|
+
data = gzip.compress(data)
|
|
97
|
+
elif self.body_content is not None:
|
|
98
|
+
# We serialize using pydantic instead of json.dumps. This is because pydantic is faster
|
|
99
|
+
# and handles more complex types such as datetime, float('nan'), etc.
|
|
100
|
+
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"))
|
|
103
|
+
return data
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
_BODY_SERIALIZER = TypeAdapter(dict[str, JsonValue])
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ItemsResultMessage2(BaseModel):
|
|
110
|
+
ids: list[Hashable]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class ItemsFailedRequest2(ItemsResultMessage2):
|
|
114
|
+
error_message: str
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ItemsSuccessResponse2(ItemsResultMessage2):
|
|
118
|
+
status_code: int
|
|
119
|
+
body: str
|
|
120
|
+
content: bytes
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class ItemsFailedResponse2(ItemsResultMessage2):
|
|
124
|
+
status_code: int
|
|
125
|
+
error: ErrorDetails2
|
|
126
|
+
body: str
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class BaseModelObject(BaseModel):
|
|
130
|
+
"""Base class for all object. This includes resources and nested objects."""
|
|
131
|
+
|
|
132
|
+
# We allow extra fields to support forward compatibility.
|
|
133
|
+
model_config = ConfigDict(alias_generator=to_camel, extra="allow")
|
|
134
|
+
|
|
135
|
+
def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
|
136
|
+
"""Dump the resource to a dictionary.
|
|
137
|
+
|
|
138
|
+
This is the default serialization method for request resources.
|
|
139
|
+
"""
|
|
140
|
+
return self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True)
|
|
141
|
+
|
|
142
|
+
@classmethod
|
|
143
|
+
def _load(cls, resource: dict[str, Any]) -> "Self":
|
|
144
|
+
"""Load method to match CogniteResource signature."""
|
|
145
|
+
return cls.model_validate(resource)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class RequestResource(BaseModelObject, ABC):
|
|
149
|
+
@abstractmethod
|
|
150
|
+
def as_id(self) -> Hashable: ...
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _set_default_tracker(data: dict[str, Any]) -> ItemsRequestTracker:
|
|
154
|
+
if "tracker" not in data or data["tracker"] is None:
|
|
155
|
+
return ItemsRequestTracker(data.get("max_failures_before_abort", 50))
|
|
156
|
+
return data["tracker"]
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ItemsRequest2(BaseRequestMessage):
|
|
160
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
161
|
+
items: list[RequestResource]
|
|
162
|
+
extra_body_fields: dict[str, JsonValue] | None = None
|
|
163
|
+
max_failures_before_abort: int = 50
|
|
164
|
+
tracker: ItemsRequestTracker = Field(init=False, default_factory=_set_default_tracker, exclude=True)
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def content(self) -> str | bytes | None:
|
|
168
|
+
body: dict[str, JsonValue] = {"items": [item.dump() for item in self.items]}
|
|
169
|
+
if self.extra_body_fields:
|
|
170
|
+
body.update(self.extra_body_fields)
|
|
171
|
+
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"))
|
|
174
|
+
return res
|
|
175
|
+
|
|
176
|
+
def split(self, status_attempts: int) -> list["ItemsRequest2"]:
|
|
177
|
+
"""Split the request into multiple requests with a single item each."""
|
|
178
|
+
mid = len(self.items) // 2
|
|
179
|
+
if mid == 0:
|
|
180
|
+
return [self]
|
|
181
|
+
self.tracker.register_failure()
|
|
182
|
+
messages: list[ItemsRequest2] = []
|
|
183
|
+
for part in (self.items[:mid], self.items[mid:]):
|
|
184
|
+
new_request = self.model_copy(update={"items": part, "status_attempt": status_attempts})
|
|
185
|
+
new_request.tracker = self.tracker
|
|
186
|
+
messages.append(new_request)
|
|
187
|
+
return messages
|
|
@@ -14,9 +14,6 @@ from cognite.client.data_classes import (
|
|
|
14
14
|
filters,
|
|
15
15
|
)
|
|
16
16
|
from cognite.client.data_classes.aggregations import Count
|
|
17
|
-
from cognite.client.data_classes.capabilities import (
|
|
18
|
-
UserProfilesAcl,
|
|
19
|
-
)
|
|
20
17
|
from cognite.client.data_classes.data_modeling import ContainerId, NodeList, Space, SpaceList, View, ViewId, ViewList
|
|
21
18
|
from cognite.client.data_classes.data_modeling.statistics import SpaceStatistics
|
|
22
19
|
from cognite.client.utils import ms_to_datetime
|
|
@@ -28,7 +25,7 @@ from cognite_toolkit._cdf_tk.client.data_classes.canvas import Canvas
|
|
|
28
25
|
from cognite_toolkit._cdf_tk.client.data_classes.charts import Chart, ChartList, Visibility
|
|
29
26
|
from cognite_toolkit._cdf_tk.client.data_classes.migration import ResourceViewMapping
|
|
30
27
|
from cognite_toolkit._cdf_tk.client.data_classes.raw import RawTable
|
|
31
|
-
from cognite_toolkit._cdf_tk.exceptions import
|
|
28
|
+
from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitValueError
|
|
32
29
|
|
|
33
30
|
from . import humanize_collection
|
|
34
31
|
from .aggregators import (
|
|
@@ -309,9 +306,14 @@ class InteractiveCanvasSelect:
|
|
|
309
306
|
opening_choices: ClassVar[list[questionary.Choice]] = [
|
|
310
307
|
questionary.Choice(title="All public Canvases", value=CanvasFilter(visibility="public", select_all=True)),
|
|
311
308
|
questionary.Choice(title="Selected public Canvases", value=CanvasFilter(visibility="public", select_all=False)),
|
|
312
|
-
questionary.Choice(
|
|
313
|
-
|
|
314
|
-
|
|
309
|
+
questionary.Choice(
|
|
310
|
+
title="All public Canvases by given user",
|
|
311
|
+
value=CanvasFilter(created_by="user", select_all=True, visibility="public"),
|
|
312
|
+
),
|
|
313
|
+
questionary.Choice(
|
|
314
|
+
title="Selected public Canvases by given user",
|
|
315
|
+
value=CanvasFilter(created_by="user", select_all=False, visibility="public"),
|
|
316
|
+
),
|
|
315
317
|
]
|
|
316
318
|
|
|
317
319
|
def __init__(self, client: ToolkitClient) -> None:
|
|
@@ -406,13 +408,6 @@ class InteractiveChartSelect:
|
|
|
406
408
|
return user_response
|
|
407
409
|
|
|
408
410
|
def _select_external_ids(self, select_filter: ChartFilter) -> list[str]:
|
|
409
|
-
if not self.client.iam.verify_capabilities(
|
|
410
|
-
UserProfilesAcl([UserProfilesAcl.Action.Read], scope=UserProfilesAcl.Scope.All())
|
|
411
|
-
):
|
|
412
|
-
raise AuthorizationError(
|
|
413
|
-
"The current user does not have permission to list user profiles, "
|
|
414
|
-
"which is required to select Charts owned by a specific user."
|
|
415
|
-
)
|
|
416
411
|
available_charts = self.client.charts.list(visibility=(select_filter.visibility or "PUBLIC"))
|
|
417
412
|
if select_filter.select_all and select_filter.owned_by is None:
|
|
418
413
|
return [chart.external_id for chart in available_charts]
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import importlib.util
|
|
2
|
+
from dataclasses import dataclass
|
|
2
3
|
from typing import TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingDependencyError
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
|
-
from sqlparse.sql import Identifier
|
|
8
|
-
from sqlparse.tokens import Token
|
|
9
|
-
from dataclasses import dataclass
|
|
8
|
+
from sqlparse.sql import Identifier, Token
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
@dataclass(frozen=True)
|
|
@@ -8,10 +8,13 @@ from cognite.client.data_classes._base import CogniteObject, WriteableCogniteRes
|
|
|
8
8
|
JsonVal: TypeAlias = None | str | int | float | bool | dict[str, "JsonVal"] | list["JsonVal"]
|
|
9
9
|
|
|
10
10
|
AssetCentricDestinationType: TypeAlias = Literal["assets", "files", "events", "timeseries", "sequences"]
|
|
11
|
-
AssetCentricType: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence"
|
|
11
|
+
AssetCentricType: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence"]
|
|
12
|
+
AssetCentricTypeExtended: TypeAlias = Literal["asset", "file", "event", "timeseries", "sequence", "annotation"]
|
|
12
13
|
AssetCentricResource: TypeAlias = Asset | FileMetadata | Event | TimeSeries
|
|
13
14
|
AssetCentricResourceExtended: TypeAlias = Asset | FileMetadata | Event | TimeSeries | Annotation
|
|
14
|
-
AssetCentricKind: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata"
|
|
15
|
+
AssetCentricKind: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata"]
|
|
16
|
+
AssetCentricKindExtended: TypeAlias = Literal["Assets", "Events", "TimeSeries", "FileMetadata", "Annotations"]
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
DataType: TypeAlias = Literal["string", "integer", "float", "boolean", "json", "date", "timestamp", "epoch"]
|
|
17
20
|
PythonTypes: TypeAlias = str | int | float | bool | datetime | date | dict[str, Any] | list[Any]
|
|
@@ -25,3 +28,4 @@ PrimitiveType: TypeAlias = str | int | float | bool
|
|
|
25
28
|
|
|
26
29
|
T_WriteCogniteResource = TypeVar("T_WriteCogniteResource", bound=CogniteObject)
|
|
27
30
|
T_AssetCentricResource = TypeVar("T_AssetCentricResource", bound=AssetCentricResource)
|
|
31
|
+
T_AssetCentricResourceExtended = TypeVar("T_AssetCentricResourceExtended", bound=AssetCentricResourceExtended)
|
|
@@ -8,18 +8,29 @@ from cognite.client.utils._text import to_snake_case
|
|
|
8
8
|
from pydantic import BaseModel, TypeAdapter, ValidationError
|
|
9
9
|
from pydantic_core import ErrorDetails
|
|
10
10
|
|
|
11
|
-
from cognite_toolkit._cdf_tk.
|
|
11
|
+
from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
|
|
12
|
+
from cognite_toolkit._cdf_tk.constants import DEV_ONLY_MODULES
|
|
13
|
+
from cognite_toolkit._cdf_tk.data_classes import BuildConfigYAML, BuildVariables, ModuleDirectories
|
|
14
|
+
from cognite_toolkit._cdf_tk.exceptions import (
|
|
15
|
+
ToolkitDuplicatedModuleError,
|
|
16
|
+
ToolkitEnvError,
|
|
17
|
+
ToolkitMissingModuleError,
|
|
18
|
+
)
|
|
19
|
+
from cognite_toolkit._cdf_tk.hints import ModuleDefinition
|
|
12
20
|
from cognite_toolkit._cdf_tk.resource_classes import BaseModelResource
|
|
13
21
|
from cognite_toolkit._cdf_tk.tk_warnings import (
|
|
14
22
|
DataSetMissingWarning,
|
|
23
|
+
MediumSeverityWarning,
|
|
15
24
|
TemplateVariableWarning,
|
|
16
25
|
WarningList,
|
|
17
26
|
)
|
|
18
27
|
from cognite_toolkit._cdf_tk.tk_warnings.fileread import ResourceFormatWarning
|
|
28
|
+
from cognite_toolkit._cdf_tk.utils import humanize_collection
|
|
19
29
|
|
|
20
30
|
__all__ = [
|
|
21
31
|
"humanize_validation_error",
|
|
22
32
|
"validate_data_set_is_set",
|
|
33
|
+
"validate_module_selection",
|
|
23
34
|
"validate_modules_variables",
|
|
24
35
|
]
|
|
25
36
|
|
|
@@ -210,3 +221,70 @@ def as_json_path(loc: tuple[str | int, ...]) -> str:
|
|
|
210
221
|
|
|
211
222
|
suffix = ".".join([str(x) if isinstance(x, str) else f"[{x + 1}]" for x in loc]).replace(".[", "[")
|
|
212
223
|
return f"{prefix}{suffix}"
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def validate_module_selection(
|
|
227
|
+
modules: ModuleDirectories,
|
|
228
|
+
config: BuildConfigYAML,
|
|
229
|
+
packages: dict[str, list[str]],
|
|
230
|
+
selected_modules: set[str | Path],
|
|
231
|
+
organization_dir: Path,
|
|
232
|
+
) -> WarningList:
|
|
233
|
+
"""Validates module selection and returns warnings for non-critical issues.
|
|
234
|
+
|
|
235
|
+
Critical errors (duplicate modules, missing modules, no modules selected) are still raised
|
|
236
|
+
as exceptions as they prevent the build from proceeding.
|
|
237
|
+
"""
|
|
238
|
+
warnings: WarningList = WarningList()
|
|
239
|
+
|
|
240
|
+
# Validations: Ambiguous selection.
|
|
241
|
+
selected_names = {s for s in config.environment.selected if isinstance(s, str)}
|
|
242
|
+
if duplicate_modules := {
|
|
243
|
+
module_name: paths
|
|
244
|
+
for module_name, paths in modules.as_path_by_name().items()
|
|
245
|
+
if len(paths) > 1 and module_name in selected_names
|
|
246
|
+
}:
|
|
247
|
+
# If the user has selected a module by name, and there are multiple modules with that name, raise an error.
|
|
248
|
+
# Note, if the user uses a path to select a module, this error will not be raised.
|
|
249
|
+
raise ToolkitDuplicatedModuleError(
|
|
250
|
+
f"Ambiguous module selected in config.{config.environment.name}.yaml:", duplicate_modules
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# Package Referenced Modules Exists
|
|
254
|
+
for package, package_modules in packages.items():
|
|
255
|
+
if package not in selected_names:
|
|
256
|
+
# We do not check packages that are not selected.
|
|
257
|
+
# Typically, the user will delete the modules that are irrelevant for them;
|
|
258
|
+
# thus we only check the selected packages.
|
|
259
|
+
continue
|
|
260
|
+
if missing_packages := set(package_modules) - modules.available_names:
|
|
261
|
+
raise ToolkitMissingModuleError(
|
|
262
|
+
f"Package {package} defined in {CDFToml.file_name!s} is referring "
|
|
263
|
+
f"the following missing modules {missing_packages}."
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# Selected modules does not exists
|
|
267
|
+
if missing_modules := set(selected_modules) - modules.available:
|
|
268
|
+
hint = ModuleDefinition.long(missing_modules, organization_dir)
|
|
269
|
+
raise ToolkitMissingModuleError(
|
|
270
|
+
f"The following selected modules are missing, please check path: {missing_modules}.\n{hint}"
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
# Nothing is Selected
|
|
274
|
+
if not modules.selected:
|
|
275
|
+
raise ToolkitEnvError(
|
|
276
|
+
f"No selected modules specified in {config.filepath!s}, have you configured "
|
|
277
|
+
f"the environment ({config.environment.name})?"
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Dev modules warning (non-critical)
|
|
281
|
+
dev_modules = modules.available_names & DEV_ONLY_MODULES
|
|
282
|
+
if dev_modules and config.environment.validation_type != "dev":
|
|
283
|
+
warnings.append(
|
|
284
|
+
MediumSeverityWarning(
|
|
285
|
+
"The following modules should [bold]only[/bold] be used a in CDF Projects designated as dev (development): "
|
|
286
|
+
f"{humanize_collection(dev_modules)!r}",
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return warnings
|
|
@@ -4,13 +4,14 @@ 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
|
+
version = "0.7.30"
|
|
8
8
|
|
|
9
|
-
[alpha_flags]
|
|
10
|
-
external-libraries = true
|
|
11
9
|
|
|
12
10
|
[plugins]
|
|
13
|
-
|
|
11
|
+
dump = false
|
|
12
|
+
dev = false
|
|
13
|
+
data = false
|
|
14
|
+
|
|
14
15
|
|
|
15
16
|
[library.toolkit-data]
|
|
16
17
|
url = "https://github.com/cognitedata/toolkit-data/releases/download/latest/packages.zip"
|
cognite_toolkit/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.7.30"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
environment:
|
|
2
|
+
name: dev
|
|
3
|
+
project: infield-experimental-test-aws
|
|
4
|
+
validation-type: dev
|
|
5
|
+
selected:
|
|
6
|
+
- modules/eriks-location
|
|
7
|
+
|
|
8
|
+
variables:
|
|
9
|
+
modules:
|
|
10
|
+
eriks-location:
|
|
11
|
+
- location: erik-infield-cdm2
|
|
12
|
+
location_name: Oslo CDM - Erik tookit
|
|
13
|
+
location_description: Used to test toolkit ingestion for InField cdm
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognite_toolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.30
|
|
4
4
|
Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
|
|
5
|
-
|
|
6
|
-
Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
|
|
7
|
-
Project-URL: GitHub, https://github.com/cognitedata/toolkit
|
|
8
|
-
Project-URL: Documentation, https://docs.cognite.com/cdf/deploy/cdf_toolkit/references/resource_library
|
|
5
|
+
Author: Cognite AS
|
|
9
6
|
Author-email: Cognite AS <support@cognite.com>
|
|
10
7
|
License-Expression: Apache-2.0
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Requires-Python: >=3.10
|
|
13
|
-
Requires-Dist: cognite-sdk<8.0.0,>=7.83.0
|
|
14
|
-
Requires-Dist: filelock>=3.18.0
|
|
15
|
-
Requires-Dist: httpx>=0.28.1
|
|
16
|
-
Requires-Dist: mixpanel>=4.10.1
|
|
17
|
-
Requires-Dist: packaging>=25
|
|
18
|
-
Requires-Dist: pandas<3.0.0,>=1.5.3
|
|
19
|
-
Requires-Dist: pip>=25.0.1
|
|
20
|
-
Requires-Dist: pydantic>=2.11.0
|
|
21
|
-
Requires-Dist: python-dateutil>=2.9.0
|
|
22
8
|
Requires-Dist: python-dotenv>=1.0.0
|
|
9
|
+
Requires-Dist: cognite-sdk>=7.87.0,<8.0.0
|
|
10
|
+
Requires-Dist: httpx>=0.28.1
|
|
11
|
+
Requires-Dist: pandas>=1.5.3,<3.0.0
|
|
23
12
|
Requires-Dist: pyyaml>=6.0.1
|
|
24
|
-
Requires-Dist:
|
|
13
|
+
Requires-Dist: typer>=0.12.0,<1.0.0
|
|
25
14
|
Requires-Dist: rich>=13.9.4
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: typer<1.0.0,>=0.12.0
|
|
15
|
+
Requires-Dist: questionary>=2.0.1
|
|
16
|
+
Requires-Dist: tomli>=2.0.1,<3.0.0 ; python_full_version < '3.11'
|
|
17
|
+
Requires-Dist: packaging>=25
|
|
30
18
|
Requires-Dist: typing-extensions>=4.0.0
|
|
19
|
+
Requires-Dist: toml>=0.10.2
|
|
20
|
+
Requires-Dist: sentry-sdk>=2.1.0
|
|
21
|
+
Requires-Dist: mixpanel>=4.10.1
|
|
22
|
+
Requires-Dist: pydantic>=2.11.0
|
|
23
|
+
Requires-Dist: python-dateutil>=2.9.0
|
|
24
|
+
Requires-Dist: pip>=25.0.1
|
|
25
|
+
Requires-Dist: filelock>=3.18.0
|
|
26
|
+
Requires-Dist: sqlparse>=0.5.3 ; extra == 'sql'
|
|
27
|
+
Requires-Dist: pyarrow>=20.0.0 ; extra == 'table'
|
|
28
|
+
Requires-Dist: openpyxl>=3.1.5 ; extra == 'table'
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
|
|
31
|
+
Project-URL: Documentation, https://docs.cognite.com/cdf/deploy/cdf_toolkit/references/resource_library
|
|
32
|
+
Project-URL: GitHub, https://github.com/cognitedata/toolkit
|
|
33
|
+
Project-URL: Homepage, https://docs.cognite.com/cdf/deploy/cdf_toolkit/
|
|
31
34
|
Provides-Extra: sql
|
|
32
|
-
Requires-Dist: sqlparse>=0.5.3; extra == 'sql'
|
|
33
35
|
Provides-Extra: table
|
|
34
|
-
Requires-Dist: openpyxl>=3.1.5; extra == 'table'
|
|
35
|
-
Requires-Dist: pyarrow>=20.0.0; extra == 'table'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
38
|
# Cognite Data Fusion Toolkit
|