Skip to content

Commit

Permalink
fixup! Add datapoints.delete_point method
Browse files Browse the repository at this point in the history
  • Loading branch information
erlendvollset committed Nov 15, 2022
1 parent 2fd0ad0 commit 4016979
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
50 changes: 35 additions & 15 deletions cognite/client/_api/datapoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import math
import re as regexp
from datetime import datetime
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union, cast
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Set, Tuple, Union, cast, overload

import cognite.client.utils._time
from cognite.client import utils
Expand Down Expand Up @@ -322,28 +322,48 @@ def insert_multiple(self, datapoints: List[Dict[str, Union[str, int, List]]]) ->
dps_poster = DatapointsPoster(self)
dps_poster.insert(datapoints)

def delete_point(self, timestamp: Union[int, str, datetime], id: int = None, external_id: str = None) -> None:
"""Delete a range of datapoints from a time series.
@overload
def delete_point(self, point: Dict[str, Union[int, str, datetime]]) -> None:
...

@overload
def delete_point(self, point: Sequence[Dict[str, Union[int, str, datetime]]]) -> None:
...

def delete_point(
self, point: Union[Dict[str, Union[int, str, datetime]], Sequence[Dict[str, Union[int, str, datetime]]]]
) -> None:
"""Delete a single datapoint from one or more time series.
Args:
timestamp (Union[int, str, datetime]): The timestamp of the datapoint to delete
id (int): Id of time series to delete data from
external_id (str): External id of time series to delete data from
point (Union[Dict[str, Union[int, str, datetime]], Sequence[Dict[str, Union[int, str, datetime]]]]): The point or points to delete
Returns:
None
Examples:
Deleting the last week of data from a time series::
Deleting the a single datapoint from a single time series::
>>> from cognite.client import CogniteClient
>>> c = CogniteClient()
>>> c.datapoints.delete_range(start="1w-ago", end="now", id=1)
>>> c.datapoints.delete_point(point={"id": 1, "timestamp"})
"""
start = utils._time.timestamp_to_ms(timestamp)
end = start + 1
self.delete_range(start=start, end=end, id=id, external_id=external_id)
point_list = point if isinstance(point, Sequence) else [point]
valid_ranges = []
for point in point_list:
for key in point:
if key not in ("id", "externalId", "timestamp"):
raise AssertionError(
f"Invalid key '{key}' in point. Must contain 'timestamp', and 'id' or 'externalId"
)
id = cast(Optional[int], point.get("id"))
external_id = cast(Optional[str], point.get("externalId"))
valid_range = Identifier.of_either(id, external_id).as_dict()
start = utils._time.timestamp_to_ms(point["timestamp"])
valid_range.update({"start": start, "end": start + 1})
valid_ranges.append(valid_range)
self.delete_ranges(ranges=valid_ranges)

def delete_range(
self, start: Union[int, str, datetime], end: Union[int, str, datetime], id: int = None, external_id: str = None
Expand Down Expand Up @@ -375,11 +395,11 @@ def delete_range(
delete_dps_object.update({"inclusiveBegin": start, "exclusiveEnd": end})
self._delete_datapoints_ranges([delete_dps_object])

def delete_ranges(self, ranges: List[Dict[str, Any]]) -> None:
def delete_ranges(self, ranges: List[Dict[str, Union[int, str, datetime]]]) -> None:
"""`Delete a range of datapoints from multiple time series. <https://docs.cognite.com/api/v1/#operation/deleteDatapoints>`_
Args:
ranges (List[Dict[str, Any]]): The list of datapoint ids along with time range to delete. See examples below.
ranges (List[Dict[str, Union[int, str, datetime]): The list of datapoint ids along with time range to delete. See examples below.
Returns:
None
Expand All @@ -401,8 +421,8 @@ def delete_ranges(self, ranges: List[Dict[str, Any]]) -> None:
raise AssertionError(
"Invalid key '{}' in range. Must contain 'start', 'end', and 'id' or 'externalId".format(key)
)
id = range.get("id")
external_id = range.get("externalId")
id = cast(Optional[int], range.get("id"))
external_id = cast(Optional[str], range.get("externalId"))
valid_range = Identifier.of_either(id, external_id).as_dict()
start = utils._time.timestamp_to_ms(range["start"])
end = utils._time.timestamp_to_ms(range["end"])
Expand Down
14 changes: 13 additions & 1 deletion tests/tests_unit/test_api/test_datapoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,12 +704,24 @@ def mock_delete_datapoints(rsps, cognite_client):

class TestDeleteDatapoints:
def test_delete_point(self, cognite_client, mock_delete_datapoints):
res = cognite_client.datapoints.delete_point(1, id=1)
res = cognite_client.datapoints.delete_point({"id": 1, "timestamp": 1})
assert res is None
assert {"items": [{"id": 1, "inclusiveBegin": 1, "exclusiveEnd": 2}]} == jsgz_load(
mock_delete_datapoints.calls[0].request.body
)

def test_delete_points(self, cognite_client, mock_delete_datapoints):
res = cognite_client.datapoints.delete_point(
[{"id": 1, "timestamp": 1}, {"externalId": "abc", "timestamp": 10}]
)
assert res is None
assert {
"items": [
{"id": 1, "inclusiveBegin": 1, "exclusiveEnd": 2},
{"externalId": "abc", "inclusiveBegin": 10, "exclusiveEnd": 11},
]
} == jsgz_load(mock_delete_datapoints.calls[0].request.body)

def test_delete_range(self, cognite_client, mock_delete_datapoints):
res = cognite_client.datapoints.delete_range(start=datetime(2018, 1, 1), end=datetime(2018, 1, 2), id=1)
assert res is None
Expand Down

0 comments on commit 4016979

Please sign in to comment.