diff --git a/cognite/client/_api/datapoint_tasks.py b/cognite/client/_api/datapoint_tasks.py index 0a44d7f1b9..d8832e915b 100644 --- a/cognite/client/_api/datapoint_tasks.py +++ b/cognite/client/_api/datapoint_tasks.py @@ -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 @@ -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 @@ -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 @@ -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): 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) diff --git a/cognite/client/_api/datapoints.py b/cognite/client/_api/datapoints.py index 5c7870e592..386b1066cf 100644 --- a/cognite/client/_api/datapoints.py +++ b/cognite/client/_api/datapoints.py @@ -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, @@ -799,7 +799,7 @@ async def retrieve( ) -> DatapointsList: ... @overload - async def retrieve( + async def retrieve( # type: ignore[overload-overlap] self, *, external_id: str | DatapointsQuery, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -1007,9 +1007,9 @@ async def retrieve( `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) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -1367,9 +1367,9 @@ async def retrieve_arrays( `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) @@ -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, @@ -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) diff --git a/cognite/client/_sync_api/datapoints.py b/cognite/client/_sync_api/datapoints.py index 5c21bb663d..0ea6e0b11e 100644 --- a/cognite/client/_sync_api/datapoints.py +++ b/cognite/client/_sync_api/datapoints.py @@ -1,6 +1,6 @@ """ =============================================================================== -dfa197641edb7840e903b3b65c021f58 +776e29ac071cd1fd4a9af3a984a5e4c0 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -8,7 +8,7 @@ from __future__ import annotations import datetime -from collections.abc import Iterator, Sequence +from collections.abc import Iterable, Iterator, Sequence from typing import TYPE_CHECKING, Any, Literal, overload from zoneinfo import ZoneInfo @@ -203,7 +203,7 @@ def retrieve( 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, @@ -220,7 +220,7 @@ def retrieve( ) -> DatapointsList: ... @overload - def retrieve( + def retrieve( # type: ignore[overload-overlap] self, *, external_id: str | DatapointsQuery, @@ -243,7 +243,7 @@ def retrieve( 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, @@ -283,7 +283,7 @@ def retrieve( 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, @@ -303,8 +303,8 @@ def retrieve( 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, @@ -324,8 +324,8 @@ def retrieve( 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, @@ -345,8 +345,8 @@ def retrieve( 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, @@ -366,9 +366,9 @@ def retrieve( 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, @@ -387,9 +387,9 @@ def retrieve( 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, @@ -429,9 +429,9 @@ def retrieve( `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) @@ -658,7 +658,7 @@ def retrieve_arrays( 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, @@ -675,7 +675,7 @@ def retrieve_arrays( ) -> DatapointsArrayList: ... @overload - def retrieve_arrays( + def retrieve_arrays( # type: ignore[overload-overlap] self, *, external_id: str | DatapointsQuery, @@ -698,7 +698,7 @@ def retrieve_arrays( 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, @@ -738,7 +738,7 @@ def retrieve_arrays( 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, @@ -757,9 +757,9 @@ def retrieve_arrays( 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, @@ -784,9 +784,9 @@ def retrieve_arrays( `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) @@ -878,9 +878,9 @@ def retrieve_arrays( 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, @@ -909,9 +909,9 @@ 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) diff --git a/cognite/client/utils/_datapoints.py b/cognite/client/utils/_datapoints.py index 117a45cbab..3fb03217d1 100644 --- a/cognite/client/utils/_datapoints.py +++ b/cognite/client/utils/_datapoints.py @@ -4,7 +4,7 @@ import operator as op import warnings from collections import defaultdict -from collections.abc import Callable, Iterator, Sequence +from collections.abc import Callable, Iterable, Iterator from itertools import chain from typing import TYPE_CHECKING, Any, Literal, TypeAlias, cast @@ -31,7 +31,6 @@ MinDatapoint, MinDatapointWithStatus, ) -from cognite.client.utils.useful_types import SequenceNotStr if NUMPY_IS_AVAILABLE: import numpy as np @@ -50,9 +49,9 @@ DatapointsRaw = NumericDatapoints | StringDatapoints RawDatapointValue = float | str -DatapointsId = int | DatapointsQuery | Sequence[int | DatapointsQuery] -DatapointsExternalId = str | DatapointsQuery | SequenceNotStr[str | DatapointsQuery] -DatapointsInstanceId = NodeId | DatapointsQuery | Sequence[NodeId | DatapointsQuery] +DatapointsId = int | DatapointsQuery | Iterable[int | DatapointsQuery] +DatapointsExternalId = str | DatapointsQuery | Iterable[str | DatapointsQuery] +DatapointsInstanceId = NodeId | DatapointsQuery | Iterable[NodeId | DatapointsQuery] class DpsUnpackFns: diff --git a/cognite/client/utils/useful_types.py b/cognite/client/utils/useful_types.py index 0c89f69455..1261a141c2 100644 --- a/cognite/client/utils/useful_types.py +++ b/cognite/client/utils/useful_types.py @@ -1,8 +1,10 @@ from __future__ import annotations -from collections.abc import Iterator, Sequence +from collections.abc import Iterable, Iterator, Sequence from typing import Any, Protocol, SupportsIndex, TypeGuard, TypeVar, overload, runtime_checkable +from typing_extensions import TypeIs + _T_co = TypeVar("_T_co", covariant=True) @@ -33,5 +35,9 @@ def is_sequence_not_str(obj: Any) -> TypeGuard[SequenceNotStr]: return isinstance(obj, Sequence) and not isinstance(obj, str) +def is_iterable_not_str(obj: Any) -> TypeIs[SequenceNotStr]: + return isinstance(obj, Iterable) and not isinstance(obj, str) + + class SupportsRead(Protocol[_T_co]): def read(self, length: int = ..., /) -> _T_co: ... diff --git a/tests/tests_unit/test_api/test_datapoints_tasks.py b/tests/tests_unit/test_api/test_datapoints_tasks.py index ec8d9ac71e..0c71f47b97 100644 --- a/tests/tests_unit/test_api/test_datapoints_tasks.py +++ b/tests/tests_unit/test_api/test_datapoints_tasks.py @@ -3,6 +3,7 @@ import math import re from collections.abc import Iterable, Sequence +from dataclasses import dataclass from datetime import datetime, timezone from typing import Any @@ -34,12 +35,17 @@ def test_no_identifiers_raises( ): _FullDatapointsQuery(id=ids, external_id=xids, instance_id=inst_id).parse_into_queries() + @dataclass + class Foo: + id: int | None = None + external_id: str | None = None + @pytest.mark.parametrize( "ids, xids, exp_attr_to_fail", ( - ({123}, None, "id"), - (None, {"foo"}, "external_id"), - ({123}, {"foo"}, "id"), + (Foo(id=123), None, "id"), + (None, Foo(external_id="foo"), "external_id"), + (Foo(id=123), Foo(external_id="foo"), "id"), ), ) def test_wrong_identifier_type_raises( @@ -50,25 +56,6 @@ def test_wrong_identifier_type_raises( with pytest.raises(TypeError, match=re.escape(err_msg)): _FullDatapointsQuery(id=ids, external_id=xids).parse_into_queries() - @pytest.mark.parametrize( - "ids, xids, iids, exp_attr_to_fail, exp_wrong_type", - ( - ({"id": 123}, None, None, "id", "int"), - (None, {"external_id": "foo"}, None, "external_id", "str"), - (None, None, {"instance_id": "bar"}, "instance_id", "NodeId"), - ), - ) - def test_passing_dict_for_identifier_raises( - self, ids: dict | None, xids: dict | None, iids: dict | None, exp_attr_to_fail: str, exp_wrong_type: str - ) -> None: - err_msg = ( - f"Got unsupported type , as, or part of argument `{exp_attr_to_fail}`. Expected one " - f"of {exp_wrong_type}, DatapointsQuery, or a (mixed) list of these" - ) - - with pytest.raises(TypeError, match=re.escape(err_msg)): - _FullDatapointsQuery(id=ids, external_id=xids, instance_id=iids).parse_into_queries() # type: ignore[arg-type] - @pytest.mark.parametrize("limit, exp_limit", [(0, 0), (1, 1), (-1, None), (math.inf, None), (None, None)]) def test_valid_limits(self, limit: int | None, exp_limit: int | None, query_validator: _DpsQueryValidator) -> None: query = _FullDatapointsQuery(id=1, limit=limit)