cognite-toolkit 0.7.28__py3-none-any.whl → 0.7.29__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.
@@ -35,19 +35,26 @@ class ToolAPI:
35
35
 
36
36
 
37
37
  class ToolkitClient(CogniteClient):
38
- def __init__(self, config: ToolkitClientConfig | None = None, enable_set_pending_ids: bool = False) -> None:
38
+ def __init__(
39
+ self,
40
+ config: ToolkitClientConfig | None = None,
41
+ enable_set_pending_ids: bool = False,
42
+ console: Console | None = None,
43
+ ) -> None:
39
44
  super().__init__(config=config)
40
45
  http_client = HTTPClient(self.config)
41
46
  self.http_client = http_client
42
47
  toolkit_config = ToolkitClientConfig.from_client_config(self.config)
43
- self.console = Console()
48
+ self.console = console or Console()
44
49
  self.tool = ToolAPI(http_client, self.console)
45
50
  self.search = SearchAPI(self._config, self._API_VERSION, self)
46
51
  self.robotics = RoboticsAPI(self._config, self._API_VERSION, self)
47
52
  self.dml = DMLAPI(self._config, self._API_VERSION, self)
48
53
  self.verify = VerifyAPI(self._config, self._API_VERSION, self)
49
54
  self.lookup = LookUpGroup(self._config, self._API_VERSION, self, self.console)
50
- self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(toolkit_config, self._API_VERSION, self)
55
+ self.functions: ExtendedFunctionsAPI = ExtendedFunctionsAPI(
56
+ toolkit_config, self._API_VERSION, self, self.console
57
+ )
51
58
  self.data_modeling: ExtendedDataModelingAPI = ExtendedDataModelingAPI(self._config, self._API_VERSION, self)
52
59
  if enable_set_pending_ids:
53
60
  self.time_series: ExtendedTimeSeriesAPI = ExtendedTimeSeriesAPI(self._config, self._API_VERSION, self)
@@ -17,15 +17,16 @@ class ExtendedFunctionsAPI(FunctionsAPI):
17
17
  config: ToolkitClientConfig,
18
18
  api_version: str | None,
19
19
  cognite_client: CogniteClient,
20
+ console: Console | None = None,
20
21
  ) -> None:
21
22
  """
22
23
  Extended Functions API to include custom headers and payload preparation.
23
24
  """
24
25
  super().__init__(config, api_version, cognite_client)
25
26
  self._toolkit_config = config
26
- self._toolkit_http_client = HTTPClient(config, max_retries=global_config.max_retries)
27
+ self._toolkit_http_client = HTTPClient(config, max_retries=global_config.max_retries, console=console)
27
28
 
28
- def create_with_429_retry(self, function: FunctionWrite, console: Console | None = None) -> Function:
29
+ def create_with_429_retry(self, function: FunctionWrite) -> Function:
29
30
  """Create a function with manual retry handling for 429 Too Many Requests responses.
30
31
 
31
32
  This method is a workaround for scenarios where the function creation API is temporarily unavailable
@@ -43,16 +44,13 @@ class ExtendedFunctionsAPI(FunctionsAPI):
43
44
  endpoint_url=self._toolkit_config.create_api_url("/functions"),
44
45
  method="POST",
45
46
  body_content={"items": [function.dump(camel_case=True)]},
46
- ),
47
- console=console,
47
+ )
48
48
  )
49
49
  result.raise_for_status()
50
50
  # We assume the API response is one item on a successful creation
51
51
  return Function._load(result.get_first_body()["items"][0], cognite_client=self._cognite_client) # type: ignore[arg-type,index]
52
52
 
53
- def delete_with_429_retry(
54
- self, external_id: SequenceNotStr[str], ignore_unknown_ids: bool = False, console: Console | None = None
55
- ) -> None:
53
+ def delete_with_429_retry(self, external_id: SequenceNotStr[str], ignore_unknown_ids: bool = False) -> None:
56
54
  """Delete one or more functions with retry handling for 429 Too Many Requests responses.
57
55
 
58
56
  This method is an improvement over the standard delete method in the FunctionsAPI.
@@ -77,7 +75,6 @@ class ExtendedFunctionsAPI(FunctionsAPI):
77
75
  endpoint_url=self._toolkit_config.create_api_url("/functions/delete"),
78
76
  method="POST",
79
77
  body_content=body_content,
80
- ),
81
- console=console,
78
+ )
82
79
  ).raise_for_status()
83
80
  return None
@@ -231,6 +231,8 @@ class AnnotationMigrationIO(
231
231
  CHUNK_SIZE = 1000
232
232
  UPLOAD_ENDPOINT = InstanceIO.UPLOAD_ENDPOINT
233
233
 
234
+ SUPPORTED_ANNOTATION_TYPES = frozenset({"diagrams.AssetLink", "diagrams.FileLink"})
235
+
234
236
  def __init__(
235
237
  self,
236
238
  client: ToolkitClient,
@@ -272,6 +274,10 @@ class AnnotationMigrationIO(
272
274
  for data_chunk in self.annotation_io.stream_data(asset_centric_selector, limit):
273
275
  mapping_list = AssetCentricMappingList[Annotation]([])
274
276
  for resource in data_chunk.items:
277
+ if resource.annotation_type not in self.SUPPORTED_ANNOTATION_TYPES:
278
+ # This should not happen, as the annotation_io should already filter these out.
279
+ # This is just in case.
280
+ continue
275
281
  mapping = AnnotationMapping(
276
282
  instance_id=EdgeId(space=self.instance_space, external_id=f"annotation_{resource.id!r}"),
277
283
  id=resource.id,
@@ -294,11 +300,15 @@ class AnnotationMigrationIO(
294
300
  resources = self.client.annotations.retrieve_multiple(current_batch.get_ids())
295
301
  resources_by_id = {resource.id: resource for resource in resources}
296
302
  not_found = 0
303
+ incorrect_type_count = 0
297
304
  for mapping in current_batch:
298
305
  resource = resources_by_id.get(mapping.id)
299
306
  if resource is None:
300
307
  not_found += 1
301
308
  continue
309
+ if resource.annotation_type not in self.SUPPORTED_ANNOTATION_TYPES:
310
+ incorrect_type_count += 1
311
+ continue
302
312
  mapping.ingestion_view = self._get_mapping(mapping.ingestion_view, resource)
303
313
  chunk.append(AssetCentricMapping(mapping=mapping, resource=resource))
304
314
  if chunk:
@@ -308,6 +318,11 @@ class AnnotationMigrationIO(
308
318
  MediumSeverityWarning(
309
319
  f"Could not find {not_found} annotations referenced in the CSV file. They will be skipped during migration."
310
320
  ).print_warning(include_timestamp=True, console=self.client.console)
321
+ if incorrect_type_count:
322
+ MediumSeverityWarning(
323
+ f"Found {incorrect_type_count} annotations with unsupported types. Only 'diagrams.AssetLink' and "
324
+ "'diagrams.FileLink' are supported. These annotations will be skipped during migration."
325
+ ).print_warning(include_timestamp=True, console=self.client.console)
311
326
 
312
327
  def _get_mapping(self, current_mapping: str | None, resource: Annotation) -> str:
313
328
  try:
@@ -320,7 +320,7 @@ class FunctionCRUD(ResourceCRUD[str, FunctionWrite, Function]):
320
320
  " problem persists, please contact Cognite support."
321
321
  )
322
322
  item.file_id = file_id
323
- created_item = self.client.functions.create_with_429_retry(item, console=self.console)
323
+ created_item = self.client.functions.create_with_429_retry(item)
324
324
  self._warn_if_cpu_or_memory_changed(created_item, item)
325
325
  created.append(created_item)
326
326
  return created
@@ -404,7 +404,7 @@ class FunctionCRUD(ResourceCRUD[str, FunctionWrite, Function]):
404
404
  def delete(self, ids: SequenceNotStr[str]) -> int:
405
405
  functions = self.retrieve(ids)
406
406
 
407
- self.client.functions.delete_with_429_retry(external_id=ids, ignore_unknown_ids=True, console=self.console)
407
+ self.client.functions.delete_with_429_retry(external_id=ids, ignore_unknown_ids=True)
408
408
  file_ids = {func.file_id for func in functions if func.file_id}
409
409
  self.client.files.delete(id=list(file_ids), ignore_unknown_ids=True)
410
410
  return len(ids)
@@ -33,7 +33,8 @@ class AnnotationIO(StorageIO[AssetCentricSelector, Annotation]):
33
33
  annotated_resource_type="file",
34
34
  annotated_resource_ids=[{"id": file_metadata.id} for file_metadata in file_chunk.items],
35
35
  annotation_type=annotation_type,
36
- )
36
+ ),
37
+ limit=-1,
37
38
  )
38
39
  if limit is not None and total + len(results) > limit:
39
40
  results = results[: limit - total]
@@ -23,6 +23,15 @@ from cognite_toolkit._cdf_tk.utils.http_client._data_classes import (
23
23
  ResponseList,
24
24
  ResponseMessage,
25
25
  )
26
+ from cognite_toolkit._cdf_tk.utils.http_client._data_classes2 import (
27
+ BaseRequestMessage,
28
+ ErrorDetails2,
29
+ FailedRequest2,
30
+ FailedResponse2,
31
+ HTTPResult2,
32
+ RequestMessage2,
33
+ SuccessResponse2,
34
+ )
26
35
  from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
27
36
 
28
37
  if sys.version_info >= (3, 11):
@@ -48,6 +57,7 @@ class HTTPClient:
48
57
  Default is {408, 429, 502, 503, 504}.
49
58
  split_items_status_codes (frozenset[int]): In the case of ItemRequest with multiple
50
59
  items, these status codes will trigger splitting the request into smaller batches.
60
+ console (Console | None): Optional Rich Console for printing warnings.
51
61
 
52
62
  """
53
63
 
@@ -59,6 +69,7 @@ class HTTPClient:
59
69
  pool_maxsize: int = 20,
60
70
  retry_status_codes: Set[int] = frozenset({408, 429, 502, 503, 504}),
61
71
  split_items_status_codes: Set[int] = frozenset({400, 408, 409, 422, 502, 503, 504}),
72
+ console: Console | None = None,
62
73
  ):
63
74
  self.config = config
64
75
  self._max_retries = max_retries
@@ -66,6 +77,7 @@ class HTTPClient:
66
77
  self._pool_maxsize = pool_maxsize
67
78
  self._retry_status_codes = retry_status_codes
68
79
  self._split_items_status_codes = split_items_status_codes
80
+ self._console = console
69
81
 
70
82
  # Thread-safe session for connection pooling
71
83
  self.session = self._create_thread_safe_session()
@@ -80,12 +92,11 @@ class HTTPClient:
80
92
  self.session.close()
81
93
  return False # Do not suppress exceptions
82
94
 
83
- def request(self, message: RequestMessage, console: Console | None = None) -> Sequence[HTTPMessage]:
95
+ def request(self, message: RequestMessage) -> Sequence[HTTPMessage]:
84
96
  """Send an HTTP request and return the response.
85
97
 
86
98
  Args:
87
99
  message (RequestMessage): The request message to send.
88
- console (Console | None): The rich console to use for printing warnings.
89
100
 
90
101
  Returns:
91
102
  Sequence[HTTPMessage]: The response message(s). This can also
@@ -98,12 +109,12 @@ class HTTPClient:
98
109
  return message.create_failed_request(error_msg)
99
110
  try:
100
111
  response = self._make_request(message)
101
- results = self._handle_response(response, message, console)
112
+ results = self._handle_response(response, message)
102
113
  except Exception as e:
103
114
  results = self._handle_error(e, message)
104
115
  return results
105
116
 
106
- def request_with_retries(self, message: RequestMessage, console: Console | None = None) -> ResponseList:
117
+ def request_with_retries(self, message: RequestMessage) -> ResponseList:
107
118
  """Send an HTTP request and handle retries.
108
119
 
109
120
  This method will keep retrying the request until it either succeeds or
@@ -114,7 +125,6 @@ class HTTPClient:
114
125
 
115
126
  Args:
116
127
  message (RequestMessage): The request message to send.
117
- console (Console | None): The rich console to use for printing warnings.
118
128
 
119
129
  Returns:
120
130
  Sequence[ResponseMessage | FailedRequestMessage]: The final response
@@ -127,7 +137,7 @@ class HTTPClient:
127
137
  final_responses = ResponseList([])
128
138
  while pending_requests:
129
139
  current_request = pending_requests.popleft()
130
- results = self.request(current_request, console)
140
+ results = self.request(current_request)
131
141
 
132
142
  for result in results:
133
143
  if isinstance(result, RequestMessage):
@@ -194,9 +204,7 @@ class HTTPClient:
194
204
  follow_redirects=False,
195
205
  )
196
206
 
197
- def _handle_response(
198
- self, response: httpx.Response, request: RequestMessage, console: Console | None = None
199
- ) -> Sequence[HTTPMessage]:
207
+ def _handle_response(self, response: httpx.Response, request: RequestMessage) -> Sequence[HTTPMessage]:
200
208
  if 200 <= response.status_code < 300:
201
209
  return request.create_success_response(response)
202
210
  elif (
@@ -216,11 +224,11 @@ class HTTPClient:
216
224
 
217
225
  retry_after = self._get_retry_after_in_header(response)
218
226
  if retry_after is not None and response.status_code == 429 and request.status_attempt < self._max_retries:
219
- if console is not None:
227
+ if self._console is not None:
220
228
  short_url = request.endpoint_url.removeprefix(self.config.base_api_url)
221
229
  HighSeverityWarning(
222
230
  f"Rate limit exceeded for the {short_url!r} endpoint. Retrying after {retry_after} seconds."
223
- ).print_warning(console=console)
231
+ ).print_warning(console=self._console)
224
232
  request.status_attempt += 1
225
233
  time.sleep(retry_after)
226
234
  return [request]
@@ -273,3 +281,110 @@ class HTTPClient:
273
281
  error_msg = f"RequestException after {request.total_attempts - 1} attempts ({error_type} error): {e!s}"
274
282
 
275
283
  return request.create_failed_request(error_msg)
284
+
285
+ def request_single(self, message: RequestMessage2) -> RequestMessage2 | HTTPResult2:
286
+ """Send an HTTP request and return the response.
287
+
288
+ Args:
289
+ message (RequestMessage2): The request message to send.
290
+ Returns:
291
+ HTTPMessage: The response message.
292
+ """
293
+ try:
294
+ response = self._make_request2(message)
295
+ result = self._handle_response_single(response, message)
296
+ except Exception as e:
297
+ result = self._handle_error_single(e, message)
298
+ return result
299
+
300
+ def request_single_retries(self, message: RequestMessage2) -> HTTPResult2:
301
+ """Send an HTTP request and handle retries.
302
+
303
+ This method will keep retrying the request until it either succeeds or
304
+ exhausts the maximum number of retries.
305
+
306
+ Note this method will use the current thread to process all request, thus
307
+ it is blocking.
308
+
309
+ Args:
310
+ message (RequestMessage2): The request message to send.
311
+ Returns:
312
+ HTTPMessage2: The final response message, which can be either successful response or failed request.
313
+ """
314
+ if message.total_attempts > 0:
315
+ raise RuntimeError(f"RequestMessage has already been attempted {message.total_attempts} times.")
316
+ current_request = message
317
+ while True:
318
+ result = self.request_single(current_request)
319
+ if isinstance(result, RequestMessage2):
320
+ current_request = result
321
+ elif isinstance(result, HTTPResult2):
322
+ return result
323
+ else:
324
+ raise TypeError(f"Unexpected result type: {type(result)}")
325
+
326
+ def _make_request2(self, message: BaseRequestMessage) -> httpx.Response:
327
+ headers = self._create_headers(message.api_version, message.content_type, message.accept)
328
+ return self.session.request(
329
+ method=message.method,
330
+ url=message.endpoint_url,
331
+ content=message.content,
332
+ headers=headers,
333
+ params=message.parameters,
334
+ timeout=self.config.timeout,
335
+ follow_redirects=False,
336
+ )
337
+
338
+ def _handle_response_single(
339
+ self, response: httpx.Response, request: RequestMessage2
340
+ ) -> RequestMessage2 | HTTPResult2:
341
+ if 200 <= response.status_code < 300:
342
+ return SuccessResponse2(
343
+ status_code=response.status_code,
344
+ body=response.text,
345
+ content=response.content,
346
+ )
347
+ retry_after = self._get_retry_after_in_header(response)
348
+ if retry_after is not None and response.status_code == 429 and request.status_attempt < self._max_retries:
349
+ if self._console is not None:
350
+ short_url = request.endpoint_url.removeprefix(self.config.base_api_url)
351
+ HighSeverityWarning(
352
+ f"Rate limit exceeded for the {short_url!r} endpoint. Retrying after {retry_after} seconds."
353
+ ).print_warning(console=self._console)
354
+ request.status_attempt += 1
355
+ time.sleep(retry_after)
356
+ return request
357
+
358
+ if request.status_attempt < self._max_retries and response.status_code in self._retry_status_codes:
359
+ request.status_attempt += 1
360
+ time.sleep(self._backoff_time(request.total_attempts))
361
+ return request
362
+ else:
363
+ # Permanent failure
364
+ return FailedResponse2(
365
+ status_code=response.status_code,
366
+ body=response.text,
367
+ error=ErrorDetails2.from_response(response),
368
+ )
369
+
370
+ def _handle_error_single(self, e: Exception, request: RequestMessage2) -> RequestMessage2 | HTTPResult2:
371
+ if isinstance(e, httpx.ReadTimeout | httpx.TimeoutException):
372
+ error_type = "read"
373
+ request.read_attempt += 1
374
+ attempts = request.read_attempt
375
+ elif isinstance(e, ConnectionError | httpx.ConnectError | httpx.ConnectTimeout):
376
+ error_type = "connect"
377
+ request.connect_attempt += 1
378
+ attempts = request.connect_attempt
379
+ else:
380
+ error_msg = f"Unexpected exception: {e!s}"
381
+ return FailedRequest2(error=error_msg)
382
+
383
+ if attempts <= self._max_retries:
384
+ time.sleep(self._backoff_time(request.total_attempts))
385
+ return request
386
+ else:
387
+ # We have already incremented the attempt count, so we subtract 1 here
388
+ error_msg = f"RequestException after {request.total_attempts - 1} attempts ({error_type} error): {e!s}"
389
+
390
+ return FailedRequest2(error=error_msg)
@@ -0,0 +1,97 @@
1
+ import gzip
2
+ from abc import ABC, abstractmethod
3
+ from typing import Any, Literal
4
+
5
+ import httpx
6
+ from cognite.client import global_config
7
+ from pydantic import BaseModel, JsonValue, TypeAdapter, model_validator
8
+
9
+ from cognite_toolkit._cdf_tk.utils.useful_types import PrimitiveType
10
+
11
+
12
+ class HTTPResult2(BaseModel): ...
13
+
14
+
15
+ class FailedRequest2(HTTPResult2):
16
+ error: str
17
+
18
+
19
+ class SuccessResponse2(HTTPResult2):
20
+ status_code: int
21
+ body: str
22
+ content: bytes
23
+
24
+
25
+ class ErrorDetails2(BaseModel):
26
+ """This is the expected structure of error details in the CDF API"""
27
+
28
+ code: int
29
+ message: str
30
+ missing: list[JsonValue] | None = None
31
+ duplicated: list[JsonValue] | None = None
32
+ is_auto_retryable: bool | None = None
33
+
34
+ @classmethod
35
+ def from_response(cls, response: httpx.Response) -> "ErrorDetails2":
36
+ """Populate the error details from a httpx response."""
37
+ try:
38
+ res = TypeAdapter(dict[Literal["error"], ErrorDetails2]).validate_json(response.text)
39
+ except ValueError:
40
+ return cls(code=response.status_code, message=response.text)
41
+ return res["error"]
42
+
43
+
44
+ class FailedResponse2(HTTPResult2):
45
+ status_code: int
46
+ body: str
47
+ error: ErrorDetails2
48
+
49
+
50
+ class BaseRequestMessage(BaseModel, ABC):
51
+ endpoint_url: str
52
+ method: Literal["GET", "POST", "PATCH", "DELETE", "PUT"]
53
+ connect_attempt: int = 0
54
+ read_attempt: int = 0
55
+ status_attempt: int = 0
56
+ api_version: str | None = None
57
+ content_type: str = "application/json"
58
+ accept: str = "application/json"
59
+
60
+ parameters: dict[str, PrimitiveType] | None = None
61
+
62
+ @property
63
+ def total_attempts(self) -> int:
64
+ return self.connect_attempt + self.read_attempt + self.status_attempt
65
+
66
+ @property
67
+ @abstractmethod
68
+ def content(self) -> str | bytes | None: ...
69
+
70
+
71
+ class RequestMessage2(BaseRequestMessage):
72
+ data_content: bytes | None = None
73
+ body_content: dict[str, JsonValue] | None = None
74
+
75
+ @model_validator(mode="before")
76
+ def check_data_or_body(cls, values: dict[str, Any]) -> dict[str, Any]:
77
+ if values.get("data_content") is not None and values.get("body_content") is not None:
78
+ raise ValueError("Only one of data_content or body_content can be set.")
79
+ return values
80
+
81
+ @property
82
+ def content(self) -> str | bytes | None:
83
+ data: str | bytes | None = None
84
+ if self.data_content is not None:
85
+ data = self.data_content
86
+ if not global_config.disable_gzip:
87
+ data = gzip.compress(data)
88
+ elif self.body_content is not None:
89
+ # We serialize using pydantic instead of json.dumps. This is because pydantic is faster
90
+ # and handles more complex types such as datetime, float('nan'), etc.
91
+ data = _BODY_SERIALIZER.dump_json(self.body_content)
92
+ if not global_config.disable_gzip and isinstance(data, str):
93
+ data = gzip.compress(data.encode("utf-8"))
94
+ return data
95
+
96
+
97
+ _BODY_SERIALIZER = TypeAdapter(dict[str, JsonValue])
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.7.28
15
+ image: cognite/toolkit:0.7.29
16
16
  env:
17
17
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
18
18
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -10,7 +10,7 @@ jobs:
10
10
  environment: dev
11
11
  name: Deploy Dry Run
12
12
  container:
13
- image: cognite/toolkit:0.7.28
13
+ image: cognite/toolkit:0.7.29
14
14
  env:
15
15
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
16
16
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -4,7 +4,7 @@ default_env = "<DEFAULT_ENV_PLACEHOLDER>"
4
4
  [modules]
5
5
  # This is the version of the modules. It should not be changed manually.
6
6
  # It will be updated by the 'cdf modules upgrade' command.
7
- version = "0.7.28"
7
+ version = "0.7.29"
8
8
 
9
9
 
10
10
  [plugins]
@@ -1 +1 @@
1
- __version__ = "0.7.28"
1
+ __version__ = "0.7.29"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.7.28
3
+ Version: 0.7.29
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Author: Cognite AS
6
6
  Author-email: Cognite AS <support@cognite.com>
@@ -28,14 +28,14 @@ cognite_toolkit/_cdf_tk/builders/_transformation.py,sha256=STB42zhzOW5M_-b8cKOQ_
28
28
  cognite_toolkit/_cdf_tk/cdf_toml.py,sha256=VSWV9h44HusWIaKpWgjrOMrc3hDoPTTXBXlp6-NOrIM,9079
29
29
  cognite_toolkit/_cdf_tk/client/__init__.py,sha256=a6rQXDGfW2g7K5WwrOW5oakh1TdFlBjUVjf9wusOox8,135
30
30
  cognite_toolkit/_cdf_tk/client/_constants.py,sha256=COUGcea37mDF2sf6MGqJXWmecTY_6aCImslxXrYW1I0,73
31
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py,sha256=1syPhlnCWJZzLuF9e1cjID06C-eOw5VLkOYz97cg3lA,3299
31
+ cognite_toolkit/_cdf_tk/client/_toolkit_client.py,sha256=y_GGNlCtu_qcjFVIb3bwLUS9zCqzJ0BK0_K-paw1Gt4,3417
32
32
  cognite_toolkit/_cdf_tk/client/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  cognite_toolkit/_cdf_tk/client/api/canvas.py,sha256=i2NwyhvmklTPx3e-yd4lvSxyn6JEjSpv8WXa1SxtmV8,8789
34
34
  cognite_toolkit/_cdf_tk/client/api/charts.py,sha256=t-VOrRGwpjmYUtUqGObQWYwGb5gOHVp4cHZBm8ZVGn0,4953
35
35
  cognite_toolkit/_cdf_tk/client/api/dml.py,sha256=8b1lo86JdvfEsz9mP2rx0Mp9fyWsU6mbXHqLBtvSidU,3546
36
36
  cognite_toolkit/_cdf_tk/client/api/extended_data_modeling.py,sha256=T08lXIrgDRGKhF-44FYoBMd4oJRYiWRzYhHsNkLyLAo,12967
37
37
  cognite_toolkit/_cdf_tk/client/api/extended_files.py,sha256=azdPnCqXUVuPLTuiV9WZ97VJTJ6mN2hOEtD9LklLw8M,9191
38
- cognite_toolkit/_cdf_tk/client/api/extended_functions.py,sha256=QaFCYmiL4KDWRpRB5gBHd6Z9fuxNLnWl16k1mOzWFuk,3608
38
+ cognite_toolkit/_cdf_tk/client/api/extended_functions.py,sha256=_MbkztZskZAt43ZERddhmeZYKHeQSDteFlnaCLL5J6k,3523
39
39
  cognite_toolkit/_cdf_tk/client/api/extended_raw.py,sha256=9DVbM2aWmIyzbaW-lh10_pzVYJUEQFnIKnxvt413Bjk,2118
40
40
  cognite_toolkit/_cdf_tk/client/api/extended_timeseries.py,sha256=xK7XhTfe4W9FvaueUIfR7Q64JOIDwq_svHRjORM76Q4,17774
41
41
  cognite_toolkit/_cdf_tk/client/api/fixed_transformations.py,sha256=m66cqbx4oCtjv5TBQOWLNFrz475qVTCXBu_pTxbdCD4,5589
@@ -107,7 +107,7 @@ cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py,sha256=b_6_yYibtzWiBFrY
107
107
  cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py,sha256=i1eUsNX6Dueol9STIEwyksBnBsWUk13O8qHIjW964pM,7860
108
108
  cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py,sha256=ERn3qFrJFXdtXaMjHq3Gk7MxH03MGFk3FrtWCOBJQts,5544
109
109
  cognite_toolkit/_cdf_tk/commands/_migrate/issues.py,sha256=n8en744-r7GL9eUyxEojFes1yk69V04SnlpVXHrdPOQ,6972
110
- cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py,sha256=wrdBH5P6NgiZQSYLR0iJ3ZvqfQ5fY-_Ne2yKv9E1g4o,16277
110
+ cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py,sha256=nc77Eu1a2sGS8Pb0bkMgqWebYmWlLbQe8xPCay5aoNo,17208
111
111
  cognite_toolkit/_cdf_tk/commands/_migrate/prepare.py,sha256=RfqaNoso5CyBwc-p6ckwcYqBfZXKhdJgdGIyd0TATaI,2635
112
112
  cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py,sha256=N1H_-rBpPUD6pbrlcofn1uEK1bA694EUXEe1zIXeqyo,2489
113
113
  cognite_toolkit/_cdf_tk/commands/_profile.py,sha256=_4iX3AHAI6eLmRVUlWXCSvVHx1BZW2yDr_i2i9ECg6U,43120
@@ -143,7 +143,7 @@ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py,sha256=SagiSp3JERgEU3
143
143
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py,sha256=a2HywkruYNJGLZxqOjlp8mrpRGtJDPqIb6qY00eUbEI,17701
144
144
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py,sha256=dcC850Vyvc5Hfi9Z3MfXE8s_q14Hqq4EqegFz_V6aCI,20662
145
145
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py,sha256=vyeRsiIOEbUeYslBsgXoyCk5hozDsubUilA7bdjqS5c,14855
146
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py,sha256=v3kjn3igwTF53LJ6pp0O8d4S1XFJ1eXQGCchWAcaAx0,28439
146
+ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py,sha256=4J7ObIRT1fKl1542-byaRs3lUfx2LiNbNg55tQkIg-g,28395
147
147
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/group_scoped.py,sha256=WEg8-CxMP64WfE_XXIlH114zM51K0uLaYa4atd992zI,1690
148
148
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py,sha256=P0hlXK0_FmO86U-gDHMHz8N0vpDtPoKupiQfhNP5KLE,14619
149
149
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py,sha256=QrgSCcLN0NtpQuP7zcCUYaWoiq3JiUB2j0A15d8MNNc,7856
@@ -238,7 +238,7 @@ cognite_toolkit/_cdf_tk/resource_classes/workflow.py,sha256=fMNfW93D8tdVwO7YgEYY
238
238
  cognite_toolkit/_cdf_tk/resource_classes/workflow_trigger.py,sha256=aSN0WFPupQ383A7RT-0Monw-inkVdYYSsK3UwHXW1HA,5216
239
239
  cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py,sha256=ui724EaM9Nlm3wTnm7Givgv6GLQ-xbsfZgidyRKv09U,2991
240
240
  cognite_toolkit/_cdf_tk/storageio/__init__.py,sha256=h5Wr4i7zNIgsslrsRJxmp7ls4bNRKl0uZzQ7GLRMP7g,1920
241
- cognite_toolkit/_cdf_tk/storageio/_annotations.py,sha256=JI_g18_Y9S7pbc9gm6dZMyo3Z-bCndJXF9C2lOva0bQ,4848
241
+ cognite_toolkit/_cdf_tk/storageio/_annotations.py,sha256=QcFrikDgz-9VjNy4Xq7wchM4VOQh-z2JaHcWR2C1sEs,4879
242
242
  cognite_toolkit/_cdf_tk/storageio/_applications.py,sha256=M7FEK4xC0BjP2i6FyYs1589zEA3afJiOKCzY56RV6NU,19685
243
243
  cognite_toolkit/_cdf_tk/storageio/_asset_centric.py,sha256=TirKLSNPoLqKjczsw0djWAsR0VvopwmU23aUxrBOJN8,32464
244
244
  cognite_toolkit/_cdf_tk/storageio/_base.py,sha256=ElvqhIEBnhcz0yY1Ds164wVN0_7CFNK-uT0-z7LcR9U,13067
@@ -281,8 +281,9 @@ cognite_toolkit/_cdf_tk/utils/fileio/_writers.py,sha256=mc23m0kJgl57FUDvwLmS7yR3
281
281
  cognite_toolkit/_cdf_tk/utils/graphql_parser.py,sha256=2i2wDjg_Uw3hJ-pHtPK8hczIuCj5atrK8HZbgWJB-Pk,11532
282
282
  cognite_toolkit/_cdf_tk/utils/hashing.py,sha256=3NyNfljyYNTqAyAFBd6XlyWaj43jRzENxIuPdOY6nqo,2116
283
283
  cognite_toolkit/_cdf_tk/utils/http_client/__init__.py,sha256=G8b7Bg4yIet5R4Igh3dS2SntWzE6I0iTGBeNlNsSxkQ,857
284
- cognite_toolkit/_cdf_tk/utils/http_client/_client.py,sha256=7B9c5_mwmWlf-_juq8-oVJAnc3iJuQDPgY-8uuhD7wA,11487
284
+ cognite_toolkit/_cdf_tk/utils/http_client/_client.py,sha256=OrrGq3GjusxPPzhFoW8iyiphpdbWOWAoaYOeOy9kqjQ,16212
285
285
  cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py,sha256=8KEDyRRaOLhwN2eA2vaBAzZ__JDUicUDyir6x_PE5lk,14817
286
+ cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py,sha256=mUrmTqTm60WP4JpMmNO07-NfgWQM8Wby7OLCo02I71U,3031
286
287
  cognite_toolkit/_cdf_tk/utils/http_client/_exception.py,sha256=fC9oW6BN0HbUe2AkYABMP7Kj0-9dNYXVFBY5RQztq2c,126
287
288
  cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py,sha256=EBBnd-JZ7nc_jYNFJokCHN2UZ9sx0McFLZvlceUYYic,1215
288
289
  cognite_toolkit/_cdf_tk/utils/interactive_select.py,sha256=dP_ZFHvzQRPQxRt6EzURY3Z3Ld_otJtCz-nGqUNtt1k,35725
@@ -302,14 +303,14 @@ cognite_toolkit/_repo_files/.gitignore,sha256=ip9kf9tcC5OguF4YF4JFEApnKYw0nG0vPi
302
303
  cognite_toolkit/_repo_files/AzureDevOps/.devops/README.md,sha256=OLA0D7yCX2tACpzvkA0IfkgQ4_swSd-OlJ1tYcTBpsA,240
303
304
  cognite_toolkit/_repo_files/AzureDevOps/.devops/deploy-pipeline.yml,sha256=brULcs8joAeBC_w_aoWjDDUHs3JheLMIR9ajPUK96nc,693
304
305
  cognite_toolkit/_repo_files/AzureDevOps/.devops/dry-run-pipeline.yml,sha256=OBFDhFWK1mlT4Dc6mDUE2Es834l8sAlYG50-5RxRtHk,723
305
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=WjbXrAgIoTssRXTsTBHolXqsIg4BKfCLRtfmT37lTM4,667
306
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=qfSb9a7NFcwbEDJo8JoRrnvPvjyrjlWO7SVjxqVMjjM,2430
307
- cognite_toolkit/_resources/cdf.toml,sha256=kw_vOm_sjuQP0yBUwjl4b5PP2mLyTEyG3HzTXFWtGFk,475
308
- cognite_toolkit/_version.py,sha256=zxRa3gUEpxj8fTU5qOT60NDmCfmdbg7_Z6ZkpKAhrNg,23
306
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=FQFw5rkuhjbBY-cBoP38pdrcUZF6qkK2Y9YKbab8LzU,667
307
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=e87zJqrsOVfo7QqSnIZY5U32szqyvq5Bjq-e_16xHiQ,2430
308
+ cognite_toolkit/_resources/cdf.toml,sha256=tJP7KRNhWsrkXisd58pe5ZlzUBOAfe4zR5TTAP63tzg,475
309
+ cognite_toolkit/_version.py,sha256=XdC0R1utqmwH52az-uz3mk0vLZyV2OyWiin3soRIguo,23
309
310
  cognite_toolkit/config.dev.yaml,sha256=M33FiIKdS3XKif-9vXniQ444GTZ-bLXV8aFH86u9iUQ,332
310
311
  cognite_toolkit/demo/__init__.py,sha256=-m1JoUiwRhNCL18eJ6t7fZOL7RPfowhCuqhYFtLgrss,72
311
312
  cognite_toolkit/demo/_base.py,sha256=6xKBUQpXZXGQ3fJ5f7nj7oT0s2n7OTAGIa17ZlKHZ5U,8052
312
- cognite_toolkit-0.7.28.dist-info/WHEEL,sha256=93kfTGt3a0Dykt_T-gsjtyS5_p8F_d6CE1NwmBOirzo,79
313
- cognite_toolkit-0.7.28.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
314
- cognite_toolkit-0.7.28.dist-info/METADATA,sha256=8484D-s0BzjQMFkFVIPhKFv2p4jELcUAVka0_qC7yT4,4507
315
- cognite_toolkit-0.7.28.dist-info/RECORD,,
313
+ cognite_toolkit-0.7.29.dist-info/WHEEL,sha256=93kfTGt3a0Dykt_T-gsjtyS5_p8F_d6CE1NwmBOirzo,79
314
+ cognite_toolkit-0.7.29.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
315
+ cognite_toolkit-0.7.29.dist-info/METADATA,sha256=71UXU4S9UVcZVxhDGazAQOCbTSYyQzD6Kj2FkxNJHYs,4507
316
+ cognite_toolkit-0.7.29.dist-info/RECORD,,