cognite-toolkit 0.7.47__py3-none-any.whl → 0.7.49__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/apps/_migrate_app.py +6 -6
- cognite_toolkit/_cdf_tk/client/_toolkit_client.py +6 -4
- cognite_toolkit/_cdf_tk/client/api/instances.py +139 -0
- cognite_toolkit/_cdf_tk/client/api/location_filters.py +177 -0
- cognite_toolkit/_cdf_tk/client/api/raw.py +2 -2
- cognite_toolkit/_cdf_tk/client/api/robotics.py +19 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_capabilities.py +127 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_data_postprocessing.py +138 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_frames.py +122 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_locations.py +127 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_maps.py +122 -0
- cognite_toolkit/_cdf_tk/client/api/robotics_robots.py +122 -0
- cognite_toolkit/_cdf_tk/client/api/search_config.py +101 -0
- cognite_toolkit/_cdf_tk/client/api/streams.py +63 -55
- cognite_toolkit/_cdf_tk/client/api/three_d.py +293 -277
- cognite_toolkit/_cdf_tk/client/cdf_client/api.py +34 -5
- cognite_toolkit/_cdf_tk/client/http_client/_client.py +5 -2
- cognite_toolkit/_cdf_tk/client/http_client/_data_classes2.py +4 -3
- cognite_toolkit/_cdf_tk/client/request_classes/filters.py +45 -1
- cognite_toolkit/_cdf_tk/client/resource_classes/apm_config.py +128 -0
- cognite_toolkit/_cdf_tk/client/resource_classes/cognite_file.py +53 -0
- cognite_toolkit/_cdf_tk/client/resource_classes/data_modeling/__init__.py +4 -0
- cognite_toolkit/_cdf_tk/client/resource_classes/data_modeling/_instance.py +22 -11
- cognite_toolkit/_cdf_tk/client/resource_classes/identifiers.py +7 -0
- cognite_toolkit/_cdf_tk/client/resource_classes/location_filter.py +9 -2
- cognite_toolkit/_cdf_tk/client/resource_classes/resource_view_mapping.py +38 -0
- cognite_toolkit/_cdf_tk/client/resource_classes/robotics/_map.py +6 -1
- cognite_toolkit/_cdf_tk/client/resource_classes/robotics/_robot.py +10 -5
- cognite_toolkit/_cdf_tk/client/resource_classes/streams.py +1 -20
- cognite_toolkit/_cdf_tk/client/resource_classes/three_d.py +30 -9
- cognite_toolkit/_cdf_tk/client/testing.py +2 -2
- cognite_toolkit/_cdf_tk/commands/_migrate/command.py +103 -108
- cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +6 -1
- cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +119 -41
- cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +21 -38
- cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +14 -12
- cognite_toolkit/_cdf_tk/commands/build_v2/_module_parser.py +138 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/_modules_parser.py +163 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +83 -96
- cognite_toolkit/_cdf_tk/commands/build_v2/{build_input.py → build_parameters.py} +8 -22
- cognite_toolkit/_cdf_tk/commands/build_v2/data_classes/_modules.py +27 -0
- cognite_toolkit/_cdf_tk/commands/build_v2/data_classes/_resource.py +22 -0
- cognite_toolkit/_cdf_tk/cruds/__init__.py +11 -5
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +14 -30
- cognite_toolkit/_cdf_tk/data_classes/__init__.py +3 -0
- cognite_toolkit/_cdf_tk/data_classes/_issues.py +36 -0
- cognite_toolkit/_cdf_tk/data_classes/_module_directories.py +2 -1
- cognite_toolkit/_cdf_tk/storageio/_base.py +2 -0
- cognite_toolkit/_cdf_tk/storageio/logger.py +162 -0
- cognite_toolkit/_cdf_tk/utils/__init__.py +8 -1
- cognite_toolkit/_cdf_tk/utils/interactive_select.py +3 -1
- cognite_toolkit/_cdf_tk/utils/modules.py +7 -0
- 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.47.dist-info → cognite_toolkit-0.7.49.dist-info}/METADATA +1 -1
- {cognite_toolkit-0.7.47.dist-info → cognite_toolkit-0.7.49.dist-info}/RECORD +61 -43
- cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +0 -27
- /cognite_toolkit/_cdf_tk/client/resource_classes/{search_config_resource.py → search_config.py} +0 -0
- {cognite_toolkit-0.7.47.dist-info → cognite_toolkit-0.7.49.dist-info}/WHEEL +0 -0
- {cognite_toolkit-0.7.47.dist-info → cognite_toolkit-0.7.49.dist-info}/entry_points.txt +0 -0
|
@@ -868,13 +868,13 @@ class MigrateApp(typer.Typer):
|
|
|
868
868
|
"performed to select the Canvas to migrate."
|
|
869
869
|
),
|
|
870
870
|
] = None,
|
|
871
|
-
|
|
871
|
+
allow_missing_ref: Annotated[
|
|
872
872
|
bool,
|
|
873
873
|
typer.Option(
|
|
874
|
-
"--
|
|
875
|
-
"-
|
|
876
|
-
help="If set, the
|
|
877
|
-
"If not set, the migration will
|
|
874
|
+
"--allow-missing-ref",
|
|
875
|
+
"-a",
|
|
876
|
+
help="If set, the command will migrate Canvases that reference resources that have not been migrated to data modeling. "
|
|
877
|
+
"If not set, the migration will fail if any referenced resource are missing.",
|
|
878
878
|
),
|
|
879
879
|
] = False,
|
|
880
880
|
log_dir: Annotated[
|
|
@@ -926,7 +926,7 @@ class MigrateApp(typer.Typer):
|
|
|
926
926
|
lambda: cmd.migrate(
|
|
927
927
|
selected=selector,
|
|
928
928
|
data=CanvasIO(client, exclude_existing_version=True),
|
|
929
|
-
mapper=CanvasMapper(client, dry_run=dry_run, skip_on_missing_ref=
|
|
929
|
+
mapper=CanvasMapper(client, dry_run=dry_run, skip_on_missing_ref=not allow_missing_ref),
|
|
930
930
|
log_dir=log_dir,
|
|
931
931
|
dry_run=dry_run,
|
|
932
932
|
verbose=verbose,
|
|
@@ -11,7 +11,7 @@ from cognite_toolkit._cdf_tk.client.api.legacy.extended_files import ExtendedFil
|
|
|
11
11
|
from cognite_toolkit._cdf_tk.client.api.legacy.extended_functions import ExtendedFunctionsAPI
|
|
12
12
|
from cognite_toolkit._cdf_tk.client.api.legacy.extended_raw import ExtendedRawAPI
|
|
13
13
|
from cognite_toolkit._cdf_tk.client.api.legacy.extended_timeseries import ExtendedTimeSeriesAPI
|
|
14
|
-
from cognite_toolkit._cdf_tk.client.api.legacy.robotics import RoboticsAPI
|
|
14
|
+
from cognite_toolkit._cdf_tk.client.api.legacy.robotics import RoboticsAPI as RoboticsLegacyAPI
|
|
15
15
|
from cognite_toolkit._cdf_tk.client.http_client import HTTPClient
|
|
16
16
|
|
|
17
17
|
from .api.assets import AssetsAPI
|
|
@@ -26,6 +26,7 @@ from .api.lookup import LookUpGroup
|
|
|
26
26
|
from .api.migration import MigrationAPI
|
|
27
27
|
from .api.project import ProjectAPI
|
|
28
28
|
from .api.raw import RawAPI
|
|
29
|
+
from .api.robotics import RoboticsAPI
|
|
29
30
|
from .api.search import SearchAPI
|
|
30
31
|
from .api.security_categories import SecurityCategoriesAPI
|
|
31
32
|
from .api.sequences import SequencesAPI
|
|
@@ -53,10 +54,11 @@ class ToolAPI:
|
|
|
53
54
|
self.labels = LabelsAPI(http_client)
|
|
54
55
|
self.filemetadata = FileMetadataAPI(http_client)
|
|
55
56
|
self.raw = RawAPI(http_client)
|
|
57
|
+
self.robotics = RoboticsAPI(http_client)
|
|
56
58
|
self.security_categories = SecurityCategoriesAPI(http_client)
|
|
57
59
|
self.sequences = SequencesAPI(http_client)
|
|
58
60
|
self.simulators = SimulatorsAPI(http_client)
|
|
59
|
-
self.three_d = ThreeDAPI(http_client
|
|
61
|
+
self.three_d = ThreeDAPI(http_client)
|
|
60
62
|
self.timeseries = TimeSeriesAPI(http_client)
|
|
61
63
|
self.transformations = TransformationsAPI(http_client)
|
|
62
64
|
self.workflows = WorkflowsAPI(http_client)
|
|
@@ -76,7 +78,7 @@ class ToolkitClient(CogniteClient):
|
|
|
76
78
|
self.console = console or Console()
|
|
77
79
|
self.tool = ToolAPI(http_client, self.console)
|
|
78
80
|
self.search = SearchAPI(self._config, self._API_VERSION, self)
|
|
79
|
-
self.robotics =
|
|
81
|
+
self.robotics = RoboticsLegacyAPI(self._config, self._API_VERSION, self)
|
|
80
82
|
self.dml = DMLAPI(self._config, self._API_VERSION, self)
|
|
81
83
|
self.verify = VerifyAPI(self._config, self._API_VERSION, self)
|
|
82
84
|
self.lookup = LookUpGroup(self._config, self._API_VERSION, self, self.console)
|
|
@@ -94,7 +96,7 @@ class ToolkitClient(CogniteClient):
|
|
|
94
96
|
self.charts = ChartsAPI(self._config, self._API_VERSION, self)
|
|
95
97
|
self.project = ProjectAPI(config=toolkit_config, cognite_client=self)
|
|
96
98
|
self.infield = InfieldAPI(http_client, self.console)
|
|
97
|
-
self.streams = StreamsAPI(http_client
|
|
99
|
+
self.streams = StreamsAPI(http_client)
|
|
98
100
|
|
|
99
101
|
@property
|
|
100
102
|
def config(self) -> ToolkitClientConfig:
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from collections.abc import Iterable, Sequence
|
|
2
|
+
from typing import Any, Literal
|
|
3
|
+
|
|
4
|
+
from cognite_toolkit._cdf_tk.client.cdf_client import CDFResourceAPI, PagedResponse, ResponseItems
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.cdf_client.api import Endpoint
|
|
6
|
+
from cognite_toolkit._cdf_tk.client.http_client import HTTPClient, ItemsSuccessResponse2, SuccessResponse2
|
|
7
|
+
from cognite_toolkit._cdf_tk.client.request_classes.filters import InstanceFilter
|
|
8
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.data_modeling import (
|
|
9
|
+
InstanceRequest,
|
|
10
|
+
InstanceResponse,
|
|
11
|
+
ViewReference,
|
|
12
|
+
)
|
|
13
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.instance_api import TypedInstanceIdentifier
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InstancesAPI(CDFResourceAPI[TypedInstanceIdentifier, InstanceRequest, InstanceResponse]):
|
|
17
|
+
def __init__(self, http_client: HTTPClient) -> None:
|
|
18
|
+
super().__init__(
|
|
19
|
+
http_client=http_client,
|
|
20
|
+
method_endpoint_map={
|
|
21
|
+
"upsert": Endpoint(method="POST", path="/models/instances", item_limit=1000),
|
|
22
|
+
"retrieve": Endpoint(method="POST", path="/models/instances/byids", item_limit=1000),
|
|
23
|
+
"delete": Endpoint(method="POST", path="/models/instances/delete", item_limit=1000),
|
|
24
|
+
"list": Endpoint(method="POST", path="/models/instances/list", item_limit=1000),
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def _validate_page_response(
|
|
29
|
+
self, response: SuccessResponse2 | ItemsSuccessResponse2
|
|
30
|
+
) -> PagedResponse[InstanceResponse]:
|
|
31
|
+
return PagedResponse[InstanceResponse].model_validate_json(response.body)
|
|
32
|
+
|
|
33
|
+
def _validate_response(self, response: SuccessResponse2) -> ResponseItems[TypedInstanceIdentifier]:
|
|
34
|
+
return ResponseItems[TypedInstanceIdentifier].model_validate_json(response.body)
|
|
35
|
+
|
|
36
|
+
def create(self, items: Sequence[InstanceRequest]) -> list[InstanceResponse]:
|
|
37
|
+
"""Create instances in CDF.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
items: List of InstanceRequest objects to create.
|
|
41
|
+
Returns:
|
|
42
|
+
List of created InstanceResponse objects.
|
|
43
|
+
"""
|
|
44
|
+
return self._request_item_response(items, "upsert")
|
|
45
|
+
|
|
46
|
+
def retrieve(
|
|
47
|
+
self, items: Sequence[TypedInstanceIdentifier], source: ViewReference | None = None
|
|
48
|
+
) -> list[InstanceResponse]:
|
|
49
|
+
"""Retrieve instances from CDF.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
items: List of ExternalId objects to retrieve.
|
|
53
|
+
source: Optional ViewReference to specify the source view for the instances.
|
|
54
|
+
Returns:
|
|
55
|
+
List of retrieved InstanceResponse objects.
|
|
56
|
+
"""
|
|
57
|
+
return self._request_item_response(
|
|
58
|
+
items, method="retrieve", extra_body={"sources": [{"source": source.dump()}]} if source else None
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def delete(self, items: Sequence[TypedInstanceIdentifier]) -> list[TypedInstanceIdentifier]:
|
|
62
|
+
"""Delete instances from CDF.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
items: List of TypedInstanceIdentifier objects to delete.
|
|
66
|
+
"""
|
|
67
|
+
response_items: list[TypedInstanceIdentifier] = []
|
|
68
|
+
for response in self._chunk_requests(items, "delete", self._serialize_items):
|
|
69
|
+
response_items.extend(self._validate_response(response).items)
|
|
70
|
+
return response_items
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def _create_sort_body(instance_type: Literal["node", "edge"] | None) -> list[dict]:
|
|
74
|
+
"""We sort by space and externalId to get a stable sort order.
|
|
75
|
+
|
|
76
|
+
This is also more performant than sorting by using the default sort, which will sort on
|
|
77
|
+
internal CDF IDs. This will be slow if you have deleted a lot of instances, as they will be counted.
|
|
78
|
+
By sorting on space and externalId, we avoid this issue.
|
|
79
|
+
"""
|
|
80
|
+
instance_type = instance_type or "node"
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
"property": [instance_type, "space"],
|
|
84
|
+
"direction": "ascending",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"property": [instance_type, "externalId"],
|
|
88
|
+
"direction": "ascending",
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def _create_body(cls, filter: InstanceFilter | None) -> dict[str, Any]:
|
|
94
|
+
return {
|
|
95
|
+
**(filter.model_dump(exclude_none=True) if filter else {}),
|
|
96
|
+
"sort": cls._create_sort_body(filter.instance_type if filter else "node"),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
def paginate(
|
|
100
|
+
self,
|
|
101
|
+
filter: InstanceFilter | None = None,
|
|
102
|
+
limit: int = 100,
|
|
103
|
+
cursor: str | None = None,
|
|
104
|
+
) -> PagedResponse[InstanceResponse]:
|
|
105
|
+
"""Iterate over all instances in CDF.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
filter: InstanceFilter to filter instances.
|
|
109
|
+
limit: Maximum number of items to return.
|
|
110
|
+
cursor: Cursor for pagination.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
PagedResponse of InstanceResponse objects.
|
|
114
|
+
"""
|
|
115
|
+
return self._paginate(
|
|
116
|
+
cursor=cursor,
|
|
117
|
+
limit=limit,
|
|
118
|
+
body=self._create_body(filter),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def iterate(self, filter: InstanceFilter | None = None, limit: int = 100) -> Iterable[list[InstanceResponse]]:
|
|
122
|
+
"""Iterate over all instances in CDF.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
filter: InstanceFilter to filter instances.
|
|
126
|
+
limit: Maximum number of items to return per page.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Iterable of lists of InstanceResponse objects.
|
|
130
|
+
"""
|
|
131
|
+
return self._iterate(limit=limit, body=self._create_body(filter))
|
|
132
|
+
|
|
133
|
+
def list(self, filter: InstanceFilter | None = None, limit: int | None = 100) -> list[InstanceResponse]:
|
|
134
|
+
"""List all instances in CDF.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
List of InstanceResponse objects.
|
|
138
|
+
"""
|
|
139
|
+
return self._list(limit=limit, body=self._create_body(filter))
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from collections.abc import Iterable, Sequence
|
|
2
|
+
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.cdf_client import CDFResourceAPI, PagedResponse
|
|
4
|
+
from cognite_toolkit._cdf_tk.client.cdf_client.api import Endpoint
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.http_client import (
|
|
6
|
+
HTTPClient,
|
|
7
|
+
ItemsSuccessResponse2,
|
|
8
|
+
RequestMessage2,
|
|
9
|
+
SuccessResponse2,
|
|
10
|
+
)
|
|
11
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.identifiers import InternalId
|
|
12
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.location_filter import (
|
|
13
|
+
LocationFilterRequest,
|
|
14
|
+
LocationFilterResponse,
|
|
15
|
+
)
|
|
16
|
+
from cognite_toolkit._cdf_tk.utils.collection import chunker_sequence
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class LocationFiltersAPI(CDFResourceAPI[InternalId, LocationFilterRequest, LocationFilterResponse]):
|
|
20
|
+
"""API for managing Location Filters using the CDFResourceAPI pattern.
|
|
21
|
+
|
|
22
|
+
This API manages location filter configurations at:
|
|
23
|
+
/apps/v1/projects/{project}/storage/config/locationfilters
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
BASE_PATH = "/storage/config/locationfilters"
|
|
27
|
+
|
|
28
|
+
def __init__(self, http_client: HTTPClient) -> None:
|
|
29
|
+
super().__init__(
|
|
30
|
+
http_client=http_client,
|
|
31
|
+
method_endpoint_map={
|
|
32
|
+
"create": Endpoint(method="POST", path=self.BASE_PATH, item_limit=1),
|
|
33
|
+
"retrieve": Endpoint(method="POST", path=f"{self.BASE_PATH}/byids", item_limit=1000),
|
|
34
|
+
"update": Endpoint(method="PUT", path=f"{self.BASE_PATH}/{{id}}", item_limit=1),
|
|
35
|
+
"delete": Endpoint(method="DELETE", path=f"{self.BASE_PATH}/{{id}}", item_limit=1),
|
|
36
|
+
"list": Endpoint(method="POST", path=f"{self.BASE_PATH}/list", item_limit=1000),
|
|
37
|
+
},
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def _make_url(self, path: str = "") -> str:
|
|
41
|
+
"""Create the full URL for this resource endpoint using the apps URL format."""
|
|
42
|
+
return self._http_client.config.create_app_url(path)
|
|
43
|
+
|
|
44
|
+
def _validate_page_response(
|
|
45
|
+
self, response: SuccessResponse2 | ItemsSuccessResponse2
|
|
46
|
+
) -> PagedResponse[LocationFilterResponse]:
|
|
47
|
+
return PagedResponse[LocationFilterResponse].model_validate_json(response.body)
|
|
48
|
+
|
|
49
|
+
def create(self, items: Sequence[LocationFilterRequest]) -> list[LocationFilterResponse]:
|
|
50
|
+
"""Create a new location filter.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
items: The location filter to create.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
The created location filter.
|
|
57
|
+
"""
|
|
58
|
+
endpoint = self._method_endpoint_map["create"]
|
|
59
|
+
results: list[LocationFilterResponse] = []
|
|
60
|
+
for item in items:
|
|
61
|
+
request = RequestMessage2(
|
|
62
|
+
endpoint_url=self._make_url(endpoint.path),
|
|
63
|
+
method=endpoint.method,
|
|
64
|
+
body_content=item.model_dump(mode="json", by_alias=True),
|
|
65
|
+
)
|
|
66
|
+
result = self._http_client.request_single_retries(request)
|
|
67
|
+
response = result.get_success_or_raise()
|
|
68
|
+
results.append(LocationFilterResponse.model_validate_json(response.body))
|
|
69
|
+
return results
|
|
70
|
+
|
|
71
|
+
def retrieve(self, items: Sequence[InternalId]) -> list[LocationFilterResponse]:
|
|
72
|
+
"""Retrieve a single location filter by ID.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
items: The ID of the location filter to retrieve.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
The retrieved location filter.
|
|
79
|
+
"""
|
|
80
|
+
endpoint = self._method_endpoint_map["retrieve"]
|
|
81
|
+
results: list[LocationFilterResponse] = []
|
|
82
|
+
for chunk in chunker_sequence(items, endpoint.item_limit):
|
|
83
|
+
request = RequestMessage2(
|
|
84
|
+
endpoint_url=self._make_url(endpoint.path),
|
|
85
|
+
method=endpoint.method,
|
|
86
|
+
body_content={"ids": [item.id for item in chunk]},
|
|
87
|
+
)
|
|
88
|
+
result = self._http_client.request_single_retries(request)
|
|
89
|
+
response = result.get_success_or_raise()
|
|
90
|
+
results.extend(self._validate_page_response(response).items)
|
|
91
|
+
return results
|
|
92
|
+
|
|
93
|
+
def update(self, items: Sequence[LocationFilterRequest]) -> list[LocationFilterResponse]:
|
|
94
|
+
"""Update an existing location filter.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
items: The updated location filter data.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
The updated location filter.
|
|
101
|
+
"""
|
|
102
|
+
endpoint = self._method_endpoint_map["update"]
|
|
103
|
+
results: list[LocationFilterResponse] = []
|
|
104
|
+
for item in items:
|
|
105
|
+
if item.id is None:
|
|
106
|
+
raise ValueError("Item must have an ID for update operation.")
|
|
107
|
+
request = RequestMessage2(
|
|
108
|
+
endpoint_url=self._make_url(endpoint.path.format(id=item.id)),
|
|
109
|
+
method=endpoint.method,
|
|
110
|
+
body_content=item.model_dump(mode="json", by_alias=True),
|
|
111
|
+
)
|
|
112
|
+
result = self._http_client.request_single_retries(request)
|
|
113
|
+
response = result.get_success_or_raise()
|
|
114
|
+
parsed = LocationFilterResponse.model_validate_json(response.body)
|
|
115
|
+
parsed.id = item.id
|
|
116
|
+
results.append(parsed)
|
|
117
|
+
return results
|
|
118
|
+
|
|
119
|
+
def delete(self, items: Sequence[InternalId]) -> list[LocationFilterResponse]:
|
|
120
|
+
"""Delete a location filter.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
items: The ID of the location filter to delete.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
list[LocationFilterResponse]: The deleted location filters.
|
|
127
|
+
"""
|
|
128
|
+
endpoint = self._method_endpoint_map["delete"]
|
|
129
|
+
results: list[LocationFilterResponse] = []
|
|
130
|
+
for item in items:
|
|
131
|
+
request = RequestMessage2(
|
|
132
|
+
endpoint_url=self._make_url(endpoint.path.format(id=item.id)),
|
|
133
|
+
method=endpoint.method,
|
|
134
|
+
)
|
|
135
|
+
result = self._http_client.request_single_retries(request)
|
|
136
|
+
response = result.get_success_or_raise()
|
|
137
|
+
results.append(LocationFilterResponse.model_validate_json(response.body))
|
|
138
|
+
return results
|
|
139
|
+
|
|
140
|
+
def paginate(
|
|
141
|
+
self,
|
|
142
|
+
flat: bool = True,
|
|
143
|
+
) -> PagedResponse[LocationFilterResponse]:
|
|
144
|
+
"""Get a single page of location filters.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
flat: Whether to return a flat list (default True).
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
PagedResponse of LocationFilterResponse objects.
|
|
151
|
+
"""
|
|
152
|
+
return self._paginate(cursor=None, limit=100, body={"flat": flat})
|
|
153
|
+
|
|
154
|
+
def iterate(
|
|
155
|
+
self,
|
|
156
|
+
flat: bool = True,
|
|
157
|
+
) -> Iterable[list[LocationFilterResponse]]:
|
|
158
|
+
"""Iterate over all location filters.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
flat: Whether to return a flat list (default True).
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
Iterable of lists of LocationFilterResponse objects.
|
|
165
|
+
"""
|
|
166
|
+
return self._iterate(limit=None, body={"flat": flat})
|
|
167
|
+
|
|
168
|
+
def list(self, flat: bool = True) -> list[LocationFilterResponse]:
|
|
169
|
+
"""List all location filters.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
flat: Whether to return a flat list (default True).
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
List of LocationFilterResponse objects.
|
|
176
|
+
"""
|
|
177
|
+
return self._list(limit=None, body={"flat": flat})
|
|
@@ -128,7 +128,7 @@ class RawTablesAPI(CDFResourceAPI[RAWTable, RAWTable, RAWTable]):
|
|
|
128
128
|
List of created RAWTable objects.
|
|
129
129
|
"""
|
|
130
130
|
result: list[RAWTable] = []
|
|
131
|
-
for db_name, group in self._group_items_by_text_field(items, "db_name").items():
|
|
131
|
+
for (db_name,), group in self._group_items_by_text_field(items, "db_name").items():
|
|
132
132
|
if not db_name:
|
|
133
133
|
raise ValueError("db_name must be set on all RAWTable items for creation.")
|
|
134
134
|
endpoint = f"/raw/dbs/{db_name}/tables"
|
|
@@ -145,7 +145,7 @@ class RawTablesAPI(CDFResourceAPI[RAWTable, RAWTable, RAWTable]):
|
|
|
145
145
|
Args:
|
|
146
146
|
items: List of RAWTable objects to delete.
|
|
147
147
|
"""
|
|
148
|
-
for db_name, group in self._group_items_by_text_field(items, "db_name").items():
|
|
148
|
+
for (db_name,), group in self._group_items_by_text_field(items, "db_name").items():
|
|
149
149
|
if not db_name:
|
|
150
150
|
raise ValueError("db_name must be set on all RAWTable items for deletion.")
|
|
151
151
|
endpoint = f"/raw/dbs/{db_name}/tables/delete"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_capabilities import CapabilitiesAPI
|
|
2
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_data_postprocessing import DataPostProcessingAPI
|
|
3
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_frames import FramesAPI
|
|
4
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_locations import LocationsAPI
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_maps import MapsAPI
|
|
6
|
+
from cognite_toolkit._cdf_tk.client.api.robotics_robots import RobotsAPI
|
|
7
|
+
from cognite_toolkit._cdf_tk.client.http_client import HTTPClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RoboticsAPI:
|
|
11
|
+
"""API for Robotics resources."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, http_client: HTTPClient) -> None:
|
|
14
|
+
self.capabilities = CapabilitiesAPI(http_client)
|
|
15
|
+
self.data_postprocessing = DataPostProcessingAPI(http_client)
|
|
16
|
+
self.frames = FramesAPI(http_client)
|
|
17
|
+
self.locations = LocationsAPI(http_client)
|
|
18
|
+
self.maps = MapsAPI(http_client)
|
|
19
|
+
self.robots = RobotsAPI(http_client)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from collections.abc import Iterable, Sequence
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from cognite_toolkit._cdf_tk.client.cdf_client import CDFResourceAPI, PagedResponse, ResponseItems
|
|
5
|
+
from cognite_toolkit._cdf_tk.client.cdf_client.api import Endpoint
|
|
6
|
+
from cognite_toolkit._cdf_tk.client.http_client import HTTPClient, ItemsSuccessResponse2, SuccessResponse2
|
|
7
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.identifiers import ExternalId
|
|
8
|
+
from cognite_toolkit._cdf_tk.client.resource_classes.robotics._capability import (
|
|
9
|
+
RobotCapabilityRequest,
|
|
10
|
+
RobotCapabilityResponse,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CapabilitiesAPI(CDFResourceAPI[ExternalId, RobotCapabilityRequest, RobotCapabilityResponse]):
|
|
15
|
+
"""API for managing Capability resources in CDF."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, http_client: HTTPClient) -> None:
|
|
18
|
+
super().__init__(
|
|
19
|
+
http_client=http_client,
|
|
20
|
+
method_endpoint_map={
|
|
21
|
+
"create": Endpoint(
|
|
22
|
+
method="POST", path="/robotics/capabilities", item_limit=1000, concurrency_max_workers=1
|
|
23
|
+
),
|
|
24
|
+
"retrieve": Endpoint(
|
|
25
|
+
method="POST", path="/robotics/capabilities/byids", item_limit=1000, concurrency_max_workers=1
|
|
26
|
+
),
|
|
27
|
+
"update": Endpoint(
|
|
28
|
+
method="POST", path="/robotics/capabilities/update", item_limit=1000, concurrency_max_workers=1
|
|
29
|
+
),
|
|
30
|
+
"delete": Endpoint(
|
|
31
|
+
method="POST", path="/robotics/capabilities/delete", item_limit=1000, concurrency_max_workers=1
|
|
32
|
+
),
|
|
33
|
+
"list": Endpoint(method="GET", path="/robotics/capabilities", item_limit=1000),
|
|
34
|
+
},
|
|
35
|
+
disable_gzip=True,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def _validate_page_response(
|
|
39
|
+
self, response: SuccessResponse2 | ItemsSuccessResponse2
|
|
40
|
+
) -> PagedResponse[RobotCapabilityResponse]:
|
|
41
|
+
return PagedResponse[RobotCapabilityResponse].model_validate_json(response.body)
|
|
42
|
+
|
|
43
|
+
def _reference_response(self, response: SuccessResponse2) -> ResponseItems[ExternalId]:
|
|
44
|
+
return ResponseItems[ExternalId].model_validate_json(response.body)
|
|
45
|
+
|
|
46
|
+
def create(self, items: Sequence[RobotCapabilityRequest]) -> list[RobotCapabilityResponse]:
|
|
47
|
+
"""Create capabilities in CDF.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
items: List of RobotCapabilityRequest objects to create.
|
|
51
|
+
Returns:
|
|
52
|
+
List of created RobotCapabilityResponse objects.
|
|
53
|
+
"""
|
|
54
|
+
return self._request_item_response(items, "create")
|
|
55
|
+
|
|
56
|
+
def retrieve(self, items: Sequence[ExternalId]) -> list[RobotCapabilityResponse]:
|
|
57
|
+
"""Retrieve capabilities from CDF.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
items: List of ExternalId objects to retrieve.
|
|
61
|
+
Returns:
|
|
62
|
+
List of retrieved RobotCapabilityResponse objects.
|
|
63
|
+
"""
|
|
64
|
+
return self._request_item_response(items, method="retrieve")
|
|
65
|
+
|
|
66
|
+
def update(
|
|
67
|
+
self, items: Sequence[RobotCapabilityRequest], mode: Literal["patch", "replace"] = "replace"
|
|
68
|
+
) -> list[RobotCapabilityResponse]:
|
|
69
|
+
"""Update capabilities in CDF.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
items: List of RobotCapabilityRequest objects to update.
|
|
73
|
+
mode: Update mode, either "patch" or "replace".
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
List of updated RobotCapabilityResponse objects.
|
|
77
|
+
"""
|
|
78
|
+
return self._update(items, mode=mode)
|
|
79
|
+
|
|
80
|
+
def delete(self, items: Sequence[ExternalId]) -> None:
|
|
81
|
+
"""Delete capabilities from CDF.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
items: List of ExternalId objects to delete.
|
|
85
|
+
"""
|
|
86
|
+
self._request_no_response(items, "delete")
|
|
87
|
+
|
|
88
|
+
def paginate(
|
|
89
|
+
self,
|
|
90
|
+
limit: int = 100,
|
|
91
|
+
cursor: str | None = None,
|
|
92
|
+
) -> PagedResponse[RobotCapabilityResponse]:
|
|
93
|
+
"""Paginate over capabilities in CDF.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
limit: Maximum number of items per page.
|
|
97
|
+
cursor: Cursor for pagination.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
PagedResponse of RobotCapabilityResponse objects.
|
|
101
|
+
"""
|
|
102
|
+
return self._paginate(cursor=cursor, limit=limit)
|
|
103
|
+
|
|
104
|
+
def iterate(
|
|
105
|
+
self,
|
|
106
|
+
limit: int | None = 100,
|
|
107
|
+
) -> Iterable[list[RobotCapabilityResponse]]:
|
|
108
|
+
"""Iterate over all capabilities in CDF.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
limit: Maximum number of items to return. None returns all.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Iterable of lists of RobotCapabilityResponse objects.
|
|
115
|
+
"""
|
|
116
|
+
return self._iterate(limit=limit)
|
|
117
|
+
|
|
118
|
+
def list(self, limit: int | None = 100) -> list[RobotCapabilityResponse]:
|
|
119
|
+
"""List all capabilities in CDF.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
limit: Maximum number of items to return. None returns all.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
List of RobotCapabilityResponse objects.
|
|
126
|
+
"""
|
|
127
|
+
return self._list(limit=limit)
|