diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/__init__.py b/sdk/cosmos/azure-cosmos/azure/cosmos/__init__.py index 4f737f0c9450..d7501df99558 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/__init__.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/__init__.py @@ -43,7 +43,6 @@ ) from .partition_key import PartitionKey from .permission import Permission -from ._feed_range import FeedRange __all__ = ( "CosmosClient", @@ -67,7 +66,6 @@ "ConnectionRetryPolicy", "ThroughputProperties", "CosmosDict", - "CosmosList", - "FeedRange" + "CosmosList" ) __version__ = VERSION diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_change_feed/change_feed_state.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_change_feed/change_feed_state.py index a3adecbf34c2..1f7d63f96d72 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_change_feed/change_feed_state.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_change_feed/change_feed_state.py @@ -383,7 +383,9 @@ def from_initial_state( feed_range: Optional[FeedRangeInternal] = None if change_feed_state_context.get("feedRange"): - feed_range = change_feed_state_context.get("feedRange") + feed_range_str = base64.b64decode(change_feed_state_context["feedRange"]).decode('utf-8') + feed_range_json = json.loads(feed_range_str) + feed_range = FeedRangeInternalEpk.from_json(feed_range_json) elif change_feed_state_context.get("partitionKey"): if change_feed_state_context.get("partitionKeyFeedRange"): feed_range =\ @@ -412,4 +414,4 @@ def from_initial_state( feed_range=feed_range, change_feed_start_from=change_feed_start_from, continuation=None) - raise RuntimeError("feed_range is empty") + raise ValueError("feed_range is empty") diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_feed_range.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_feed_range.py deleted file mode 100644 index 2bda669b6bc0..000000000000 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_feed_range.py +++ /dev/null @@ -1,70 +0,0 @@ -# The MIT License (MIT) -# Copyright (c) 2014 Microsoft Corporation - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import base64 -import json -from abc import ABC -from typing import Any, Dict - -from azure.cosmos._change_feed.feed_range_internal import FeedRangeInternalEpk -from azure.cosmos._routing.routing_range import Range - -# pylint: disable=protected-access -class FeedRange(ABC): - """Represents a single feed range in an Azure Cosmos DB SQL API container. - - """ - @staticmethod - def from_string(json_str: str) -> 'FeedRange': - """ - Create a feed range from previously obtained string representation. - - :param str json_str: A string representation of a feed range. - :return: A feed range. - :rtype: ~azure.cosmos.FeedRange - """ - feed_range_json_str = base64.b64decode(json_str).decode('utf-8') - feed_range_json = json.loads(feed_range_json_str) - if feed_range_json.get(FeedRangeEpk.type_property_name): - return FeedRangeEpk._from_json(feed_range_json) - - raise ValueError("Invalid feed range base64 encoded string [Wrong feed range type]") - -class FeedRangeEpk(FeedRange): - type_property_name = "Range" - - def __init__(self, feed_range: Range) -> None: - if feed_range is None: - raise ValueError("feed_range cannot be None") - - self._feed_range_internal = FeedRangeInternalEpk(feed_range) - - def __str__(self) -> str: - """Get a json representation of the feed range. - The returned json string can be used to create a new feed range from it. - - :return: A json representation of the feed range. - """ - return self._feed_range_internal.__str__() - - @classmethod - def _from_json(cls, data: Dict[str, Any]) -> 'FeedRange': - return cls(FeedRangeInternalEpk.from_json(data)._range) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py b/sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py index 59cf276f0381..1434ea68d5ea 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/aio/_container.py @@ -32,6 +32,7 @@ from azure.core.tracing.decorator_async import distributed_trace_async # type: ignore from ._cosmos_client_connection_async import CosmosClientConnection +from .._change_feed.feed_range_internal import FeedRangeInternalEpk from .._cosmos_responses import CosmosDict, CosmosList from ._scripts import ScriptsProxy from .._base import ( @@ -42,7 +43,6 @@ GenerateGuidId, _set_properties_cache ) -from .._feed_range import FeedRange, FeedRangeEpk from .._routing.routing_range import Range from ..offer import ThroughputProperties from ..partition_key import ( @@ -534,7 +534,7 @@ def query_items_change_feed( def query_items_change_feed( self, *, - feed_range: FeedRange, + feed_range: str, max_item_count: Optional[int] = None, start_time: Optional[Union[datetime, Literal["Now", "Beginning"]]] = None, priority: Optional[Literal["High", "Low"]] = None, @@ -542,8 +542,7 @@ def query_items_change_feed( ) -> AsyncItemPaged[Dict[str, Any]]: """Get a sorted list of items that were changed, in the order in which they were modified. - :keyword feed_range: The feed range that is used to define the scope. - :type feed_range: ~azure.cosmos.FeedRange + :keyword str feed_range: The feed range that is used to define the scope. :keyword int max_item_count: Max number of items to be returned in the enumeration operation. :keyword start_time: The start time to start processing chang feed items. Beginning: Processing the change feed items from the beginning of the change feed. @@ -621,8 +620,7 @@ def query_items_change_feed( # pylint: disable=unused-argument """Get a sorted list of items that were changed, in the order in which they were modified. :keyword str continuation: The continuation token retrieved from previous response. - :keyword feed_range: The feed range that is used to define the scope. - :type feed_range: ~azure.cosmos.FeedRange + :keyword str feed_range: The feed range that is used to define the scope. :keyword partition_key: The partition key that is used to define the scope (logical partition or a subset of a container) :type partition_key: Union[str, int, float, bool, List[Union[str, int, float, bool]]] @@ -692,8 +690,7 @@ def query_items_change_feed( # pylint: disable=unused-argument self._get_epk_range_for_partition_key(kwargs.pop('partition_key')) if kwargs.get("feed_range") is not None: - feed_range: FeedRangeEpk = kwargs.pop('feed_range') - change_feed_state_context["feedRange"] = feed_range._feed_range_internal + change_feed_state_context["feedRange"] = kwargs.pop('feed_range') feed_options["containerProperties"] = self._get_properties() feed_options["changeFeedStateContext"] = change_feed_state_context @@ -1299,7 +1296,7 @@ async def read_feed_ranges( *, force_refresh: Optional[bool] = False, **kwargs: Any - ) -> List[FeedRange]: + ) -> List[str]: """ Obtains a list of feed ranges that can be used to parallelize feed operations. :keyword bool force_refresh: @@ -1318,5 +1315,5 @@ async def read_feed_ranges( [Range("", "FF", True, False)], **kwargs) - return [FeedRangeEpk(Range.PartitionKeyRangeToRange(partitionKeyRange)) + return [FeedRangeInternalEpk(Range.PartitionKeyRangeToRange(partitionKeyRange)).__str__() for partitionKeyRange in partition_key_ranges] diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/container.py b/sdk/cosmos/azure-cosmos/azure/cosmos/container.py index ed9a211b0091..b1e9c6f947e6 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/container.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/container.py @@ -38,9 +38,9 @@ GenerateGuidId, _set_properties_cache ) +from ._change_feed.feed_range_internal import FeedRangeInternalEpk from ._cosmos_client_connection import CosmosClientConnection from ._cosmos_responses import CosmosDict, CosmosList -from ._feed_range import FeedRange, FeedRangeEpk from ._routing.routing_range import Range from .offer import Offer, ThroughputProperties from .partition_key import ( @@ -354,7 +354,7 @@ def query_items_change_feed( def query_items_change_feed( self, *, - feed_range: FeedRange, + feed_range: str, max_item_count: Optional[int] = None, start_time: Optional[Union[datetime, Literal["Now", "Beginning"]]] = None, priority: Optional[Literal["High", "Low"]] = None, @@ -363,8 +363,7 @@ def query_items_change_feed( """Get a sorted list of items that were changed, in the order in which they were modified. - :keyword feed_range: The feed range that is used to define the scope. - :type feed_range: ~azure.cosmos.FeedRange + :keyword str feed_range: The feed range that is used to define the scope. :keyword int max_item_count: Max number of items to be returned in the enumeration operation. :keyword start_time: The start time to start processing chang feed items. Beginning: Processing the change feed items from the beginning of the change feed. @@ -441,8 +440,7 @@ def query_items_change_feed( """Get a sorted list of items that were changed, in the order in which they were modified. :keyword str continuation: The continuation token retrieved from previous response. - :keyword feed_range: The feed range that is used to define the scope. - :type feed_range: ~azure.cosmos.FeedRange + :keyword str feed_range: The feed range that is used to define the scope. :keyword partition_key: The partition key that is used to define the scope (logical partition or a subset of a container) :type partition_key: Union[str, int, float, bool, List[Union[str, int, float, bool]]] @@ -528,8 +526,7 @@ def query_items_change_feed( self._get_epk_range_for_partition_key(kwargs.pop('partition_key')) if kwargs.get("feed_range") is not None: - feed_range: FeedRangeEpk = kwargs.pop('feed_range') - change_feed_state_context["feedRange"] = feed_range._feed_range_internal + change_feed_state_context["feedRange"] = kwargs.pop('feed_range') container_properties = self._get_properties() feed_options["changeFeedStateContext"] = change_feed_state_context @@ -1368,7 +1365,7 @@ def read_feed_ranges( self, *, force_refresh: Optional[bool] = False, - **kwargs: Any) -> List[FeedRange]: + **kwargs: Any) -> List[str]: """ Obtains a list of feed ranges that can be used to parallelize feed operations. @@ -1387,5 +1384,5 @@ def read_feed_ranges( [Range("", "FF", True, False)], # default to full range **kwargs) - return [FeedRangeEpk(Range.PartitionKeyRangeToRange(partitionKeyRange)) + return [FeedRangeInternalEpk(Range.PartitionKeyRangeToRange(partitionKeyRange)).__str__() for partitionKeyRange in partition_key_ranges]