cognite-toolkit 0.7.42__py3-none-any.whl → 0.7.43__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 +1 -1
- cognite_toolkit/_cdf_tk/client/api/events.py +20 -2
- cognite_toolkit/_cdf_tk/client/api/timeseries.py +20 -2
- cognite_toolkit/_cdf_tk/client/data_classes/agent.py +6 -9
- cognite_toolkit/_cdf_tk/client/data_classes/asset.py +7 -14
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +2 -2
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/__init__.py +148 -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/_references.py +78 -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/event.py +12 -15
- cognite_toolkit/_cdf_tk/client/data_classes/filemetadata.py +8 -18
- 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/testing.py +1 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +7 -5
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +4 -4
- 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/relationship.py +2 -2
- 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 +54 -46
- 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.43.dist-info}/METADATA +1 -1
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.43.dist-info}/RECORD +39 -27
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.43.dist-info}/WHEEL +0 -0
- {cognite_toolkit-0.7.42.dist-info → cognite_toolkit-0.7.43.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.identifiers import Identifier
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SpaceReference(Identifier):
|
|
9
|
+
space: str
|
|
10
|
+
|
|
11
|
+
def __str__(self) -> str:
|
|
12
|
+
return self.space
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ContainerReference(Identifier):
|
|
16
|
+
type: Literal["container"] = Field("container", exclude=True)
|
|
17
|
+
space: str
|
|
18
|
+
external_id: str
|
|
19
|
+
|
|
20
|
+
def __str__(self) -> str:
|
|
21
|
+
return f"{self.space}:{self.external_id}"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ViewReference(Identifier):
|
|
25
|
+
type: Literal["view"] = Field("view", exclude=True)
|
|
26
|
+
space: str
|
|
27
|
+
external_id: str
|
|
28
|
+
version: str
|
|
29
|
+
|
|
30
|
+
def __str__(self) -> str:
|
|
31
|
+
return f"{self.space}:{self.external_id}(version={self.version})"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DataModelReference(Identifier):
|
|
35
|
+
space: str
|
|
36
|
+
external_id: str
|
|
37
|
+
version: str
|
|
38
|
+
|
|
39
|
+
def __str__(self) -> str:
|
|
40
|
+
return f"{self.space}:{self.external_id}(version={self.version})"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class NodeReference(Identifier):
|
|
44
|
+
space: str
|
|
45
|
+
external_id: str
|
|
46
|
+
|
|
47
|
+
def __str__(self) -> str:
|
|
48
|
+
return f"{self.space}:{self.external_id}"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ContainerDirectReference(Identifier):
|
|
52
|
+
source: ContainerReference
|
|
53
|
+
identifier: str
|
|
54
|
+
|
|
55
|
+
def __str__(self) -> str:
|
|
56
|
+
return f"{self.source!s}.{self.identifier}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ViewDirectReference(Identifier):
|
|
60
|
+
source: ViewReference
|
|
61
|
+
identifier: str
|
|
62
|
+
|
|
63
|
+
def __str__(self) -> str:
|
|
64
|
+
return f"{self.source!s}.{self.identifier}"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class ContainerIndexReference(ContainerReference):
|
|
68
|
+
identifier: str
|
|
69
|
+
|
|
70
|
+
def __str__(self) -> str:
|
|
71
|
+
return f"{self.space}:{self.external_id}(index={self.identifier})"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ContainerConstraintReference(ContainerReference):
|
|
75
|
+
identifier: str
|
|
76
|
+
|
|
77
|
+
def __str__(self) -> str:
|
|
78
|
+
return f"{self.space}:{self.external_id}(constraint={self.identifier})"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestResource, ResponseResource
|
|
4
|
+
|
|
5
|
+
from ._references import SpaceReference
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Space(BaseModelObject, ABC):
|
|
9
|
+
space: str
|
|
10
|
+
name: str | None = None
|
|
11
|
+
description: str | None = None
|
|
12
|
+
|
|
13
|
+
def as_id(self) -> SpaceReference:
|
|
14
|
+
return SpaceReference(space=self.space)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SpaceRequest(Space, RequestResource): ...
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SpaceResponse(Space, ResponseResource[SpaceRequest]):
|
|
21
|
+
created_time: int
|
|
22
|
+
last_updated_time: int
|
|
23
|
+
is_global: bool
|
|
24
|
+
|
|
25
|
+
def as_request_resource(self) -> SpaceRequest:
|
|
26
|
+
return SpaceRequest.model_validate(self.model_dump(by_alias=True), extra="ignore")
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Any, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import Field, JsonValue, field_serializer, model_validator
|
|
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 ._data_types import DirectNodeRelation
|
|
10
|
+
from ._references import ContainerReference, ViewReference
|
|
11
|
+
from ._view_property import (
|
|
12
|
+
MultiReverseDirectRelationPropertyResponse,
|
|
13
|
+
SingleReverseDirectRelationPropertyResponse,
|
|
14
|
+
ViewCorePropertyRequest,
|
|
15
|
+
ViewCorePropertyResponse,
|
|
16
|
+
ViewRequestProperty,
|
|
17
|
+
ViewResponseProperty,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class View(BaseModelObject, ABC):
|
|
22
|
+
space: str
|
|
23
|
+
external_id: str
|
|
24
|
+
version: str
|
|
25
|
+
name: str | None = None
|
|
26
|
+
description: str | None = None
|
|
27
|
+
filter: JsonValue | None
|
|
28
|
+
implements: list[ViewReference] | None = None
|
|
29
|
+
|
|
30
|
+
def as_id(self) -> ViewReference:
|
|
31
|
+
return ViewReference(space=self.space, external_id=self.external_id, version=self.version)
|
|
32
|
+
|
|
33
|
+
@model_validator(mode="before")
|
|
34
|
+
def set_connection_type_on_primary_properties(cls, data: dict[str, Any]) -> dict[str, Any]:
|
|
35
|
+
if "properties" not in data:
|
|
36
|
+
return data
|
|
37
|
+
properties = data["properties"]
|
|
38
|
+
if not isinstance(properties, dict):
|
|
39
|
+
return data
|
|
40
|
+
# We assume all properties without connectionType are core properties.
|
|
41
|
+
# The reason we set connectionType is to make it easy for pydantic to discriminate the union.
|
|
42
|
+
# This also leads to better error messages, as if there is a union and pydantic does not know which
|
|
43
|
+
# type to pick it will give errors from all type in the union.
|
|
44
|
+
new_properties: dict[str, Any] = {}
|
|
45
|
+
for prop_id, prop in properties.items():
|
|
46
|
+
if isinstance(prop, dict) and "connectionType" not in prop:
|
|
47
|
+
prop_copy = prop.copy()
|
|
48
|
+
prop_copy["connectionType"] = "primary_property"
|
|
49
|
+
new_properties[prop_id] = prop_copy
|
|
50
|
+
else:
|
|
51
|
+
new_properties[prop_id] = prop
|
|
52
|
+
if new_properties:
|
|
53
|
+
new_data = data.copy()
|
|
54
|
+
new_data["properties"] = new_properties
|
|
55
|
+
return new_data
|
|
56
|
+
|
|
57
|
+
return data
|
|
58
|
+
|
|
59
|
+
@field_serializer("implements", mode="plain")
|
|
60
|
+
@classmethod
|
|
61
|
+
def serialize_implements(
|
|
62
|
+
cls, implements: list[ViewReference] | None, info: FieldSerializationInfo
|
|
63
|
+
) -> list[dict[str, Any]] | None:
|
|
64
|
+
if implements is None:
|
|
65
|
+
return None
|
|
66
|
+
output: list[dict[str, Any]] = []
|
|
67
|
+
for view in implements:
|
|
68
|
+
dumped = view.model_dump(**vars(info))
|
|
69
|
+
dumped["type"] = "view"
|
|
70
|
+
output.append(dumped)
|
|
71
|
+
return output
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ViewRequest(View, RequestResource):
|
|
75
|
+
properties: dict[str, ViewRequestProperty] = Field(
|
|
76
|
+
description="View with included properties and expected edges, indexed by a unique space-local identifier."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def used_containers(self) -> set[ContainerReference]:
|
|
81
|
+
"""Get all containers referenced by this view."""
|
|
82
|
+
return {prop.container for prop in self.properties.values() if isinstance(prop, ViewCorePropertyRequest)}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ViewResponse(View, ResponseResource[ViewRequest]):
|
|
86
|
+
properties: dict[str, ViewResponseProperty]
|
|
87
|
+
|
|
88
|
+
created_time: int
|
|
89
|
+
last_updated_time: int
|
|
90
|
+
writable: bool
|
|
91
|
+
queryable: bool
|
|
92
|
+
used_for: Literal["node", "edge", "all"]
|
|
93
|
+
is_global: bool
|
|
94
|
+
mapped_containers: list[ContainerReference]
|
|
95
|
+
|
|
96
|
+
def as_request_resource(self) -> ViewRequest:
|
|
97
|
+
dumped = self.model_dump(by_alias=True, exclude={"properties"})
|
|
98
|
+
properties: dict[str, Any] = {}
|
|
99
|
+
for key, value in self.properties.items():
|
|
100
|
+
if isinstance(value, ViewCorePropertyResponse) and isinstance(value.type, DirectNodeRelation):
|
|
101
|
+
# Special case. In the request the source of DirectNodeRelation is set on the Property object,
|
|
102
|
+
# while in the response it is set on the DirectNodeRelation object.
|
|
103
|
+
request_object = value.as_request().model_dump(by_alias=True)
|
|
104
|
+
request_object["source"] = value.type.source.model_dump(by_alias=True) if value.type.source else None
|
|
105
|
+
properties[key] = request_object
|
|
106
|
+
elif isinstance(
|
|
107
|
+
value,
|
|
108
|
+
ViewCorePropertyResponse
|
|
109
|
+
| SingleReverseDirectRelationPropertyResponse
|
|
110
|
+
| MultiReverseDirectRelationPropertyResponse,
|
|
111
|
+
):
|
|
112
|
+
properties[key] = value.as_request().model_dump(by_alias=True)
|
|
113
|
+
else:
|
|
114
|
+
properties[key] = value.model_dump(by_alias=True)
|
|
115
|
+
|
|
116
|
+
dumped["properties"] = properties
|
|
117
|
+
return ViewRequest.model_validate(dumped, extra="ignore")
|
|
118
|
+
|
|
119
|
+
@field_serializer("mapped_containers", mode="plain")
|
|
120
|
+
@classmethod
|
|
121
|
+
def serialize_mapped_containers(
|
|
122
|
+
cls, mapped_containers: list[ContainerReference], info: FieldSerializationInfo
|
|
123
|
+
) -> list[dict[str, Any]]:
|
|
124
|
+
return [container.model_dump(**vars(info)) | {"type": "container"} for container in mapped_containers]
|
|
125
|
+
|
|
126
|
+
@field_serializer("properties", mode="plain")
|
|
127
|
+
@classmethod
|
|
128
|
+
def serialize_properties_special_handling_direct_relation_with_source(
|
|
129
|
+
cls, properties: dict[str, ViewResponseProperty], info: FieldSerializationInfo
|
|
130
|
+
) -> dict[str, dict[str, Any]]:
|
|
131
|
+
output: dict[str, dict[str, Any]] = {}
|
|
132
|
+
for prop_id, prop in properties.items():
|
|
133
|
+
output[prop_id] = prop.model_dump(**vars(info))
|
|
134
|
+
if (
|
|
135
|
+
isinstance(prop, ViewCorePropertyResponse)
|
|
136
|
+
and isinstance(prop.type, DirectNodeRelation)
|
|
137
|
+
and prop.type.source
|
|
138
|
+
):
|
|
139
|
+
# We manually include the source as this is excluded by default. The reason why this is excluded
|
|
140
|
+
# is that the DirectNodeRelation is used for both request and response, and in the request the source
|
|
141
|
+
# does not exist on the DirectNodeRelation, but on the Property object.
|
|
142
|
+
output[prop_id]["type"]["source"] = prop.type.source.model_dump(**vars(info)) | {"type": "view"}
|
|
143
|
+
return output
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Annotated, Any, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import Field, JsonValue, 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 ._data_types import DataType
|
|
10
|
+
from ._references import ContainerDirectReference, ContainerReference, NodeReference, ViewDirectReference, ViewReference
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ViewPropertyDefinition(BaseModelObject, ABC):
|
|
14
|
+
connection_type: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ViewCoreProperty(ViewPropertyDefinition, ABC):
|
|
18
|
+
# Core properties do not have connection type in the API, but we add it here such that
|
|
19
|
+
# we can use it as a discriminator in unions. The exclude=True ensures that it is not
|
|
20
|
+
# sent to the API.
|
|
21
|
+
connection_type: Literal["primary_property"] = Field(default="primary_property", exclude=True)
|
|
22
|
+
name: str | None = None
|
|
23
|
+
description: str | None = None
|
|
24
|
+
container: ContainerReference
|
|
25
|
+
container_property_identifier: str
|
|
26
|
+
|
|
27
|
+
@field_serializer("container", mode="plain")
|
|
28
|
+
@classmethod
|
|
29
|
+
def serialize_container(cls, container: ContainerReference, info: FieldSerializationInfo) -> dict[str, Any]:
|
|
30
|
+
return {**container.model_dump(**vars(info)), "type": "container"}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ViewCorePropertyRequest(ViewCoreProperty):
|
|
34
|
+
source: ViewReference | None = None
|
|
35
|
+
|
|
36
|
+
@field_serializer("source", mode="plain")
|
|
37
|
+
@classmethod
|
|
38
|
+
def serialize_source(cls, source: ViewReference | None, info: FieldSerializationInfo) -> dict[str, Any] | None:
|
|
39
|
+
if source is None:
|
|
40
|
+
return None
|
|
41
|
+
return {**source.model_dump(**vars(info)), "type": "view"}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ConstraintOrIndexState(BaseModelObject):
|
|
45
|
+
nullability: Literal["current", "pending", "failed"] | None = None
|
|
46
|
+
max_list_size: Literal["current", "pending", "failed"] | None = None
|
|
47
|
+
max_text_size: Literal["current", "pending", "failed"] | None = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ViewCorePropertyResponse(ViewCoreProperty):
|
|
51
|
+
immutable: bool | None = None
|
|
52
|
+
nullable: bool | None = None
|
|
53
|
+
auto_increment: bool | None = None
|
|
54
|
+
default_value: str | int | bool | dict[str, JsonValue] | None = None
|
|
55
|
+
constraint_state: ConstraintOrIndexState
|
|
56
|
+
type: DataType
|
|
57
|
+
|
|
58
|
+
def as_request(self) -> ViewCorePropertyRequest:
|
|
59
|
+
return ViewCorePropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ConnectionPropertyDefinition(ViewPropertyDefinition, ABC):
|
|
63
|
+
name: str | None = None
|
|
64
|
+
description: str | None = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class EdgeProperty(ConnectionPropertyDefinition, ABC):
|
|
68
|
+
source: ViewReference
|
|
69
|
+
type: NodeReference
|
|
70
|
+
edge_source: ViewReference | None = None
|
|
71
|
+
direction: Literal["outwards", "inwards"] = "outwards"
|
|
72
|
+
|
|
73
|
+
@field_serializer("source", "edge_source", mode="plain")
|
|
74
|
+
@classmethod
|
|
75
|
+
def serialize_source(cls, source: ViewReference | None, info: FieldSerializationInfo) -> dict[str, Any] | None:
|
|
76
|
+
if source is None:
|
|
77
|
+
return None
|
|
78
|
+
return {**source.model_dump(**vars(info)), "type": "view"}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SingleEdgeProperty(EdgeProperty):
|
|
82
|
+
connection_type: Literal["single_edge_connection"] = "single_edge_connection"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class MultiEdgeProperty(EdgeProperty):
|
|
86
|
+
connection_type: Literal["multi_edge_connection"] = "multi_edge_connection"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ReverseDirectRelationProperty(ConnectionPropertyDefinition, ABC):
|
|
90
|
+
source: ViewReference
|
|
91
|
+
through: ContainerDirectReference | ViewDirectReference
|
|
92
|
+
|
|
93
|
+
@field_serializer("source", mode="plain")
|
|
94
|
+
@classmethod
|
|
95
|
+
def serialize_source(cls, source: ViewReference, info: FieldSerializationInfo) -> dict[str, Any]:
|
|
96
|
+
return {**source.model_dump(**vars(info)), "type": "view"}
|
|
97
|
+
|
|
98
|
+
@field_serializer("through", mode="plain")
|
|
99
|
+
@classmethod
|
|
100
|
+
def serialize_through(
|
|
101
|
+
cls, through: ContainerDirectReference | ViewDirectReference, info: FieldSerializationInfo
|
|
102
|
+
) -> dict[str, Any]:
|
|
103
|
+
output = through.model_dump(**vars(info))
|
|
104
|
+
if isinstance(through, ContainerDirectReference):
|
|
105
|
+
output["source"]["type"] = "container"
|
|
106
|
+
else:
|
|
107
|
+
output["source"]["type"] = "view"
|
|
108
|
+
return output
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class SingleReverseDirectRelationPropertyRequest(ReverseDirectRelationProperty):
|
|
112
|
+
connection_type: Literal["single_reverse_direct_relation"] = "single_reverse_direct_relation"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class MultiReverseDirectRelationPropertyRequest(ReverseDirectRelationProperty):
|
|
116
|
+
connection_type: Literal["multi_reverse_direct_relation"] = "multi_reverse_direct_relation"
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class SingleReverseDirectRelationPropertyResponse(ReverseDirectRelationProperty):
|
|
120
|
+
connection_type: Literal["single_reverse_direct_relation"] = "single_reverse_direct_relation"
|
|
121
|
+
targets_list: bool
|
|
122
|
+
|
|
123
|
+
def as_request(self) -> SingleReverseDirectRelationPropertyRequest:
|
|
124
|
+
return SingleReverseDirectRelationPropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class MultiReverseDirectRelationPropertyResponse(ReverseDirectRelationProperty):
|
|
128
|
+
connection_type: Literal["multi_reverse_direct_relation"] = "multi_reverse_direct_relation"
|
|
129
|
+
targets_list: bool
|
|
130
|
+
|
|
131
|
+
def as_request(self) -> MultiReverseDirectRelationPropertyRequest:
|
|
132
|
+
return MultiReverseDirectRelationPropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
ViewRequestProperty = Annotated[
|
|
136
|
+
SingleEdgeProperty
|
|
137
|
+
| MultiEdgeProperty
|
|
138
|
+
| SingleReverseDirectRelationPropertyRequest
|
|
139
|
+
| MultiReverseDirectRelationPropertyRequest
|
|
140
|
+
| ViewCorePropertyRequest,
|
|
141
|
+
Field(discriminator="connection_type"),
|
|
142
|
+
]
|
|
143
|
+
ViewResponseProperty = Annotated[
|
|
144
|
+
SingleEdgeProperty
|
|
145
|
+
| MultiEdgeProperty
|
|
146
|
+
| SingleReverseDirectRelationPropertyResponse
|
|
147
|
+
| MultiReverseDirectRelationPropertyResponse
|
|
148
|
+
| ViewCorePropertyResponse,
|
|
149
|
+
Field(discriminator="connection_type"),
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
ViewRequestPropertyAdapter: TypeAdapter[ViewRequestProperty] = TypeAdapter(ViewRequestProperty)
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
from typing import ClassVar
|
|
2
2
|
|
|
3
|
-
from cognite_toolkit._cdf_tk.client.data_classes.base import
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
4
|
+
BaseModelObject,
|
|
5
|
+
RequestUpdateable,
|
|
6
|
+
ResponseResource,
|
|
7
|
+
)
|
|
4
8
|
|
|
5
9
|
from .identifiers import ExternalId, InternalOrExternalId
|
|
6
10
|
|
|
7
11
|
|
|
8
|
-
class
|
|
9
|
-
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "asset_ids"})
|
|
12
|
+
class Event(BaseModelObject):
|
|
10
13
|
external_id: str | None = None
|
|
11
14
|
data_set_id: int | None = None
|
|
12
15
|
start_time: int | None = None
|
|
@@ -24,20 +27,14 @@ class EventRequest(RequestUpdateable):
|
|
|
24
27
|
return ExternalId(external_id=self.external_id)
|
|
25
28
|
|
|
26
29
|
|
|
27
|
-
class
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
type: str | None = None
|
|
33
|
-
subtype: str | None = None
|
|
34
|
-
description: str | None = None
|
|
35
|
-
metadata: dict[str, str] | None = None
|
|
36
|
-
asset_ids: list[int] | None = None
|
|
37
|
-
source: str | None = None
|
|
30
|
+
class EventRequest(Event, RequestUpdateable):
|
|
31
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "asset_ids"})
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class EventResponse(Event, ResponseResource[EventRequest]):
|
|
38
35
|
id: int
|
|
39
36
|
created_time: int
|
|
40
37
|
last_updated_time: int
|
|
41
38
|
|
|
42
39
|
def as_request_resource(self) -> EventRequest:
|
|
43
|
-
return EventRequest.model_validate(self.dump())
|
|
40
|
+
return EventRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -2,15 +2,13 @@ from typing import ClassVar, Literal
|
|
|
2
2
|
|
|
3
3
|
from pydantic import JsonValue
|
|
4
4
|
|
|
5
|
-
from cognite_toolkit._cdf_tk.client.data_classes.base import RequestUpdateable, ResponseResource
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestUpdateable, ResponseResource
|
|
6
6
|
|
|
7
7
|
from .identifiers import ExternalId
|
|
8
8
|
from .instance_api import NodeReference
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class
|
|
12
|
-
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "labels", "asset_ids", "security_categories"})
|
|
13
|
-
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"asset_ids", "security_categories"})
|
|
11
|
+
class FileMetadata(BaseModelObject):
|
|
14
12
|
external_id: str | None = None
|
|
15
13
|
name: str
|
|
16
14
|
directory: str | None = None
|
|
@@ -31,26 +29,18 @@ class FileMetadataRequest(RequestUpdateable):
|
|
|
31
29
|
return ExternalId(external_id=self.external_id)
|
|
32
30
|
|
|
33
31
|
|
|
34
|
-
class
|
|
32
|
+
class FileMetadataRequest(FileMetadata, RequestUpdateable):
|
|
33
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "labels", "asset_ids", "security_categories"})
|
|
34
|
+
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"asset_ids", "security_categories"})
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class FileMetadataResponse(FileMetadata, ResponseResource[FileMetadataRequest]):
|
|
35
38
|
created_time: int
|
|
36
39
|
last_updated_time: int
|
|
37
40
|
uploaded_time: int | None = None
|
|
38
41
|
uploaded: bool
|
|
39
42
|
id: int
|
|
40
|
-
external_id: str | None = None
|
|
41
|
-
name: str
|
|
42
|
-
directory: str | None = None
|
|
43
43
|
instance_id: NodeReference | None = None
|
|
44
|
-
source: str | None = None
|
|
45
|
-
mime_type: str | None = None
|
|
46
|
-
metadata: dict[str, str] | None = None
|
|
47
|
-
asset_ids: list[int] | None = None
|
|
48
|
-
data_set_id: int | None = None
|
|
49
|
-
labels: list[dict[Literal["externalId"], str]] | None = None
|
|
50
|
-
geo_location: JsonValue | None = None
|
|
51
|
-
source_created_time: int | None = None
|
|
52
|
-
source_modified_time: int | None = None
|
|
53
|
-
security_categories: list[int] | None = None
|
|
54
44
|
|
|
55
45
|
def as_request_resource(self) -> FileMetadataRequest:
|
|
56
46
|
return FileMetadataRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Any, Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import RequestUpdateable, ResponseResource
|
|
6
|
+
|
|
7
|
+
from .identifiers import ExternalId
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SimulatorModelRequest(RequestUpdateable):
|
|
11
|
+
# The 'id' field is not part of the request when creating a new resource,
|
|
12
|
+
# but is needed when updating an existing resource.
|
|
13
|
+
id: int | None = Field(default=None, exclude=True)
|
|
14
|
+
external_id: str
|
|
15
|
+
simulator_external_id: str
|
|
16
|
+
name: str
|
|
17
|
+
description: str | None = None
|
|
18
|
+
data_set_id: int
|
|
19
|
+
type: str
|
|
20
|
+
|
|
21
|
+
def as_id(self) -> ExternalId:
|
|
22
|
+
return ExternalId(external_id=self.external_id)
|
|
23
|
+
|
|
24
|
+
def as_update(self, mode: Literal["patch", "replace"]) -> dict[str, Any]:
|
|
25
|
+
if self.id is None:
|
|
26
|
+
raise ValueError("id must be provided to create an update dictionary")
|
|
27
|
+
return {
|
|
28
|
+
"id": self.id,
|
|
29
|
+
"update": {
|
|
30
|
+
"name": {"set": self.name},
|
|
31
|
+
**{"description": {"set": self.description} if self.description is not None else {}},
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SimulatorModelResponse(ResponseResource[SimulatorModelRequest]):
|
|
37
|
+
id: int
|
|
38
|
+
external_id: str
|
|
39
|
+
simulator_external_id: str
|
|
40
|
+
name: str
|
|
41
|
+
description: str | None = None
|
|
42
|
+
data_set_id: int
|
|
43
|
+
type: str | None = None
|
|
44
|
+
created_time: int
|
|
45
|
+
last_updated_time: int
|
|
46
|
+
|
|
47
|
+
def as_request_resource(self) -> SimulatorModelRequest:
|
|
48
|
+
if self.type is None:
|
|
49
|
+
raise ValueError("Cannot convert SimulatorModelResponse to SimulatorModelRequest when type is None")
|
|
50
|
+
return SimulatorModelRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
from typing import Any, ClassVar, Literal
|
|
2
2
|
|
|
3
|
-
from cognite_toolkit._cdf_tk.client.data_classes.base import
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
4
|
+
BaseModelObject,
|
|
5
|
+
RequestUpdateable,
|
|
6
|
+
ResponseResource,
|
|
7
|
+
)
|
|
4
8
|
|
|
5
9
|
from .identifiers import ExternalId, InternalOrExternalId
|
|
6
10
|
from .instance_api import NodeReference
|
|
7
11
|
|
|
8
12
|
|
|
9
|
-
class
|
|
10
|
-
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "security_categories"})
|
|
11
|
-
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"is_step"})
|
|
13
|
+
class TimeSeries(BaseModelObject):
|
|
12
14
|
external_id: str | None = None
|
|
13
15
|
name: str | None = None
|
|
14
16
|
is_string: bool = False
|
|
@@ -26,30 +28,25 @@ class TimeSeriesRequest(RequestUpdateable):
|
|
|
26
28
|
raise ValueError("Cannot convert TimeSeriesRequest to ExternalId when external_id is None")
|
|
27
29
|
return ExternalId(external_id=self.external_id)
|
|
28
30
|
|
|
31
|
+
|
|
32
|
+
class TimeSeriesRequest(TimeSeries, RequestUpdateable):
|
|
33
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "security_categories"})
|
|
34
|
+
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"is_step"})
|
|
35
|
+
|
|
29
36
|
def as_update(self, mode: Literal["patch", "replace"]) -> dict[str, Any]:
|
|
30
37
|
dumped = super().as_update(mode)
|
|
38
|
+
update = dumped["update"] if "update" in dumped else dumped
|
|
31
39
|
# isString is immutable in CDF, so we remove it from update payloads
|
|
32
|
-
|
|
40
|
+
update.pop("isString", None)
|
|
33
41
|
return dumped
|
|
34
42
|
|
|
35
43
|
|
|
36
|
-
class TimeSeriesResponse(ResponseResource[TimeSeriesRequest]):
|
|
44
|
+
class TimeSeriesResponse(TimeSeries, ResponseResource[TimeSeriesRequest]):
|
|
37
45
|
id: int
|
|
38
46
|
instance_id: NodeReference | None = None
|
|
39
|
-
external_id: str | None = None
|
|
40
|
-
name: str | None = None
|
|
41
|
-
is_string: bool
|
|
42
|
-
metadata: dict[str, str] | None = None
|
|
43
|
-
unit: str | None = None
|
|
44
47
|
type: str
|
|
45
|
-
unit_external_id: str | None = None
|
|
46
|
-
asset_id: int | None = None
|
|
47
|
-
is_step: bool
|
|
48
|
-
description: str | None = None
|
|
49
|
-
security_categories: list[int] | None = None
|
|
50
|
-
data_set_id: int | None = None
|
|
51
48
|
created_time: int
|
|
52
49
|
last_updated_time: int
|
|
53
50
|
|
|
54
51
|
def as_request_resource(self) -> TimeSeriesRequest:
|
|
55
|
-
return TimeSeriesRequest.model_validate(self.dump())
|
|
52
|
+
return TimeSeriesRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -142,7 +142,7 @@ class ToolkitClientMock(CogniteClientMock):
|
|
|
142
142
|
self.tool.three_d = MagicMock(spec=ThreeDAPI)
|
|
143
143
|
self.tool.three_d.models = MagicMock(spec_set=ThreeDModelAPI)
|
|
144
144
|
self.tool.assets = MagicMock(spec_set=AssetsAPI)
|
|
145
|
-
self.tool.
|
|
145
|
+
self.tool.timeseries = MagicMock(spec_set=TimeSeriesAPI)
|
|
146
146
|
self.tool.events = MagicMock(spec_set=EventsAPI)
|
|
147
147
|
|
|
148
148
|
self.streams = MagicMock(spec=StreamsAPI)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from collections.abc import Iterable, Mapping, Set
|
|
2
2
|
from typing import Any, ClassVar, cast
|
|
3
3
|
|
|
4
|
-
from cognite.client.data_classes import Annotation,
|
|
4
|
+
from cognite.client.data_classes import Annotation, FileMetadata
|
|
5
5
|
from cognite.client.data_classes.data_modeling import (
|
|
6
6
|
DirectRelation,
|
|
7
7
|
DirectRelationReference,
|
|
@@ -17,10 +17,12 @@ from cognite.client.utils._identifier import InstanceId
|
|
|
17
17
|
|
|
18
18
|
from cognite_toolkit._cdf_tk.client import ToolkitClient
|
|
19
19
|
from cognite_toolkit._cdf_tk.client.data_classes.asset import AssetResponse
|
|
20
|
+
from cognite_toolkit._cdf_tk.client.data_classes.event import EventResponse
|
|
20
21
|
from cognite_toolkit._cdf_tk.client.data_classes.legacy.migration import (
|
|
21
22
|
AssetCentricId,
|
|
22
23
|
ResourceViewMappingApply,
|
|
23
24
|
)
|
|
25
|
+
from cognite_toolkit._cdf_tk.client.data_classes.timeseries import TimeSeriesResponse
|
|
24
26
|
from cognite_toolkit._cdf_tk.utils.collection import flatten_dict_json_path
|
|
25
27
|
from cognite_toolkit._cdf_tk.utils.dtype_conversion import (
|
|
26
28
|
asset_centric_convert_to_primary_property,
|
|
@@ -120,12 +122,12 @@ class DirectRelationCache:
|
|
|
120
122
|
source_ids.add(resource.source)
|
|
121
123
|
if resource.asset_ids:
|
|
122
124
|
asset_ids.update(resource.asset_ids)
|
|
123
|
-
elif isinstance(resource,
|
|
125
|
+
elif isinstance(resource, EventResponse):
|
|
124
126
|
if resource.source:
|
|
125
127
|
source_ids.add(resource.source)
|
|
126
128
|
if resource.asset_ids:
|
|
127
129
|
asset_ids.update(resource.asset_ids)
|
|
128
|
-
elif isinstance(resource,
|
|
130
|
+
elif isinstance(resource, TimeSeriesResponse):
|
|
129
131
|
if resource.asset_id is not None:
|
|
130
132
|
asset_ids.add(resource.asset_id)
|
|
131
133
|
if asset_ids:
|
|
@@ -248,9 +250,9 @@ def _lookup_resource_type(resource_type: AssetCentricResourceExtended) -> AssetC
|
|
|
248
250
|
return "asset"
|
|
249
251
|
elif isinstance(resource_type, FileMetadata):
|
|
250
252
|
return "file"
|
|
251
|
-
elif isinstance(resource_type,
|
|
253
|
+
elif isinstance(resource_type, EventResponse):
|
|
252
254
|
return "event"
|
|
253
|
-
elif isinstance(resource_type,
|
|
255
|
+
elif isinstance(resource_type, TimeSeriesResponse):
|
|
254
256
|
return "timeseries"
|
|
255
257
|
elif isinstance(resource_type, Annotation):
|
|
256
258
|
if resource_type.annotated_resource_type == "file" and resource_type.annotation_type in (
|