Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add intersects_bounding_box to 3D asset mapping API #1511

Merged
merged 3 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ Changes are grouped as follows
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## [7.1.0] - 2023-11-16
### Added
- The list method for asset mappings in the 3D API now supports `intersects_bounding_box`, allowing users to only
return asset mappings for assets whose bounding box intersects with the given bounding box.

## [7.0.3] - 2023-11-15
### Fixed
- Bug when `cognite.client.data_classes.filter` used with any `data_modeling` endpoint raised a `CogniteAPIError` for
snake_cased properties. This is now fixed.
- When calling `client.relationships.retrieve`, `.retrieve_multiple`, or `.list` with `fetch_resources=True`, the
- Bug when `cognite.client.data_classes.filter` used with any `data_modeling` endpoint raised a `CogniteAPIError` for
snake_cased properties. This is now fixed.
- When calling `client.relationships.retrieve`, `.retrieve_multiple`, or `.list` with `fetch_resources=True`, the
`target` and `source` resources were not instantiated with a `cognite_client`. This is now fixed.

## [7.0.2] - 2023-11-15
Expand Down
18 changes: 16 additions & 2 deletions cognite/client/_api/three_d.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any, Iterator, Sequence, cast

from cognite.client._api_client import APIClient
from cognite.client._constants import DEFAULT_LIMIT_READ
from cognite.client.data_classes import (
BoundingBox3D,
ThreeDAssetMapping,
ThreeDAssetMappingList,
ThreeDModel,
Expand Down Expand Up @@ -559,6 +561,7 @@ def list(
revision_id: int,
node_id: int | None = None,
asset_id: int | None = None,
intersects_bounding_box: BoundingBox3D | None = None,
limit: int | None = DEFAULT_LIMIT_READ,
) -> ThreeDAssetMappingList:
"""`List 3D node asset mappings. <https://developer.cognite.com/api#tag/3D-Asset-Mapping/operation/get3DMappings>`_
Expand All @@ -568,26 +571,37 @@ def list(
revision_id (int): Id of the revision.
node_id (int | None): List only asset mappings associated with this node.
asset_id (int | None): List only asset mappings associated with this asset.
intersects_bounding_box (BoundingBox3D | None): If given, only return asset mappings for assets whose bounding box intersects with the given bounding box.
limit (int | None): Maximum number of asset mappings to return. Defaults to 25. Set to -1, float("inf") or None to return all items.

Returns:
ThreeDAssetMappingList: The list of asset mappings.

Example:

List 3d node asset mappings::
List 3d node asset mappings:

>>> from cognite.client import CogniteClient
>>> c = CogniteClient()
>>> res = c.three_d.asset_mappings.list(model_id=1, revision_id=1)

List 3d node asset mappings for assets whose bounding box intersects with a given bounding box:

>>> from cognite.client.data_classes import BoundingBox3D
>>> bbox = BoundingBox3D(min=[0.0, 0.0, 0.0], max=[1.0, 1.0, 1.0])
>>> res = c.three_d.asset_mappings.list(
... model_id=1, revision_id=1, intersects_bounding_box=bbox)
"""
path = interpolate_and_url_encode(self._RESOURCE_PATH, model_id, revision_id)
flt: dict[str, str | int | None] = {"nodeId": node_id, "assetId": asset_id}
if intersects_bounding_box:
flt["intersectsBoundingBox"] = json.dumps(intersects_bounding_box.dump(camel_case=True))
return self._list(
list_cls=ThreeDAssetMappingList,
resource_cls=ThreeDAssetMapping,
resource_path=path,
method="GET",
filter={"nodeId": node_id, "assetId": asset_id},
filter=flt,
limit=limit,
)

Expand Down
2 changes: 1 addition & 1 deletion cognite/client/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from __future__ import annotations

__version__ = "7.0.3"
__version__ = "7.1.0"
__api_subversion__ = "V20220125"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[tool.poetry]
name = "cognite-sdk"

version = "7.0.3"
version = "7.1.0"
description = "Cognite Python SDK"
readme = "README.md"
documentation = "https://cognite-sdk-python.readthedocs-hosted.com"
authors = [
"Erlend Vollset <[email protected]>",
"Håkon Treider <håkon[email protected]>",
"Håkon Treider <hakon[email protected]>",
"Anders Albert <[email protected]>"
]
license = "Apache-2.0"
Expand Down
18 changes: 17 additions & 1 deletion tests/tests_unit/test_api/test_3d.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
from urllib.parse import unquote_plus

import pytest

Expand All @@ -13,6 +14,7 @@
ThreeDModelUpdate,
ThreeDNodeList,
)
from cognite.client.data_classes import BoundingBox3D
from cognite.client.exceptions import CogniteAPIError
from tests.utils import jsgz_load

Expand Down Expand Up @@ -286,11 +288,25 @@ def mock_3d_asset_mappings_response(self, cognite_client, rsps):

def test_list(self, cognite_client, mock_3d_asset_mappings_response):
res = cognite_client.three_d.asset_mappings.list(
model_id=1, revision_id=1, node_id=None, asset_id=None, limit=None
model_id=1, revision_id=1, node_id=None, asset_id=None, intersects_bounding_box=None, limit=None
)
assert isinstance(res, ThreeDAssetMappingList)
assert mock_3d_asset_mappings_response.calls[0].response.json()["items"] == res.dump(camel_case=True)

url = mock_3d_asset_mappings_response.calls[0].request.url
assert "intersectsBoundingBox" not in unquote_plus(url)

def test_list__with_intersects_bounding_box(self, cognite_client, mock_3d_asset_mappings_response):
bbox = BoundingBox3D(min=[0.0, 0.0, 0.0], max=[1.0, 1.0, 1.0])
res = cognite_client.three_d.asset_mappings.list(
model_id=1, revision_id=1, node_id=None, asset_id=None, intersects_bounding_box=bbox, limit=None
)
assert isinstance(res, ThreeDAssetMappingList)
assert mock_3d_asset_mappings_response.calls[0].response.json()["items"] == res.dump(camel_case=True)

url = mock_3d_asset_mappings_response.calls[0].request.url
assert 'intersectsBoundingBox={"max": [1.0, 1.0, 1.0], "min": [0.0, 0.0, 0.0]}' in unquote_plus(url)

def test_create(self, cognite_client, mock_3d_asset_mappings_response):
res = cognite_client.three_d.asset_mappings.create(
model_id=1, revision_id=1, asset_mapping=ThreeDAssetMapping(node_id=1, asset_id=1)
Expand Down