cognite-toolkit 0.7.43__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 +6 -0
- 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/cdf_client/__init__.py +2 -1
- cognite_toolkit/_cdf_tk/client/cdf_client/api.py +40 -6
- cognite_toolkit/_cdf_tk/client/data_classes/annotation.py +79 -0
- cognite_toolkit/_cdf_tk/client/data_classes/base.py +13 -3
- cognite_toolkit/_cdf_tk/client/data_classes/data_modeling/__init__.py +16 -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 +8 -0
- cognite_toolkit/_cdf_tk/client/data_classes/dataset.py +35 -0
- cognite_toolkit/_cdf_tk/client/data_classes/extraction_pipeline.py +59 -0
- cognite_toolkit/_cdf_tk/client/data_classes/filemetadata.py +7 -1
- 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/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 +5 -0
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +4 -3
- cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +7 -3
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +56 -59
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +1 -1
- cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +34 -29
- cognite_toolkit/_cdf_tk/storageio/_file_content.py +22 -19
- 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.43.dist-info → cognite_toolkit-0.7.44.dist-info}/METADATA +11 -1
- {cognite_toolkit-0.7.43.dist-info → cognite_toolkit-0.7.44.dist-info}/RECORD +50 -24
- {cognite_toolkit-0.7.43.dist-info → cognite_toolkit-0.7.44.dist-info}/WHEEL +1 -1
- {cognite_toolkit-0.7.43.dist-info → cognite_toolkit-0.7.44.dist-info}/entry_points.txt +0 -0
|
@@ -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")
|
|
@@ -20,11 +20,21 @@ class BaseModelObject(BaseModel):
|
|
|
20
20
|
# We allow extra fields to support forward compatibility.
|
|
21
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
|
|
@@ -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.
|
|
@@ -42,6 +42,15 @@ from ._indexes import (
|
|
|
42
42
|
IndexDefinition,
|
|
43
43
|
InvertedIndex,
|
|
44
44
|
)
|
|
45
|
+
from ._instance import (
|
|
46
|
+
EdgeRequest,
|
|
47
|
+
EdgeResponse,
|
|
48
|
+
InstanceDefinition,
|
|
49
|
+
InstanceResponseDefinition,
|
|
50
|
+
InstanceSource,
|
|
51
|
+
NodeRequest,
|
|
52
|
+
NodeResponse,
|
|
53
|
+
)
|
|
45
54
|
from ._references import (
|
|
46
55
|
ContainerConstraintReference,
|
|
47
56
|
ContainerDirectReference,
|
|
@@ -99,6 +108,8 @@ __all__ = [
|
|
|
99
108
|
"DateProperty",
|
|
100
109
|
"DirectNodeRelation",
|
|
101
110
|
"EdgeProperty",
|
|
111
|
+
"EdgeRequest",
|
|
112
|
+
"EdgeResponse",
|
|
102
113
|
"EnumProperty",
|
|
103
114
|
"EnumValue",
|
|
104
115
|
"FileCDFExternalIdReference",
|
|
@@ -108,6 +119,9 @@ __all__ = [
|
|
|
108
119
|
"Index",
|
|
109
120
|
"IndexAdapter",
|
|
110
121
|
"IndexDefinition",
|
|
122
|
+
"InstanceDefinition",
|
|
123
|
+
"InstanceResponseDefinition",
|
|
124
|
+
"InstanceSource",
|
|
111
125
|
"Int32Property",
|
|
112
126
|
"Int64Property",
|
|
113
127
|
"InvertedIndex",
|
|
@@ -117,6 +131,8 @@ __all__ = [
|
|
|
117
131
|
"MultiReverseDirectRelationPropertyRequest",
|
|
118
132
|
"MultiReverseDirectRelationPropertyResponse",
|
|
119
133
|
"NodeReference",
|
|
134
|
+
"NodeRequest",
|
|
135
|
+
"NodeResponse",
|
|
120
136
|
"PropertyTypeDefinition",
|
|
121
137
|
"RequiresConstraintDefinition",
|
|
122
138
|
"ReverseDirectRelationProperty",
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Any, Generic, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import JsonValue, field_serializer, field_validator
|
|
5
|
+
|
|
6
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
7
|
+
BaseModelObject,
|
|
8
|
+
RequestResource,
|
|
9
|
+
ResponseResource,
|
|
10
|
+
T_RequestResource,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from ._references import ContainerReference, EdgeReference, NodeReference, ViewReference
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InstanceDefinition(BaseModelObject, ABC):
|
|
17
|
+
"""Base class for node and edge instances."""
|
|
18
|
+
|
|
19
|
+
instance_type: str # "node" | "edge"
|
|
20
|
+
space: str
|
|
21
|
+
external_id: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class InstanceSource(BaseModelObject):
|
|
25
|
+
source: ViewReference | ContainerReference
|
|
26
|
+
properties: dict[str, JsonValue] | None = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InstanceRequestDefinition(InstanceDefinition, RequestResource, ABC):
|
|
30
|
+
existing_version: int | None = None
|
|
31
|
+
sources: list[InstanceSource]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class InstanceResponseDefinition(InstanceDefinition, ResponseResource, Generic[T_RequestResource], ABC):
|
|
35
|
+
version: int
|
|
36
|
+
created_time: int
|
|
37
|
+
last_updated_time: int
|
|
38
|
+
deleted_time: int | None = None
|
|
39
|
+
properties: dict[ViewReference | ContainerReference, dict[str, JsonValue]] | None = None
|
|
40
|
+
|
|
41
|
+
@field_validator("properties", mode="before")
|
|
42
|
+
def parse_reference(cls, value: Any) -> Any:
|
|
43
|
+
if not isinstance(value, dict):
|
|
44
|
+
return value
|
|
45
|
+
parsed: dict[ViewReference | ContainerReference, dict[str, Any]] = {}
|
|
46
|
+
for space, inner_dict in value.items():
|
|
47
|
+
if not isinstance(inner_dict, dict) or not isinstance(space, str):
|
|
48
|
+
raise ValueError(
|
|
49
|
+
f"Invalid properties format expected dict[str, dict[...]], got: dict[{type(space).__name__}, {type(inner_dict).__name__}]"
|
|
50
|
+
)
|
|
51
|
+
for view_or_container_identifier, prop in inner_dict.items():
|
|
52
|
+
if not isinstance(view_or_container_identifier, str):
|
|
53
|
+
raise ValueError(
|
|
54
|
+
"Invalid properties format expected dict[str, dict[str, ...]]], "
|
|
55
|
+
f"got: dict[{type(space).__name__}, "
|
|
56
|
+
f"dict[{type(view_or_container_identifier).__name__}, ...]]"
|
|
57
|
+
)
|
|
58
|
+
source_ref: ViewReference | ContainerReference
|
|
59
|
+
if "/" in view_or_container_identifier:
|
|
60
|
+
external_id, version = view_or_container_identifier.split("/", 1)
|
|
61
|
+
source_ref = ViewReference(space=space, external_id=external_id, version=version)
|
|
62
|
+
else:
|
|
63
|
+
source_ref = ContainerReference(space=space, external_id=view_or_container_identifier)
|
|
64
|
+
parsed[source_ref] = prop
|
|
65
|
+
return parsed
|
|
66
|
+
|
|
67
|
+
@field_serializer("properties", mode="plain")
|
|
68
|
+
def serialize_properties(self, value: dict[ViewReference | ContainerReference, dict[str, Any]] | None) -> Any:
|
|
69
|
+
if value is None:
|
|
70
|
+
return None
|
|
71
|
+
serialized: dict[str, dict[str, Any]] = {}
|
|
72
|
+
for source_ref, props in value.items():
|
|
73
|
+
space = source_ref.space
|
|
74
|
+
if space not in serialized:
|
|
75
|
+
serialized[space] = {}
|
|
76
|
+
if isinstance(source_ref, ViewReference):
|
|
77
|
+
identifier = f"{source_ref.external_id}/{source_ref.version}"
|
|
78
|
+
else:
|
|
79
|
+
identifier = source_ref.external_id
|
|
80
|
+
serialized[space][identifier] = props
|
|
81
|
+
return serialized
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class NodeRequest(InstanceRequestDefinition):
|
|
85
|
+
"""A node request resource."""
|
|
86
|
+
|
|
87
|
+
instance_type: Literal["node"] = "node"
|
|
88
|
+
type: NodeReference | None = None
|
|
89
|
+
|
|
90
|
+
def as_id(self) -> NodeReference:
|
|
91
|
+
return NodeReference(space=self.space, external_id=self.external_id)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class EdgeRequest(InstanceRequestDefinition):
|
|
95
|
+
"""An edge request resource."""
|
|
96
|
+
|
|
97
|
+
instance_type: Literal["edge"] = "edge"
|
|
98
|
+
type: NodeReference
|
|
99
|
+
start_node: NodeReference
|
|
100
|
+
end_node: NodeReference
|
|
101
|
+
|
|
102
|
+
def as_id(self) -> EdgeReference:
|
|
103
|
+
return EdgeReference(space=self.space, external_id=self.external_id)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class NodeResponse(InstanceResponseDefinition[NodeRequest]):
|
|
107
|
+
"""A node response from the API."""
|
|
108
|
+
|
|
109
|
+
instance_type: Literal["node"] = "node"
|
|
110
|
+
type: NodeReference | None = None
|
|
111
|
+
|
|
112
|
+
def as_id(self) -> NodeReference:
|
|
113
|
+
return NodeReference(space=self.space, external_id=self.external_id)
|
|
114
|
+
|
|
115
|
+
def as_request_resource(self) -> NodeRequest:
|
|
116
|
+
dumped = self.dump()
|
|
117
|
+
if self.properties:
|
|
118
|
+
dumped["sources"] = [
|
|
119
|
+
InstanceSource(source=source_ref, properties=props) for source_ref, props in self.properties.items()
|
|
120
|
+
]
|
|
121
|
+
dumped["existingVersion"] = dumped.pop("version", None)
|
|
122
|
+
return NodeRequest.model_validate(dumped, extra="ignore")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class EdgeResponse(InstanceResponseDefinition[EdgeRequest]):
|
|
126
|
+
"""An edge response from the API."""
|
|
127
|
+
|
|
128
|
+
instance_type: Literal["edge"] = "edge"
|
|
129
|
+
type: NodeReference
|
|
130
|
+
start_node: NodeReference
|
|
131
|
+
end_node: NodeReference
|
|
132
|
+
|
|
133
|
+
def as_id(self) -> EdgeReference:
|
|
134
|
+
return EdgeReference(space=self.space, external_id=self.external_id)
|
|
135
|
+
|
|
136
|
+
def as_request_resource(self) -> EdgeRequest:
|
|
137
|
+
dumped = self.dump()
|
|
138
|
+
if self.properties:
|
|
139
|
+
dumped["sources"] = [
|
|
140
|
+
InstanceSource(source=source_ref, properties=props) for source_ref, props in self.properties.items()
|
|
141
|
+
]
|
|
142
|
+
dumped["existingVersion"] = dumped.pop("version", None)
|
|
143
|
+
return EdgeRequest.model_validate(dumped, extra="ignore")
|
|
@@ -48,6 +48,14 @@ class NodeReference(Identifier):
|
|
|
48
48
|
return f"{self.space}:{self.external_id}"
|
|
49
49
|
|
|
50
50
|
|
|
51
|
+
class EdgeReference(Identifier):
|
|
52
|
+
space: str
|
|
53
|
+
external_id: str
|
|
54
|
+
|
|
55
|
+
def __str__(self) -> str:
|
|
56
|
+
return f"{self.space}:{self.external_id}"
|
|
57
|
+
|
|
58
|
+
|
|
51
59
|
class ContainerDirectReference(Identifier):
|
|
52
60
|
source: ContainerReference
|
|
53
61
|
identifier: str
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
4
|
+
BaseModelObject,
|
|
5
|
+
RequestUpdateable,
|
|
6
|
+
ResponseResource,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from .identifiers import ExternalId
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DataSet(BaseModelObject):
|
|
13
|
+
external_id: str | None = None
|
|
14
|
+
name: str | None = None
|
|
15
|
+
description: str | None = None
|
|
16
|
+
metadata: dict[str, str] | None = None
|
|
17
|
+
write_protected: bool = False
|
|
18
|
+
|
|
19
|
+
def as_id(self) -> ExternalId:
|
|
20
|
+
if self.external_id is None:
|
|
21
|
+
raise ValueError("Cannot convert DataSet to ExternalId when external_id is None")
|
|
22
|
+
return ExternalId(external_id=self.external_id)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DataSetRequest(DataSet, RequestUpdateable):
|
|
26
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata"})
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DataSetResponse(DataSet, ResponseResource[DataSetRequest]):
|
|
30
|
+
id: int
|
|
31
|
+
created_time: int
|
|
32
|
+
last_updated_time: int
|
|
33
|
+
|
|
34
|
+
def as_request_resource(self) -> DataSetRequest:
|
|
35
|
+
return DataSetRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
4
|
+
BaseModelObject,
|
|
5
|
+
RequestUpdateable,
|
|
6
|
+
ResponseResource,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from .identifiers import ExternalId
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RawTable(BaseModelObject):
|
|
13
|
+
db_name: str
|
|
14
|
+
table_name: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Contact(BaseModelObject):
|
|
18
|
+
name: str | None = None
|
|
19
|
+
email: str | None = None
|
|
20
|
+
role: str | None = None
|
|
21
|
+
send_notification: bool | None = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class NotificationConfig(BaseModelObject):
|
|
25
|
+
allowed_not_seen_range_in_minutes: int | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ExtractionPipeline(BaseModelObject):
|
|
29
|
+
external_id: str
|
|
30
|
+
name: str
|
|
31
|
+
description: str | None = None
|
|
32
|
+
data_set_id: int
|
|
33
|
+
raw_tables: list[RawTable] | None = None
|
|
34
|
+
schedule: str | None = None
|
|
35
|
+
contacts: list[Contact] | None = None
|
|
36
|
+
metadata: dict[str, str] | None = None
|
|
37
|
+
source: str | None = None
|
|
38
|
+
documentation: str | None = None
|
|
39
|
+
notification_config: NotificationConfig | None = None
|
|
40
|
+
created_by: str | None = None
|
|
41
|
+
|
|
42
|
+
def as_id(self) -> ExternalId:
|
|
43
|
+
return ExternalId(external_id=self.external_id)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExtractionPipelineRequest(ExtractionPipeline, RequestUpdateable):
|
|
47
|
+
container_fields: ClassVar[frozenset[str]] = frozenset({"raw_tables", "contacts", "metadata"})
|
|
48
|
+
non_nullable_fields: ClassVar[frozenset[str]] = frozenset(
|
|
49
|
+
{"documentation", "source", "notification_config", "schedule", "description"}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ExtractionPipelineResponse(ExtractionPipeline, ResponseResource[ExtractionPipelineRequest]):
|
|
54
|
+
id: int
|
|
55
|
+
created_time: int
|
|
56
|
+
last_updated_time: int
|
|
57
|
+
|
|
58
|
+
def as_request_resource(self) -> ExtractionPipelineRequest:
|
|
59
|
+
return ExtractionPipelineRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import ClassVar, Literal
|
|
2
2
|
|
|
3
|
-
from pydantic import JsonValue
|
|
3
|
+
from pydantic import Field, JsonValue
|
|
4
4
|
|
|
5
5
|
from cognite_toolkit._cdf_tk.client.data_classes.base import BaseModelObject, RequestUpdateable, ResponseResource
|
|
6
6
|
|
|
@@ -32,6 +32,10 @@ class FileMetadata(BaseModelObject):
|
|
|
32
32
|
class FileMetadataRequest(FileMetadata, RequestUpdateable):
|
|
33
33
|
container_fields: ClassVar[frozenset[str]] = frozenset({"metadata", "labels", "asset_ids", "security_categories"})
|
|
34
34
|
non_nullable_fields: ClassVar[frozenset[str]] = frozenset({"asset_ids", "security_categories"})
|
|
35
|
+
# This field is not part of the request when creating or updating a resource
|
|
36
|
+
# but we added it here for convenience so that it is available when converting
|
|
37
|
+
# from response to request.
|
|
38
|
+
instance_id: NodeReference | None = Field(default=None, exclude=True)
|
|
35
39
|
|
|
36
40
|
|
|
37
41
|
class FileMetadataResponse(FileMetadata, ResponseResource[FileMetadataRequest]):
|
|
@@ -41,6 +45,8 @@ class FileMetadataResponse(FileMetadata, ResponseResource[FileMetadataRequest]):
|
|
|
41
45
|
uploaded: bool
|
|
42
46
|
id: int
|
|
43
47
|
instance_id: NodeReference | None = None
|
|
48
|
+
# This field is required in the upload endpoint response, but not in any other file metadata response
|
|
49
|
+
upload_url: str | None = None
|
|
44
50
|
|
|
45
51
|
def as_request_resource(self) -> FileMetadataRequest:
|
|
46
52
|
return FileMetadataRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
2
|
+
BaseModelObject,
|
|
3
|
+
RequestUpdateable,
|
|
4
|
+
ResponseResource,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from .identifiers import ExternalId
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Credentials(BaseModelObject):
|
|
11
|
+
nonce: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class HostedExtractorDestination(BaseModelObject):
|
|
15
|
+
external_id: str
|
|
16
|
+
target_data_set_id: int | None = None
|
|
17
|
+
|
|
18
|
+
def as_id(self) -> ExternalId:
|
|
19
|
+
return ExternalId(external_id=self.external_id)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class HostedExtractorDestinationRequest(HostedExtractorDestination, RequestUpdateable):
|
|
23
|
+
credentials: Credentials | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HostedExtractorDestinationResponse(
|
|
27
|
+
HostedExtractorDestination, ResponseResource[HostedExtractorDestinationRequest]
|
|
28
|
+
):
|
|
29
|
+
session_id: int | None = None
|
|
30
|
+
created_time: int
|
|
31
|
+
last_updated_time: int
|
|
32
|
+
|
|
33
|
+
def as_request_resource(self) -> HostedExtractorDestinationRequest:
|
|
34
|
+
return HostedExtractorDestinationRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from typing import Annotated, Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, JsonValue
|
|
4
|
+
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
6
|
+
BaseModelObject,
|
|
7
|
+
RequestUpdateable,
|
|
8
|
+
ResponseResource,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from .identifiers import ExternalId
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class JobFormatDefinition(BaseModelObject):
|
|
15
|
+
type: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PrefixConfig(BaseModelObject):
|
|
19
|
+
from_topic: bool | None = None
|
|
20
|
+
prefix: str | None = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SpaceRef(BaseModelObject):
|
|
24
|
+
space: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CogniteFormat(JobFormatDefinition):
|
|
28
|
+
type: Literal["cognite"] = "cognite"
|
|
29
|
+
encoding: str | None = None
|
|
30
|
+
compression: str | None = None
|
|
31
|
+
prefix: PrefixConfig | None = None
|
|
32
|
+
data_models: list[SpaceRef] | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class CustomFormat(JobFormatDefinition):
|
|
36
|
+
type: Literal["custom"] = "custom"
|
|
37
|
+
encoding: str | None = None
|
|
38
|
+
compression: str | None = None
|
|
39
|
+
mapping_id: str
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class RockwellFormat(JobFormatDefinition):
|
|
43
|
+
type: Literal["rockwell"] = "rockwell"
|
|
44
|
+
encoding: str | None = None
|
|
45
|
+
compression: str | None = None
|
|
46
|
+
prefix: PrefixConfig | None = None
|
|
47
|
+
data_models: list[SpaceRef] | None = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ValueFormat(JobFormatDefinition):
|
|
51
|
+
type: Literal["value"] = "value"
|
|
52
|
+
encoding: str | None = None
|
|
53
|
+
compression: str | None = None
|
|
54
|
+
prefix: PrefixConfig | None = None
|
|
55
|
+
data_models: list[SpaceRef] | None = None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
JobFormat = Annotated[
|
|
59
|
+
CogniteFormat | CustomFormat | RockwellFormat | ValueFormat,
|
|
60
|
+
Field(discriminator="type"),
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class IncrementalLoadDefinition(BaseModelObject):
|
|
65
|
+
type: str
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class BodyIncrementalLoad(IncrementalLoadDefinition):
|
|
69
|
+
type: Literal["body"] = "body"
|
|
70
|
+
value: str
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class NextUrlIncrementalLoad(IncrementalLoadDefinition):
|
|
74
|
+
type: Literal["nextUrl"] = "nextUrl"
|
|
75
|
+
value: str
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class HeaderIncrementalLoad(IncrementalLoadDefinition):
|
|
79
|
+
type: Literal["headerValue"] = "headerValue"
|
|
80
|
+
key: str
|
|
81
|
+
value: str
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class QueryParamIncrementalLoad(IncrementalLoadDefinition):
|
|
85
|
+
type: Literal["queryParam"] = "queryParam"
|
|
86
|
+
key: str
|
|
87
|
+
value: str
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class MQTTConfig(BaseModelObject):
|
|
91
|
+
topic_filter: str
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class KafkaConfig(BaseModelObject):
|
|
95
|
+
topic: str
|
|
96
|
+
partitions: int | None = None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class RestConfig(BaseModelObject):
|
|
100
|
+
interval: Literal["5m", "15m", "1h", "6h", "12h", "1d"]
|
|
101
|
+
path: str
|
|
102
|
+
method: Literal["get", "post"] | None = None
|
|
103
|
+
body: JsonValue | None = None
|
|
104
|
+
query: dict[str, str] | None = None
|
|
105
|
+
headers: dict[str, str] | None = None
|
|
106
|
+
incremental_load: BodyIncrementalLoad | HeaderIncrementalLoad | QueryParamIncrementalLoad | None = Field(
|
|
107
|
+
None, discriminator="type"
|
|
108
|
+
)
|
|
109
|
+
pagination: (
|
|
110
|
+
BodyIncrementalLoad | NextUrlIncrementalLoad | HeaderIncrementalLoad | QueryParamIncrementalLoad | None
|
|
111
|
+
) = Field(None, discriminator="type")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class HostedExtractorJob(BaseModelObject):
|
|
115
|
+
external_id: str
|
|
116
|
+
destination_id: str
|
|
117
|
+
source_id: str
|
|
118
|
+
format: JobFormat
|
|
119
|
+
config: MQTTConfig | KafkaConfig | RestConfig
|
|
120
|
+
|
|
121
|
+
def as_id(self) -> ExternalId:
|
|
122
|
+
return ExternalId(external_id=self.external_id)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class HostedExtractorJobRequest(HostedExtractorJob, RequestUpdateable): ...
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class HostedExtractorJobResponse(HostedExtractorJob, ResponseResource[HostedExtractorJobRequest]):
|
|
129
|
+
status: str | None = None
|
|
130
|
+
created_time: int
|
|
131
|
+
last_updated_time: int
|
|
132
|
+
|
|
133
|
+
def as_request_resource(self) -> HostedExtractorJobRequest:
|
|
134
|
+
return HostedExtractorJobRequest.model_validate(self.dump(), extra="ignore")
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from typing import Annotated, Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.data_classes.base import (
|
|
6
|
+
BaseModelObject,
|
|
7
|
+
RequestUpdateable,
|
|
8
|
+
ResponseResource,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from .identifiers import ExternalId
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Mapping(BaseModelObject):
|
|
15
|
+
expression: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MappingInputDefinition(BaseModelObject):
|
|
19
|
+
type: str
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ProtobufFile(BaseModelObject):
|
|
23
|
+
file_name: str
|
|
24
|
+
content: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProtobufInput(BaseModelObject):
|
|
28
|
+
type: Literal["protobuf"] = "protobuf"
|
|
29
|
+
message_name: str
|
|
30
|
+
files: list[ProtobufFile]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CSVInput(BaseModelObject):
|
|
34
|
+
type: Literal["csv"] = "csv"
|
|
35
|
+
delimiter: str = ","
|
|
36
|
+
custom_keys: list[str] | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class XMLInput(BaseModelObject):
|
|
40
|
+
type: Literal["xml"] = "xml"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class JSONInput(BaseModelObject):
|
|
44
|
+
type: Literal["json"] = "json"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
MappingInput = Annotated[
|
|
48
|
+
ProtobufInput | CSVInput | XMLInput | JSONInput,
|
|
49
|
+
Field(discriminator="type"),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class HostedExtractorMapping(BaseModelObject):
|
|
54
|
+
external_id: str
|
|
55
|
+
mapping: Mapping
|
|
56
|
+
published: bool
|
|
57
|
+
|
|
58
|
+
def as_id(self) -> ExternalId:
|
|
59
|
+
return ExternalId(external_id=self.external_id)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class HostedExtractorMappingRequest(HostedExtractorMapping, RequestUpdateable):
|
|
63
|
+
input: MappingInput | None = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class HostedExtractorMappingResponse(HostedExtractorMapping, ResponseResource[HostedExtractorMappingRequest]):
|
|
67
|
+
input: MappingInput
|
|
68
|
+
created_time: int
|
|
69
|
+
last_updated_time: int
|
|
70
|
+
|
|
71
|
+
def as_request_resource(self) -> HostedExtractorMappingRequest:
|
|
72
|
+
return HostedExtractorMappingRequest.model_validate(self.dump(), extra="ignore")
|