cognite-toolkit 0.7.42__py3-none-any.whl → 0.7.44__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_tk/client/_toolkit_client.py +7 -1
- cognite_toolkit/_cdf_tk/client/api/events.py +20 -2
- cognite_toolkit/_cdf_tk/client/api/filemetadata.py +145 -0
- cognite_toolkit/_cdf_tk/client/api/raw.py +174 -0
- cognite_toolkit/_cdf_tk/client/api/simulator_models.py +118 -0
- cognite_toolkit/_cdf_tk/client/api/simulators.py +8 -0
- cognite_toolkit/_cdf_tk/client/api/timeseries.py +20 -2
- cognite_toolkit/_cdf_tk/client/cdf_client/__init__.py +2 -1
- cognite_toolkit/_cdf_tk/client/cdf_client/api.py +40 -6
- cognite_toolkit/_cdf_tk/client/data_classes/agent.py +6 -9
- cognite_toolkit/_cdf_tk/client/data_classes/annotation.py +79 -0
- cognite_toolkit/_cdf_tk/client/data_classes/asset.py +7 -14
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +15 -5
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/__init__.py +164 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_constraints.py +37 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_container.py +50 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_data_model.py +73 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_data_types.py +116 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_indexes.py +26 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_instance.py +143 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_references.py +86 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_space.py +26 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_view.py +143 -0
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/_view_property.py +152 -0
- cognite_toolkit/_cdf_tk/client/data_classes/dataset.py +35 -0
- cognite_toolkit/_cdf_tk/client/data_classes/event.py +12 -15
- cognite_toolkit/_cdf_tk/client/data_classes/extraction_pipeline.py +59 -0
- cognite_toolkit/_cdf_tk/client/data_classes/filemetadata.py +15 -19
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_destination.py +34 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_job.py +134 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_mapping.py +72 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/__init__.py +63 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_auth.py +63 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_base.py +26 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_certificate.py +20 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_eventhub.py +31 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_kafka.py +53 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_mqtt.py +36 -0
- cognite_toolkit/_cdf_tk/client/data_classes/hosted_extractor_source/_rest.py +49 -0
- cognite_toolkit/_cdf_tk/client/data_classes/identifiers.py +8 -0
- cognite_toolkit/_cdf_tk/client/data_classes/label.py +27 -0
- cognite_toolkit/_cdf_tk/client/data_classes/raw.py +3 -2
- cognite_toolkit/_cdf_tk/client/data_classes/securitycategory.py +24 -0
- cognite_toolkit/_cdf_tk/client/data_classes/sequence.py +45 -0
- cognite_toolkit/_cdf_tk/client/data_classes/simulator_model.py +50 -0
- cognite_toolkit/_cdf_tk/client/data_classes/timeseries.py +15 -18
- cognite_toolkit/_cdf_tk/client/data_classes/transformation.py +140 -0
- cognite_toolkit/_cdf_tk/client/data_classes/workflow.py +27 -0
- cognite_toolkit/_cdf_tk/client/data_classes/workflow_trigger.py +63 -0
- cognite_toolkit/_cdf_tk/client/data_classes/workflow_version.py +155 -0
- cognite_toolkit/_cdf_tk/client/testing.py +6 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +10 -7
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +4 -4
- cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +7 -3
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +5 -1
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +40 -39
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +56 -59
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -3
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +48 -47
- cognite_toolkit/_cdf_tk/resource_classes/__init__.py +2 -0
- cognite_toolkit/_cdf_tk/resource_classes/simulator_model.py +17 -0
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +84 -71
- cognite_toolkit/_cdf_tk/storageio/_file_content.py +22 -19
- cognite_toolkit/_cdf_tk/utils/useful_types2.py +5 -3
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
- cognite_toolkit/_resources/cdf.toml +1 -1
- cognite_toolkit/_version.py +1 -1
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.44.dist-info}/METADATA +11 -1
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.44.dist-info}/RECORD +72 -34
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.44.dist-info}/WHEEL +1 -1
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.44.dist-info}/entry_points.txt +0 -0
|
@@ -5,6 +5,7 @@ that handle CRUD operations for CDF Data Modeling API resources.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
|
+
from collections import defaultdict
|
|
8
9
|
from collections.abc import Callable, Iterable, Sequence
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from functools import partial
|
|
@@ -97,9 +98,10 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
97
98
|
method: APIMethod,
|
|
98
99
|
params: dict[str, Any] | None = None,
|
|
99
100
|
extra_body: dict[str, Any] | None = None,
|
|
101
|
+
endpoint: str | None = None,
|
|
100
102
|
) -> list[T_ResponseResource]:
|
|
101
103
|
response_items: list[T_ResponseResource] = []
|
|
102
|
-
for response in self._chunk_requests(items, method, self._serialize_items, params, extra_body):
|
|
104
|
+
for response in self._chunk_requests(items, method, self._serialize_items, params, extra_body, endpoint):
|
|
103
105
|
response_items.extend(self._page_response(response).items)
|
|
104
106
|
return response_items
|
|
105
107
|
|
|
@@ -121,8 +123,9 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
121
123
|
method: APIMethod,
|
|
122
124
|
params: dict[str, Any] | None = None,
|
|
123
125
|
extra_body: dict[str, Any] | None = None,
|
|
126
|
+
endpoint: str | None = None,
|
|
124
127
|
) -> None:
|
|
125
|
-
list(self._chunk_requests(items, method, self._serialize_items, params, extra_body))
|
|
128
|
+
list(self._chunk_requests(items, method, self._serialize_items, params, extra_body, endpoint))
|
|
126
129
|
return None
|
|
127
130
|
|
|
128
131
|
def _chunk_requests(
|
|
@@ -132,14 +135,28 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
132
135
|
serialization: Callable[[Sequence[_T_BaseModel]], list[dict[str, JsonValue]]],
|
|
133
136
|
params: dict[str, Any] | None = None,
|
|
134
137
|
extra_body: dict[str, Any] | None = None,
|
|
138
|
+
endpoint_path: str | None = None,
|
|
135
139
|
) -> Iterable[SuccessResponse2]:
|
|
140
|
+
"""Send requests in chunks and yield responses.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
items: The items to process.
|
|
144
|
+
method: The API method to use. This is used ot look the up the endpoint.
|
|
145
|
+
serialization: A function to serialize the items to JSON-compatible dicts.
|
|
146
|
+
params: Optional query parameters for the request.
|
|
147
|
+
extra_body: Optional extra body content to include in the request.
|
|
148
|
+
endpoint_path: Optional override for the endpoint path.
|
|
149
|
+
|
|
150
|
+
Yields:
|
|
151
|
+
The successful responses from the API.
|
|
152
|
+
"""
|
|
136
153
|
# Filter out None
|
|
137
154
|
request_params = self._filter_out_none_values(params)
|
|
138
155
|
endpoint = self._method_endpoint_map[method]
|
|
139
156
|
|
|
140
157
|
for chunk in chunker_sequence(items, endpoint.item_limit):
|
|
141
158
|
request = RequestMessage2(
|
|
142
|
-
endpoint_url=f"{self._make_url(endpoint.path)}",
|
|
159
|
+
endpoint_url=f"{self._make_url(endpoint_path or endpoint.path)}",
|
|
143
160
|
method=endpoint.method,
|
|
144
161
|
body_content={"items": serialization(chunk), **(extra_body or {})}, # type: ignore[dict-item]
|
|
145
162
|
parameters=request_params,
|
|
@@ -154,12 +171,24 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
154
171
|
request_params = {k: v for k, v in params.items() if v is not None}
|
|
155
172
|
return request_params
|
|
156
173
|
|
|
174
|
+
@classmethod
|
|
175
|
+
def _group_items_by_text_field(
|
|
176
|
+
cls, items: Sequence[_T_BaseModel], field_name: str
|
|
177
|
+
) -> dict[str, list[_T_BaseModel]]:
|
|
178
|
+
"""Group items by a text field."""
|
|
179
|
+
grouped_items: dict[str, list[_T_BaseModel]] = defaultdict(list)
|
|
180
|
+
for item in items:
|
|
181
|
+
key = str(getattr(item, field_name))
|
|
182
|
+
grouped_items[key].append(item)
|
|
183
|
+
return grouped_items
|
|
184
|
+
|
|
157
185
|
def _iterate(
|
|
158
186
|
self,
|
|
159
187
|
limit: int,
|
|
160
188
|
cursor: str | None = None,
|
|
161
189
|
params: dict[str, Any] | None = None,
|
|
162
190
|
body: dict[str, Any] | None = None,
|
|
191
|
+
endpoint_path: str | None = None,
|
|
163
192
|
) -> PagedResponse[T_ResponseResource]:
|
|
164
193
|
"""Fetch a single page of resources.
|
|
165
194
|
|
|
@@ -171,8 +200,11 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
171
200
|
- space: Filter by space
|
|
172
201
|
- includeGlobal: Whether to include global resources
|
|
173
202
|
body : Body content for the request, if applicable.
|
|
203
|
+
limit: Maximum number of items to return in the page.
|
|
204
|
+
cursor: Cursor for pagination.
|
|
174
205
|
limit: Maximum number of items to return in the page.
|
|
175
206
|
cursor: Cursor for pagination.
|
|
207
|
+
|
|
176
208
|
Returns:
|
|
177
209
|
A Page containing the items and the cursor for the next page.
|
|
178
210
|
"""
|
|
@@ -194,7 +226,7 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
194
226
|
raise NotImplementedError(f"Unsupported method {endpoint.method} for pagination.")
|
|
195
227
|
|
|
196
228
|
request = RequestMessage2(
|
|
197
|
-
endpoint_url=self._make_url(endpoint.path),
|
|
229
|
+
endpoint_url=self._make_url(endpoint_path or endpoint.path),
|
|
198
230
|
method=endpoint.method,
|
|
199
231
|
parameters=request_params,
|
|
200
232
|
body_content=body,
|
|
@@ -203,7 +235,9 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
203
235
|
response = result.get_success_or_raise()
|
|
204
236
|
return self._page_response(response)
|
|
205
237
|
|
|
206
|
-
def _list(
|
|
238
|
+
def _list(
|
|
239
|
+
self, limit: int | None = None, params: dict[str, Any] | None = None, endpoint_path: str | None = None
|
|
240
|
+
) -> list[T_ResponseResource]:
|
|
207
241
|
"""List all resources, handling pagination automatically."""
|
|
208
242
|
all_items: list[T_ResponseResource] = []
|
|
209
243
|
next_cursor: str | None = None
|
|
@@ -211,7 +245,7 @@ class CDFResourceAPI(Generic[T_Identifier, T_RequestResource, T_ResponseResource
|
|
|
211
245
|
endpoint = self._method_endpoint_map["list"]
|
|
212
246
|
while True:
|
|
213
247
|
page_limit = endpoint.item_limit if limit is None else min(limit - total, endpoint.item_limit)
|
|
214
|
-
page = self._iterate(limit=page_limit, cursor=next_cursor, params=params)
|
|
248
|
+
page = self._iterate(limit=page_limit, cursor=next_cursor, params=params, endpoint_path=endpoint_path)
|
|
215
249
|
all_items.extend(page.items)
|
|
216
250
|
total += len(page.items)
|
|
217
251
|
if page.next_cursor is None or (limit is not None and total >= limit):
|
|
@@ -98,29 +98,26 @@ AgentTool = Annotated[
|
|
|
98
98
|
]
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
class
|
|
101
|
+
class Agent(BaseModelObject):
|
|
102
102
|
external_id: str
|
|
103
103
|
name: str
|
|
104
104
|
description: str | None = None
|
|
105
105
|
instructions: str | None = None
|
|
106
106
|
model: str = "azure/gpt-4o-mini"
|
|
107
107
|
tools: list[AgentTool] | None = None
|
|
108
|
-
runtime_version: str | None = None
|
|
109
108
|
|
|
110
109
|
def as_id(self) -> ExternalId:
|
|
111
110
|
return ExternalId(external_id=self.external_id)
|
|
112
111
|
|
|
113
112
|
|
|
114
|
-
class
|
|
113
|
+
class AgentRequest(Agent, RequestResource):
|
|
114
|
+
runtime_version: str | None = None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class AgentResponse(Agent, ResponseResource[AgentRequest]):
|
|
115
118
|
created_time: int
|
|
116
119
|
last_updated_time: int
|
|
117
120
|
owner_id: str
|
|
118
|
-
external_id: str
|
|
119
|
-
name: str
|
|
120
|
-
description: str | None = None
|
|
121
|
-
instructions: str | None = None
|
|
122
|
-
model: str = "azure/gpt-4o-mini"
|
|
123
|
-
tools: list[AgentTool] | None = None
|
|
124
121
|
runtime_version: str
|
|
125
122
|
|
|
126
123
|
def as_request_resource(self) -> AgentRequest:
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from typing import Any, Literal, TypeAlias
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, JsonValue
|
|
4
|
+
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestUpdateable, ResponseResource
|
|
6
|
+
|
|
7
|
+
from .identifiers import InternalId
|
|
8
|
+
|
|
9
|
+
AnnotationStatus: TypeAlias = Literal["suggested", "rejected", "approved"]
|
|
10
|
+
AnnotationType: TypeAlias = Literal[
|
|
11
|
+
"diagrams.AssetLink",
|
|
12
|
+
"diagrams.FileLink",
|
|
13
|
+
"diagrams.InstanceLink",
|
|
14
|
+
"diagrams.Junction",
|
|
15
|
+
"diagrams.Line",
|
|
16
|
+
"diagrams.UnhandledSymbolObject",
|
|
17
|
+
"diagrams.UnhandledTextObject",
|
|
18
|
+
"documents.ExtractedText",
|
|
19
|
+
"forms.Detection",
|
|
20
|
+
"images.AssetLink",
|
|
21
|
+
"images.Classification",
|
|
22
|
+
"images.InstanceLink",
|
|
23
|
+
"images.KeypointCollection",
|
|
24
|
+
"images.ObjectDetection",
|
|
25
|
+
"images.TextRegion",
|
|
26
|
+
"isoplan.IsoPlanAnnotation",
|
|
27
|
+
"pointcloud.BoundingVolume",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Annotation(BaseModelObject):
|
|
32
|
+
annotated_resource_type: str
|
|
33
|
+
annotated_resource_id: int
|
|
34
|
+
annotation_type: AnnotationType
|
|
35
|
+
creating_app: str
|
|
36
|
+
creating_app_version: str
|
|
37
|
+
creating_user: str | None
|
|
38
|
+
data: dict[str, JsonValue]
|
|
39
|
+
status: AnnotationStatus
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AnnotationRequest(Annotation, RequestUpdateable):
|
|
43
|
+
"""Request data class for annotations."""
|
|
44
|
+
|
|
45
|
+
# The 'id' field is not part of the request when creating a new resource,
|
|
46
|
+
# but is needed when updating an existing resource.
|
|
47
|
+
id: int | None = Field(default=None, exclude=True)
|
|
48
|
+
|
|
49
|
+
def as_id(self) -> InternalId:
|
|
50
|
+
if self.id is None:
|
|
51
|
+
raise ValueError("Cannot convert AnnotationRequest to InternalId when id is None")
|
|
52
|
+
return InternalId(id=self.id)
|
|
53
|
+
|
|
54
|
+
def as_update(self, mode: Literal["patch", "replace"]) -> dict[str, Any]:
|
|
55
|
+
"""Converts the request to an update payload for the API."""
|
|
56
|
+
if self.id is None:
|
|
57
|
+
raise ValueError("id must be provided to create an update dictionary")
|
|
58
|
+
return {
|
|
59
|
+
"id": self.id,
|
|
60
|
+
"update": {
|
|
61
|
+
"annotationType": {"set": self.annotation_type},
|
|
62
|
+
"data": {"set": self.data},
|
|
63
|
+
"status": {"set": self.status},
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class AnnotationResponse(Annotation, ResponseResource[AnnotationRequest]):
|
|
69
|
+
"""Response data class for annotations."""
|
|
70
|
+
|
|
71
|
+
id: int
|
|
72
|
+
created_time: int
|
|
73
|
+
last_updated_time: int
|
|
74
|
+
|
|
75
|
+
def as_id(self) -> InternalId:
|
|
76
|
+
return InternalId(id=self.id)
|
|
77
|
+
|
|
78
|
+
def as_request_resource(self) -> AnnotationRequest:
|
|
79
|
+
return AnnotationRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -7,9 +7,7 @@ from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, Re
|
|
|
7
7
|
from .identifiers import ExternalId
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class
|
|
11
|
-
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "labels"})
|
|
12
|
-
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"parent_id", "parent_external_id"})
|
|
10
|
+
class Asset(BaseModelObject):
|
|
13
11
|
external_id: str | None = None
|
|
14
12
|
name: str
|
|
15
13
|
parent_id: int | None = None
|
|
@@ -27,28 +25,23 @@ class AssetRequest(RequestUpdateable):
|
|
|
27
25
|
return ExternalId(external_id=self.external_id)
|
|
28
26
|
|
|
29
27
|
|
|
28
|
+
class AssetRequest(Asset, RequestUpdateable):
|
|
29
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "labels"})
|
|
30
|
+
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"parent_id", "parent_external_id"})
|
|
31
|
+
|
|
32
|
+
|
|
30
33
|
class AssetAggregateItem(BaseModelObject):
|
|
31
34
|
child_count: int
|
|
32
35
|
depth: int
|
|
33
36
|
path: list[dict[Literal["id"], int]]
|
|
34
37
|
|
|
35
38
|
|
|
36
|
-
class AssetResponse(ResponseResource[AssetRequest]):
|
|
39
|
+
class AssetResponse(Asset, ResponseResource[AssetRequest]):
|
|
37
40
|
created_time: int
|
|
38
41
|
last_updated_time: int
|
|
39
42
|
root_id: int
|
|
40
43
|
aggregates: AssetAggregateItem | None = None
|
|
41
44
|
id: int
|
|
42
|
-
external_id: str | None = None
|
|
43
|
-
name: str
|
|
44
|
-
parent_id: int | None = None
|
|
45
|
-
parent_external_id: str | None = None
|
|
46
|
-
description: str | None = None
|
|
47
|
-
metadata: dict[str, str] | None = None
|
|
48
|
-
data_set_id: int | None = None
|
|
49
|
-
source: str | None = None
|
|
50
|
-
labels: list[dict[Literal["externalId"], str]] | None = None
|
|
51
|
-
geo_location: dict[str, JsonValue] | None = None
|
|
52
45
|
|
|
53
46
|
def as_request_resource(self) -> AssetRequest:
|
|
54
47
|
return AssetRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -18,19 +18,29 @@ class BaseModelObject(BaseModel):
|
|
|
18
18
|
"""Base class for all object. This includes resources and nested objects."""
|
|
19
19
|
|
|
20
20
|
# We allow extra fields to support forward compatibility.
|
|
21
|
-
model_config = ConfigDict(alias_generator=to_camel, extra="allow")
|
|
21
|
+
model_config = ConfigDict(alias_generator=to_camel, extra="allow", populate_by_name=True)
|
|
22
22
|
|
|
23
|
-
def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
|
23
|
+
def dump(self, camel_case: bool = True, exclude_extra: bool = False) -> dict[str, Any]:
|
|
24
24
|
"""Dump the resource to a dictionary.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Args:
|
|
27
|
+
camel_case (bool): Whether to use camelCase for the keys. Default is True.
|
|
28
|
+
exclude_extra (bool): Whether to exclude extra fields not defined in the model. Default is False.
|
|
29
|
+
|
|
27
30
|
"""
|
|
31
|
+
if exclude_extra:
|
|
32
|
+
return self.model_dump(
|
|
33
|
+
mode="json",
|
|
34
|
+
by_alias=camel_case,
|
|
35
|
+
exclude_unset=True,
|
|
36
|
+
exclude=set(self.__pydantic_extra__) if self.__pydantic_extra__ else None,
|
|
37
|
+
)
|
|
28
38
|
return self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True)
|
|
29
39
|
|
|
30
40
|
@classmethod
|
|
31
41
|
def _load(cls, resource: dict[str, Any]) -> Self:
|
|
32
42
|
"""Load method to match CogniteResource signature."""
|
|
33
|
-
return cls.model_validate(resource)
|
|
43
|
+
return cls.model_validate(resource, by_alias=True)
|
|
34
44
|
|
|
35
45
|
|
|
36
46
|
class Identifier(BaseModelObject):
|
|
@@ -39,7 +49,7 @@ class Identifier(BaseModelObject):
|
|
|
39
49
|
|
|
40
50
|
model_config = ConfigDict(alias_generator=to_camel, extra="ignore", populate_by_name=True, frozen=True)
|
|
41
51
|
|
|
42
|
-
def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
|
52
|
+
def dump(self, camel_case: bool = True, exclude_extra: bool = False) -> dict[str, Any]:
|
|
43
53
|
"""Dump the resource to a dictionary.
|
|
44
54
|
|
|
45
55
|
This is the default serialization method for request resources.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
from ._constraints import (
|
|
2
|
+
Constraint,
|
|
3
|
+
ConstraintAdapter,
|
|
4
|
+
ConstraintDefinition,
|
|
5
|
+
RequiresConstraintDefinition,
|
|
6
|
+
UniquenessConstraintDefinition,
|
|
7
|
+
)
|
|
8
|
+
from ._container import (
|
|
9
|
+
Container,
|
|
10
|
+
ContainerPropertyDefinition,
|
|
11
|
+
ContainerRequest,
|
|
12
|
+
ContainerResponse,
|
|
13
|
+
)
|
|
14
|
+
from ._data_model import DataModelRequest, DataModelResponse
|
|
15
|
+
from ._data_types import (
|
|
16
|
+
BooleanProperty,
|
|
17
|
+
DataType,
|
|
18
|
+
DataTypeAdapter,
|
|
19
|
+
DateProperty,
|
|
20
|
+
DirectNodeRelation,
|
|
21
|
+
EnumProperty,
|
|
22
|
+
EnumValue,
|
|
23
|
+
FileCDFExternalIdReference,
|
|
24
|
+
Float32Property,
|
|
25
|
+
Float64Property,
|
|
26
|
+
FloatProperty,
|
|
27
|
+
Int32Property,
|
|
28
|
+
Int64Property,
|
|
29
|
+
JSONProperty,
|
|
30
|
+
ListablePropertyTypeDefinition,
|
|
31
|
+
PropertyTypeDefinition,
|
|
32
|
+
SequenceCDFExternalIdReference,
|
|
33
|
+
TextProperty,
|
|
34
|
+
TimeseriesCDFExternalIdReference,
|
|
35
|
+
TimestampProperty,
|
|
36
|
+
Unit,
|
|
37
|
+
)
|
|
38
|
+
from ._indexes import (
|
|
39
|
+
BtreeIndex,
|
|
40
|
+
Index,
|
|
41
|
+
IndexAdapter,
|
|
42
|
+
IndexDefinition,
|
|
43
|
+
InvertedIndex,
|
|
44
|
+
)
|
|
45
|
+
from ._instance import (
|
|
46
|
+
EdgeRequest,
|
|
47
|
+
EdgeResponse,
|
|
48
|
+
InstanceDefinition,
|
|
49
|
+
InstanceResponseDefinition,
|
|
50
|
+
InstanceSource,
|
|
51
|
+
NodeRequest,
|
|
52
|
+
NodeResponse,
|
|
53
|
+
)
|
|
54
|
+
from ._references import (
|
|
55
|
+
ContainerConstraintReference,
|
|
56
|
+
ContainerDirectReference,
|
|
57
|
+
ContainerIndexReference,
|
|
58
|
+
ContainerReference,
|
|
59
|
+
DataModelReference,
|
|
60
|
+
NodeReference,
|
|
61
|
+
SpaceReference,
|
|
62
|
+
ViewDirectReference,
|
|
63
|
+
ViewReference,
|
|
64
|
+
)
|
|
65
|
+
from ._space import Space, SpaceRequest, SpaceResponse
|
|
66
|
+
from ._view import View, ViewRequest, ViewResponse
|
|
67
|
+
from ._view_property import (
|
|
68
|
+
ConnectionPropertyDefinition,
|
|
69
|
+
ConstraintOrIndexState,
|
|
70
|
+
EdgeProperty,
|
|
71
|
+
MultiEdgeProperty,
|
|
72
|
+
MultiReverseDirectRelationPropertyRequest,
|
|
73
|
+
MultiReverseDirectRelationPropertyResponse,
|
|
74
|
+
ReverseDirectRelationProperty,
|
|
75
|
+
SingleEdgeProperty,
|
|
76
|
+
SingleReverseDirectRelationPropertyRequest,
|
|
77
|
+
SingleReverseDirectRelationPropertyResponse,
|
|
78
|
+
ViewCoreProperty,
|
|
79
|
+
ViewCorePropertyRequest,
|
|
80
|
+
ViewCorePropertyResponse,
|
|
81
|
+
ViewPropertyDefinition,
|
|
82
|
+
ViewRequestProperty,
|
|
83
|
+
ViewRequestPropertyAdapter,
|
|
84
|
+
ViewResponseProperty,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
__all__ = [
|
|
88
|
+
"BooleanProperty",
|
|
89
|
+
"BtreeIndex",
|
|
90
|
+
"ConnectionPropertyDefinition",
|
|
91
|
+
"Constraint",
|
|
92
|
+
"ConstraintAdapter",
|
|
93
|
+
"ConstraintDefinition",
|
|
94
|
+
"ConstraintOrIndexState",
|
|
95
|
+
"Container",
|
|
96
|
+
"ContainerConstraintReference",
|
|
97
|
+
"ContainerDirectReference",
|
|
98
|
+
"ContainerIndexReference",
|
|
99
|
+
"ContainerPropertyDefinition",
|
|
100
|
+
"ContainerReference",
|
|
101
|
+
"ContainerRequest",
|
|
102
|
+
"ContainerResponse",
|
|
103
|
+
"DataModelReference",
|
|
104
|
+
"DataModelRequest",
|
|
105
|
+
"DataModelResponse",
|
|
106
|
+
"DataType",
|
|
107
|
+
"DataTypeAdapter",
|
|
108
|
+
"DateProperty",
|
|
109
|
+
"DirectNodeRelation",
|
|
110
|
+
"EdgeProperty",
|
|
111
|
+
"EdgeRequest",
|
|
112
|
+
"EdgeResponse",
|
|
113
|
+
"EnumProperty",
|
|
114
|
+
"EnumValue",
|
|
115
|
+
"FileCDFExternalIdReference",
|
|
116
|
+
"Float32Property",
|
|
117
|
+
"Float64Property",
|
|
118
|
+
"FloatProperty",
|
|
119
|
+
"Index",
|
|
120
|
+
"IndexAdapter",
|
|
121
|
+
"IndexDefinition",
|
|
122
|
+
"InstanceDefinition",
|
|
123
|
+
"InstanceResponseDefinition",
|
|
124
|
+
"InstanceSource",
|
|
125
|
+
"Int32Property",
|
|
126
|
+
"Int64Property",
|
|
127
|
+
"InvertedIndex",
|
|
128
|
+
"JSONProperty",
|
|
129
|
+
"ListablePropertyTypeDefinition",
|
|
130
|
+
"MultiEdgeProperty",
|
|
131
|
+
"MultiReverseDirectRelationPropertyRequest",
|
|
132
|
+
"MultiReverseDirectRelationPropertyResponse",
|
|
133
|
+
"NodeReference",
|
|
134
|
+
"NodeRequest",
|
|
135
|
+
"NodeResponse",
|
|
136
|
+
"PropertyTypeDefinition",
|
|
137
|
+
"RequiresConstraintDefinition",
|
|
138
|
+
"ReverseDirectRelationProperty",
|
|
139
|
+
"SequenceCDFExternalIdReference",
|
|
140
|
+
"SingleEdgeProperty",
|
|
141
|
+
"SingleReverseDirectRelationPropertyRequest",
|
|
142
|
+
"SingleReverseDirectRelationPropertyResponse",
|
|
143
|
+
"Space",
|
|
144
|
+
"SpaceReference",
|
|
145
|
+
"SpaceRequest",
|
|
146
|
+
"SpaceResponse",
|
|
147
|
+
"TextProperty",
|
|
148
|
+
"TimeseriesCDFExternalIdReference",
|
|
149
|
+
"TimestampProperty",
|
|
150
|
+
"UniquenessConstraintDefinition",
|
|
151
|
+
"Unit",
|
|
152
|
+
"View",
|
|
153
|
+
"ViewCoreProperty",
|
|
154
|
+
"ViewCorePropertyRequest",
|
|
155
|
+
"ViewCorePropertyResponse",
|
|
156
|
+
"ViewDirectReference",
|
|
157
|
+
"ViewPropertyDefinition",
|
|
158
|
+
"ViewReference",
|
|
159
|
+
"ViewRequest",
|
|
160
|
+
"ViewRequestProperty",
|
|
161
|
+
"ViewRequestPropertyAdapter",
|
|
162
|
+
"ViewResponse",
|
|
163
|
+
"ViewResponseProperty",
|
|
164
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Annotated, Any, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import Field, TypeAdapter, field_serializer
|
|
5
|
+
from pydantic_core.core_schema import FieldSerializationInfo
|
|
6
|
+
|
|
7
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject
|
|
8
|
+
|
|
9
|
+
from ._references import ContainerReference
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ConstraintDefinition(BaseModelObject, ABC):
|
|
13
|
+
constraint_type: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class UniquenessConstraintDefinition(ConstraintDefinition):
|
|
17
|
+
constraint_type: Literal["uniqueness"] = "uniqueness"
|
|
18
|
+
properties: list[str]
|
|
19
|
+
by_space: bool | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RequiresConstraintDefinition(ConstraintDefinition):
|
|
23
|
+
constraint_type: Literal["requires"] = "requires"
|
|
24
|
+
require: ContainerReference
|
|
25
|
+
|
|
26
|
+
@field_serializer("require", mode="plain")
|
|
27
|
+
@classmethod
|
|
28
|
+
def serialize_require(cls, require: ContainerReference, info: FieldSerializationInfo) -> dict[str, Any]:
|
|
29
|
+
return {**require.model_dump(**vars(info)), "type": "container"}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Constraint = Annotated[
|
|
33
|
+
UniquenessConstraintDefinition | RequiresConstraintDefinition,
|
|
34
|
+
Field(discriminator="constraint_type"),
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
ConstraintAdapter: TypeAdapter[Constraint] = TypeAdapter(Constraint)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import JsonValue
|
|
5
|
+
|
|
6
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestResource, ResponseResource
|
|
7
|
+
|
|
8
|
+
from ._constraints import Constraint
|
|
9
|
+
from ._data_types import DataType
|
|
10
|
+
from ._indexes import Index
|
|
11
|
+
from ._references import ContainerReference
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ContainerPropertyDefinition(BaseModelObject):
|
|
15
|
+
immutable: bool | None = None
|
|
16
|
+
nullable: bool | None = None
|
|
17
|
+
auto_increment: bool | None = None
|
|
18
|
+
default_value: str | int | float | bool | dict[str, JsonValue] | None = None
|
|
19
|
+
description: str | None = None
|
|
20
|
+
name: str | None = None
|
|
21
|
+
type: DataType
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Container(BaseModelObject, ABC):
|
|
25
|
+
space: str
|
|
26
|
+
external_id: str
|
|
27
|
+
name: str | None = None
|
|
28
|
+
description: str | None = None
|
|
29
|
+
used_for: Literal["node", "edge", "all"] | None = None
|
|
30
|
+
properties: dict[str, ContainerPropertyDefinition]
|
|
31
|
+
constraints: dict[str, Constraint] | None = None
|
|
32
|
+
indexes: dict[str, Index] | None = None
|
|
33
|
+
|
|
34
|
+
def as_id(self) -> ContainerReference:
|
|
35
|
+
return ContainerReference(
|
|
36
|
+
space=self.space,
|
|
37
|
+
external_id=self.external_id,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ContainerRequest(Container, RequestResource): ...
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ContainerResponse(Container, ResponseResource[ContainerRequest]):
|
|
45
|
+
created_time: int
|
|
46
|
+
last_updated_time: int
|
|
47
|
+
is_global: bool
|
|
48
|
+
|
|
49
|
+
def as_request_resource(self) -> "ContainerRequest":
|
|
50
|
+
return ContainerRequest.model_validate(self.model_dump(by_alias=True))
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic import field_serializer
|
|
5
|
+
from pydantic_core.core_schema import FieldSerializationInfo
|
|
6
|
+
|
|
7
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestResource, ResponseResource
|
|
8
|
+
|
|
9
|
+
from ._references import DataModelReference, ViewReference
|
|
10
|
+
from ._view import ViewResponse
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DataModel(BaseModelObject, ABC):
|
|
14
|
+
"""Cognite Data Model resource.
|
|
15
|
+
|
|
16
|
+
Data models group and structure views into reusable collections.
|
|
17
|
+
A data model contains a set of views where the node types can
|
|
18
|
+
refer to each other with direct relations and edges.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
space: str
|
|
22
|
+
external_id: str
|
|
23
|
+
version: str
|
|
24
|
+
description: str | None = None
|
|
25
|
+
|
|
26
|
+
def as_id(self) -> DataModelReference:
|
|
27
|
+
return DataModelReference(
|
|
28
|
+
space=self.space,
|
|
29
|
+
external_id=self.external_id,
|
|
30
|
+
version=self.version,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DataModelRequest(DataModel, RequestResource):
|
|
35
|
+
views: list[ViewReference] | None = None
|
|
36
|
+
|
|
37
|
+
@field_serializer("views", mode="plain")
|
|
38
|
+
@classmethod
|
|
39
|
+
def serialize_views(
|
|
40
|
+
cls, views: list[ViewReference] | None, info: FieldSerializationInfo
|
|
41
|
+
) -> list[dict[str, Any]] | None:
|
|
42
|
+
if views is None:
|
|
43
|
+
return None
|
|
44
|
+
return [{**view.model_dump(**vars(info)), "type": "view"} for view in views]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class DataModelResponse(DataModel, ResponseResource[DataModelRequest]):
|
|
48
|
+
views: list[ViewReference] | None = None
|
|
49
|
+
created_time: int
|
|
50
|
+
last_updated_time: int
|
|
51
|
+
is_global: bool
|
|
52
|
+
|
|
53
|
+
def as_request_resource(self) -> DataModelRequest:
|
|
54
|
+
return DataModelRequest.model_validate(self.model_dump(by_alias=True), extra="ignore")
|
|
55
|
+
|
|
56
|
+
@field_serializer("views", mode="plain")
|
|
57
|
+
@classmethod
|
|
58
|
+
def serialize_views(
|
|
59
|
+
cls, views: list[ViewReference] | None, info: FieldSerializationInfo
|
|
60
|
+
) -> list[dict[str, Any]] | None:
|
|
61
|
+
if views is None:
|
|
62
|
+
return None
|
|
63
|
+
return [{**view.model_dump(**vars(info)), "type": "view"} for view in views]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class DataModelResponseWithViews(DataModel, ResponseResource[DataModelRequest]):
|
|
67
|
+
views: list[ViewResponse] | None = None
|
|
68
|
+
created_time: int
|
|
69
|
+
last_updated_time: int
|
|
70
|
+
is_global: bool
|
|
71
|
+
|
|
72
|
+
def as_request_resource(self) -> DataModelRequest:
|
|
73
|
+
return DataModelRequest.model_validate(self.model_dump(by_alias=True), extra="ignore")
|