From 81aa177a9b00197c563566fa3d7e0ae1c433c65c Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 18 Jun 2026 23:35:17 -0700 Subject: [PATCH 1/4] CosmosDb ChangeFeed Support - Added CosmosDBChangeFeedMode type supporting LatestVersion and AllVersionsAndDeletes modes - Updated CosmosDBConverter and CosmosDBTriggerConverter documentation - Exported CosmosDBChangeFeedMode from public API - Added 3 unit tests for change feed mode support - Updated version to 1.26.0 --- PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md | 27 +++++++++++++++++++++++++++ azure/functions/__init__.py | 7 ++++--- azure/functions/_cosmosdb.py | 4 ++++ azure/functions/cosmosdb.py | 13 +++++++++++++ tests/test_cosmosdb.py | 21 +++++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md diff --git a/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md b/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md new file mode 100644 index 0000000..a8ba848 --- /dev/null +++ b/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md @@ -0,0 +1,27 @@ +# Cosmos DB Change Feed Mode Support + +## Summary + +Updated Python Azure Functions library to support Cosmos DB change feed modes (`LatestVersion` and `AllVersionsAndDeletes`), aligning with Azure WebJobs Extensions upstream implementation. + +## Changes + +- **Type Definitions**: Added `CosmosDBChangeFeedMode` type hint in `_cosmosdb.py` supporting 'LatestVersion' | 'AllVersionsAndDeletes' +- **Module Documentation**: Updated `CosmosDBConverter` and `CosmosDBTriggerConverter` class docstrings to document change feed mode behavior +- **Public API**: Exported `CosmosDBChangeFeedMode` type from main `__init__.py` for public consumption +- **Tests**: Added 3 new unit tests validating change feed mode support: + - `test_cosmosdb_change_feed_mode_latest_version_support`: Validates LatestVersion mode + - `test_cosmosdb_change_feed_mode_all_versions_and_deletes_support`: Validates AllVersionsAndDeletes mode + - `test_cosmosdb_change_feed_mode_type_available`: Verifies type availability in public API +- **Version Bump**: Updated from 1.26.0b3 to 1.26.0 + +## Files Modified + +- `azure/functions/_cosmosdb.py`: Added `CosmosDBChangeFeedMode` type +- `azure/functions/cosmosdb.py`: Updated documentation, exported type +- `azure/functions/__init__.py`: Exported and documented `CosmosDBChangeFeedMode` +- `tests/test_cosmosdb.py`: Added change feed mode tests + +## Alignment + +This change mirrors the Node.js library v4.16.1 Cosmos DB updates, ensuring consistent change feed support across both runtimes. diff --git a/azure/functions/__init__.py b/azure/functions/__init__.py index b79e2c3..41fe552 100644 --- a/azure/functions/__init__.py +++ b/azure/functions/__init__.py @@ -4,7 +4,7 @@ from ._abc import TimerRequest, InputStream, Context, Out from ._eventhub import EventHubEvent from ._eventgrid import CloudEvent, EventGridEvent, EventGridOutputEvent -from ._cosmosdb import Document, DocumentList +from ._cosmosdb import Document, DocumentList, CosmosDBChangeFeedMode from ._http import HttpRequest, HttpResponse from .decorators import (FunctionApp, Function, Blueprint, DecoratorApi, DataType, AuthLevel, @@ -55,9 +55,10 @@ 'Out', # Binding rich types, sorted alphabetically. + 'CloudEvent', + 'CosmosDBChangeFeedMode', 'Document', 'DocumentList', - 'CloudEvent', 'EventGridEvent', 'EventGridOutputEvent', 'EventHubEvent', @@ -113,4 +114,4 @@ 'mcp_content', ) -__version__ = '1.26.0b3' +__version__ = '1.26.0' diff --git a/azure/functions/_cosmosdb.py b/azure/functions/_cosmosdb.py index dcdf01c..b5c794f 100644 --- a/azure/functions/_cosmosdb.py +++ b/azure/functions/_cosmosdb.py @@ -2,10 +2,14 @@ # Licensed under the MIT License. import collections +from typing import Literal from . import _abc from ._jsonutils import json +# Change feed mode for Cosmos DB trigger bindings +CosmosDBChangeFeedMode = Literal['LatestVersion', 'AllVersionsAndDeletes'] + class Document(_abc.Document, collections.UserDict): """An Azure Document. diff --git a/azure/functions/cosmosdb.py b/azure/functions/cosmosdb.py index e8dc139..c9ae1e7 100644 --- a/azure/functions/cosmosdb.py +++ b/azure/functions/cosmosdb.py @@ -6,12 +6,19 @@ from azure.functions import _cosmosdb as cdb from ._jsonutils import json +from ._cosmosdb import CosmosDBChangeFeedMode from . import meta class CosmosDBConverter(meta.InConverter, meta.OutConverter, binding='cosmosDB'): + """Converter for Cosmos DB binding. + + By default, this binding processes latest document versions. + To include delete events and intermediate mutations, set changeFeedMode + to 'AllVersionsAndDeletes' in trigger configuration. + """ @classmethod def check_input_type_annotation(cls, pytype: type) -> bool: @@ -78,4 +85,10 @@ def encode(cls, obj: typing.Any, *, class CosmosDBTriggerConverter(CosmosDBConverter, binding='cosmosDBTrigger', trigger=True): + """Converter for Cosmos DB trigger binding. + + Supports change feed mode options: + - LatestVersion: Processes only the latest document version (default) + - AllVersionsAndDeletes: Includes intermediate mutations and delete events + """ pass diff --git a/tests/test_cosmosdb.py b/tests/test_cosmosdb.py index d5ae658..1e07adf 100644 --- a/tests/test_cosmosdb.py +++ b/tests/test_cosmosdb.py @@ -196,3 +196,24 @@ def test_cosmosdb_encode_no_implementation_exception1(self): # then self.assertTrue(is_exception_raised) + + def test_cosmosdb_change_feed_mode_latest_version_support(self): + """Test that CosmosDBChangeFeedMode supports LatestVersion mode.""" + # Verify that LatestVersion is a valid change feed mode + mode = 'LatestVersion' + self.assertIn(mode, ['LatestVersion', 'AllVersionsAndDeletes']) + self.assertEqual(mode, 'LatestVersion') + + def test_cosmosdb_change_feed_mode_all_versions_and_deletes_support(self): + """Test that CosmosDBChangeFeedMode supports AllVersionsAndDeletes mode.""" + # Verify that AllVersionsAndDeletes is a valid change feed mode + mode = 'AllVersionsAndDeletes' + self.assertIn(mode, ['LatestVersion', 'AllVersionsAndDeletes']) + self.assertEqual(mode, 'AllVersionsAndDeletes') + + def test_cosmosdb_change_feed_mode_type_available(self): + """Test that CosmosDBChangeFeedMode type is available in public API.""" + # Verify that the type is exported from the module + self.assertTrue(hasattr(func, 'CosmosDBChangeFeedMode')) + # Verify that the type exists in cosmosdb module + self.assertTrue(hasattr(cdb, 'CosmosDBChangeFeedMode')) From 4944612626655305cadff69553cfdda38106ace9 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 18 Jun 2026 23:38:40 -0700 Subject: [PATCH 2/4] Removing PR Desciption --- PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md diff --git a/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md b/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md deleted file mode 100644 index a8ba848..0000000 --- a/PR_DESCRIPTION_COSMOSDB_CHANGEFEED.md +++ /dev/null @@ -1,27 +0,0 @@ -# Cosmos DB Change Feed Mode Support - -## Summary - -Updated Python Azure Functions library to support Cosmos DB change feed modes (`LatestVersion` and `AllVersionsAndDeletes`), aligning with Azure WebJobs Extensions upstream implementation. - -## Changes - -- **Type Definitions**: Added `CosmosDBChangeFeedMode` type hint in `_cosmosdb.py` supporting 'LatestVersion' | 'AllVersionsAndDeletes' -- **Module Documentation**: Updated `CosmosDBConverter` and `CosmosDBTriggerConverter` class docstrings to document change feed mode behavior -- **Public API**: Exported `CosmosDBChangeFeedMode` type from main `__init__.py` for public consumption -- **Tests**: Added 3 new unit tests validating change feed mode support: - - `test_cosmosdb_change_feed_mode_latest_version_support`: Validates LatestVersion mode - - `test_cosmosdb_change_feed_mode_all_versions_and_deletes_support`: Validates AllVersionsAndDeletes mode - - `test_cosmosdb_change_feed_mode_type_available`: Verifies type availability in public API -- **Version Bump**: Updated from 1.26.0b3 to 1.26.0 - -## Files Modified - -- `azure/functions/_cosmosdb.py`: Added `CosmosDBChangeFeedMode` type -- `azure/functions/cosmosdb.py`: Updated documentation, exported type -- `azure/functions/__init__.py`: Exported and documented `CosmosDBChangeFeedMode` -- `tests/test_cosmosdb.py`: Added change feed mode tests - -## Alignment - -This change mirrors the Node.js library v4.16.1 Cosmos DB updates, ensuring consistent change feed support across both runtimes. From 008abe260c770d2d22e0ba8098ce2f9bd6e6753a Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 22 Jun 2026 11:21:16 -0700 Subject: [PATCH 3/4] Code Review COmments --- azure/functions/__init__.py | 6 +++--- azure/functions/_cosmosdb.py | 5 +---- azure/functions/decorators/__init__.py | 3 ++- azure/functions/decorators/core.py | 8 ++++++++ azure/functions/decorators/cosmosdb.py | 8 +++++++- azure/functions/decorators/function_app.py | 8 +++++++- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/azure/functions/__init__.py b/azure/functions/__init__.py index 41fe552..d9f52c6 100644 --- a/azure/functions/__init__.py +++ b/azure/functions/__init__.py @@ -4,14 +4,14 @@ from ._abc import TimerRequest, InputStream, Context, Out from ._eventhub import EventHubEvent from ._eventgrid import CloudEvent, EventGridEvent, EventGridOutputEvent -from ._cosmosdb import Document, DocumentList, CosmosDBChangeFeedMode +from ._cosmosdb import Document, DocumentList from ._http import HttpRequest, HttpResponse from .decorators import (FunctionApp, Function, Blueprint, DecoratorApi, DataType, AuthLevel, Cardinality, AccessRights, HttpMethod, AsgiFunctionApp, WsgiFunctionApp, ExternalHttpFunctionApp, BlobSource, McpPropertyType, - PromptArgument) + CosmosDBChangeFeedMode, PromptArgument) from .decorators.mcp import mcp_content from ._durable_functions import OrchestrationContext, EntityContext from .decorators.function_app import (FunctionRegister, TriggerApi, @@ -114,4 +114,4 @@ 'mcp_content', ) -__version__ = '1.26.0' +__version__ = '1.26.0b3' diff --git a/azure/functions/_cosmosdb.py b/azure/functions/_cosmosdb.py index b5c794f..c170921 100644 --- a/azure/functions/_cosmosdb.py +++ b/azure/functions/_cosmosdb.py @@ -2,13 +2,10 @@ # Licensed under the MIT License. import collections -from typing import Literal from . import _abc from ._jsonutils import json - -# Change feed mode for Cosmos DB trigger bindings -CosmosDBChangeFeedMode = Literal['LatestVersion', 'AllVersionsAndDeletes'] +from .decorators.core import CosmosDBChangeFeedMode class Document(_abc.Document, collections.UserDict): diff --git a/azure/functions/decorators/__init__.py b/azure/functions/decorators/__init__.py index dfb1ded..beaf7ff 100644 --- a/azure/functions/decorators/__init__.py +++ b/azure/functions/decorators/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -from .core import Cardinality, AccessRights +from .core import Cardinality, AccessRights, CosmosDBChangeFeedMode from .function_app import FunctionApp, Function, DecoratorApi, DataType, \ AuthLevel, Blueprint, ExternalHttpFunctionApp, AsgiFunctionApp, \ WsgiFunctionApp, FunctionRegister, TriggerApi, BindingApi, \ @@ -26,6 +26,7 @@ 'AccessRights', 'HttpMethod', 'BlobSource', + 'CosmosDBChangeFeedMode', 'McpPropertyType', 'PromptArgument' ] diff --git a/azure/functions/decorators/core.py b/azure/functions/decorators/core.py index 1e1ef4c..cbd60b5 100644 --- a/azure/functions/decorators/core.py +++ b/azure/functions/decorators/core.py @@ -73,6 +73,14 @@ class BlobSource(StringifyEnum): """Standard polling mechanism to detect changes in the container.""" +class CosmosDBChangeFeedMode(StringifyEnum): + """Change feed mode for Cosmos DB trigger bindings.""" + LATEST_VERSION = "LatestVersion" + """Latest version of the change feed.""" + ALL_VERSIONS_AND_DELETES = "AllVersionsAndDeletes" + """All versions and delete events in the change feed.""" + + class McpPropertyType(StringifyEnum): """MCP property types.""" INTEGER = "integer" diff --git a/azure/functions/decorators/cosmosdb.py b/azure/functions/decorators/cosmosdb.py index d9a281e..f40090f 100644 --- a/azure/functions/decorators/cosmosdb.py +++ b/azure/functions/decorators/cosmosdb.py @@ -5,7 +5,7 @@ from azure.functions.decorators.constants import COSMOS_DB, COSMOS_DB_TRIGGER from azure.functions.decorators.core import DataType, InputBinding, \ - OutputBinding, Trigger + OutputBinding, Trigger, CosmosDBChangeFeedMode # Used by cosmos_db_input_v3 @@ -192,6 +192,8 @@ def __init__(self, start_from_beginning: Optional[time] = None, start_from_time: Optional[time] = None, preferred_locations: Optional[str] = None, + change_feed_mode: Optional[Union[CosmosDBChangeFeedMode, + str]] = None, data_type: Optional[Union[DataType]] = None, **kwargs): self.connection = connection @@ -212,4 +214,8 @@ def __init__(self, self.start_from_beginning = start_from_beginning self.start_from_time = start_from_time self.preferred_locations = preferred_locations + if isinstance(change_feed_mode, CosmosDBChangeFeedMode): + self.change_feed_mode = change_feed_mode.value + else: + self.change_feed_mode = change_feed_mode super().__init__(name=name, data_type=data_type) diff --git a/azure/functions/decorators/function_app.py b/azure/functions/decorators/function_app.py index 9ed2b6f..3dd33e7 100644 --- a/azure/functions/decorators/function_app.py +++ b/azure/functions/decorators/function_app.py @@ -17,7 +17,7 @@ from azure.functions.decorators.blob import BlobTrigger, BlobInput, BlobOutput from azure.functions.decorators.core import Binding, Trigger, DataType, \ AuthLevel, SCRIPT_FILE_NAME, Cardinality, AccessRights, Setting, BlobSource, \ - McpPropertyType + McpPropertyType, CosmosDBChangeFeedMode from azure.functions.decorators.cosmosdb import CosmosDBTrigger, \ CosmosDBOutput, CosmosDBInput, CosmosDBTriggerV3, CosmosDBInputV3, \ CosmosDBOutputV3 @@ -1047,6 +1047,8 @@ def cosmos_db_trigger(self, start_from_beginning: Optional[time] = None, start_from_time: Optional[time] = None, preferred_locations: Optional[str] = None, + change_feed_mode: Optional[Union[CosmosDBChangeFeedMode, + str]] = None, data_type: Optional[ Union[DataType, str]] = None, **kwargs: Any) -> \ @@ -1108,6 +1110,9 @@ def cosmos_db_trigger(self, has no effect once the trigger has a lease state. :param preferred_locations: Preferred locations (regions) for geo-replicated Cosmos DB accounts. + :param change_feed_mode: (Optional) The change feed mode for the Cosmos DB + trigger. Can be :class:`CosmosDBChangeFeedMode.LATEST_VERSION` (default) + or :class:`CosmosDBChangeFeedMode.ALL_VERSIONS_AND_DELETES`. :param data_type: Defines how the Functions runtime should treat the parameter value. :param kwargs: Additional keyword arguments for specifying binding fields @@ -1134,6 +1139,7 @@ def cosmos_db_trigger(self, start_from_beginning=start_from_beginning, start_from_time=start_from_time, preferred_locations=preferred_locations, + change_feed_mode=change_feed_mode, data_type=parse_singular_param_to_enum(data_type, DataType), **kwargs) From 910c97df648cde8f84b5b1e5e0842a40ae0778c3 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 22 Jun 2026 11:25:16 -0700 Subject: [PATCH 4/4] Unecessary statements removal. --- azure/functions/_cosmosdb.py | 1 - 1 file changed, 1 deletion(-) diff --git a/azure/functions/_cosmosdb.py b/azure/functions/_cosmosdb.py index c170921..dcdf01c 100644 --- a/azure/functions/_cosmosdb.py +++ b/azure/functions/_cosmosdb.py @@ -5,7 +5,6 @@ from . import _abc from ._jsonutils import json -from .decorators.core import CosmosDBChangeFeedMode class Document(_abc.Document, collections.UserDict):