cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.39__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognite_toolkit/_cdf.py +21 -23
- cognite_toolkit/_cdf_tk/apps/__init__.py +4 -0
- cognite_toolkit/_cdf_tk/apps/_core_app.py +19 -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 +693 -25
- cognite_toolkit/_cdf_tk/apps/_dump_app.py +44 -102
- cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
- cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
- cognite_toolkit/_cdf_tk/apps/_migrate_app.py +424 -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/builders/_raw.py +1 -1
- cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py +32 -12
- cognite_toolkit/_cdf_tk/client/api/infield.py +114 -17
- cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
- cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
- cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +15 -18
- cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
- cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
- cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
- cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
- cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
- cognite_toolkit/_cdf_tk/client/api/migration.py +177 -4
- cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
- cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
- cognite_toolkit/_cdf_tk/client/api/streams.py +88 -0
- cognite_toolkit/_cdf_tk/client/api/three_d.py +384 -0
- cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +37 -33
- 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/instance_api.py +18 -13
- cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
- cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +47 -4
- cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +3 -3
- cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/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 +112 -0
- cognite_toolkit/_cdf_tk/client/testing.py +42 -18
- cognite_toolkit/_cdf_tk/commands/__init__.py +7 -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 +140 -92
- cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +108 -26
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +448 -45
- cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
- cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +6 -6
- cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +52 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +377 -11
- cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
- cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
- cognite_toolkit/_cdf_tk/commands/_purge.py +36 -39
- 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 +16 -62
- cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
- 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 +10 -8
- 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/commands/run.py +1 -1
- 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 +10 -19
- 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 +5 -15
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +45 -44
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +5 -12
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +206 -67
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +6 -18
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +126 -35
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +7 -28
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -30
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +4 -8
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +4 -16
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +5 -13
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +5 -11
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +16 -45
- 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 +75 -32
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
- cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
- cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
- 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/search_config.py +1 -1
- cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
- cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
- 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 +340 -28
- 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 +435 -0
- cognite_toolkit/_cdf_tk/storageio/_instances.py +35 -3
- cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
- cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +71 -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/storageio/selectors/_three_d.py +34 -0
- cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
- cognite_toolkit/_cdf_tk/tracker.py +2 -2
- cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
- 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/__init__.py +28 -0
- cognite_toolkit/_cdf_tk/utils/http_client/_client.py +285 -18
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +56 -4
- cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +247 -0
- cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
- cognite_toolkit/_cdf_tk/utils/interactive_select.py +60 -18
- 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 +83 -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.39.dist-info}/METADATA +24 -24
- cognite_toolkit-0.7.39.dist-info/RECORD +322 -0
- cognite_toolkit-0.7.39.dist-info/WHEEL +4 -0
- {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +1 -0
- cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
- 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/prototypes/import_app.py +0 -41
- cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
- cognite_toolkit-0.6.97.dist-info/RECORD +0 -306
- cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
- cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
- /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
- /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
- /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
- /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import gzip
|
|
2
|
+
import sys
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections import UserList
|
|
5
|
+
from collections.abc import Hashable, Sequence
|
|
6
|
+
from typing import Any, Literal
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
from cognite.client import global_config
|
|
10
|
+
from pydantic import BaseModel, ConfigDict, Field, JsonValue, TypeAdapter, model_validator
|
|
11
|
+
from pydantic.alias_generators import to_camel
|
|
12
|
+
|
|
13
|
+
from cognite_toolkit._cdf_tk.utils.http_client._exception import ToolkitAPIError
|
|
14
|
+
from cognite_toolkit._cdf_tk.utils.http_client._tracker import ItemsRequestTracker
|
|
15
|
+
from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
|
|
16
|
+
|
|
17
|
+
if sys.version_info >= (3, 11):
|
|
18
|
+
from typing import Self
|
|
19
|
+
else:
|
|
20
|
+
from typing_extensions import Self
|
|
21
|
+
|
|
22
|
+
|
|
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(f"Request failed with status code {self.status_code}: {self.error.message}")
|
|
30
|
+
elif isinstance(self, FailedRequest2):
|
|
31
|
+
raise ToolkitAPIError(f"Request failed with error: {self.error}")
|
|
32
|
+
else:
|
|
33
|
+
raise ToolkitAPIError("Unknown HTTPResult2 type")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class FailedRequest2(HTTPResult2):
|
|
37
|
+
error: str
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SuccessResponse2(HTTPResult2):
|
|
41
|
+
status_code: int
|
|
42
|
+
body: str
|
|
43
|
+
content: bytes
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def body_json(self) -> dict[str, Any]:
|
|
47
|
+
"""Parse the response body as JSON."""
|
|
48
|
+
return TypeAdapter(dict[str, JsonValue]).validate_json(self.body)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ErrorDetails2(BaseModel):
|
|
52
|
+
"""This is the expected structure of error details in the CDF API"""
|
|
53
|
+
|
|
54
|
+
code: int
|
|
55
|
+
message: str
|
|
56
|
+
missing: list[JsonValue] | None = None
|
|
57
|
+
duplicated: list[JsonValue] | None = None
|
|
58
|
+
is_auto_retryable: bool | None = None
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def from_response(cls, response: httpx.Response) -> "ErrorDetails2":
|
|
62
|
+
"""Populate the error details from a httpx response."""
|
|
63
|
+
try:
|
|
64
|
+
res = TypeAdapter(dict[Literal["error"], ErrorDetails2]).validate_json(response.text)
|
|
65
|
+
except ValueError:
|
|
66
|
+
return cls(code=response.status_code, message=response.text)
|
|
67
|
+
return res["error"]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class FailedResponse2(HTTPResult2):
|
|
71
|
+
status_code: int
|
|
72
|
+
body: str
|
|
73
|
+
error: ErrorDetails2
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class BaseRequestMessage(BaseModel, ABC):
|
|
77
|
+
endpoint_url: str
|
|
78
|
+
method: Literal["GET", "POST", "PATCH", "DELETE", "PUT"]
|
|
79
|
+
connect_attempt: int = 0
|
|
80
|
+
read_attempt: int = 0
|
|
81
|
+
status_attempt: int = 0
|
|
82
|
+
api_version: str | None = None
|
|
83
|
+
content_type: str = "application/json"
|
|
84
|
+
accept: str = "application/json"
|
|
85
|
+
|
|
86
|
+
parameters: dict[str, PrimitiveType] | None = None
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def total_attempts(self) -> int:
|
|
90
|
+
return self.connect_attempt + self.read_attempt + self.status_attempt
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def content(self) -> str | bytes | None: ...
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class RequestMessage2(BaseRequestMessage):
|
|
98
|
+
data_content: bytes | None = None
|
|
99
|
+
body_content: dict[str, JsonValue] | None = None
|
|
100
|
+
|
|
101
|
+
@model_validator(mode="before")
|
|
102
|
+
def check_data_or_body(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
103
|
+
if values.get("data_content") is not None and values.get("body_content") is not None:
|
|
104
|
+
raise ValueError("Only one of data_content or body_content can be set.")
|
|
105
|
+
return values
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def content(self) -> str | bytes | None:
|
|
109
|
+
data: str | bytes | None = None
|
|
110
|
+
if self.data_content is not None:
|
|
111
|
+
data = self.data_content
|
|
112
|
+
if not global_config.disable_gzip:
|
|
113
|
+
data = gzip.compress(data)
|
|
114
|
+
elif self.body_content is not None:
|
|
115
|
+
# We serialize using pydantic instead of json.dumps. This is because pydantic is faster
|
|
116
|
+
# and handles more complex types such as datetime, float('nan'), etc.
|
|
117
|
+
data = _BODY_SERIALIZER.dump_json(self.body_content)
|
|
118
|
+
if not global_config.disable_gzip and isinstance(data, bytes):
|
|
119
|
+
data = gzip.compress(data)
|
|
120
|
+
return data
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
_BODY_SERIALIZER = TypeAdapter(dict[str, JsonValue])
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ItemsResultMessage2(BaseModel):
|
|
127
|
+
ids: list[Hashable]
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class ItemsFailedRequest2(ItemsResultMessage2):
|
|
131
|
+
error_message: str
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class ItemsSuccessResponse2(ItemsResultMessage2):
|
|
135
|
+
status_code: int
|
|
136
|
+
body: str
|
|
137
|
+
content: bytes
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class ItemsFailedResponse2(ItemsResultMessage2):
|
|
141
|
+
status_code: int
|
|
142
|
+
error: ErrorDetails2
|
|
143
|
+
body: str
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class BaseModelObject(BaseModel):
|
|
147
|
+
"""Base class for all object. This includes resources and nested objects."""
|
|
148
|
+
|
|
149
|
+
# We allow extra fields to support forward compatibility.
|
|
150
|
+
model_config = ConfigDict(alias_generator=to_camel, extra="allow")
|
|
151
|
+
|
|
152
|
+
def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
|
153
|
+
"""Dump the resource to a dictionary.
|
|
154
|
+
|
|
155
|
+
This is the default serialization method for request resources.
|
|
156
|
+
"""
|
|
157
|
+
return self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True)
|
|
158
|
+
|
|
159
|
+
@classmethod
|
|
160
|
+
def _load(cls, resource: dict[str, Any]) -> "Self":
|
|
161
|
+
"""Load method to match CogniteResource signature."""
|
|
162
|
+
return cls.model_validate(resource)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class RequestResource(BaseModelObject, ABC):
|
|
166
|
+
@abstractmethod
|
|
167
|
+
def as_id(self) -> Hashable: ...
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _set_default_tracker(data: dict[str, Any]) -> ItemsRequestTracker:
|
|
171
|
+
if "tracker" not in data or data["tracker"] is None:
|
|
172
|
+
return ItemsRequestTracker(data.get("max_failures_before_abort", 50))
|
|
173
|
+
return data["tracker"]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class ItemsRequest2(BaseRequestMessage):
|
|
177
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
178
|
+
items: Sequence[RequestResource]
|
|
179
|
+
extra_body_fields: dict[str, JsonValue] | None = None
|
|
180
|
+
max_failures_before_abort: int = 50
|
|
181
|
+
tracker: ItemsRequestTracker = Field(init=False, default_factory=_set_default_tracker, exclude=True)
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def content(self) -> str | bytes | None:
|
|
185
|
+
body: dict[str, JsonValue] = {"items": [item.dump() for item in self.items]}
|
|
186
|
+
if self.extra_body_fields:
|
|
187
|
+
body.update(self.extra_body_fields)
|
|
188
|
+
res = _BODY_SERIALIZER.dump_json(body)
|
|
189
|
+
if not global_config.disable_gzip and isinstance(res, bytes):
|
|
190
|
+
return gzip.compress(res)
|
|
191
|
+
return res
|
|
192
|
+
|
|
193
|
+
def split(self, status_attempts: int) -> list["ItemsRequest2"]:
|
|
194
|
+
"""Split the request into multiple requests with a single item each."""
|
|
195
|
+
mid = len(self.items) // 2
|
|
196
|
+
if mid == 0:
|
|
197
|
+
return [self]
|
|
198
|
+
self.tracker.register_failure()
|
|
199
|
+
messages: list[ItemsRequest2] = []
|
|
200
|
+
for part in (self.items[:mid], self.items[mid:]):
|
|
201
|
+
new_request = self.model_copy(update={"items": part, "status_attempt": status_attempts})
|
|
202
|
+
new_request.tracker = self.tracker
|
|
203
|
+
messages.append(new_request)
|
|
204
|
+
return messages
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class ItemResponse(BaseModel):
|
|
208
|
+
items: list[dict[str, JsonValue]]
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class ItemsResultList(UserList[ItemsResultMessage2]):
|
|
212
|
+
def __init__(self, collection: Sequence[ItemsResultMessage2] | None = None) -> None:
|
|
213
|
+
super().__init__(collection or [])
|
|
214
|
+
|
|
215
|
+
def raise_for_status(self) -> None:
|
|
216
|
+
"""Raises an exception if any response in the list indicates a failure."""
|
|
217
|
+
failed_responses = [resp for resp in self.data if isinstance(resp, ItemsFailedResponse2)]
|
|
218
|
+
failed_requests = [resp for resp in self.data if isinstance(resp, ItemsFailedRequest2)]
|
|
219
|
+
if not failed_responses and not failed_requests:
|
|
220
|
+
return
|
|
221
|
+
error_messages = "; ".join(f"Status {err.status_code}: {err.error.message}" for err in failed_responses)
|
|
222
|
+
if failed_requests:
|
|
223
|
+
if error_messages:
|
|
224
|
+
error_messages += "; "
|
|
225
|
+
error_messages += "; ".join(f"Request error: {err.error_message}" for err in failed_requests)
|
|
226
|
+
raise ToolkitAPIError(f"One or more requests failed: {error_messages}")
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def has_failed(self) -> bool:
|
|
230
|
+
"""Indicates whether any response in the list indicates a failure.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
bool: True if there are any failed responses or requests, False otherwise.
|
|
234
|
+
"""
|
|
235
|
+
for resp in self.data:
|
|
236
|
+
if isinstance(resp, ItemsFailedResponse2 | ItemsFailedRequest2):
|
|
237
|
+
return True
|
|
238
|
+
return False
|
|
239
|
+
|
|
240
|
+
def get_items(self) -> list[dict[str, JsonValue]]:
|
|
241
|
+
"""Get the items from all successful responses."""
|
|
242
|
+
items: list[dict[str, JsonValue]] = []
|
|
243
|
+
for resp in self.data:
|
|
244
|
+
if isinstance(resp, ItemsSuccessResponse2):
|
|
245
|
+
body_json = ItemResponse.model_validate_json(resp.body)
|
|
246
|
+
items.extend(body_json.items)
|
|
247
|
+
return items
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import threading
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
@dataclass
|
|
@@ -9,13 +10,15 @@ class ItemsRequestTracker:
|
|
|
9
10
|
Attributes:
|
|
10
11
|
max_failures_before_abort (int): Maximum number of allowed failed split requests before aborting
|
|
11
12
|
the entire operation. A value of -1 indicates no early abort.
|
|
12
|
-
lock (
|
|
13
|
+
lock (Any): A lock to ensure thread-safe updates to the failure count.
|
|
13
14
|
failed_split_count (int): The current count of failed split requests.
|
|
14
15
|
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
max_failures_before_abort: int = -1 # -1 means no early abort
|
|
18
|
-
|
|
19
|
+
# NOTE: `threading.Lock` is a factory function (backed by `_thread.allocate_lock`), not a type.
|
|
20
|
+
# Annotate as `Any` so Pydantic won't attempt to generate a schema for the lock field.
|
|
21
|
+
lock: Any = field(default_factory=threading.Lock, init=False)
|
|
19
22
|
failed_split_count: int = field(default=0, init=False)
|
|
20
23
|
|
|
21
24
|
def register_failure(self) -> None:
|
|
@@ -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
|
|
@@ -24,11 +21,12 @@ from questionary import Choice
|
|
|
24
21
|
from rich.console import Console
|
|
25
22
|
|
|
26
23
|
from cognite_toolkit._cdf_tk.client import ToolkitClient
|
|
27
|
-
from cognite_toolkit._cdf_tk.client.data_classes.canvas import Canvas
|
|
28
|
-
from cognite_toolkit._cdf_tk.client.data_classes.charts import Chart, ChartList, Visibility
|
|
29
|
-
from cognite_toolkit._cdf_tk.client.data_classes.migration import ResourceViewMapping
|
|
30
|
-
from cognite_toolkit._cdf_tk.client.data_classes.raw import RawTable
|
|
31
|
-
from cognite_toolkit._cdf_tk.
|
|
24
|
+
from cognite_toolkit._cdf_tk.client.data_classes.legacy.canvas import Canvas
|
|
25
|
+
from cognite_toolkit._cdf_tk.client.data_classes.legacy.charts import Chart, ChartList, Visibility
|
|
26
|
+
from cognite_toolkit._cdf_tk.client.data_classes.legacy.migration import ResourceViewMapping
|
|
27
|
+
from cognite_toolkit._cdf_tk.client.data_classes.legacy.raw import RawTable
|
|
28
|
+
from cognite_toolkit._cdf_tk.client.data_classes.three_d import ThreeDModelResponse
|
|
29
|
+
from cognite_toolkit._cdf_tk.exceptions import ToolkitMissingResourceError, ToolkitValueError
|
|
32
30
|
|
|
33
31
|
from . import humanize_collection
|
|
34
32
|
from .aggregators import (
|
|
@@ -309,9 +307,14 @@ class InteractiveCanvasSelect:
|
|
|
309
307
|
opening_choices: ClassVar[list[questionary.Choice]] = [
|
|
310
308
|
questionary.Choice(title="All public Canvases", value=CanvasFilter(visibility="public", select_all=True)),
|
|
311
309
|
questionary.Choice(title="Selected public Canvases", value=CanvasFilter(visibility="public", select_all=False)),
|
|
312
|
-
questionary.Choice(
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
questionary.Choice(
|
|
311
|
+
title="All public Canvases by given user",
|
|
312
|
+
value=CanvasFilter(created_by="user", select_all=True, visibility="public"),
|
|
313
|
+
),
|
|
314
|
+
questionary.Choice(
|
|
315
|
+
title="Selected public Canvases by given user",
|
|
316
|
+
value=CanvasFilter(created_by="user", select_all=False, visibility="public"),
|
|
317
|
+
),
|
|
315
318
|
]
|
|
316
319
|
|
|
317
320
|
def __init__(self, client: ToolkitClient) -> None:
|
|
@@ -406,13 +409,6 @@ class InteractiveChartSelect:
|
|
|
406
409
|
return user_response
|
|
407
410
|
|
|
408
411
|
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
412
|
available_charts = self.client.charts.list(visibility=(select_filter.visibility or "PUBLIC"))
|
|
417
413
|
if select_filter.select_all and select_filter.owned_by is None:
|
|
418
414
|
return [chart.external_id for chart in available_charts]
|
|
@@ -828,3 +824,49 @@ class ResourceViewMappingInteractiveSelect:
|
|
|
828
824
|
f"Selected Resource View Mapping is not a valid ResourceViewMapping object: {selected_mapping!r}"
|
|
829
825
|
)
|
|
830
826
|
return selected_mapping
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
class ThreeDInteractiveSelect:
|
|
830
|
+
def __init__(self, client: ToolkitClient, operation: str) -> None:
|
|
831
|
+
self.client = client
|
|
832
|
+
self.operation = operation
|
|
833
|
+
|
|
834
|
+
def select_three_d_models(self, model_type: Literal["classic", "dm"] | None = None) -> list[ThreeDModelResponse]:
|
|
835
|
+
"""Select multiple 3D models interactively."""
|
|
836
|
+
if model_type is None:
|
|
837
|
+
model_type = questionary.select(
|
|
838
|
+
f"What type of 3D models do you want to {self.operation}?",
|
|
839
|
+
choices=[
|
|
840
|
+
Choice(title="Classic models", value="classic"),
|
|
841
|
+
Choice(title="Data modeling 3D", value="dm"),
|
|
842
|
+
],
|
|
843
|
+
).ask()
|
|
844
|
+
if model_type is None:
|
|
845
|
+
raise ToolkitValueError("No 3D model type selected.")
|
|
846
|
+
published = questionary.select(
|
|
847
|
+
f"Do you want to {self.operation} published or unpublished 3D models?",
|
|
848
|
+
choices=[
|
|
849
|
+
Choice(title="Published models", value=True),
|
|
850
|
+
Choice(title="Unpublished models", value=False),
|
|
851
|
+
Choice(title="Both published and unpublished models", value=None),
|
|
852
|
+
],
|
|
853
|
+
).ask()
|
|
854
|
+
|
|
855
|
+
models = self.client.tool.three_d.models.list(published=published, include_revision_info=True, limit=None)
|
|
856
|
+
if model_type == "classic":
|
|
857
|
+
models = [model for model in models if model.space is None]
|
|
858
|
+
else:
|
|
859
|
+
models = [model for model in models if model.space is not None]
|
|
860
|
+
if not models:
|
|
861
|
+
raise ToolkitMissingResourceError(
|
|
862
|
+
f"No 3D models found for type {model_type!r} with published={published!r}."
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
choices = [Choice(title=f"{model.name} ({model.id})", value=model) for model in models]
|
|
866
|
+
selected_models = questionary.checkbox(
|
|
867
|
+
f"Select 3D models to {self.operation}:",
|
|
868
|
+
choices=choices,
|
|
869
|
+
).ask()
|
|
870
|
+
if selected_models is None or len(selected_models) == 0:
|
|
871
|
+
raise ToolkitValueError("No 3D models selected.")
|
|
872
|
+
return selected_models
|
|
@@ -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
|
|
|
@@ -171,6 +182,10 @@ def humanize_validation_error(error: ValidationError) -> list[str]:
|
|
|
171
182
|
"dict_type",
|
|
172
183
|
}:
|
|
173
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']}"
|
|
174
189
|
else:
|
|
175
190
|
# Default to the Pydantic error message
|
|
176
191
|
msg = item["msg"]
|
|
@@ -210,3 +225,70 @@ def as_json_path(loc: tuple[str | int, ...]) -> str:
|
|
|
210
225
|
|
|
211
226
|
suffix = ".".join([str(x) if isinstance(x, str) else f"[{x + 1}]" for x in loc]).replace(".[", "[")
|
|
212
227
|
return f"{prefix}{suffix}"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def validate_module_selection(
|
|
231
|
+
modules: ModuleDirectories,
|
|
232
|
+
config: BuildConfigYAML,
|
|
233
|
+
packages: dict[str, list[str]],
|
|
234
|
+
selected_modules: set[str | Path],
|
|
235
|
+
organization_dir: Path,
|
|
236
|
+
) -> WarningList:
|
|
237
|
+
"""Validates module selection and returns warnings for non-critical issues.
|
|
238
|
+
|
|
239
|
+
Critical errors (duplicate modules, missing modules, no modules selected) are still raised
|
|
240
|
+
as exceptions as they prevent the build from proceeding.
|
|
241
|
+
"""
|
|
242
|
+
warnings: WarningList = WarningList()
|
|
243
|
+
|
|
244
|
+
# Validations: Ambiguous selection.
|
|
245
|
+
selected_names = {s for s in config.environment.selected if isinstance(s, str)}
|
|
246
|
+
if duplicate_modules := {
|
|
247
|
+
module_name: paths
|
|
248
|
+
for module_name, paths in modules.as_path_by_name().items()
|
|
249
|
+
if len(paths) > 1 and module_name in selected_names
|
|
250
|
+
}:
|
|
251
|
+
# If the user has selected a module by name, and there are multiple modules with that name, raise an error.
|
|
252
|
+
# Note, if the user uses a path to select a module, this error will not be raised.
|
|
253
|
+
raise ToolkitDuplicatedModuleError(
|
|
254
|
+
f"Ambiguous module selected in config.{config.environment.name}.yaml:", duplicate_modules
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# Package Referenced Modules Exists
|
|
258
|
+
for package, package_modules in packages.items():
|
|
259
|
+
if package not in selected_names:
|
|
260
|
+
# We do not check packages that are not selected.
|
|
261
|
+
# Typically, the user will delete the modules that are irrelevant for them;
|
|
262
|
+
# thus we only check the selected packages.
|
|
263
|
+
continue
|
|
264
|
+
if missing_packages := set(package_modules) - modules.available_names:
|
|
265
|
+
raise ToolkitMissingModuleError(
|
|
266
|
+
f"Package {package} defined in {CDFToml.file_name!s} is referring "
|
|
267
|
+
f"the following missing modules {missing_packages}."
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Selected modules does not exists
|
|
271
|
+
if missing_modules := set(selected_modules) - modules.available:
|
|
272
|
+
hint = ModuleDefinition.long(missing_modules, organization_dir)
|
|
273
|
+
raise ToolkitMissingModuleError(
|
|
274
|
+
f"The following selected modules are missing, please check path: {missing_modules}.\n{hint}"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
# Nothing is Selected
|
|
278
|
+
if not modules.selected:
|
|
279
|
+
raise ToolkitEnvError(
|
|
280
|
+
f"No selected modules specified in {config.filepath!s}, have you configured "
|
|
281
|
+
f"the environment ({config.environment.name})?"
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# Dev modules warning (non-critical)
|
|
285
|
+
dev_modules = modules.available_names & DEV_ONLY_MODULES
|
|
286
|
+
if dev_modules and config.environment.validation_type != "dev":
|
|
287
|
+
warnings.append(
|
|
288
|
+
MediumSeverityWarning(
|
|
289
|
+
"The following modules should [bold]only[/bold] be used a in CDF Projects designated as dev (development): "
|
|
290
|
+
f"{humanize_collection(dev_modules)!r}",
|
|
291
|
+
)
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
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.39"
|
|
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.39"
|
|
@@ -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.39
|
|
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
|