cognite-toolkit 0.7.70__py3-none-any.whl → 0.7.71__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/_resource_base.py +0 -22
- cognite_toolkit/_cdf_tk/client/api/infield.py +56 -204
- cognite_toolkit/_cdf_tk/client/api/instances.py +239 -16
- cognite_toolkit/_cdf_tk/client/cdf_client/responses.py +3 -3
- cognite_toolkit/_cdf_tk/client/resource_classes/infield.py +133 -72
- cognite_toolkit/_cdf_tk/client/resource_classes/instance_api.py +119 -79
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +45 -46
- 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.70.dist-info → cognite_toolkit-0.7.71.dist-info}/METADATA +1 -1
- {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.71.dist-info}/RECORD +15 -15
- {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.71.dist-info}/WHEEL +0 -0
- {cognite_toolkit-0.7.70.dist-info → cognite_toolkit-0.7.71.dist-info}/entry_points.txt +0 -0
|
@@ -1,35 +1,38 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
from typing import Any, ClassVar, Literal
|
|
3
2
|
|
|
4
|
-
from pydantic import JsonValue,
|
|
5
|
-
from pydantic_core.core_schema import ValidationInfo
|
|
3
|
+
from pydantic import JsonValue, model_validator
|
|
6
4
|
|
|
7
|
-
from cognite_toolkit._cdf_tk.client._resource_base import
|
|
8
|
-
from cognite_toolkit._cdf_tk.protocols import (
|
|
9
|
-
ResourceRequestListProtocol,
|
|
10
|
-
ResourceResponseListProtocol,
|
|
11
|
-
)
|
|
5
|
+
from cognite_toolkit._cdf_tk.client._resource_base import BaseModelObject
|
|
12
6
|
from cognite_toolkit._cdf_tk.utils.text import sanitize_instance_external_id
|
|
13
7
|
|
|
14
|
-
from .instance_api import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
from .instance_api import (
|
|
9
|
+
TypedInstanceIdentifier,
|
|
10
|
+
TypedNodeIdentifier,
|
|
11
|
+
TypedViewReference,
|
|
12
|
+
WrappedInstanceListRequest,
|
|
13
|
+
WrappedInstanceListResponse,
|
|
14
|
+
WrappedInstanceRequest,
|
|
15
|
+
WrappedInstanceResponse,
|
|
16
|
+
move_properties,
|
|
17
|
+
)
|
|
20
18
|
|
|
21
|
-
INFIELD_LOCATION_CONFIG_VIEW_ID =
|
|
22
|
-
|
|
19
|
+
INFIELD_LOCATION_CONFIG_VIEW_ID = TypedViewReference(
|
|
20
|
+
space="cdf_infield", external_id="InFieldLocationConfig", version="v1"
|
|
21
|
+
)
|
|
22
|
+
INFIELD_CDM_LOCATION_CONFIG_VIEW_ID = TypedViewReference(
|
|
23
23
|
space="infield_cdm_source_desc_sche_asset_file_ts", external_id="InFieldCDMLocationConfig", version="v1"
|
|
24
24
|
)
|
|
25
|
-
DATA_EXPLORATION_CONFIG_VIEW_ID =
|
|
25
|
+
DATA_EXPLORATION_CONFIG_VIEW_ID = TypedViewReference(
|
|
26
|
+
space="cdf_infield", external_id="DataExplorationConfig", version="v1"
|
|
27
|
+
)
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
class DataExplorationConfig(
|
|
30
|
+
class DataExplorationConfig(BaseModelObject):
|
|
29
31
|
"""Data Exploration Configuration resource class."""
|
|
30
32
|
|
|
31
|
-
VIEW_ID: ClassVar[
|
|
32
|
-
|
|
33
|
+
VIEW_ID: ClassVar[TypedViewReference] = DATA_EXPLORATION_CONFIG_VIEW_ID
|
|
34
|
+
space: str | None = None
|
|
35
|
+
external_id: str | None = None
|
|
33
36
|
|
|
34
37
|
observations: dict[str, JsonValue] | None = None
|
|
35
38
|
activities: dict[str, JsonValue] | None = None
|
|
@@ -37,19 +40,19 @@ class DataExplorationConfig(InstanceRequestResource):
|
|
|
37
40
|
notifications: dict[str, JsonValue] | None = None
|
|
38
41
|
assets: dict[str, JsonValue] | None = None
|
|
39
42
|
|
|
43
|
+
@model_validator(mode="before")
|
|
44
|
+
@classmethod
|
|
45
|
+
def move_properties(cls, data: dict[str, Any]) -> dict[str, Any]:
|
|
46
|
+
return move_properties(data, cls.VIEW_ID)
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
InstanceRequestResource,
|
|
44
|
-
):
|
|
48
|
+
|
|
49
|
+
class InFieldLocationConfig(BaseModelObject):
|
|
45
50
|
"""Infield Location Configuration resource class.
|
|
46
51
|
|
|
47
52
|
This class is used for both the response and request resource for Infield Location Configuration nodes.
|
|
48
53
|
"""
|
|
49
54
|
|
|
50
|
-
VIEW_ID: ClassVar[
|
|
51
|
-
instance_type: Literal["node"] = "node"
|
|
52
|
-
|
|
55
|
+
VIEW_ID: ClassVar[TypedViewReference] = INFIELD_LOCATION_CONFIG_VIEW_ID
|
|
53
56
|
root_location_external_id: str | None = None
|
|
54
57
|
feature_toggles: dict[str, JsonValue] | None = None
|
|
55
58
|
app_instance_space: str | None = None
|
|
@@ -57,48 +60,94 @@ class InfieldLocationConfig(
|
|
|
57
60
|
data_filters: dict[str, JsonValue] | None = None
|
|
58
61
|
data_exploration_config: DataExplorationConfig | None = None
|
|
59
62
|
|
|
60
|
-
def as_request_resource(self) -> "InfieldLocationConfig":
|
|
61
|
-
return self
|
|
62
|
-
|
|
63
|
-
def as_write(self) -> Self:
|
|
64
|
-
return self
|
|
65
|
-
|
|
66
|
-
@field_validator("data_exploration_config", mode="before")
|
|
67
|
-
@classmethod
|
|
68
|
-
def generate_identifier_if_missing(cls, value: Any, info: ValidationInfo) -> Any:
|
|
69
|
-
"""We do not require the user to specify the space and externalId for the data exploration config."""
|
|
70
|
-
if isinstance(value, dict):
|
|
71
|
-
if value.get("space") is None:
|
|
72
|
-
value["space"] = info.data["space"]
|
|
73
|
-
if value.get("externalId") is None:
|
|
74
|
-
external_id = info.data["external_id"]
|
|
75
|
-
candidate = f"{external_id}_data_exploration_config"
|
|
76
|
-
value["externalId"] = sanitize_instance_external_id(candidate)
|
|
77
|
-
return value
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class InfieldLocationConfigList(
|
|
81
|
-
BaseResourceList[InfieldLocationConfig],
|
|
82
|
-
ResourceResponseListProtocol,
|
|
83
|
-
ResourceRequestListProtocol,
|
|
84
|
-
):
|
|
85
|
-
"""A list of InfieldLocationConfig objects."""
|
|
86
|
-
|
|
87
|
-
_RESOURCE = InfieldLocationConfig
|
|
88
|
-
|
|
89
|
-
def as_write(self) -> Self:
|
|
90
|
-
return self
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
class InFieldCDMLocationConfig(ResponseResource["InFieldCDMLocationConfig"], InstanceRequestResource):
|
|
94
|
-
"""InField CDM Location Configuration resource class.
|
|
95
|
-
|
|
96
|
-
This class is used for both the response and request resource for InField CDM Location Configuration nodes.
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
VIEW_ID: ClassVar[ViewReference] = INFIELD_CDM_LOCATION_CONFIG_VIEW_ID
|
|
100
|
-
instance_type: Literal["node"] = "node"
|
|
101
63
|
|
|
64
|
+
class InFieldLocationConfigRequest(WrappedInstanceListRequest, InFieldLocationConfig):
|
|
65
|
+
def dump_instances(self) -> list[dict[str, Any]]:
|
|
66
|
+
space: str | None = None
|
|
67
|
+
external_id: str | None = None
|
|
68
|
+
if self.data_exploration_config:
|
|
69
|
+
space = self.data_exploration_config.space or self.space
|
|
70
|
+
if self.data_exploration_config.external_id:
|
|
71
|
+
external_id = self.data_exploration_config.external_id
|
|
72
|
+
else:
|
|
73
|
+
candidate = f"{self.external_id}_data_exploration_config"
|
|
74
|
+
external_id = sanitize_instance_external_id(candidate)
|
|
75
|
+
|
|
76
|
+
properties = self.model_dump(
|
|
77
|
+
by_alias=True,
|
|
78
|
+
exclude_unset=True,
|
|
79
|
+
exclude={"data_exploration_config", "instance_type", "space", "external_id"},
|
|
80
|
+
)
|
|
81
|
+
if space and external_id:
|
|
82
|
+
properties["dataExplorationConfig"] = {"space": space, "externalId": external_id}
|
|
83
|
+
output: list[dict[str, Any]] = [
|
|
84
|
+
{
|
|
85
|
+
"instanceType": self.instance_type,
|
|
86
|
+
"space": self.space,
|
|
87
|
+
"externalId": self.external_id,
|
|
88
|
+
"sources": [
|
|
89
|
+
{
|
|
90
|
+
"source": self.VIEW_ID.dump(),
|
|
91
|
+
"properties": properties,
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
if space and external_id and self.data_exploration_config:
|
|
97
|
+
output.append(
|
|
98
|
+
{
|
|
99
|
+
"instanceType": "node",
|
|
100
|
+
"space": space,
|
|
101
|
+
"externalId": external_id,
|
|
102
|
+
"sources": [
|
|
103
|
+
{
|
|
104
|
+
"source": DataExplorationConfig.VIEW_ID.dump(),
|
|
105
|
+
"properties": self.data_exploration_config.model_dump(
|
|
106
|
+
by_alias=True, exclude_unset=True, exclude={"space", "external_id"}
|
|
107
|
+
),
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
return output
|
|
113
|
+
|
|
114
|
+
def as_ids(self) -> list[TypedInstanceIdentifier]:
|
|
115
|
+
output: list[TypedInstanceIdentifier] = [self.as_id()]
|
|
116
|
+
if (
|
|
117
|
+
self.data_exploration_config
|
|
118
|
+
and self.data_exploration_config.space
|
|
119
|
+
and self.data_exploration_config.external_id
|
|
120
|
+
):
|
|
121
|
+
output.append(
|
|
122
|
+
TypedNodeIdentifier(
|
|
123
|
+
space=self.data_exploration_config.space,
|
|
124
|
+
external_id=self.data_exploration_config.external_id,
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
return output
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class InFieldLocationConfigResponse(WrappedInstanceListResponse, InFieldLocationConfig):
|
|
131
|
+
def as_request_resource(self) -> InFieldLocationConfigRequest:
|
|
132
|
+
return InFieldLocationConfigRequest.model_validate(self.dump(), extra="ignore")
|
|
133
|
+
|
|
134
|
+
def as_ids(self) -> list[TypedInstanceIdentifier]:
|
|
135
|
+
output: list[TypedInstanceIdentifier] = [TypedNodeIdentifier(space=self.space, external_id=self.external_id)]
|
|
136
|
+
if (
|
|
137
|
+
self.data_exploration_config
|
|
138
|
+
and self.data_exploration_config.space
|
|
139
|
+
and self.data_exploration_config.external_id
|
|
140
|
+
):
|
|
141
|
+
output.append(
|
|
142
|
+
TypedNodeIdentifier(
|
|
143
|
+
space=self.data_exploration_config.space,
|
|
144
|
+
external_id=self.data_exploration_config.external_id,
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
return output
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class InFieldCDMLocationConfig(BaseModelObject):
|
|
102
151
|
name: str | None = None
|
|
103
152
|
description: str | None = None
|
|
104
153
|
feature_toggles: dict[str, JsonValue] | None = None
|
|
@@ -109,8 +158,20 @@ class InFieldCDMLocationConfig(ResponseResource["InFieldCDMLocationConfig"], Ins
|
|
|
109
158
|
disciplines: list[dict[str, JsonValue]] | None = None
|
|
110
159
|
data_exploration_config: dict[str, JsonValue] | None = None
|
|
111
160
|
|
|
112
|
-
def as_request_resource(self) -> "InFieldCDMLocationConfig":
|
|
113
|
-
return self
|
|
114
161
|
|
|
115
|
-
|
|
116
|
-
|
|
162
|
+
class InFieldCDMLocationConfigRequest(WrappedInstanceRequest, InFieldCDMLocationConfig):
|
|
163
|
+
VIEW_ID: ClassVar[TypedViewReference] = INFIELD_CDM_LOCATION_CONFIG_VIEW_ID
|
|
164
|
+
instance_type: Literal["node"] = "node"
|
|
165
|
+
|
|
166
|
+
def as_id(self) -> TypedNodeIdentifier:
|
|
167
|
+
return TypedNodeIdentifier(space=self.space, external_id=self.external_id)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class InFieldCDMLocationConfigResponse(
|
|
171
|
+
WrappedInstanceResponse[InFieldCDMLocationConfigRequest], InFieldCDMLocationConfig
|
|
172
|
+
):
|
|
173
|
+
VIEW_ID: ClassVar[TypedViewReference] = INFIELD_CDM_LOCATION_CONFIG_VIEW_ID
|
|
174
|
+
instance_type: Literal["node"] = "node"
|
|
175
|
+
|
|
176
|
+
def as_request_resource(self) -> InFieldCDMLocationConfigRequest:
|
|
177
|
+
return InFieldCDMLocationConfigRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
from
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, ClassVar, Literal, TypeAlias, TypeVar
|
|
2
3
|
|
|
3
|
-
from pydantic import
|
|
4
|
+
from pydantic import model_validator
|
|
4
5
|
|
|
5
|
-
from cognite_toolkit._cdf_tk.client._resource_base import
|
|
6
|
+
from cognite_toolkit._cdf_tk.client._resource_base import (
|
|
7
|
+
BaseModelObject,
|
|
8
|
+
Identifier,
|
|
9
|
+
RequestResource,
|
|
10
|
+
ResponseResource,
|
|
11
|
+
)
|
|
6
12
|
|
|
7
13
|
InstanceType: TypeAlias = Literal["node", "edge"]
|
|
8
14
|
|
|
@@ -39,6 +45,9 @@ class TypedEdgeIdentifier(TypedInstanceIdentifier):
|
|
|
39
45
|
return f"Edge({self.space}, {self.external_id})"
|
|
40
46
|
|
|
41
47
|
|
|
48
|
+
T_TypedInstanceIdentifier = TypeVar("T_TypedInstanceIdentifier", bound=TypedInstanceIdentifier)
|
|
49
|
+
|
|
50
|
+
|
|
42
51
|
class InstanceIdentifier(Identifier):
|
|
43
52
|
space: str
|
|
44
53
|
external_id: str
|
|
@@ -64,7 +73,7 @@ class InstanceResult(BaseModelObject):
|
|
|
64
73
|
)
|
|
65
74
|
|
|
66
75
|
|
|
67
|
-
class
|
|
76
|
+
class TypedViewReference(Identifier):
|
|
68
77
|
type: Literal["view"] = "view"
|
|
69
78
|
space: str
|
|
70
79
|
external_id: str
|
|
@@ -88,108 +97,139 @@ class ViewReference(Identifier):
|
|
|
88
97
|
#######################################################
|
|
89
98
|
|
|
90
99
|
|
|
91
|
-
class
|
|
92
|
-
"""This is a base class for resources that are Instances.
|
|
100
|
+
class WrappedInstanceRequest(RequestResource, ABC):
|
|
101
|
+
"""This is a base class for resources that are Instances.
|
|
102
|
+
It is used to define resources that are
|
|
103
|
+
"""
|
|
93
104
|
|
|
94
|
-
VIEW_ID: ClassVar[
|
|
105
|
+
VIEW_ID: ClassVar[TypedViewReference]
|
|
95
106
|
instance_type: InstanceType
|
|
96
107
|
space: str
|
|
97
108
|
external_id: str
|
|
109
|
+
existing_version: int | None = None
|
|
98
110
|
|
|
99
|
-
def
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
external_id=self.external_id,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
def as_request_item(self) -> "InstanceRequestItem":
|
|
107
|
-
return InstanceRequestItem(
|
|
108
|
-
instance_type=self.instance_type,
|
|
109
|
-
space=self.space,
|
|
110
|
-
external_id=self.external_id,
|
|
111
|
-
sources=[InstanceSource(source=self.VIEW_ID, resource=self)],
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class InstanceSource(BaseModelObject):
|
|
116
|
-
source: ViewReference
|
|
117
|
-
resource: InstanceRequestResource
|
|
111
|
+
def dump(
|
|
112
|
+
self, camel_case: bool = True, exclude_extra: bool = False, context: Literal["api", "toolkit"] = "api"
|
|
113
|
+
) -> dict[str, Any]:
|
|
114
|
+
"""Dump the resource to a dictionary.
|
|
118
115
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if field_id in InstanceRequestResource.model_fields:
|
|
124
|
-
# Skip space, external_id, instance_type
|
|
125
|
-
continue
|
|
126
|
-
key = field.alias or field_id
|
|
127
|
-
properties[key] = self._serialize_property(getattr(self.resource, field_id))
|
|
116
|
+
Args:
|
|
117
|
+
camel_case (bool): Whether to use camelCase for the keys. Default is True.
|
|
118
|
+
exclude_extra (bool): Whether to exclude extra fields not defined in the model. Default is False.
|
|
119
|
+
context (Literal["api", "toolkit"]): The context in which the dump is used. Default is "api".
|
|
128
120
|
|
|
121
|
+
"""
|
|
122
|
+
exclude: set[str] = set()
|
|
123
|
+
if exclude_extra:
|
|
124
|
+
exclude |= set(self.__pydantic_extra__) if self.__pydantic_extra__ else set()
|
|
125
|
+
if context == "api":
|
|
126
|
+
exclude.update({"existing_version", "instance_type", "space", "external_id"})
|
|
127
|
+
dumped = self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True, exclude=exclude)
|
|
128
|
+
if context == "toolkit":
|
|
129
|
+
return dumped
|
|
129
130
|
return {
|
|
130
|
-
"
|
|
131
|
-
"
|
|
131
|
+
"instanceType": self.instance_type,
|
|
132
|
+
"space": self.space,
|
|
133
|
+
"externalId": self.external_id,
|
|
134
|
+
"sources": [
|
|
135
|
+
{
|
|
136
|
+
"source": self.VIEW_ID.dump(camel_case=camel_case, include_type=True),
|
|
137
|
+
"properties": dumped,
|
|
138
|
+
}
|
|
139
|
+
],
|
|
132
140
|
}
|
|
133
141
|
|
|
134
|
-
@classmethod
|
|
135
|
-
def _serialize_property(cls, value: Any) -> JsonValue:
|
|
136
|
-
"""Handles serialization of direct relations."""
|
|
137
|
-
if isinstance(value, InstanceRequestResource):
|
|
138
|
-
return {"space": value.space, "externalId": value.external_id}
|
|
139
|
-
elif isinstance(value, list):
|
|
140
|
-
return [cls._serialize_property(v) for v in value]
|
|
141
|
-
return value
|
|
142
142
|
|
|
143
|
+
T_WrappedInstanceRequest = TypeVar("T_WrappedInstanceRequest", bound=WrappedInstanceRequest)
|
|
143
144
|
|
|
144
|
-
class InstanceRequestItem(RequestResource):
|
|
145
|
-
model_config = ConfigDict(populate_by_name=True)
|
|
146
|
-
instance_type: InstanceType
|
|
147
|
-
space: str
|
|
148
|
-
external_id: str
|
|
149
|
-
existing_version: int | None = None
|
|
150
|
-
sources: list[InstanceSource] | None = None
|
|
151
|
-
|
|
152
|
-
def as_id(self) -> TypedInstanceIdentifier:
|
|
153
|
-
return TypedInstanceIdentifier(
|
|
154
|
-
instance_type=self.instance_type,
|
|
155
|
-
space=self.space,
|
|
156
|
-
external_id=self.external_id,
|
|
157
|
-
)
|
|
158
145
|
|
|
159
|
-
|
|
160
|
-
|
|
146
|
+
class WrappedInstanceResponse(ResponseResource[T_WrappedInstanceRequest], ABC):
|
|
147
|
+
VIEW_ID: ClassVar[TypedViewReference]
|
|
161
148
|
instance_type: InstanceType
|
|
162
149
|
space: str
|
|
163
150
|
external_id: str
|
|
151
|
+
|
|
164
152
|
version: int
|
|
165
|
-
type: TypedInstanceIdentifier | None = None
|
|
166
153
|
created_time: int
|
|
167
154
|
last_updated_time: int
|
|
168
155
|
deleted_time: int | None = None
|
|
169
|
-
properties: dict[str, dict[str, dict[str, JsonValue]]] | None = None
|
|
170
156
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
{"space": self.space, "externalId": self.external_id} if include_identifier else {}
|
|
176
|
-
)
|
|
177
|
-
if not self.properties:
|
|
178
|
-
return output
|
|
179
|
-
if source.space not in self.properties:
|
|
180
|
-
return output
|
|
181
|
-
space_properties = self.properties[source.space]
|
|
182
|
-
view_version = f"{source.external_id}/{source.version}"
|
|
183
|
-
output.update(space_properties.get(view_version, {}))
|
|
184
|
-
return output
|
|
157
|
+
@model_validator(mode="before")
|
|
158
|
+
def move_properties(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
159
|
+
"""Move properties from sources to the top level."""
|
|
160
|
+
return move_properties(values, cls.VIEW_ID)
|
|
185
161
|
|
|
186
|
-
|
|
187
|
-
|
|
162
|
+
|
|
163
|
+
def move_properties(values: dict[str, Any], view_id: TypedViewReference) -> dict[str, Any]:
|
|
164
|
+
"""Help function to move properties from properties.space.externalId/version to the top level.
|
|
165
|
+
|
|
166
|
+
It is used in WrappedInstanceResponse to move properties from the response to the top level.
|
|
167
|
+
"""
|
|
168
|
+
if "properties" not in values:
|
|
169
|
+
return values
|
|
170
|
+
values_copy = dict(values)
|
|
171
|
+
properties = values_copy.pop("properties")
|
|
172
|
+
if not isinstance(properties, dict) or view_id.space not in properties:
|
|
173
|
+
return values
|
|
174
|
+
view_properties = properties.pop(view_id.space)
|
|
175
|
+
identifier = f"{view_id.external_id}/{view_id.version}"
|
|
176
|
+
if not isinstance(view_properties, dict) or identifier not in view_properties:
|
|
177
|
+
return values
|
|
178
|
+
source_properties = view_properties.pop(identifier)
|
|
179
|
+
values_copy.update(source_properties)
|
|
180
|
+
return values_copy
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
T_WrappedInstanceResponse = TypeVar("T_WrappedInstanceResponse", bound=WrappedInstanceResponse)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class WrappedInstanceListRequest(RequestResource, ABC):
|
|
187
|
+
VIEW_ID: ClassVar[TypedViewReference]
|
|
188
|
+
instance_type: Literal["node"] = "node"
|
|
189
|
+
space: str
|
|
190
|
+
external_id: str
|
|
191
|
+
|
|
192
|
+
@abstractmethod
|
|
193
|
+
def dump_instances(self) -> list[dict[str, Any]]:
|
|
194
|
+
"""Dumps the object to a list of instance request dictionaries."""
|
|
195
|
+
raise NotImplementedError()
|
|
196
|
+
|
|
197
|
+
def as_id(self) -> TypedNodeIdentifier:
|
|
198
|
+
return TypedNodeIdentifier(
|
|
188
199
|
instance_type=self.instance_type,
|
|
189
200
|
space=self.space,
|
|
190
201
|
external_id=self.external_id,
|
|
191
202
|
)
|
|
192
203
|
|
|
204
|
+
@abstractmethod
|
|
205
|
+
def as_ids(self) -> list[TypedInstanceIdentifier]:
|
|
206
|
+
"""Convert the response to a list of typed instance identifiers."""
|
|
207
|
+
raise NotImplementedError()
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
T_InstancesListRequest = TypeVar("T_InstancesListRequest", bound=WrappedInstanceListRequest)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class WrappedInstanceListResponse(ResponseResource[T_InstancesListRequest], ABC):
|
|
214
|
+
VIEW_ID: ClassVar[TypedViewReference]
|
|
215
|
+
instance_type: Literal["node"] = "node"
|
|
216
|
+
space: str
|
|
217
|
+
external_id: str
|
|
218
|
+
|
|
219
|
+
@model_validator(mode="before")
|
|
220
|
+
@classmethod
|
|
221
|
+
def move_properties(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
222
|
+
"""Move properties from sources to the top level."""
|
|
223
|
+
return move_properties(values, cls.VIEW_ID)
|
|
224
|
+
|
|
225
|
+
@abstractmethod
|
|
226
|
+
def as_ids(self) -> list[TypedInstanceIdentifier]:
|
|
227
|
+
"""Convert the response to a list of typed instance identifiers."""
|
|
228
|
+
raise NotImplementedError()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
T_InstancesListResponse = TypeVar("T_InstancesListResponse", bound=WrappedInstanceListResponse)
|
|
232
|
+
|
|
193
233
|
|
|
194
234
|
class NodeReference(BaseModelObject):
|
|
195
235
|
space: str
|