cognite-neat 1.0.25__py3-none-any.whl → 1.0.26__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/neat/_client/api.py +173 -3
- cognite/neat/_client/containers_api.py +29 -90
- cognite/neat/_client/data_model_api.py +46 -74
- cognite/neat/_client/filters.py +40 -0
- cognite/neat/_client/spaces_api.py +32 -67
- cognite/neat/_client/statistics_api.py +9 -4
- cognite/neat/_client/views_api.py +39 -89
- cognite/neat/_data_model/models/dms/_base.py +3 -0
- cognite/neat/_utils/http_client/_client.py +3 -1
- cognite/neat/_utils/http_client/_data_classes.py +3 -3
- cognite/neat/_version.py +1 -1
- {cognite_neat-1.0.25.dist-info → cognite_neat-1.0.26.dist-info}/METADATA +1 -1
- {cognite_neat-1.0.25.dist-info → cognite_neat-1.0.26.dist-info}/RECORD +14 -13
- {cognite_neat-1.0.25.dist-info → cognite_neat-1.0.26.dist-info}/WHEEL +0 -0
cognite/neat/_client/api.py
CHANGED
|
@@ -1,8 +1,178 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import Iterable, Sequence
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Generic, Literal, TypeAlias, TypeVar
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, JsonValue, TypeAdapter
|
|
7
|
+
|
|
1
8
|
from cognite.neat._client.config import NeatClientConfig
|
|
2
|
-
from cognite.neat.
|
|
9
|
+
from cognite.neat._data_model.models.dms._base import T_Resource, T_Response
|
|
10
|
+
from cognite.neat._utils.collection import chunker_sequence
|
|
11
|
+
from cognite.neat._utils.http_client import HTTPClient, ParametersRequest, SimpleBodyRequest, SuccessResponse
|
|
12
|
+
from cognite.neat._utils.useful_types import T_Reference
|
|
13
|
+
|
|
14
|
+
from .data_classes import PagedResponse
|
|
15
|
+
|
|
16
|
+
_T_BaseModel = TypeVar("_T_BaseModel", bound=BaseModel)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class Endpoint:
|
|
21
|
+
method: Literal["GET", "POST"]
|
|
22
|
+
path: str
|
|
23
|
+
item_limit: int
|
|
3
24
|
|
|
4
25
|
|
|
5
|
-
|
|
6
|
-
|
|
26
|
+
APIMethod: TypeAlias = Literal["apply", "retrieve", "delete", "list"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class NeatAPI(Generic[T_Reference, T_Resource, T_Response], ABC):
|
|
30
|
+
def __init__(
|
|
31
|
+
self, neat_config: NeatClientConfig, http_client: HTTPClient, endpoint_map: dict[APIMethod, Endpoint]
|
|
32
|
+
) -> None:
|
|
7
33
|
self._config = neat_config
|
|
8
34
|
self._http_client = http_client
|
|
35
|
+
self._method_endpoint_map = endpoint_map
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def _validate_page_response(self, response: SuccessResponse) -> PagedResponse[T_Response]:
|
|
39
|
+
"""Parse a single item response."""
|
|
40
|
+
raise NotImplementedError()
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def _validate_id_response(self, response: SuccessResponse) -> list[T_Reference]:
|
|
44
|
+
"""Parse a single item response."""
|
|
45
|
+
raise NotImplementedError()
|
|
46
|
+
|
|
47
|
+
def _make_url(self, path: str = "") -> str:
|
|
48
|
+
"""Create the full URL for this resource endpoint."""
|
|
49
|
+
return self._config.create_api_url(path)
|
|
50
|
+
|
|
51
|
+
def _request_item_response(
|
|
52
|
+
self,
|
|
53
|
+
items: Sequence[BaseModel],
|
|
54
|
+
method: APIMethod,
|
|
55
|
+
extra_body: dict[str, Any] | None = None,
|
|
56
|
+
) -> list[T_Response]:
|
|
57
|
+
response_items: list[T_Response] = []
|
|
58
|
+
for response in self._chunk_requests(items, method, extra_body):
|
|
59
|
+
response_items.extend(self._validate_page_response(response).items)
|
|
60
|
+
return response_items
|
|
61
|
+
|
|
62
|
+
def _request_id_response(
|
|
63
|
+
self,
|
|
64
|
+
items: Sequence[BaseModel],
|
|
65
|
+
method: APIMethod,
|
|
66
|
+
extra_body: dict[str, Any] | None = None,
|
|
67
|
+
) -> list[T_Reference]:
|
|
68
|
+
response_items: list[T_Reference] = []
|
|
69
|
+
for response in self._chunk_requests(items, method, extra_body):
|
|
70
|
+
response_items.extend(self._validate_id_response(response))
|
|
71
|
+
return response_items
|
|
72
|
+
|
|
73
|
+
def _chunk_requests(
|
|
74
|
+
self,
|
|
75
|
+
items: Sequence[_T_BaseModel],
|
|
76
|
+
method: APIMethod,
|
|
77
|
+
extra_body: dict[str, Any] | None = None,
|
|
78
|
+
) -> Iterable[SuccessResponse]:
|
|
79
|
+
"""Send requests in chunks and yield responses.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
items: The items to process.
|
|
83
|
+
method: The API method to use. This is used ot look the up the endpoint.
|
|
84
|
+
extra_body: Optional extra body content to include in the request.
|
|
85
|
+
|
|
86
|
+
Yields:
|
|
87
|
+
The successful responses from the API.
|
|
88
|
+
"""
|
|
89
|
+
# Filter out None
|
|
90
|
+
endpoint = self._method_endpoint_map[method]
|
|
91
|
+
|
|
92
|
+
for chunk in chunker_sequence(items, endpoint.item_limit):
|
|
93
|
+
request = SimpleBodyRequest(
|
|
94
|
+
endpoint_url=self._make_url(endpoint.path),
|
|
95
|
+
method=endpoint.method,
|
|
96
|
+
body=TypeAdapter(dict[str, JsonValue]).dump_json(
|
|
97
|
+
{
|
|
98
|
+
"items": [item.model_dump(by_alias=True) for item in chunk],
|
|
99
|
+
**(extra_body or {}),
|
|
100
|
+
},
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
response = self._http_client.request_with_retries(request)
|
|
104
|
+
response.raise_for_status()
|
|
105
|
+
yield response.success_response
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
def _filter_out_none_values(cls, params: dict[str, Any] | None) -> dict[str, Any] | None:
|
|
109
|
+
request_params: dict[str, Any] | None = None
|
|
110
|
+
if params:
|
|
111
|
+
request_params = {k: v for k, v in params.items() if v is not None}
|
|
112
|
+
return request_params
|
|
113
|
+
|
|
114
|
+
def _paginate(
|
|
115
|
+
self,
|
|
116
|
+
limit: int,
|
|
117
|
+
cursor: str | None = None,
|
|
118
|
+
params: dict[str, Any] | None = None,
|
|
119
|
+
) -> PagedResponse[T_Response]:
|
|
120
|
+
"""Fetch a single page of resources.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
params: Query parameters for the request. Supported parameters depend on
|
|
124
|
+
the resource type but typically include:
|
|
125
|
+
- cursor: Cursor for pagination
|
|
126
|
+
- limit: Maximum number of items (defaults to list limit)
|
|
127
|
+
- space: Filter by space
|
|
128
|
+
- includeGlobal: Whether to include global resources
|
|
129
|
+
limit: Maximum number of items to return in the page.
|
|
130
|
+
cursor: Cursor for pagination.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
A Page containing the items and the cursor for the next page.
|
|
134
|
+
"""
|
|
135
|
+
endpoint = self._method_endpoint_map["list"]
|
|
136
|
+
if not (0 < limit <= endpoint.item_limit):
|
|
137
|
+
raise ValueError(f"Limit must be between 1 and {endpoint.item_limit}, got {limit}.")
|
|
138
|
+
if endpoint.method != "GET":
|
|
139
|
+
raise NotImplementedError(f"Pagination not implemented for method {endpoint.method}.")
|
|
140
|
+
request_params = self._filter_out_none_values(params) or {}
|
|
141
|
+
request_params["limit"] = limit
|
|
142
|
+
if cursor is not None:
|
|
143
|
+
request_params["cursor"] = cursor
|
|
144
|
+
request = ParametersRequest(
|
|
145
|
+
endpoint_url=self._make_url(endpoint.path),
|
|
146
|
+
method=endpoint.method,
|
|
147
|
+
parameters=request_params,
|
|
148
|
+
)
|
|
149
|
+
result = self._http_client.request_with_retries(request)
|
|
150
|
+
result.raise_for_status()
|
|
151
|
+
return self._validate_page_response(result.success_response)
|
|
152
|
+
|
|
153
|
+
def _iterate(
|
|
154
|
+
self,
|
|
155
|
+
limit: int | None = None,
|
|
156
|
+
cursor: str | None = None,
|
|
157
|
+
params: dict[str, Any] | None = None,
|
|
158
|
+
) -> Iterable[list[T_Response]]:
|
|
159
|
+
"""Iterate over all resources, handling pagination automatically."""
|
|
160
|
+
next_cursor = cursor
|
|
161
|
+
total = 0
|
|
162
|
+
endpoint = self._method_endpoint_map["list"]
|
|
163
|
+
while True:
|
|
164
|
+
page_limit = endpoint.item_limit if limit is None else min(limit - total, endpoint.item_limit)
|
|
165
|
+
page = self._paginate(limit=page_limit, cursor=next_cursor, params=params)
|
|
166
|
+
yield page.items
|
|
167
|
+
total += len(page.items)
|
|
168
|
+
if page.next_cursor is None or (limit is not None and total >= limit):
|
|
169
|
+
break
|
|
170
|
+
next_cursor = page.next_cursor
|
|
171
|
+
|
|
172
|
+
def _list(
|
|
173
|
+
self,
|
|
174
|
+
limit: int | None = None,
|
|
175
|
+
params: dict[str, Any] | None = None,
|
|
176
|
+
) -> list[T_Response]:
|
|
177
|
+
"""List all resources, handling pagination automatically."""
|
|
178
|
+
return [item for batch in self._iterate(limit=limit, params=params) for item in batch]
|
|
@@ -1,18 +1,32 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from collections.abc import Sequence
|
|
4
2
|
|
|
5
|
-
from cognite.neat._data_model.models.dms import ContainerReference, ContainerRequest, ContainerResponse
|
|
6
|
-
from cognite.neat._utils.http_client import
|
|
7
|
-
from cognite.neat._utils.useful_types import PrimitiveType
|
|
3
|
+
from cognite.neat._data_model.models.dms import ContainerReference, ContainerRequest, ContainerResponse
|
|
4
|
+
from cognite.neat._utils.http_client import HTTPClient, SuccessResponse
|
|
8
5
|
|
|
9
|
-
from .api import NeatAPI
|
|
6
|
+
from .api import Endpoint, NeatAPI
|
|
7
|
+
from .config import NeatClientConfig
|
|
10
8
|
from .data_classes import PagedResponse
|
|
9
|
+
from .filters import ContainerFilter
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class ContainersAPI(NeatAPI):
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
def __init__(self, neat_config: NeatClientConfig, http_client: HTTPClient) -> None:
|
|
14
|
+
super().__init__(
|
|
15
|
+
neat_config,
|
|
16
|
+
http_client,
|
|
17
|
+
endpoint_map={
|
|
18
|
+
"apply": Endpoint("POST", "models/containers", item_limit=100),
|
|
19
|
+
"retrieve": Endpoint("POST", "models/containers/byids", item_limit=100),
|
|
20
|
+
"delete": Endpoint("POST", "models/containers/delete", item_limit=100),
|
|
21
|
+
"list": Endpoint("GET", "models/containers", item_limit=1000),
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def _validate_page_response(self, response: SuccessResponse) -> PagedResponse[ContainerResponse]:
|
|
26
|
+
return PagedResponse[ContainerResponse].model_validate_json(response.body)
|
|
27
|
+
|
|
28
|
+
def _validate_id_response(self, response: SuccessResponse) -> list[ContainerReference]:
|
|
29
|
+
return PagedResponse[ContainerReference].model_validate_json(response.body).items
|
|
16
30
|
|
|
17
31
|
def apply(self, items: Sequence[ContainerRequest]) -> list[ContainerResponse]:
|
|
18
32
|
"""Apply (create or update) containers in CDF.
|
|
@@ -22,25 +36,9 @@ class ContainersAPI(NeatAPI):
|
|
|
22
36
|
Returns:
|
|
23
37
|
List of ContainerResponse objects.
|
|
24
38
|
"""
|
|
25
|
-
|
|
26
|
-
return []
|
|
27
|
-
if len(items) > 100:
|
|
28
|
-
raise ValueError("Cannot apply more than 100 containers at once.")
|
|
29
|
-
result = self._http_client.request_with_retries(
|
|
30
|
-
ItemsRequest(
|
|
31
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
32
|
-
method="POST",
|
|
33
|
-
body=DataModelBody(items=items),
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
result.raise_for_status()
|
|
37
|
-
result = PagedResponse[ContainerResponse].model_validate_json(result.success_response.body)
|
|
38
|
-
return result.items
|
|
39
|
+
return self._request_item_response(items, "apply")
|
|
39
40
|
|
|
40
|
-
def retrieve(
|
|
41
|
-
self,
|
|
42
|
-
items: list[ContainerReference],
|
|
43
|
-
) -> list[ContainerResponse]:
|
|
41
|
+
def retrieve(self, items: list[ContainerReference]) -> list[ContainerResponse]:
|
|
44
42
|
"""Retrieve containers by their identifiers.
|
|
45
43
|
|
|
46
44
|
Args:
|
|
@@ -49,21 +47,7 @@ class ContainersAPI(NeatAPI):
|
|
|
49
47
|
Returns:
|
|
50
48
|
List of ContainerResponse objects.
|
|
51
49
|
"""
|
|
52
|
-
|
|
53
|
-
return []
|
|
54
|
-
if len(items) > 1000:
|
|
55
|
-
raise ValueError("Cannot retrieve more than 1000 containers at once.")
|
|
56
|
-
|
|
57
|
-
result = self._http_client.request_with_retries(
|
|
58
|
-
ItemsRequest(
|
|
59
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/byids"),
|
|
60
|
-
method="POST",
|
|
61
|
-
body=ItemIDBody(items=items),
|
|
62
|
-
)
|
|
63
|
-
)
|
|
64
|
-
result.raise_for_status()
|
|
65
|
-
result = PagedResponse[ContainerResponse].model_validate_json(result.success_response.body)
|
|
66
|
-
return result.items
|
|
50
|
+
return self._request_item_response(items, "retrieve")
|
|
67
51
|
|
|
68
52
|
def delete(self, items: list[ContainerReference]) -> list[ContainerReference]:
|
|
69
53
|
"""Delete containers by their identifiers.
|
|
@@ -74,27 +58,10 @@ class ContainersAPI(NeatAPI):
|
|
|
74
58
|
Returns:
|
|
75
59
|
List of ContainerReference objects representing the deleted containers.
|
|
76
60
|
"""
|
|
77
|
-
|
|
78
|
-
return []
|
|
79
|
-
if len(items) > 100:
|
|
80
|
-
raise ValueError("Cannot delete more than 100 containers at once.")
|
|
81
|
-
|
|
82
|
-
result = self._http_client.request_with_retries(
|
|
83
|
-
ItemsRequest(
|
|
84
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
|
|
85
|
-
method="POST",
|
|
86
|
-
body=ItemIDBody(items=items),
|
|
87
|
-
)
|
|
88
|
-
)
|
|
89
|
-
result.raise_for_status()
|
|
90
|
-
result = PagedResponse[ContainerReference].model_validate_json(result.success_response.body)
|
|
91
|
-
return result.items
|
|
61
|
+
return self._request_id_response(items, "delete")
|
|
92
62
|
|
|
93
63
|
def list(
|
|
94
|
-
self,
|
|
95
|
-
space: str | None = None,
|
|
96
|
-
include_global: bool = False,
|
|
97
|
-
limit: int | None = 10,
|
|
64
|
+
self, space: str | None = None, include_global: bool = False, limit: int | None = 10
|
|
98
65
|
) -> list[ContainerResponse]:
|
|
99
66
|
"""List containers in CDF Project.
|
|
100
67
|
|
|
@@ -106,33 +73,5 @@ class ContainersAPI(NeatAPI):
|
|
|
106
73
|
Returns:
|
|
107
74
|
List of ContainerResponse objects.
|
|
108
75
|
"""
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
elif limit is not None and limit == 0:
|
|
112
|
-
return []
|
|
113
|
-
parameters: dict[str, PrimitiveType] = {"includeGlobal": include_global}
|
|
114
|
-
if space is not None:
|
|
115
|
-
parameters["space"] = space
|
|
116
|
-
cursor: str | None = None
|
|
117
|
-
container_responses: list[ContainerResponse] = []
|
|
118
|
-
while True:
|
|
119
|
-
if cursor is not None:
|
|
120
|
-
parameters["cursor"] = cursor
|
|
121
|
-
if limit is None:
|
|
122
|
-
parameters["limit"] = self.LIST_REQUEST_LIMIT
|
|
123
|
-
else:
|
|
124
|
-
parameters["limit"] = min(self.LIST_REQUEST_LIMIT, limit - len(container_responses))
|
|
125
|
-
result = self._http_client.request_with_retries(
|
|
126
|
-
ParametersRequest(
|
|
127
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
128
|
-
method="GET",
|
|
129
|
-
parameters=parameters,
|
|
130
|
-
)
|
|
131
|
-
)
|
|
132
|
-
result.raise_for_status()
|
|
133
|
-
result = PagedResponse[ContainerResponse].model_validate_json(result.success_response.body)
|
|
134
|
-
container_responses.extend(result.items)
|
|
135
|
-
cursor = result.next_cursor
|
|
136
|
-
if cursor is None or (limit is not None and len(container_responses) >= limit):
|
|
137
|
-
break
|
|
138
|
-
return container_responses
|
|
76
|
+
filter = ContainerFilter(space=space, include_global=include_global)
|
|
77
|
+
return self._list(limit=limit, params=filter.dump())
|
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
from collections.abc import Sequence
|
|
2
2
|
|
|
3
|
-
from cognite.neat._data_model.models.dms import
|
|
4
|
-
from cognite.neat._utils.http_client import
|
|
5
|
-
from cognite.neat._utils.useful_types import PrimitiveType
|
|
3
|
+
from cognite.neat._data_model.models.dms import DataModelReference, DataModelRequest, DataModelResponse
|
|
4
|
+
from cognite.neat._utils.http_client import HTTPClient, SuccessResponse
|
|
6
5
|
|
|
7
|
-
from .api import NeatAPI
|
|
6
|
+
from .api import Endpoint, NeatAPI
|
|
7
|
+
from .config import NeatClientConfig
|
|
8
8
|
from .data_classes import PagedResponse
|
|
9
|
+
from .filters import DataModelFilter
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class DataModelsAPI(NeatAPI):
|
|
12
|
-
|
|
13
|
+
def __init__(self, neat_config: NeatClientConfig, http_client: HTTPClient) -> None:
|
|
14
|
+
super().__init__(
|
|
15
|
+
neat_config,
|
|
16
|
+
http_client,
|
|
17
|
+
endpoint_map={
|
|
18
|
+
"apply": Endpoint("POST", "/models/datamodels", item_limit=100),
|
|
19
|
+
"retrieve": Endpoint("POST", "/models/datamodels/byids", item_limit=100),
|
|
20
|
+
"delete": Endpoint("POST", "/models/datamodels/delete", item_limit=100),
|
|
21
|
+
"list": Endpoint("GET", "/models/datamodels", item_limit=1000),
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def _validate_page_response(self, response: SuccessResponse) -> PagedResponse[DataModelResponse]:
|
|
26
|
+
return PagedResponse[DataModelResponse].model_validate_json(response.body)
|
|
27
|
+
|
|
28
|
+
def _validate_id_response(self, response: SuccessResponse) -> list[DataModelReference]:
|
|
29
|
+
return PagedResponse[DataModelReference].model_validate_json(response.body).items
|
|
13
30
|
|
|
14
31
|
def apply(self, data_models: Sequence[DataModelRequest]) -> list[DataModelResponse]:
|
|
15
32
|
"""Apply (create or update) data models in CDF.
|
|
@@ -19,26 +36,9 @@ class DataModelsAPI(NeatAPI):
|
|
|
19
36
|
Returns:
|
|
20
37
|
List of DataModelResponse objects.
|
|
21
38
|
"""
|
|
22
|
-
|
|
23
|
-
return []
|
|
24
|
-
if len(data_models) > 100:
|
|
25
|
-
raise ValueError("Cannot apply more than 100 data models at once.")
|
|
26
|
-
|
|
27
|
-
result = self._http_client.request_with_retries(
|
|
28
|
-
ItemsRequest(
|
|
29
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
30
|
-
method="POST",
|
|
31
|
-
body=DataModelBody(items=data_models),
|
|
32
|
-
)
|
|
33
|
-
)
|
|
34
|
-
result.raise_for_status()
|
|
35
|
-
result = PagedResponse[DataModelResponse].model_validate_json(result.success_response.body)
|
|
36
|
-
return result.items
|
|
39
|
+
return self._request_item_response(data_models, "apply")
|
|
37
40
|
|
|
38
|
-
def retrieve(
|
|
39
|
-
self,
|
|
40
|
-
items: list[DataModelReference],
|
|
41
|
-
) -> list[DataModelResponse]:
|
|
41
|
+
def retrieve(self, items: list[DataModelReference]) -> list[DataModelResponse]:
|
|
42
42
|
"""Retrieve data models by their identifiers.
|
|
43
43
|
|
|
44
44
|
Args:
|
|
@@ -46,21 +46,7 @@ class DataModelsAPI(NeatAPI):
|
|
|
46
46
|
Returns:
|
|
47
47
|
List of DataModelResponse objects.
|
|
48
48
|
"""
|
|
49
|
-
|
|
50
|
-
return []
|
|
51
|
-
if len(items) > 100:
|
|
52
|
-
raise ValueError("Cannot retrieve more than 1000 containers at once.")
|
|
53
|
-
|
|
54
|
-
result = self._http_client.request_with_retries(
|
|
55
|
-
ItemsRequest(
|
|
56
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/byids"),
|
|
57
|
-
method="POST",
|
|
58
|
-
body=ItemIDBody(items=items),
|
|
59
|
-
)
|
|
60
|
-
)
|
|
61
|
-
result.raise_for_status()
|
|
62
|
-
result = PagedResponse[DataModelResponse].model_validate_json(result.success_response.body)
|
|
63
|
-
return result.items
|
|
49
|
+
return self._request_item_response(items, "retrieve")
|
|
64
50
|
|
|
65
51
|
def delete(self, items: list[DataModelReference]) -> list[DataModelReference]:
|
|
66
52
|
"""Delete data models by their identifiers.
|
|
@@ -70,46 +56,32 @@ class DataModelsAPI(NeatAPI):
|
|
|
70
56
|
Returns:
|
|
71
57
|
List of DataModelReference objects representing the deleted data models.
|
|
72
58
|
"""
|
|
73
|
-
|
|
74
|
-
return []
|
|
75
|
-
if len(items) > 100:
|
|
76
|
-
raise ValueError("Cannot delete more than 100 data models at once.")
|
|
77
|
-
|
|
78
|
-
result = self._http_client.request_with_retries(
|
|
79
|
-
ItemsRequest(
|
|
80
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
|
|
81
|
-
method="POST",
|
|
82
|
-
body=ItemIDBody(items=items),
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
result.raise_for_status()
|
|
86
|
-
result = PagedResponse[DataModelReference].model_validate_json(result.success_response.body)
|
|
87
|
-
return result.items
|
|
59
|
+
return self._request_id_response(items, "delete")
|
|
88
60
|
|
|
89
61
|
def list(
|
|
90
62
|
self,
|
|
91
63
|
space: str | None = None,
|
|
92
64
|
all_versions: bool = False,
|
|
65
|
+
inline_views: bool = False,
|
|
93
66
|
include_global: bool = False,
|
|
94
|
-
limit: int = 10,
|
|
67
|
+
limit: int | None = 10,
|
|
95
68
|
) -> list[DataModelResponse]:
|
|
96
|
-
"""List data models in CDF Project.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
69
|
+
"""List data models in CDF Project.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
space: If specified, only data models in this space are returned.
|
|
73
|
+
all_versions: If True, return all versions. If False, only return the latest version.
|
|
74
|
+
inline_views: If True, include views inline in the response.
|
|
75
|
+
include_global: If True, include global data models.
|
|
76
|
+
limit: Maximum number of data models to return. If None, return all data models.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
List of DataModelResponse objects.
|
|
80
|
+
"""
|
|
81
|
+
filter = DataModelFilter(
|
|
82
|
+
space=space,
|
|
83
|
+
all_versions=all_versions,
|
|
84
|
+
inline_views=inline_views,
|
|
85
|
+
include_global=include_global,
|
|
112
86
|
)
|
|
113
|
-
|
|
114
|
-
result = PagedResponse[DataModelResponse].model_validate_json(result.success_response.body)
|
|
115
|
-
return result.items
|
|
87
|
+
return self._list(limit=limit, params=filter.dump())
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Any, Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict
|
|
4
|
+
from pydantic.alias_generators import to_camel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseModelRequest(BaseModel):
|
|
8
|
+
"""Base class for all object. This includes resources and nested objects."""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Filter(BaseModel):
|
|
12
|
+
model_config = ConfigDict(alias_generator=to_camel, extra="ignore", populate_by_name=True)
|
|
13
|
+
|
|
14
|
+
def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
|
15
|
+
"""Dump the object to a dictionary.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
camel_case (bool): Whether to use camelCase for the keys. Default is True.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
return self.model_dump(mode="json", by_alias=camel_case, exclude_unset=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DataModelingFilter(Filter):
|
|
25
|
+
space: str | None = None
|
|
26
|
+
include_global: bool | None = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ContainerFilter(DataModelingFilter):
|
|
30
|
+
used_for: Literal["node", "edge", "record", "all"] | None = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ViewFilter(DataModelingFilter):
|
|
34
|
+
include_inherited_properties: bool | None = None
|
|
35
|
+
all_versions: bool | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class DataModelFilter(DataModelingFilter):
|
|
39
|
+
inline_views: bool | None = None
|
|
40
|
+
all_versions: bool | None = None
|
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
|
|
5
|
+
from cognite.neat._data_model.models.dms import SpaceRequest, SpaceResponse
|
|
4
6
|
from cognite.neat._data_model.models.dms._references import SpaceReference
|
|
5
|
-
from cognite.neat._utils.http_client import
|
|
6
|
-
from cognite.neat._utils.useful_types import PrimitiveType
|
|
7
|
+
from cognite.neat._utils.http_client import HTTPClient, SuccessResponse
|
|
7
8
|
|
|
8
|
-
from .api import NeatAPI
|
|
9
|
+
from .api import Endpoint, NeatAPI
|
|
10
|
+
from .config import NeatClientConfig
|
|
9
11
|
from .data_classes import PagedResponse
|
|
12
|
+
from .filters import DataModelingFilter
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
class SpacesAPI(NeatAPI):
|
|
13
|
-
|
|
16
|
+
def __init__(self, neat_config: NeatClientConfig, http_client: HTTPClient) -> None:
|
|
17
|
+
super().__init__(
|
|
18
|
+
neat_config,
|
|
19
|
+
http_client,
|
|
20
|
+
endpoint_map={
|
|
21
|
+
"apply": Endpoint("POST", "/models/spaces", item_limit=100),
|
|
22
|
+
"retrieve": Endpoint("POST", "/models/spaces/byids", item_limit=100),
|
|
23
|
+
"delete": Endpoint("POST", "/models/spaces/delete", item_limit=100),
|
|
24
|
+
"list": Endpoint("GET", "/models/spaces", item_limit=1000),
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def _validate_page_response(self, response: SuccessResponse) -> PagedResponse[SpaceResponse]:
|
|
29
|
+
return PagedResponse[SpaceResponse].model_validate_json(response.body)
|
|
30
|
+
|
|
31
|
+
def _validate_id_response(self, response: SuccessResponse) -> list[SpaceReference]:
|
|
32
|
+
return PagedResponse[SpaceReference].model_validate_json(response.body).items
|
|
14
33
|
|
|
15
|
-
def apply(self, spaces:
|
|
34
|
+
def apply(self, spaces: Sequence[SpaceRequest]) -> list[SpaceResponse]:
|
|
16
35
|
"""Apply (create or update) spaces in CDF.
|
|
17
36
|
|
|
18
37
|
Args:
|
|
@@ -20,20 +39,7 @@ class SpacesAPI(NeatAPI):
|
|
|
20
39
|
Returns:
|
|
21
40
|
List of SpaceResponse objects.
|
|
22
41
|
"""
|
|
23
|
-
|
|
24
|
-
return []
|
|
25
|
-
if len(spaces) > 100:
|
|
26
|
-
raise ValueError("Cannot apply more than 100 spaces at once.")
|
|
27
|
-
result = self._http_client.request_with_retries(
|
|
28
|
-
ItemsRequest(
|
|
29
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
30
|
-
method="POST",
|
|
31
|
-
body=DataModelBody(items=spaces),
|
|
32
|
-
)
|
|
33
|
-
)
|
|
34
|
-
result.raise_for_status()
|
|
35
|
-
result = PagedResponse[SpaceResponse].model_validate_json(result.success_response.body)
|
|
36
|
-
return result.items
|
|
42
|
+
return self._request_item_response(spaces, "apply")
|
|
37
43
|
|
|
38
44
|
def retrieve(self, spaces: list[SpaceReference]) -> list[SpaceResponse]:
|
|
39
45
|
"""Retrieve spaces by their identifiers.
|
|
@@ -44,21 +50,7 @@ class SpacesAPI(NeatAPI):
|
|
|
44
50
|
Returns:
|
|
45
51
|
List of SpaceResponse objects.
|
|
46
52
|
"""
|
|
47
|
-
|
|
48
|
-
return []
|
|
49
|
-
if len(spaces) > 1000:
|
|
50
|
-
raise ValueError("Cannot retrieve more than 1000 spaces at once.")
|
|
51
|
-
|
|
52
|
-
result = self._http_client.request_with_retries(
|
|
53
|
-
ItemsRequest(
|
|
54
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/byids"),
|
|
55
|
-
method="POST",
|
|
56
|
-
body=ItemIDBody(items=spaces),
|
|
57
|
-
)
|
|
58
|
-
)
|
|
59
|
-
result.raise_for_status()
|
|
60
|
-
result = PagedResponse[SpaceResponse].model_validate_json(result.success_response.body)
|
|
61
|
-
return result.items
|
|
53
|
+
return self._request_item_response(spaces, "retrieve")
|
|
62
54
|
|
|
63
55
|
def delete(self, spaces: list[SpaceReference]) -> list[SpaceReference]:
|
|
64
56
|
"""Delete spaces by their identifiers.
|
|
@@ -68,48 +60,21 @@ class SpacesAPI(NeatAPI):
|
|
|
68
60
|
Returns:
|
|
69
61
|
List of SpaceReference objects representing the deleted spaces.
|
|
70
62
|
"""
|
|
71
|
-
|
|
72
|
-
return []
|
|
73
|
-
if len(spaces) > 100:
|
|
74
|
-
raise ValueError("Cannot delete more than 100 spaces at once.")
|
|
75
|
-
result = self._http_client.request_with_retries(
|
|
76
|
-
ItemsRequest(
|
|
77
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
|
|
78
|
-
method="POST",
|
|
79
|
-
body=ItemIDBody(items=spaces),
|
|
80
|
-
)
|
|
81
|
-
)
|
|
82
|
-
result.raise_for_status()
|
|
83
|
-
result = PagedResponse[SpaceReference].model_validate_json(result.success_response.body)
|
|
84
|
-
return result.items
|
|
63
|
+
return self._request_id_response(spaces, "delete")
|
|
85
64
|
|
|
86
65
|
def list(
|
|
87
66
|
self,
|
|
88
67
|
include_global: bool = False,
|
|
89
|
-
limit: int = 10,
|
|
68
|
+
limit: int | None = 10,
|
|
90
69
|
) -> list[SpaceResponse]:
|
|
91
70
|
"""List spaces in CDF Project.
|
|
92
71
|
|
|
93
72
|
Args:
|
|
94
73
|
include_global: If True, include global spaces.
|
|
95
|
-
limit: Maximum number of spaces to return.
|
|
74
|
+
limit: Maximum number of spaces to return. If None, return all spaces.
|
|
96
75
|
|
|
97
76
|
Returns:
|
|
98
77
|
List of SpaceResponse objects.
|
|
99
78
|
"""
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
parameters: dict[str, PrimitiveType] = {
|
|
103
|
-
"includeGlobal": include_global,
|
|
104
|
-
"limit": limit,
|
|
105
|
-
}
|
|
106
|
-
result = self._http_client.request_with_retries(
|
|
107
|
-
ParametersRequest(
|
|
108
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
109
|
-
method="GET",
|
|
110
|
-
parameters=parameters,
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
|
-
result.raise_for_status()
|
|
114
|
-
result = PagedResponse[SpaceResponse].model_validate_json(result.success_response.body)
|
|
115
|
-
return result.items
|
|
79
|
+
filter = DataModelingFilter(include_global=include_global)
|
|
80
|
+
return self._list(limit=limit, params=filter.dump())
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
from cognite.neat.
|
|
2
|
-
from cognite.neat._client.data_classes import StatisticsResponse
|
|
3
|
-
from cognite.neat._utils.http_client import ParametersRequest
|
|
1
|
+
from cognite.neat._utils.http_client import HTTPClient, ParametersRequest
|
|
4
2
|
|
|
3
|
+
from .config import NeatClientConfig
|
|
4
|
+
from .data_classes import StatisticsResponse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StatisticsAPI:
|
|
8
|
+
def __init__(self, neat_config: NeatClientConfig, http_client: HTTPClient) -> None:
|
|
9
|
+
self._config = neat_config
|
|
10
|
+
self._http_client = http_client
|
|
5
11
|
|
|
6
|
-
class StatisticsAPI(NeatAPI):
|
|
7
12
|
def project(self) -> StatisticsResponse:
|
|
8
13
|
"""Retrieve project-wide usage data and limits.
|
|
9
14
|
|
|
@@ -2,46 +2,45 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from collections.abc import Sequence
|
|
4
4
|
|
|
5
|
-
from cognite.neat._data_model.models.dms import
|
|
6
|
-
from cognite.neat._utils.
|
|
7
|
-
from cognite.neat._utils.http_client import ItemIDBody, ItemsRequest, ParametersRequest
|
|
8
|
-
from cognite.neat._utils.useful_types import PrimitiveType
|
|
5
|
+
from cognite.neat._data_model.models.dms import ViewReference, ViewRequest, ViewResponse
|
|
6
|
+
from cognite.neat._utils.http_client import HTTPClient, SuccessResponse
|
|
9
7
|
|
|
10
|
-
from .api import NeatAPI
|
|
8
|
+
from .api import Endpoint, NeatAPI
|
|
9
|
+
from .config import NeatClientConfig
|
|
11
10
|
from .data_classes import PagedResponse
|
|
11
|
+
from .filters import ViewFilter
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class ViewsAPI(NeatAPI):
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
def __init__(self, neat_config: NeatClientConfig, http_client: HTTPClient) -> None:
|
|
16
|
+
super().__init__(
|
|
17
|
+
neat_config,
|
|
18
|
+
http_client,
|
|
19
|
+
endpoint_map={
|
|
20
|
+
"apply": Endpoint("POST", "/models/views", item_limit=100),
|
|
21
|
+
"retrieve": Endpoint("POST", "/models/views/byids", item_limit=100),
|
|
22
|
+
"delete": Endpoint("POST", "/models/views/delete", item_limit=100),
|
|
23
|
+
"list": Endpoint("GET", "/models/views", item_limit=1000),
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def _validate_page_response(self, response: SuccessResponse) -> PagedResponse[ViewResponse]:
|
|
28
|
+
return PagedResponse[ViewResponse].model_validate_json(response.body)
|
|
29
|
+
|
|
30
|
+
def _validate_id_response(self, response: SuccessResponse) -> list[ViewReference]:
|
|
31
|
+
return PagedResponse[ViewReference].model_validate_json(response.body).items
|
|
17
32
|
|
|
18
33
|
def apply(self, items: Sequence[ViewRequest]) -> list[ViewResponse]:
|
|
19
34
|
"""Create or update views in CDF Project.
|
|
35
|
+
|
|
20
36
|
Args:
|
|
21
37
|
items: List of ViewRequest objects to create or update.
|
|
22
38
|
Returns:
|
|
23
39
|
List of ViewResponse objects.
|
|
24
40
|
"""
|
|
25
|
-
|
|
26
|
-
return []
|
|
27
|
-
if len(items) > 100:
|
|
28
|
-
raise ValueError("Cannot apply more than 100 views at once.")
|
|
29
|
-
result = self._http_client.request_with_retries(
|
|
30
|
-
ItemsRequest(
|
|
31
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
32
|
-
method="POST",
|
|
33
|
-
body=DataModelBody(items=items),
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
result.raise_for_status()
|
|
37
|
-
result = PagedResponse[ViewResponse].model_validate_json(result.success_response.body)
|
|
38
|
-
return result.items
|
|
41
|
+
return self._request_item_response(items, "apply")
|
|
39
42
|
|
|
40
|
-
def retrieve(
|
|
41
|
-
self,
|
|
42
|
-
items: list[ViewReference],
|
|
43
|
-
include_inherited_properties: bool = True,
|
|
44
|
-
) -> list[ViewResponse]:
|
|
43
|
+
def retrieve(self, items: list[ViewReference], include_inherited_properties: bool = True) -> list[ViewResponse]:
|
|
45
44
|
"""Retrieve views by their identifiers.
|
|
46
45
|
|
|
47
46
|
Args:
|
|
@@ -51,42 +50,20 @@ class ViewsAPI(NeatAPI):
|
|
|
51
50
|
Returns:
|
|
52
51
|
List of ViewResponse objects.
|
|
53
52
|
"""
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
ItemsRequest(
|
|
58
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/byids"),
|
|
59
|
-
method="POST",
|
|
60
|
-
body=ItemIDBody(items=chunk),
|
|
61
|
-
parameters={"includeInheritedProperties": include_inherited_properties},
|
|
62
|
-
)
|
|
63
|
-
)
|
|
64
|
-
batch.raise_for_status()
|
|
65
|
-
result = PagedResponse[ViewResponse].model_validate_json(batch.success_response.body)
|
|
66
|
-
results.extend(result.items)
|
|
67
|
-
return results
|
|
53
|
+
return self._request_item_response(
|
|
54
|
+
items, "retrieve", extra_body={"includeInheritedProperties": include_inherited_properties}
|
|
55
|
+
)
|
|
68
56
|
|
|
69
57
|
def delete(self, items: list[ViewReference]) -> list[ViewReference]:
|
|
70
58
|
"""Delete views by their identifiers.
|
|
71
59
|
|
|
72
60
|
Args:
|
|
73
61
|
items: List of (space, external_id, version) tuples identifying the views to delete.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
List of ViewReference objects representing the deleted views.
|
|
74
65
|
"""
|
|
75
|
-
|
|
76
|
-
return []
|
|
77
|
-
if len(items) > 100:
|
|
78
|
-
raise ValueError("Cannot delete more than 100 views at once.")
|
|
79
|
-
|
|
80
|
-
result = self._http_client.request_with_retries(
|
|
81
|
-
ItemsRequest(
|
|
82
|
-
endpoint_url=self._config.create_api_url(f"{self.ENDPOINT}/delete"),
|
|
83
|
-
method="POST",
|
|
84
|
-
body=ItemIDBody(items=items),
|
|
85
|
-
)
|
|
86
|
-
)
|
|
87
|
-
result.raise_for_status()
|
|
88
|
-
result = PagedResponse[ViewReference].model_validate_json(result.success_response.body)
|
|
89
|
-
return result.items
|
|
66
|
+
return self._request_id_response(items, "delete")
|
|
90
67
|
|
|
91
68
|
def list(
|
|
92
69
|
self,
|
|
@@ -108,37 +85,10 @@ class ViewsAPI(NeatAPI):
|
|
|
108
85
|
Returns:
|
|
109
86
|
List of ViewResponse objects.
|
|
110
87
|
"""
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
"includeGlobal": include_global,
|
|
119
|
-
}
|
|
120
|
-
if space is not None:
|
|
121
|
-
parameters["space"] = space
|
|
122
|
-
cursor: str | None = None
|
|
123
|
-
view_responses: list[ViewResponse] = []
|
|
124
|
-
while True:
|
|
125
|
-
if cursor is not None:
|
|
126
|
-
parameters["cursor"] = cursor
|
|
127
|
-
if limit is None:
|
|
128
|
-
parameters["limit"] = self.LIST_REQUEST_LIMIT
|
|
129
|
-
else:
|
|
130
|
-
parameters["limit"] = min(self.LIST_REQUEST_LIMIT, limit - len(view_responses))
|
|
131
|
-
result = self._http_client.request_with_retries(
|
|
132
|
-
ParametersRequest(
|
|
133
|
-
endpoint_url=self._config.create_api_url(self.ENDPOINT),
|
|
134
|
-
method="GET",
|
|
135
|
-
parameters=parameters,
|
|
136
|
-
)
|
|
137
|
-
)
|
|
138
|
-
result.raise_for_status()
|
|
139
|
-
result = PagedResponse[ViewResponse].model_validate_json(result.success_response.body)
|
|
140
|
-
view_responses.extend(result.items)
|
|
141
|
-
cursor = result.next_cursor
|
|
142
|
-
if cursor is None or (limit is not None and len(view_responses) >= limit):
|
|
143
|
-
break
|
|
144
|
-
return view_responses
|
|
88
|
+
filter = ViewFilter(
|
|
89
|
+
space=space,
|
|
90
|
+
all_versions=all_versions,
|
|
91
|
+
include_inherited_properties=include_inherited_properties,
|
|
92
|
+
include_global=include_global,
|
|
93
|
+
)
|
|
94
|
+
return self._list(limit=limit, params=filter.dump())
|
|
@@ -22,6 +22,9 @@ class WriteableResource(Resource, Generic[T_Resource], ABC):
|
|
|
22
22
|
raise NotImplementedError()
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
T_Response = TypeVar("T_Response", bound=WriteableResource)
|
|
26
|
+
|
|
27
|
+
|
|
25
28
|
class APIResource(Generic[T_Reference], ABC):
|
|
26
29
|
"""Base class for all API data modeling resources."""
|
|
27
30
|
|
|
@@ -167,7 +167,9 @@ class HTTPClient:
|
|
|
167
167
|
if isinstance(item, BodyRequest):
|
|
168
168
|
data = item.data()
|
|
169
169
|
if not global_config.disable_gzip:
|
|
170
|
-
|
|
170
|
+
if isinstance(data, str):
|
|
171
|
+
data = data.encode("utf-8")
|
|
172
|
+
data = gzip.compress(data)
|
|
171
173
|
return self.session.request(
|
|
172
174
|
method=item.method,
|
|
173
175
|
url=item.endpoint_url,
|
|
@@ -118,14 +118,14 @@ class BodyRequest(ParametersRequest, ABC):
|
|
|
118
118
|
"""Base class for HTTP request messages with a body"""
|
|
119
119
|
|
|
120
120
|
@abstractmethod
|
|
121
|
-
def data(self) -> str:
|
|
121
|
+
def data(self) -> str | bytes:
|
|
122
122
|
raise NotImplementedError()
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
class SimpleBodyRequest(BodyRequest):
|
|
126
|
-
body: str
|
|
126
|
+
body: str | bytes
|
|
127
127
|
|
|
128
|
-
def data(self) -> str:
|
|
128
|
+
def data(self) -> str | bytes:
|
|
129
129
|
return self.body
|
|
130
130
|
|
|
131
131
|
|
cognite/neat/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "1.0.
|
|
1
|
+
__version__ = "1.0.26"
|
|
2
2
|
__engine__ = "^2.0.4"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognite-neat
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.26
|
|
4
4
|
Summary: Knowledge graph transformation
|
|
5
5
|
Author: Nikola Vasiljevic, Anders Albert
|
|
6
6
|
Author-email: Nikola Vasiljevic <nikola.vasiljevic@cognite.com>, Anders Albert <anders.albert@cognite.com>
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=YU2PPtzByiyLcUeWePkckaL9v-ZxoR6OF6wiq-2XVwM,297
|
|
2
2
|
cognite/neat/_client/__init__.py,sha256=DIHMeggZ81rVJwO97E5PVP8AwVAhhLpjBQu7Ns3_xdc,178
|
|
3
|
-
cognite/neat/_client/api.py,sha256=
|
|
3
|
+
cognite/neat/_client/api.py,sha256=VOtXyr9-Ouxkl3nWUj6fffr-9VG6wzVRGWSr_QqR5d8,6915
|
|
4
4
|
cognite/neat/_client/client.py,sha256=h0HELAHiBFxMNInkDu4AzbgfEIXqeM0BqqnMBmXjgi0,903
|
|
5
5
|
cognite/neat/_client/config.py,sha256=eIIdWaA13yncRP6X7vTYsTpmXmVcmkhZPv5oPnLUEVc,1484
|
|
6
|
-
cognite/neat/_client/containers_api.py,sha256=
|
|
6
|
+
cognite/neat/_client/containers_api.py,sha256=zFHb9SwfwqAxUkrEStLBV8BDSvRWvBBOY8mVuCIOWQU,3116
|
|
7
7
|
cognite/neat/_client/data_classes.py,sha256=HYPsrAJGVCUmlWTSIxJgAnIHAOzcyDveMM6Z-cuA92M,1404
|
|
8
|
-
cognite/neat/_client/data_model_api.py,sha256=
|
|
8
|
+
cognite/neat/_client/data_model_api.py,sha256=fxJ77RbKd8UAsm4jfDH3P16Jp-GwKWPrxx2jyA_xCnk,3518
|
|
9
|
+
cognite/neat/_client/filters.py,sha256=1tPpbp_GFAh7Jq5tdwUvZz6nOoWB36zIxa_ZO-1UER0,1138
|
|
9
10
|
cognite/neat/_client/init/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
11
|
cognite/neat/_client/init/credentials.py,sha256=8PCKk-rc3rxG3l9vNiY3DklIziJgJpBr9nleozS7BZw,2385
|
|
11
12
|
cognite/neat/_client/init/env_vars.py,sha256=9nOEVABp4rI2TtFHCMItLouQ5MXFL0zzL4PTclT9m-c,5469
|
|
12
13
|
cognite/neat/_client/init/interactive.py,sha256=YVnsvRblQJPojf24dA050gVlrrqADK8afSQ6hkXn7Cs,4801
|
|
13
14
|
cognite/neat/_client/init/main.py,sha256=D-9bsor07T84iFnTZLnhIFA1Xey9zsooHaDhXVeNdos,2508
|
|
14
|
-
cognite/neat/_client/spaces_api.py,sha256=
|
|
15
|
-
cognite/neat/_client/statistics_api.py,sha256=
|
|
16
|
-
cognite/neat/_client/views_api.py,sha256=
|
|
15
|
+
cognite/neat/_client/spaces_api.py,sha256=yb26ju3sKbVgiduMEbN4LDGan6vsC3z_JaW3p4FUdr0,2929
|
|
16
|
+
cognite/neat/_client/statistics_api.py,sha256=5meeh0v5mxC2SMB7xGdOwMh4KkaX3DtpUjbGEPhNBJo,913
|
|
17
|
+
cognite/neat/_client/views_api.py,sha256=YMaw7IaxU4gmixpd_t1u9JK9BHfNerf5DMNinGPCAa0,3692
|
|
17
18
|
cognite/neat/_config.py,sha256=ZvCkcaRVAvH4-ClvinoWaLWhRJpRByqdvncGFsf5gLk,9886
|
|
18
19
|
cognite/neat/_data_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
20
|
cognite/neat/_data_model/_analysis.py,sha256=dN-udKm_5oD3217O4B_QIps2Hx4v50-Pu2fR0bQNQg0,23504
|
|
@@ -52,7 +53,7 @@ cognite/neat/_data_model/models/conceptual/_data_model.py,sha256=zvJZi0OqOFMviwY
|
|
|
52
53
|
cognite/neat/_data_model/models/conceptual/_properties.py,sha256=CpF37vJYBTLT4DH4ZOu2U-JyWtkb_27V8fw52qiaE_k,4007
|
|
53
54
|
cognite/neat/_data_model/models/conceptual/_property.py,sha256=blSZQxX52zaILAtjUkldPzPeysz7wnG-UGSNU5tacI8,4138
|
|
54
55
|
cognite/neat/_data_model/models/dms/__init__.py,sha256=CW5NPMRrMyY4iyZgqYb8eZkRuwbbXUDSVNMWep3zEPI,5326
|
|
55
|
-
cognite/neat/_data_model/models/dms/_base.py,sha256=
|
|
56
|
+
cognite/neat/_data_model/models/dms/_base.py,sha256=gCjmDca_z0ZB_NHHGOkB9CCLKNxrI_npz-4mWU2yFI0,951
|
|
56
57
|
cognite/neat/_data_model/models/dms/_constants.py,sha256=TaoE9kmNVEaTl_dDrZQL7YzgP4K13ff0Rc7nr4zbIgg,1384
|
|
57
58
|
cognite/neat/_data_model/models/dms/_constraints.py,sha256=cyGgDlByXAuSMWJg7Oc25fkp33LsA61M927bCzTWlbo,1458
|
|
58
59
|
cognite/neat/_data_model/models/dms/_container.py,sha256=wtQbNUwtpymltT1jav8wD4kIfjaIYnvhhz1KS0ffAbo,6044
|
|
@@ -124,9 +125,9 @@ cognite/neat/_utils/_reader.py,sha256=9dXrODNNqWU0Gx1zXjRTOiiByFuDZlpQkQEzx3HAxY
|
|
|
124
125
|
cognite/neat/_utils/auxiliary.py,sha256=YQMpqCxccex_slmLYrR5icVX9aeLbD793ou7IrbNTFs,1654
|
|
125
126
|
cognite/neat/_utils/collection.py,sha256=BIwRrFbUXNPvHhEVujLHgVoDJXzdPEMScrbSBhyCibk,446
|
|
126
127
|
cognite/neat/_utils/http_client/__init__.py,sha256=qaCLLLhi7H3b_cmbknX0S66KILT7JSKX1YSgZjNdd1U,786
|
|
127
|
-
cognite/neat/_utils/http_client/_client.py,sha256=
|
|
128
|
+
cognite/neat/_utils/http_client/_client.py,sha256=4aj7gmOikLr2sLlmqyMaWonJGGy0IuGvCbJ5hIIuSPw,9732
|
|
128
129
|
cognite/neat/_utils/http_client/_config.py,sha256=C8IF1JoijmVMjA_FEMgAkiD1buEV1cY5Og3t-Ecyfmk,756
|
|
129
|
-
cognite/neat/_utils/http_client/_data_classes.py,sha256=
|
|
130
|
+
cognite/neat/_utils/http_client/_data_classes.py,sha256=aPF9B8Tw6_egBulUtSXHoaUhNMCg4iLaOSu5tx1cNQs,10162
|
|
130
131
|
cognite/neat/_utils/http_client/_tracker.py,sha256=EBBnd-JZ7nc_jYNFJokCHN2UZ9sx0McFLZvlceUYYic,1215
|
|
131
132
|
cognite/neat/_utils/repo.py,sha256=Ex_lW7qd4fi0YLaOJaLRwSyrN46kfMXbxecVE4mSs2I,598
|
|
132
133
|
cognite/neat/_utils/text.py,sha256=-ujNaG_hLkdurKsUmZB9ZI_kJkddlCKEf8g-g_XCk10,2010
|
|
@@ -322,9 +323,9 @@ cognite/neat/_v0/session/_template.py,sha256=BNcvrW5y7LWzRM1XFxZkfR1Nc7e8UgjBClH
|
|
|
322
323
|
cognite/neat/_v0/session/_to.py,sha256=AnsRSDDdfFyYwSgi0Z-904X7WdLtPfLlR0x1xsu_jAo,19447
|
|
323
324
|
cognite/neat/_v0/session/_wizard.py,sha256=baPJgXAAF3d1bn4nbIzon1gWfJOeS5T43UXRDJEnD3c,1490
|
|
324
325
|
cognite/neat/_v0/session/exceptions.py,sha256=jv52D-SjxGfgqaHR8vnpzo0SOJETIuwbyffSWAxSDJw,3495
|
|
325
|
-
cognite/neat/_version.py,sha256=
|
|
326
|
+
cognite/neat/_version.py,sha256=lZxKXnsRmb2ksFvFfpJkeZtX4W01ZenoMN457_FWsB0,45
|
|
326
327
|
cognite/neat/legacy.py,sha256=eI2ecxOV8ilGHyLZlN54ve_abtoK34oXognkFv3yvF0,219
|
|
327
328
|
cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
328
|
-
cognite_neat-1.0.
|
|
329
|
-
cognite_neat-1.0.
|
|
330
|
-
cognite_neat-1.0.
|
|
329
|
+
cognite_neat-1.0.26.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
|
|
330
|
+
cognite_neat-1.0.26.dist-info/METADATA,sha256=jISdpgKdsL7q8pj6OfhnOzfV6VI40aR-iYoLlnTjAP0,6689
|
|
331
|
+
cognite_neat-1.0.26.dist-info/RECORD,,
|
|
File without changes
|