Skip to content
Open
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
25 changes: 12 additions & 13 deletions cognite/client/_api/datapoint_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import warnings
from abc import ABC, abstractmethod
from collections import defaultdict
from collections.abc import Iterable, Iterator, Sequence
from collections.abc import Iterable, Iterator
from dataclasses import dataclass
from functools import cached_property
from itertools import pairwise
Expand Down Expand Up @@ -62,7 +62,7 @@
time_shift_to_ms,
timestamp_to_ms,
)
from cognite.client.utils.useful_types import SequenceNotStr, is_sequence_not_str
from cognite.client.utils.useful_types import is_iterable_not_str

if NUMPY_IS_AVAILABLE:
import numpy as np
Expand Down Expand Up @@ -110,11 +110,11 @@ class _FullDatapointsQuery:
def is_single_identifier(self) -> bool:
# Exactly one of the identifiers given...
if exactly_one_is_not_none(self.external_id, self.id, self.instance_id):
# ...and that one is not a sequence:
# ...and that one is not a iterable:
return not (
isinstance(self.id, Sequence)
or is_sequence_not_str(self.external_id)
or isinstance(self.instance_id, Sequence)
isinstance(self.id, Iterable)
or is_iterable_not_str(self.external_id)
or isinstance(self.instance_id, Iterable)
)
return False

Expand Down Expand Up @@ -154,14 +154,13 @@ def _parse(
arg_name: Literal["id", "external_id", "instance_id"],
exp_type: type,
) -> list[DatapointsQuery]:
user_queries: SequenceNotStr[int | str | NodeId | DatapointsQuery]
if isinstance(identifier, (DatapointsQuery, exp_type)):
# Lazy - we postpone evaluation:
user_queries = [identifier]

elif is_sequence_not_str(identifier):
# We use Sequence because we require an ordering of elements (and finite iterable)
user_queries: Iterable[int | str | NodeId | DatapointsQuery]
if isinstance(identifier, Iterable) and not isinstance(identifier, str):
Comment thread
MortGron marked this conversation as resolved.
user_queries = identifier
elif isinstance(identifier, (DatapointsQuery, exp_type)):
# Lazy - we postpone evaluation:
# mypy 1.19.1 thinks identifier can be an iterable that is not a string here
user_queries = [identifier] # type: ignore[list-item]
else:
self._raise_on_wrong_ts_identifier_type(identifier, arg_name, exp_type)
Comment thread
MortGron marked this conversation as resolved.

Expand Down
70 changes: 35 additions & 35 deletions cognite/client/_api/datapoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ async def retrieve(
async def retrieve(
self,
*,
id: Sequence[int | DatapointsQuery],
id: Iterable[int | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -799,7 +799,7 @@ async def retrieve(
) -> DatapointsList: ...

@overload
async def retrieve(
async def retrieve( # type: ignore[overload-overlap]
self,
*,
external_id: str | DatapointsQuery,
Expand All @@ -822,7 +822,7 @@ async def retrieve(
async def retrieve(
self,
*,
external_id: SequenceNotStr[str | DatapointsQuery],
external_id: Iterable[str | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand Down Expand Up @@ -862,7 +862,7 @@ async def retrieve(
async def retrieve(
self,
*,
instance_id: Sequence[NodeId | DatapointsQuery],
instance_id: Iterable[NodeId | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -882,8 +882,8 @@ async def retrieve(
async def retrieve(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery],
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery],
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery],
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -903,8 +903,8 @@ async def retrieve(
async def retrieve(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery],
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -924,8 +924,8 @@ async def retrieve(
async def retrieve(
self,
*,
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery],
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -945,9 +945,9 @@ async def retrieve(
async def retrieve(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery],
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery],
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery],
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery],
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -966,9 +966,9 @@ async def retrieve(
async def retrieve(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery] = None,
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery] = None,
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand Down Expand Up @@ -1007,9 +1007,9 @@ async def retrieve(
`status codes. <https://docs.cognite.com/dev/concepts/reference/status_codes/>`_

Args:
id (None | int | DatapointsQuery | Sequence[int | DatapointsQuery]): Id, dict (with id) or (mixed) sequence of these. See examples below.
external_id (None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery]): External id, dict (with external id) or (mixed) sequence of these. See examples below.
instance_id (None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery]): Instance id or sequence of instance ids.
id (None | int | DatapointsQuery | Iterable[int | DatapointsQuery]): Id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as ids. See examples below.
external_id (None | str | DatapointsQuery | Iterable[str | DatapointsQuery]): External id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as external_ids. See examples below.
instance_id (None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery]): Instance id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as instance_ids.
Comment on lines +1010 to +1012
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The overloads for retrieve_latest (starting at line 1642) and its internal helper RetrieveLatestDpsFetcher._parse_user_input (line 2552) were not updated to support Iterable and still rely on Sequence and MutableSequence. This results in an inconsistent API where set or tuple of LatestDatapointQuery objects will not be correctly processed, and their individual settings (like before or target_unit) will be ignored.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what Gemini asks for here is consistency across the retrieve datapoints methods. I personally am ok with incrementally chaning the methods to accept Iterable of IDs, that is, skipping retrieve_latest for now. What do you think @cognitedata/python-sdk-maintainers ?

start (int | str | datetime.datetime | None): Inclusive start. Default: 1970-01-01 UTC.
end (int | str | datetime.datetime | None): Exclusive end. Default: "now"
aggregates (Aggregate | str | list[Aggregate | str] | None): Single aggregate or list of aggregates to retrieve. Available options: ``average``, ``continuous_variance``, ``count``, ``count_bad``, ``count_good``, ``count_uncertain``, ``discrete_variance``, ``duration_bad``, ``duration_good``, ``duration_uncertain``, ``interpolation``, ``max``, ``max_datapoint``, ``min``, ``min_datapoint``, ``step_interpolation``, ``sum`` and ``total_variation``. Default: None (raw datapoints returned)
Expand Down Expand Up @@ -1242,7 +1242,7 @@ async def retrieve_arrays(
async def retrieve_arrays(
self,
*,
id: Sequence[int | DatapointsQuery],
id: Iterable[int | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -1259,7 +1259,7 @@ async def retrieve_arrays(
) -> DatapointsArrayList: ...

@overload
async def retrieve_arrays(
async def retrieve_arrays( # type: ignore[overload-overlap]
self,
*,
external_id: str | DatapointsQuery,
Expand All @@ -1282,7 +1282,7 @@ async def retrieve_arrays(
async def retrieve_arrays(
self,
*,
external_id: SequenceNotStr[str | DatapointsQuery],
external_id: Iterable[str | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand Down Expand Up @@ -1322,7 +1322,7 @@ async def retrieve_arrays(
async def retrieve_arrays(
self,
*,
instance_id: Sequence[NodeId | DatapointsQuery],
instance_id: Iterable[NodeId | DatapointsQuery],
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -1341,9 +1341,9 @@ async def retrieve_arrays(
async def retrieve_arrays(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery] = None,
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery] = None,
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand All @@ -1367,9 +1367,9 @@ async def retrieve_arrays(
`status codes. <https://docs.cognite.com/dev/concepts/reference/status_codes/>`_

Args:
id (None | int | DatapointsQuery | Sequence[int | DatapointsQuery]): Id, dict (with id) or (mixed) sequence of these. See examples below.
external_id (None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery]): External id, dict (with external id) or (mixed) sequence of these. See examples below.
instance_id (None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery]): Instance id or sequence of instance ids.
id (None | int | DatapointsQuery | Iterable[int | DatapointsQuery]): Id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as ids. See examples below.
external_id (None | str | DatapointsQuery | Iterable[str | DatapointsQuery]): External id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as external_ids. See examples below.
instance_id (None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery]): Instance id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as instance_ids.
start (int | str | datetime.datetime | None): Inclusive start. Default: 1970-01-01 UTC.
end (int | str | datetime.datetime | None): Exclusive end. Default: "now"
aggregates (Aggregate | str | list[Aggregate | str] | None): Single aggregate or list of aggregates to retrieve. Available options: ``average``, ``continuous_variance``, ``count``, ``count_bad``, ``count_good``, ``count_uncertain``, ``discrete_variance``, ``duration_bad``, ``duration_good``, ``duration_uncertain``, ``interpolation``, ``max``, ``max_datapoint``, ``min``, ``min_datapoint``, ``step_interpolation``, ``sum`` and ``total_variation``. Default: None (raw datapoints returned)
Expand Down Expand Up @@ -1470,9 +1470,9 @@ async def retrieve_arrays(
async def retrieve_dataframe(
self,
*,
id: None | int | DatapointsQuery | Sequence[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery] = None,
id: None | int | DatapointsQuery | Iterable[int | DatapointsQuery] = None,
external_id: None | str | DatapointsQuery | Iterable[str | DatapointsQuery] = None,
instance_id: None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery] = None,
start: int | str | datetime.datetime | None = None,
end: int | str | datetime.datetime | None = None,
aggregates: Aggregate | str | list[Aggregate | str] | None = None,
Expand Down Expand Up @@ -1500,9 +1500,9 @@ async def retrieve_dataframe(
For many more usage examples, check out the :py:meth:`~DatapointsAPI.retrieve` method which accepts exactly the same arguments.

Args:
id (None | int | DatapointsQuery | Sequence[int | DatapointsQuery]): Id, DatapointsQuery or (mixed) sequence of these. See examples.
external_id (None | str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery]): External id, DatapointsQuery or (mixed) sequence of these. See examples.
instance_id (None | NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery]): Instance id, DatapointsQuery or (mixed) sequence of these. See examples.
id (None | int | DatapointsQuery | Iterable[int | DatapointsQuery]): Id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as ids. See examples.
external_id (None | str | DatapointsQuery | Iterable[str | DatapointsQuery]): External id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as external_ids. See examples.
instance_id (None | NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery]): Instance id, DatapointsQuery or (mixed) iterable of these. If a dict is passed, its keys will be used as instance_ids. See examples.
start (int | str | datetime.datetime | None): Inclusive start. Default: 1970-01-01 UTC.
end (int | str | datetime.datetime | None): Exclusive end. Default: "now"
aggregates (Aggregate | str | list[Aggregate | str] | None): Single aggregate or list of aggregates to retrieve. Available options: ``average``, ``continuous_variance``, ``count``, ``count_bad``, ``count_good``, ``count_uncertain``, ``discrete_variance``, ``duration_bad``, ``duration_good``, ``duration_uncertain``, ``interpolation``, ``max``, ``max_datapoint``, ``min``, ``min_datapoint``, ``step_interpolation``, ``sum`` and ``total_variation``. Default: None (raw datapoints returned)
Expand Down
Loading
Loading