From 2a2b28cf797cada0f1d1a5bd320f035defcaaf4d Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 19 May 2023 16:01:53 -0700 Subject: [PATCH 01/43] [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- .vscode/cspell.json | 3 + scripts/devops_tasks/test_run_samples.py | 15 +- sdk/eventgrid/azure-eventgrid/MANIFEST.in | 6 +- sdk/eventgrid/azure-eventgrid/README.md | 4 + .../azure-eventgrid/azure/__init__.py | 2 +- .../azure/eventgrid/__init__.py | 24 +- .../azure/eventgrid/_client.py | 87 + .../azure/eventgrid/_configuration.py | 70 + .../eventgrid/_generated/models/_patch.py | 20 - .../azure/eventgrid/_legacy/__init__.py | 19 + .../eventgrid/{ => _legacy}/_constants.py | 0 .../{ => _legacy}/_event_mappings.py | 0 .../{ => _legacy}/_generated/__init__.py | 0 .../{ => _legacy}/_generated/_client.py | 12 +- .../_generated/_configuration.py | 28 +- .../_generated/_operations/__init__.py | 0 .../_generated/_operations/_operations.py | 139 +- .../_generated/_operations}/_patch.py | 4 +- .../_generated}/_patch.py | 4 +- .../_legacy/_generated/_serialization.py | 2127 +++++++++++++++++ .../{ => _legacy}/_generated/_vendor.py | 0 .../{ => _legacy}/_generated/aio/__init__.py | 0 .../{ => _legacy}/_generated/aio/_client.py | 16 +- .../_generated/aio/_configuration.py | 32 +- .../_generated/aio/_operations/__init__.py | 0 .../_generated/aio/_operations/_operations.py | 67 +- .../_generated/aio/_operations}/_patch.py | 4 +- .../_generated/aio}/_patch.py | 4 +- .../{ => _legacy}/_generated/aio/_vendor.py | 0 .../_generated/models/__init__.py | 0 .../_generated/models/_models.py | 4 +- .../_legacy/_generated/models/_patch.py | 22 + .../{ => _legacy}/_generated/py.typed | 0 .../azure/eventgrid/{ => _legacy}/_helpers.py | 31 +- .../{ => _legacy}/_messaging_shared.py | 1 - .../azure/eventgrid/{ => _legacy}/_models.py | 0 .../eventgrid/{ => _legacy}/_policies.py | 1 - .../{ => _legacy}/_publisher_client.py | 33 +- .../_signature_credential_policy.py | 0 .../azure/eventgrid/_legacy/_version.py | 12 + .../azure/eventgrid/_legacy/aio/__init__.py | 9 + .../aio/_publisher_client_async.py | 27 +- .../azure/eventgrid/_model_base.py | 695 ++++++ .../azure/eventgrid/_operations/__init__.py | 18 + .../eventgrid/_operations/_operations.py | 739 ++++++ .../azure/eventgrid/_operations/_patch.py | 186 ++ .../azure-eventgrid/azure/eventgrid/_patch.py | 71 + .../{_generated => }/_serialization.py | 8 +- .../azure/eventgrid/_vendor.py | 38 + .../azure/eventgrid/_version.py | 9 +- .../azure/eventgrid/aio/__init__.py | 25 +- .../azure/eventgrid/aio/_client.py | 87 + .../azure/eventgrid/aio/_configuration.py | 70 + .../eventgrid/aio/_operations/__init__.py | 18 + .../eventgrid/aio/_operations/_operations.py | 504 ++++ .../azure/eventgrid/aio/_operations/_patch.py | 157 ++ .../azure/eventgrid/aio/_patch.py | 50 + .../azure/eventgrid/aio/_vendor.py | 25 + .../azure/eventgrid/models/__init__.py | 29 + .../azure/eventgrid/models/_models.py | 383 +++ .../azure/eventgrid/models/_patch.py | 127 + .../azure-eventgrid/azure/eventgrid/py.typed | 1 + sdk/eventgrid/azure-eventgrid/mypy.ini | 10 +- sdk/eventgrid/azure-eventgrid/pyproject.toml | 2 +- .../azure-eventgrid/samples/README.md | 3 + .../sample_acknowledge_operation_async.py | 38 + .../sample_all_operations_async.py | 126 + .../sample_publish_operation_async.py | 46 + .../sample_receive_operation_async.py | 38 + .../sample_reject_operation_async.py | 38 + .../sample_release_operation_async.py | 38 + .../sample_authentication_async.py | 4 +- ...le_publish_cloud_event_using_dict_async.py | 28 +- .../sample_publish_cncf_cloud_events_async.py | 26 +- ..._publish_custom_schema_to_a_topic_async.py | 8 +- ...ample_publish_eg_event_using_dict_async.py | 40 +- ...ple_publish_eg_events_to_a_domain_async.py | 42 +- ...mple_publish_eg_events_to_a_topic_async.py | 25 +- ...s_to_a_topic_using_sas_credential_async.py | 24 +- ...nts_using_cloud_events_1.0_schema_async.py | 25 +- .../sample_publish_to_channel_async.py | 32 +- .../consume_cloud_events_from_eventhub.py | 7 +- ...consume_cloud_events_from_storage_queue.py | 13 +- ...eventgrid_events_from_service_bus_queue.py | 8 +- .../EventGridTrigger1/__init__.py | 17 +- ...ish_cloud_events_to_custom_topic_sample.py | 23 +- ...ish_cloud_events_to_domain_topic_sample.py | 26 +- ...sh_custom_schema_events_to_topic_sample.py | 10 +- ...vent_grid_events_to_custom_topic_sample.py | 28 +- ...ish_with_shared_access_signature_sample.py | 26 +- .../sample_acknowledge_operation.py | 31 + .../sample_all_operations.py | 116 + .../sample_eg_client_authentication.py | 27 + .../sample_publish_operation.py | 35 + .../sample_receive_operation.py | 31 + .../sample_reject_operation.py | 30 + .../sample_release_operation.py | 30 + .../sync_samples/sample_authentication.py | 2 +- .../sync_samples/sample_generate_sas.py | 4 +- .../sample_publish_cloud_event_using_dict.py | 24 +- .../sample_publish_cncf_cloud_events.py | 22 +- ...sample_publish_custom_schema_to_a_topic.py | 6 +- .../sample_publish_eg_event_using_dict.py | 40 +- .../sample_publish_eg_events_to_a_domain.py | 38 +- .../sample_publish_eg_events_to_a_topic.py | 20 +- ..._events_to_a_topic_using_sas_credential.py | 20 +- ...sh_events_using_cloud_events_1.0_schema.py | 20 +- sdk/eventgrid/azure-eventgrid/setup.py | 72 +- .../azure-eventgrid/swagger/_constants.py | 46 +- .../swagger/postprocess_eventnames.py | 9 +- sdk/eventgrid/azure-eventgrid/tests/_mocks.py | 96 +- .../azure-eventgrid/tests/conftest.py | 12 +- .../tests/eventgrid_preparer.py | 43 +- .../tests/perfstress_tests/send.py | 49 +- .../tests/test_cloud_event_tracing.py | 54 +- .../azure-eventgrid/tests/test_cncf_events.py | 20 +- .../tests/test_cncf_events_async.py | 19 +- .../tests/test_eg_client_exceptions.py | 240 ++ .../tests/test_eg_event_get_bytes.py | 183 +- .../tests/test_eg_publisher_client.py | 278 +-- .../tests/test_eg_publisher_client_async.py | 252 +- .../azure-eventgrid/tests/test_exceptions.py | 57 +- .../tests/test_exceptions_async.py | 61 +- .../tests/test_serialization.py | 148 +- .../azure-eventgrid/tsp-location.yaml | 4 + 125 files changed, 7867 insertions(+), 1090 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py delete mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_patch.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/__init__.py rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_constants.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_event_mappings.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/__init__.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/_client.py (88%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/_configuration.py (72%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/_operations/__init__.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/_operations/_operations.py (76%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{_generated => _legacy/_generated/_operations}/_patch.py (84%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{_generated/aio/_operations => _legacy/_generated}/_patch.py (84%) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/_vendor.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/__init__.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/_client.py (87%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/_configuration.py (68%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/_operations/__init__.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/_operations/_operations.py (86%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{_generated/aio => _legacy/_generated/aio/_operations}/_patch.py (84%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{_generated/_operations => _legacy/_generated/aio}/_patch.py (84%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/aio/_vendor.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/models/__init__.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/models/_models.py (99%) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_generated/py.typed (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_helpers.py (90%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_messaging_shared.py (99%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_models.py (100%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_policies.py (99%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_publisher_client.py (93%) rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/_signature_credential_policy.py (100%) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_version.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/__init__.py rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{ => _legacy}/aio/_publisher_client_async.py (93%) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py rename sdk/eventgrid/azure-eventgrid/azure/eventgrid/{_generated => }/_serialization.py (99%) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py create mode 100644 sdk/eventgrid/azure-eventgrid/tsp-location.yaml diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 669fabcf0879..7e1a1a05ccea 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -200,6 +200,7 @@ "centraluseuap", "creds", "ctoring", + "ctxt", "ctypes", "curr", "dateutil", @@ -209,6 +210,7 @@ "dependened", "deque", "deserialization", + "deserializers", "disablecov", "distilbert", "distilroberta", @@ -449,6 +451,7 @@ "yarl", "SDDL", "dacl", + "wday", "whls", "aiter", "solft", diff --git a/scripts/devops_tasks/test_run_samples.py b/scripts/devops_tasks/test_run_samples.py index 4d2637facf54..8d14f0ca5520 100644 --- a/scripts/devops_tasks/test_run_samples.py +++ b/scripts/devops_tasks/test_run_samples.py @@ -87,7 +87,20 @@ "consume_cloud_events_from_eventhub.py", "consume_eventgrid_events_from_service_bus_queue.py", "sample_publish_events_to_a_topic_using_sas_credential.py", - "sample_publish_events_to_a_topic_using_sas_credential_async.py" + "sample_publish_events_to_a_topic_using_sas_credential_async.py", + 'sample_publish_operation.py', + 'sample_receive_operation.py', + 'sample_reject_operation.py', + 'sample_eg_client_authentication.py', + 'sample_all_operations.py', + 'sample_release_operation.py', + 'sample_acknowledge_operation.py', + 'sample_publish_operation_async.py', + 'sample_release_operation_async.py', + 'sample_reject_operation_async.py', + 'sample_acknowledge_operation_async.py', + 'sample_receive_operation_async.py', + 'sample_all_operations_async.py' ], "azure-eventhub": [ "client_identity_authentication.py", # TODO: remove after fixing issue #29177 diff --git a/sdk/eventgrid/azure-eventgrid/MANIFEST.in b/sdk/eventgrid/azure-eventgrid/MANIFEST.in index a4f0c46bcd94..8aee6afa5284 100644 --- a/sdk/eventgrid/azure-eventgrid/MANIFEST.in +++ b/sdk/eventgrid/azure-eventgrid/MANIFEST.in @@ -1,6 +1,6 @@ -recursive-include tests *.py *.yaml -recursive-include samples *.py include *.md include LICENSE -include azure/__init__.py include azure/eventgrid/py.typed +recursive-include tests *.py +recursive-include samples *.py *.md +include azure/__init__.py \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 5771e39aba6f..5b1959dfa632 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -10,6 +10,10 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow | [Samples][python-eg-samples] | [Changelog][python-eg-changelog] +## _Disclaimer_ + +This is the first beta release of Azure EventGrid's `EventGridClient`, along with the GA `EventGridPublisherClient`. `EventGridClient` supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. + ## Getting started ### Prerequisites diff --git a/sdk/eventgrid/azure-eventgrid/azure/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/__init__.py index 0c36c2076ba0..5960c353a898 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/__init__.py @@ -1 +1 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore +__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py index 1dc3655a13bb..32166aad43a3 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py @@ -2,18 +2,24 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._publisher_client import EventGridPublisherClient -from ._event_mappings import SystemEventNames -from ._helpers import generate_sas -from ._models import EventGridEvent +from ._client import EventGridClient from ._version import VERSION +__version__ = VERSION + +try: + from ._patch import __all__ as _patch_all + from ._patch import * # pylint: disable=unused-wildcard-import +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk __all__ = [ - "EventGridPublisherClient", - "EventGridEvent", - "generate_sas", - "SystemEventNames", + 'EventGridClient', ] -__version__ = VERSION +__all__.extend([p for p in _patch_all if p not in __all__]) + +_patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py new file mode 100644 index 000000000000..839215bd35b5 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py @@ -0,0 +1,87 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from copy import deepcopy +from typing import Any + +from azure.core import PipelineClient +from azure.core.credentials import AzureKeyCredential +from azure.core.rest import HttpRequest, HttpResponse + +from ._configuration import EventGridClientConfiguration +from ._operations import EventGridClientOperationsMixin +from ._serialization import Deserializer, Serializer + +class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + """Azure Messaging EventGrid Client. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: AzureKeyCredential, + **kwargs: Any + ) -> None: + _endpoint = '{endpoint}' + self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + self._client: PipelineClient = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + + def send_request( + self, + request: HttpRequest, + **kwargs: Any + ) -> HttpResponse: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.HttpResponse + """ + + request_copy = deepcopy(request) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, **kwargs) + + def close(self) -> None: + self._client.close() + + def __enter__(self) -> "EventGridClient": + self._client.__enter__() + return self + + def __exit__(self, *exc_details: Any) -> None: + self._client.__exit__(*exc_details) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py new file mode 100644 index 000000000000..f294505931a0 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py @@ -0,0 +1,70 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any + +from azure.core.configuration import Configuration +from azure.core.credentials import AzureKeyCredential +from azure.core.pipeline import policies + +from ._version import VERSION + + +class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + """Configuration for EventGridClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: AzureKeyCredential, + **kwargs: Any + ) -> None: + super(EventGridClientConfiguration, self).__init__(**kwargs) + api_version: str = kwargs.pop('api_version', "2023-06-01-preview") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + + self.endpoint = endpoint + self.credential = credential + self.api_version = api_version + kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self._configure(**kwargs) + + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AzureKeyCredentialPolicy(self.credential, "SharedAccessKey", **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_patch.py deleted file mode 100644 index f7dd32510333..000000000000 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_patch.py +++ /dev/null @@ -1,20 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Customize generated code here. - -Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize -""" -from typing import List - -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level - - -def patch_sdk(): - """Do not remove from this file. - - `patch_sdk` is a last resort escape hatch that allows you to do customizations - you can't accomplish using the techniques described in - https://aka.ms/azsdk/python/dpcodegen/python/customize - """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/__init__.py new file mode 100644 index 000000000000..1dc3655a13bb --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/__init__.py @@ -0,0 +1,19 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- + +from ._publisher_client import EventGridPublisherClient +from ._event_mappings import SystemEventNames +from ._helpers import generate_sas +from ._models import EventGridEvent +from ._version import VERSION + +__all__ = [ + "EventGridPublisherClient", + "EventGridEvent", + "generate_sas", + "SystemEventNames", +] +__version__ = VERSION diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_constants.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_constants.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_event_mappings.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_event_mappings.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/__init__.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/__init__.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/__init__.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py similarity index 88% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_client.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py index f3ad2db7363a..d1897c866468 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py @@ -28,12 +28,18 @@ class EventGridPublisherClient( :paramtype api_version: str """ - def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__( + self, **kwargs: Any + ) -> None: # pylint: disable=missing-client-constructor-parameter-credential _endpoint = "https://{topicHostname}" self._config = EventGridPublisherClientConfiguration(**kwargs) - self._client: PipelineClient = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) + self._client: PipelineClient = PipelineClient( + base_url=_endpoint, config=self._config, **kwargs + ) - client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)} + client_models = { + k: v for k, v in _models.__dict__.items() if isinstance(v, type) + } self._serialize = Serializer(client_models) self._deserialize = Deserializer(client_models) self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py similarity index 72% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_configuration.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py index d105970e51f9..5077ede3b176 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py @@ -20,7 +20,9 @@ VERSION = "unknown" -class EventGridPublisherClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes +class EventGridPublisherClientConfiguration( + Configuration +): # pylint: disable=too-many-instance-attributes """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance @@ -40,12 +42,24 @@ def __init__(self, **kwargs: Any) -> None: self._configure(**kwargs) def _configure(self, **kwargs: Any) -> None: - self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.user_agent_policy = kwargs.get( + "user_agent_policy" + ) or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy( + **kwargs + ) self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.logging_policy = kwargs.get( + "logging_policy" + ) or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get( + "http_logging_policy" + ) or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs) + self.custom_hook_policy = kwargs.get( + "custom_hook_policy" + ) or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy( + **kwargs + ) self.authentication_policy = kwargs.get("authentication_policy") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/__init__.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/__init__.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/__init__.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py similarity index 76% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_operations.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py index 86ab83d13741..f1db47f93f7a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py @@ -37,7 +37,9 @@ from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] +ClsType = Optional[ + Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any] +] _SERIALIZER = Serializer() _SERIALIZER.client_side_validation = False @@ -47,8 +49,12 @@ def build_event_grid_publisher_publish_events_request(**kwargs: Any) -> HttpRequ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) + api_version: Literal["2018-01-01"] = kwargs.pop( + "api_version", _params.pop("api-version", "2018-01-01") + ) # Construct URL _url = "/api/events" @@ -57,9 +63,13 @@ def build_event_grid_publisher_publish_events_request(**kwargs: Any) -> HttpRequ # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Content-Type"] = _SERIALIZER.header( + "content_type", content_type, "str" + ) - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest( + method="POST", url=_url, params=_params, headers=_headers, **kwargs + ) def build_event_grid_publisher_publish_cloud_event_events_request( @@ -68,8 +78,12 @@ def build_event_grid_publisher_publish_cloud_event_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) + api_version: Literal["2018-01-01"] = kwargs.pop( + "api_version", _params.pop("api-version", "2018-01-01") + ) # Construct URL _url = "/api/events" @@ -78,17 +92,27 @@ def build_event_grid_publisher_publish_cloud_event_events_request( # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Content-Type"] = _SERIALIZER.header( + "content_type", content_type, "str" + ) - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, json=json, **kwargs) + return HttpRequest( + method="POST", url=_url, params=_params, headers=_headers, json=json, **kwargs + ) -def build_event_grid_publisher_publish_custom_event_events_request(**kwargs: Any) -> HttpRequest: +def build_event_grid_publisher_publish_custom_event_events_request( + **kwargs: Any, +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) + api_version: Literal["2018-01-01"] = kwargs.pop( + "api_version", _params.pop("api-version", "2018-01-01") + ) # Construct URL _url = "/api/events" @@ -97,9 +121,13 @@ def build_event_grid_publisher_publish_custom_event_events_request(**kwargs: Any # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Content-Type"] = _SERIALIZER.header( + "content_type", content_type, "str" + ) - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest( + method="POST", url=_url, params=_params, headers=_headers, **kwargs + ) class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @@ -110,7 +138,7 @@ def publish_events( # pylint: disable=inconsistent-return-statements events: List[_models.EventGridEvent], *, content_type: str = "application/json", - **kwargs: Any + **kwargs: Any, ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -129,7 +157,12 @@ def publish_events( # pylint: disable=inconsistent-return-statements @overload def publish_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: IO, + *, + content_type: str = "application/json", + **kwargs: Any, ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -148,7 +181,10 @@ def publish_events( # pylint: disable=inconsistent-return-statements @distributed_trace def publish_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: Union[List[_models.EventGridEvent], IO], **kwargs: Any + self, + topic_hostname: str, + events: Union[List[_models.EventGridEvent], IO], + **kwargs: Any, ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -176,7 +212,9 @@ def publish_events( # pylint: disable=inconsistent-return-statements _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -196,19 +234,25 @@ def publish_events( # pylint: disable=inconsistent-return-statements params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs + pipeline_response: PipelineResponse = ( + self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs + ) ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: @@ -241,7 +285,10 @@ def publish_cloud_event_events( # pylint: disable=inconsistent-return-statement _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop( - "content_type", _headers.pop("Content-Type", "application/cloudevents-batch+json; charset=utf-8") + "content_type", + _headers.pop( + "Content-Type", "application/cloudevents-batch+json; charset=utf-8" + ), ) cls: ClsType[None] = kwargs.pop("cls", None) @@ -255,19 +302,25 @@ def publish_cloud_event_events( # pylint: disable=inconsistent-return-statement params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs + pipeline_response: PipelineResponse = ( + self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs + ) ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: @@ -275,7 +328,12 @@ def publish_cloud_event_events( # pylint: disable=inconsistent-return-statement @overload def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: List[JSON], *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: List[JSON], + *, + content_type: str = "application/json", + **kwargs: Any, ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -294,7 +352,12 @@ def publish_custom_event_events( # pylint: disable=inconsistent-return-statemen @overload def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: IO, + *, + content_type: str = "application/json", + **kwargs: Any, ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -341,7 +404,9 @@ def publish_custom_event_events( # pylint: disable=inconsistent-return-statemen _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -361,19 +426,25 @@ def publish_custom_event_events( # pylint: disable=inconsistent-return-statemen params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs + pipeline_response: PipelineResponse = ( + self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs + ) ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py similarity index 84% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_patch.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py index f7dd32510333..d400d2d124e2 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py @@ -8,7 +8,9 @@ """ from typing import List -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level +__all__: List[ + str +] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py similarity index 84% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_patch.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py index f7dd32510333..d400d2d124e2 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py @@ -8,7 +8,9 @@ """ from typing import List -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level +__all__: List[ + str +] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py new file mode 100644 index 000000000000..615a169a649a --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py @@ -0,0 +1,2127 @@ +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# 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. +# +# -------------------------------------------------------------------------- + +# pylint: skip-file +# pyright: reportUnnecessaryTypeIgnoreComment=false + +from base64 import b64decode, b64encode +import calendar +import datetime +import decimal +import email +from enum import Enum +import json +import logging +import re +import sys +import codecs +from typing import ( + Dict, + Any, + cast, + Optional, + Union, + AnyStr, + IO, + Mapping, + Callable, + TypeVar, + MutableMapping, + Type, + List, + Mapping, +) + +try: + from urllib import quote # type: ignore +except ImportError: + from urllib.parse import quote +import xml.etree.ElementTree as ET + +import isodate # type: ignore + +from azure.core.exceptions import ( + DeserializationError, + SerializationError, + raise_with_traceback, +) +from azure.core.serialization import NULL as AzureCoreNull + +_BOM = codecs.BOM_UTF8.decode(encoding="utf-8") + +ModelType = TypeVar("ModelType", bound="Model") +JSON = MutableMapping[str, Any] + + +class RawDeserializer: + # Accept "text" because we're open minded people... + JSON_REGEXP = re.compile(r"^(application|text)/([a-z+.]+\+)?json$") + + # Name used in context + CONTEXT_NAME = "deserialized_data" + + @classmethod + def deserialize_from_text( + cls, data: Optional[Union[AnyStr, IO]], content_type: Optional[str] = None + ) -> Any: + """Decode data according to content-type. + + Accept a stream of data as well, but will be load at once in memory for now. + + If no content-type, will return the string version (not bytes, not stream) + + :param data: Input, could be bytes or stream (will be decoded with UTF8) or text + :type data: str or bytes or IO + :param str content_type: The content type. + """ + if hasattr(data, "read"): + # Assume a stream + data = cast(IO, data).read() + + if isinstance(data, bytes): + data_as_str = data.decode(encoding="utf-8-sig") + else: + # Explain to mypy the correct type. + data_as_str = cast(str, data) + + # Remove Byte Order Mark if present in string + data_as_str = data_as_str.lstrip(_BOM) + + if content_type is None: + return data + + if cls.JSON_REGEXP.match(content_type): + try: + return json.loads(data_as_str) + except ValueError as err: + raise DeserializationError("JSON is invalid: {}".format(err), err) + elif "xml" in (content_type or []): + try: + try: + if isinstance(data, unicode): # type: ignore + # If I'm Python 2.7 and unicode XML will scream if I try a "fromstring" on unicode string + data_as_str = data_as_str.encode(encoding="utf-8") # type: ignore + except NameError: + pass + + return ET.fromstring(data_as_str) # nosec + except ET.ParseError: + # It might be because the server has an issue, and returned JSON with + # content-type XML.... + # So let's try a JSON load, and if it's still broken + # let's flow the initial exception + def _json_attemp(data): + try: + return True, json.loads(data) + except ValueError: + return False, None # Don't care about this one + + success, json_result = _json_attemp(data) + if success: + return json_result + # If i'm here, it's not JSON, it's not XML, let's scream + # and raise the last context in this block (the XML exception) + # The function hack is because Py2.7 messes up with exception + # context otherwise. + _LOGGER.critical("Wasn't XML not JSON, failing") + raise_with_traceback(DeserializationError, "XML is invalid") + raise DeserializationError( + "Cannot deserialize content-type: {}".format(content_type) + ) + + @classmethod + def deserialize_from_http_generics( + cls, body_bytes: Optional[Union[AnyStr, IO]], headers: Mapping + ) -> Any: + """Deserialize from HTTP response. + + Use bytes and headers to NOT use any requests/aiohttp or whatever + specific implementation. + Headers will tested for "content-type" + """ + # Try to use content-type from headers if available + content_type = None + if "content-type" in headers: + content_type = headers["content-type"].split(";")[0].strip().lower() + # Ouch, this server did not declare what it sent... + # Let's guess it's JSON... + # Also, since Autorest was considering that an empty body was a valid JSON, + # need that test as well.... + else: + content_type = "application/json" + + if body_bytes: + return cls.deserialize_from_text(body_bytes, content_type) + return None + + +try: + basestring # type: ignore + unicode_str = unicode # type: ignore +except NameError: + basestring = str + unicode_str = str + +_LOGGER = logging.getLogger(__name__) + +try: + _long_type = long # type: ignore +except NameError: + _long_type = int + + +class UTC(datetime.tzinfo): + """Time Zone info for handling UTC""" + + def utcoffset(self, dt): + """UTF offset for UTC is 0.""" + return datetime.timedelta(0) + + def tzname(self, dt): + """Timestamp representation.""" + return "Z" + + def dst(self, dt): + """No daylight saving for UTC.""" + return datetime.timedelta(hours=1) + + +try: + from datetime import timezone as _FixedOffset # type: ignore +except ImportError: # Python 2.7 + + class _FixedOffset(datetime.tzinfo): # type: ignore + """Fixed offset in minutes east from UTC. + Copy/pasted from Python doc + :param datetime.timedelta offset: offset in timedelta format + """ + + def __init__(self, offset): + self.__offset = offset + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return str(self.__offset.total_seconds() / 3600) + + def __repr__(self): + return "".format(self.tzname(None)) + + def dst(self, dt): + return datetime.timedelta(0) + + def __getinitargs__(self): + return (self.__offset,) + + +try: + from datetime import timezone + + TZ_UTC = timezone.utc +except ImportError: + TZ_UTC = UTC() # type: ignore + +_FLATTEN = re.compile(r"(? None: + self.additional_properties: Dict[str, Any] = {} + for k in kwargs: + if k not in self._attribute_map: + _LOGGER.warning( + "%s is not a known attribute of class %s and will be ignored", + k, + self.__class__, + ) + elif k in self._validation and self._validation[k].get("readonly", False): + _LOGGER.warning( + "Readonly attribute %s will be ignored in class %s", + k, + self.__class__, + ) + else: + setattr(self, k, kwargs[k]) + + def __eq__(self, other: Any) -> bool: + """Compare objects by comparing all attributes.""" + if isinstance(other, self.__class__): + return self.__dict__ == other.__dict__ + return False + + def __ne__(self, other: Any) -> bool: + """Compare objects by comparing all attributes.""" + return not self.__eq__(other) + + def __str__(self) -> str: + return str(self.__dict__) + + @classmethod + def enable_additional_properties_sending(cls) -> None: + cls._attribute_map["additional_properties"] = {"key": "", "type": "{object}"} + + @classmethod + def is_xml_model(cls) -> bool: + try: + cls._xml_map # type: ignore + except AttributeError: + return False + return True + + @classmethod + def _create_xml_node(cls): + """Create XML node.""" + try: + xml_map = cls._xml_map # type: ignore + except AttributeError: + xml_map = {} + + return _create_xml_node( + xml_map.get("name", cls.__name__), + xml_map.get("prefix", None), + xml_map.get("ns", None), + ) + + def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: + """Return the JSON that would be sent to azure from this model. + + This is an alias to `as_dict(full_restapi_key_transformer, keep_readonly=False)`. + + If you want XML serialization, you can pass the kwargs is_xml=True. + + :param bool keep_readonly: If you want to serialize the readonly attributes + :returns: A dict JSON compatible object + :rtype: dict + """ + serializer = Serializer(self._infer_class_models()) + return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) + + def as_dict( + self, + keep_readonly: bool = True, + key_transformer: Callable[ + [str, Dict[str, Any], Any], Any + ] = attribute_transformer, + **kwargs: Any + ) -> JSON: + """Return a dict that can be serialized using json.dump. + + Advanced usage might optionally use a callback as parameter: + + .. code::python + + def my_key_transformer(key, attr_desc, value): + return key + + Key is the attribute name used in Python. Attr_desc + is a dict of metadata. Currently contains 'type' with the + msrest type and 'key' with the RestAPI encoded key. + Value is the current value in this object. + + The string returned will be used to serialize the key. + If the return type is a list, this is considered hierarchical + result dict. + + See the three examples in this file: + + - attribute_transformer + - full_restapi_key_transformer + - last_restapi_key_transformer + + If you want XML serialization, you can pass the kwargs is_xml=True. + + :param function key_transformer: A key transformer function. + :returns: A dict JSON compatible object + :rtype: dict + """ + serializer = Serializer(self._infer_class_models()) + return serializer._serialize( + self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs + ) + + @classmethod + def _infer_class_models(cls): + try: + str_models = cls.__module__.rsplit(".", 1)[0] + models = sys.modules[str_models] + client_models = { + k: v for k, v in models.__dict__.items() if isinstance(v, type) + } + if cls.__name__ not in client_models: + raise ValueError("Not Autorest generated code") + except Exception: + # Assume it's not Autorest generated (tests?). Add ourselves as dependencies. + client_models = {cls.__name__: cls} + return client_models + + @classmethod + def deserialize( + cls: Type[ModelType], data: Any, content_type: Optional[str] = None + ) -> ModelType: + """Parse a str using the RestAPI syntax and return a model. + + :param str data: A str using RestAPI structure. JSON by default. + :param str content_type: JSON by default, set application/xml if XML. + :returns: An instance of this model + :raises: DeserializationError if something went wrong + """ + deserializer = Deserializer(cls._infer_class_models()) + return deserializer(cls.__name__, data, content_type=content_type) + + @classmethod + def from_dict( + cls: Type[ModelType], + data: Any, + key_extractors: Optional[Callable[[str, Dict[str, Any], Any], Any]] = None, + content_type: Optional[str] = None, + ) -> ModelType: + """Parse a dict using given key extractor return a model. + + By default consider key + extractors (rest_key_case_insensitive_extractor, attribute_key_case_insensitive_extractor + and last_rest_key_case_insensitive_extractor) + + :param dict data: A dict using RestAPI structure + :param str content_type: JSON by default, set application/xml if XML. + :returns: An instance of this model + :raises: DeserializationError if something went wrong + """ + deserializer = Deserializer(cls._infer_class_models()) + deserializer.key_extractors = ( # type: ignore + [ # type: ignore + attribute_key_case_insensitive_extractor, + rest_key_case_insensitive_extractor, + last_rest_key_case_insensitive_extractor, + ] + if key_extractors is None + else key_extractors + ) + return deserializer(cls.__name__, data, content_type=content_type) + + @classmethod + def _flatten_subtype(cls, key, objects): + if "_subtype_map" not in cls.__dict__: + return {} + result = dict(cls._subtype_map[key]) + for valuetype in cls._subtype_map[key].values(): + result.update(objects[valuetype]._flatten_subtype(key, objects)) + return result + + @classmethod + def _classify(cls, response, objects): + """Check the class _subtype_map for any child classes. + We want to ignore any inherited _subtype_maps. + Remove the polymorphic key from the initial data. + """ + for subtype_key in cls.__dict__.get("_subtype_map", {}).keys(): + subtype_value = None + + if not isinstance(response, ET.Element): + rest_api_response_key = cls._get_rest_key_parts(subtype_key)[-1] + subtype_value = response.pop( + rest_api_response_key, None + ) or response.pop(subtype_key, None) + else: + subtype_value = xml_key_extractor( + subtype_key, cls._attribute_map[subtype_key], response + ) + if subtype_value: + # Try to match base class. Can be class name only + # (bug to fix in Autorest to support x-ms-discriminator-name) + if cls.__name__ == subtype_value: + return cls + flatten_mapping_type = cls._flatten_subtype(subtype_key, objects) + try: + return objects[flatten_mapping_type[subtype_value]] # type: ignore + except KeyError: + _LOGGER.warning( + "Subtype value %s has no mapping, use base class %s.", + subtype_value, + cls.__name__, + ) + break + else: + _LOGGER.warning( + "Discriminator %s is absent or null, use base class %s.", + subtype_key, + cls.__name__, + ) + break + return cls + + @classmethod + def _get_rest_key_parts(cls, attr_key): + """Get the RestAPI key of this attr, split it and decode part + :param str attr_key: Attribute key must be in attribute_map. + :returns: A list of RestAPI part + :rtype: list + """ + rest_split_key = _FLATTEN.split(cls._attribute_map[attr_key]["key"]) + return [_decode_attribute_map_key(key_part) for key_part in rest_split_key] + + +def _decode_attribute_map_key(key): + """This decode a key in an _attribute_map to the actual key we want to look at + inside the received data. + + :param str key: A key string from the generated code + """ + return key.replace("\\.", ".") + + +class Serializer(object): + """Request object model serializer.""" + + basic_types = {str: "str", int: "int", bool: "bool", float: "float"} + + _xml_basic_types_serializers = {"bool": lambda x: str(x).lower()} + days = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"} + months = { + 1: "Jan", + 2: "Feb", + 3: "Mar", + 4: "Apr", + 5: "May", + 6: "Jun", + 7: "Jul", + 8: "Aug", + 9: "Sep", + 10: "Oct", + 11: "Nov", + 12: "Dec", + } + validation = { + "min_length": lambda x, y: len(x) < y, + "max_length": lambda x, y: len(x) > y, + "minimum": lambda x, y: x < y, + "maximum": lambda x, y: x > y, + "minimum_ex": lambda x, y: x <= y, + "maximum_ex": lambda x, y: x >= y, + "min_items": lambda x, y: len(x) < y, + "max_items": lambda x, y: len(x) > y, + "pattern": lambda x, y: not re.match(y, x, re.UNICODE), + "unique": lambda x, y: len(x) != len(set(x)), + "multiple": lambda x, y: x % y != 0, + } + + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + self.serialize_type = { + "iso-8601": Serializer.serialize_iso, + "rfc-1123": Serializer.serialize_rfc, + "unix-time": Serializer.serialize_unix, + "duration": Serializer.serialize_duration, + "date": Serializer.serialize_date, + "time": Serializer.serialize_time, + "decimal": Serializer.serialize_decimal, + "long": Serializer.serialize_long, + "bytearray": Serializer.serialize_bytearray, + "base64": Serializer.serialize_base64, + "object": self.serialize_object, + "[]": self.serialize_iter, + "{}": self.serialize_dict, + } + self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.key_transformer = full_restapi_key_transformer + self.client_side_validation = True + + def _serialize(self, target_obj, data_type=None, **kwargs): + """Serialize data into a string according to type. + + :param target_obj: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str, dict + :raises: SerializationError if serialization fails. + """ + key_transformer = kwargs.get("key_transformer", self.key_transformer) + keep_readonly = kwargs.get("keep_readonly", False) + if target_obj is None: + return None + + attr_name = None + class_name = target_obj.__class__.__name__ + + if data_type: + return self.serialize_data(target_obj, data_type, **kwargs) + + if not hasattr(target_obj, "_attribute_map"): + data_type = type(target_obj).__name__ + if data_type in self.basic_types.values(): + return self.serialize_data(target_obj, data_type, **kwargs) + + # Force "is_xml" kwargs if we detect a XML model + try: + is_xml_model_serialization = kwargs["is_xml"] + except KeyError: + is_xml_model_serialization = kwargs.setdefault( + "is_xml", target_obj.is_xml_model() + ) + + serialized = {} + if is_xml_model_serialization: + serialized = target_obj._create_xml_node() + try: + attributes = target_obj._attribute_map + for attr, attr_desc in attributes.items(): + attr_name = attr + if not keep_readonly and target_obj._validation.get(attr_name, {}).get( + "readonly", False + ): + continue + + if attr_name == "additional_properties" and attr_desc["key"] == "": + if target_obj.additional_properties is not None: + serialized.update(target_obj.additional_properties) + continue + try: + orig_attr = getattr(target_obj, attr) + if is_xml_model_serialization: + pass # Don't provide "transformer" for XML for now. Keep "orig_attr" + else: # JSON + keys, orig_attr = key_transformer( + attr, attr_desc.copy(), orig_attr + ) + keys = keys if isinstance(keys, list) else [keys] + + kwargs["serialization_ctxt"] = attr_desc + new_attr = self.serialize_data( + orig_attr, attr_desc["type"], **kwargs + ) + + if is_xml_model_serialization: + xml_desc = attr_desc.get("xml", {}) + xml_name = xml_desc.get("name", attr_desc["key"]) + xml_prefix = xml_desc.get("prefix", None) + xml_ns = xml_desc.get("ns", None) + if xml_desc.get("attr", False): + if xml_ns: + ET.register_namespace(xml_prefix, xml_ns) + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + serialized.set(xml_name, new_attr) # type: ignore + continue + if xml_desc.get("text", False): + serialized.text = new_attr # type: ignore + continue + if isinstance(new_attr, list): + serialized.extend(new_attr) # type: ignore + elif isinstance(new_attr, ET.Element): + # If the down XML has no XML/Name, we MUST replace the tag with the local tag. But keeping the namespaces. + if "name" not in getattr(orig_attr, "_xml_map", {}): + splitted_tag = new_attr.tag.split("}") + if len(splitted_tag) == 2: # Namespace + new_attr.tag = "}".join([splitted_tag[0], xml_name]) + else: + new_attr.tag = xml_name + serialized.append(new_attr) # type: ignore + else: # That's a basic type + # Integrate namespace if necessary + local_node = _create_xml_node(xml_name, xml_prefix, xml_ns) + local_node.text = unicode_str(new_attr) + serialized.append(local_node) # type: ignore + else: # JSON + for k in reversed(keys): # type: ignore + new_attr = {k: new_attr} + + _new_attr = new_attr + _serialized = serialized + for k in keys: # type: ignore + if k not in _serialized: + _serialized.update(_new_attr) # type: ignore + _new_attr = _new_attr[k] # type: ignore + _serialized = _serialized[k] + except ValueError: + continue + + except (AttributeError, KeyError, TypeError) as err: + msg = "Attribute {} in object {} cannot be serialized.\n{}".format( + attr_name, class_name, str(target_obj) + ) + raise_with_traceback(SerializationError, msg, err) + else: + return serialized + + def body(self, data, data_type, **kwargs): + """Serialize data intended for a request body. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: dict + :raises: SerializationError if serialization fails. + :raises: ValueError if data is None + """ + + # Just in case this is a dict + internal_data_type_str = data_type.strip("[]{}") + internal_data_type = self.dependencies.get(internal_data_type_str, None) + try: + is_xml_model_serialization = kwargs["is_xml"] + except KeyError: + if internal_data_type and issubclass(internal_data_type, Model): + is_xml_model_serialization = kwargs.setdefault( + "is_xml", internal_data_type.is_xml_model() + ) + else: + is_xml_model_serialization = False + if internal_data_type and not isinstance(internal_data_type, Enum): + try: + deserializer = Deserializer(self.dependencies) + # Since it's on serialization, it's almost sure that format is not JSON REST + # We're not able to deal with additional properties for now. + deserializer.additional_properties_detection = False + if is_xml_model_serialization: + deserializer.key_extractors = [ # type: ignore + attribute_key_case_insensitive_extractor, + ] + else: + deserializer.key_extractors = [ + rest_key_case_insensitive_extractor, + attribute_key_case_insensitive_extractor, + last_rest_key_case_insensitive_extractor, + ] + data = deserializer._deserialize(data_type, data) + except DeserializationError as err: + raise_with_traceback( + SerializationError, "Unable to build a model: " + str(err), err + ) + + return self._serialize(data, data_type, **kwargs) + + def url(self, name, data, data_type, **kwargs): + """Serialize data intended for a URL path. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + + if kwargs.get("skip_quote") is True: + output = str(output) + else: + output = quote(str(output), safe="") + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return output + + def query(self, name, data, data_type, **kwargs): + """Serialize data intended for a URL query. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + # Treat the list aside, since we don't want to encode the div separator + if data_type.startswith("["): + internal_data_type = data_type[1:-1] + data = [ + self.serialize_data(d, internal_data_type, **kwargs) + if d is not None + else "" + for d in data + ] + if not kwargs.get("skip_quote", False): + data = [quote(str(d), safe="") for d in data] + return str(self.serialize_iter(data, internal_data_type, **kwargs)) + + # Not a list, regular serialization + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + if kwargs.get("skip_quote") is True: + output = str(output) + else: + output = quote(str(output), safe="") + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return str(output) + + def header(self, name, data, data_type, **kwargs): + """Serialize data intended for a request header. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + if data_type in ["[str]"]: + data = ["" if d is None else d for d in data] + + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return str(output) + + def serialize_data(self, data, data_type, **kwargs): + """Serialize generic data according to supplied data type. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :param bool required: Whether it's essential that the data not be + empty or None + :raises: AttributeError if required data is None. + :raises: ValueError if data is None + :raises: SerializationError if serialization fails. + """ + if data is None: + raise ValueError("No value for given attribute") + + try: + if data is AzureCoreNull: + return None + if data_type in self.basic_types.values(): + return self.serialize_basic(data, data_type, **kwargs) + + elif data_type in self.serialize_type: + return self.serialize_type[data_type](data, **kwargs) + + # If dependencies is empty, try with current data class + # It has to be a subclass of Enum anyway + enum_type = self.dependencies.get(data_type, data.__class__) + if issubclass(enum_type, Enum): + return Serializer.serialize_enum(data, enum_obj=enum_type) + + iter_type = data_type[0] + data_type[-1] + if iter_type in self.serialize_type: + return self.serialize_type[iter_type](data, data_type[1:-1], **kwargs) + + except (ValueError, TypeError) as err: + msg = "Unable to serialize value: {!r} as type: {!r}." + raise_with_traceback(SerializationError, msg.format(data, data_type), err) + else: + return self._serialize(data, **kwargs) + + @classmethod + def _get_custom_serializers(cls, data_type, **kwargs): + custom_serializer = kwargs.get("basic_types_serializers", {}).get(data_type) + if custom_serializer: + return custom_serializer + if kwargs.get("is_xml", False): + return cls._xml_basic_types_serializers.get(data_type) + + @classmethod + def serialize_basic(cls, data, data_type, **kwargs): + """Serialize basic builting data type. + Serializes objects to str, int, float or bool. + + Possible kwargs: + - basic_types_serializers dict[str, callable] : If set, use the callable as serializer + - is_xml bool : If set, use xml_basic_types_serializers + + :param data: Object to be serialized. + :param str data_type: Type of object in the iterable. + """ + custom_serializer = cls._get_custom_serializers(data_type, **kwargs) + if custom_serializer: + return custom_serializer(data) + if data_type == "str": + return cls.serialize_unicode(data) + return eval(data_type)(data) # nosec + + @classmethod + def serialize_unicode(cls, data): + """Special handling for serializing unicode strings in Py2. + Encode to UTF-8 if unicode, otherwise handle as a str. + + :param data: Object to be serialized. + :rtype: str + """ + try: # If I received an enum, return its value + return data.value + except AttributeError: + pass + + try: + if isinstance(data, unicode): # type: ignore + # Don't change it, JSON and XML ElementTree are totally able + # to serialize correctly u'' strings + return data + except NameError: + return str(data) + else: + return str(data) + + def serialize_iter(self, data, iter_type, div=None, **kwargs): + """Serialize iterable. + + Supported kwargs: + - serialization_ctxt dict : The current entry of _attribute_map, or same format. + serialization_ctxt['type'] should be same as data_type. + - is_xml bool : If set, serialize as XML + + :param list attr: Object to be serialized. + :param str iter_type: Type of object in the iterable. + :param bool required: Whether the objects in the iterable must + not be None or empty. + :param str div: If set, this str will be used to combine the elements + in the iterable into a combined string. Default is 'None'. + :rtype: list, str + """ + if isinstance(data, str): + raise SerializationError("Refuse str type as a valid iter type.") + + serialization_ctxt = kwargs.get("serialization_ctxt", {}) + is_xml = kwargs.get("is_xml", False) + + serialized = [] + for d in data: + try: + serialized.append(self.serialize_data(d, iter_type, **kwargs)) + except ValueError: + serialized.append(None) + + if div: + serialized = ["" if s is None else str(s) for s in serialized] + serialized = div.join(serialized) + + if "xml" in serialization_ctxt or is_xml: + # XML serialization is more complicated + xml_desc = serialization_ctxt.get("xml", {}) + xml_name = xml_desc.get("name") + if not xml_name: + xml_name = serialization_ctxt["key"] + + # Create a wrap node if necessary (use the fact that Element and list have "append") + is_wrapped = xml_desc.get("wrapped", False) + node_name = xml_desc.get("itemsName", xml_name) + if is_wrapped: + final_result = _create_xml_node( + xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None) + ) + else: + final_result = [] + # All list elements to "local_node" + for el in serialized: + if isinstance(el, ET.Element): + el_node = el + else: + el_node = _create_xml_node( + node_name, + xml_desc.get("prefix", None), + xml_desc.get("ns", None), + ) + if el is not None: # Otherwise it writes "None" :-p + el_node.text = str(el) + final_result.append(el_node) + return final_result + return serialized + + def serialize_dict(self, attr, dict_type, **kwargs): + """Serialize a dictionary of objects. + + :param dict attr: Object to be serialized. + :param str dict_type: Type of object in the dictionary. + :param bool required: Whether the objects in the dictionary must + not be None or empty. + :rtype: dict + """ + serialization_ctxt = kwargs.get("serialization_ctxt", {}) + serialized = {} + for key, value in attr.items(): + try: + serialized[self.serialize_unicode(key)] = self.serialize_data( + value, dict_type, **kwargs + ) + except ValueError: + serialized[self.serialize_unicode(key)] = None + + if "xml" in serialization_ctxt: + # XML serialization is more complicated + xml_desc = serialization_ctxt["xml"] + xml_name = xml_desc["name"] + + final_result = _create_xml_node( + xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None) + ) + for key, value in serialized.items(): + ET.SubElement(final_result, key).text = value + return final_result + + return serialized + + def serialize_object(self, attr, **kwargs): + """Serialize a generic object. + This will be handled as a dictionary. If object passed in is not + a basic type (str, int, float, dict, list) it will simply be + cast to str. + + :param dict attr: Object to be serialized. + :rtype: dict or str + """ + if attr is None: + return None + if isinstance(attr, ET.Element): + return attr + obj_type = type(attr) + if obj_type in self.basic_types: + return self.serialize_basic(attr, self.basic_types[obj_type], **kwargs) + if obj_type is _long_type: + return self.serialize_long(attr) + if obj_type is unicode_str: + return self.serialize_unicode(attr) + if obj_type is datetime.datetime: + return self.serialize_iso(attr) + if obj_type is datetime.date: + return self.serialize_date(attr) + if obj_type is datetime.time: + return self.serialize_time(attr) + if obj_type is datetime.timedelta: + return self.serialize_duration(attr) + if obj_type is decimal.Decimal: + return self.serialize_decimal(attr) + + # If it's a model or I know this dependency, serialize as a Model + elif obj_type in self.dependencies.values() or isinstance(attr, Model): + return self._serialize(attr) + + if obj_type == dict: + serialized = {} + for key, value in attr.items(): + try: + serialized[self.serialize_unicode(key)] = self.serialize_object( + value, **kwargs + ) + except ValueError: + serialized[self.serialize_unicode(key)] = None + return serialized + + if obj_type == list: + serialized = [] + for obj in attr: + try: + serialized.append(self.serialize_object(obj, **kwargs)) + except ValueError: + pass + return serialized + return str(attr) + + @staticmethod + def serialize_enum(attr, enum_obj=None): + try: + result = attr.value + except AttributeError: + result = attr + try: + enum_obj(result) # type: ignore + return result + except ValueError: + for enum_value in enum_obj: # type: ignore + if enum_value.value.lower() == str(attr).lower(): + return enum_value.value + error = "{!r} is not valid value for enum {!r}" + raise SerializationError(error.format(attr, enum_obj)) + + @staticmethod + def serialize_bytearray(attr, **kwargs): + """Serialize bytearray into base-64 string. + + :param attr: Object to be serialized. + :rtype: str + """ + return b64encode(attr).decode() + + @staticmethod + def serialize_base64(attr, **kwargs): + """Serialize str into base-64 string. + + :param attr: Object to be serialized. + :rtype: str + """ + encoded = b64encode(attr).decode("ascii") + return encoded.strip("=").replace("+", "-").replace("/", "_") + + @staticmethod + def serialize_decimal(attr, **kwargs): + """Serialize Decimal object to float. + + :param attr: Object to be serialized. + :rtype: float + """ + return float(attr) + + @staticmethod + def serialize_long(attr, **kwargs): + """Serialize long (Py2) or int (Py3). + + :param attr: Object to be serialized. + :rtype: int/long + """ + return _long_type(attr) + + @staticmethod + def serialize_date(attr, **kwargs): + """Serialize Date object into ISO-8601 formatted string. + + :param Date attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_date(attr) + t = "{:04}-{:02}-{:02}".format(attr.year, attr.month, attr.day) + return t + + @staticmethod + def serialize_time(attr, **kwargs): + """Serialize Time object into ISO-8601 formatted string. + + :param datetime.time attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_time(attr) + t = "{:02}:{:02}:{:02}".format(attr.hour, attr.minute, attr.second) + if attr.microsecond: + t += ".{:02}".format(attr.microsecond) + return t + + @staticmethod + def serialize_duration(attr, **kwargs): + """Serialize TimeDelta object into ISO-8601 formatted string. + + :param TimeDelta attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_duration(attr) + return isodate.duration_isoformat(attr) + + @staticmethod + def serialize_rfc(attr, **kwargs): + """Serialize Datetime object into RFC-1123 formatted string. + + :param Datetime attr: Object to be serialized. + :rtype: str + :raises: TypeError if format invalid. + """ + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + utc = attr.utctimetuple() + except AttributeError: + raise TypeError("RFC1123 object must be valid Datetime object.") + + return "{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT".format( + Serializer.days[utc.tm_wday], + utc.tm_mday, + Serializer.months[utc.tm_mon], + utc.tm_year, + utc.tm_hour, + utc.tm_min, + utc.tm_sec, + ) + + @staticmethod + def serialize_iso(attr, **kwargs): + """Serialize Datetime object into ISO-8601 formatted string. + + :param Datetime attr: Object to be serialized. + :rtype: str + :raises: SerializationError if format invalid. + """ + if isinstance(attr, str): + attr = isodate.parse_datetime(attr) + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + utc = attr.utctimetuple() + if utc.tm_year > 9999 or utc.tm_year < 1: + raise OverflowError("Hit max or min date") + + microseconds = str(attr.microsecond).rjust(6, "0").rstrip("0").ljust(3, "0") + if microseconds: + microseconds = "." + microseconds + date = "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}".format( + utc.tm_year, + utc.tm_mon, + utc.tm_mday, + utc.tm_hour, + utc.tm_min, + utc.tm_sec, + ) + return date + microseconds + "Z" + except (ValueError, OverflowError) as err: + msg = "Unable to serialize datetime object." + raise_with_traceback(SerializationError, msg, err) + except AttributeError as err: + msg = "ISO-8601 object must be valid Datetime object." + raise_with_traceback(TypeError, msg, err) + + @staticmethod + def serialize_unix(attr, **kwargs): + """Serialize Datetime object into IntTime format. + This is represented as seconds. + + :param Datetime attr: Object to be serialized. + :rtype: int + :raises: SerializationError if format invalid + """ + if isinstance(attr, int): + return attr + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + return int(calendar.timegm(attr.utctimetuple())) + except AttributeError: + raise TypeError("Unix time object must be valid Datetime object.") + + +def rest_key_extractor(attr, attr_desc, data): + key = attr_desc["key"] + working_data = data + + while "." in key: + # Need the cast, as for some reasons "split" is typed as list[str | Any] + dict_keys = cast(List[str], _FLATTEN.split(key)) + if len(dict_keys) == 1: + key = _decode_attribute_map_key(dict_keys[0]) + break + working_key = _decode_attribute_map_key(dict_keys[0]) + working_data = working_data.get(working_key, data) + if working_data is None: + # If at any point while following flatten JSON path see None, it means + # that all properties under are None as well + # https://github.com/Azure/msrest-for-python/issues/197 + return None + key = ".".join(dict_keys[1:]) + + return working_data.get(key) + + +def rest_key_case_insensitive_extractor(attr, attr_desc, data): + key = attr_desc["key"] + working_data = data + + while "." in key: + dict_keys = _FLATTEN.split(key) + if len(dict_keys) == 1: + key = _decode_attribute_map_key(dict_keys[0]) + break + working_key = _decode_attribute_map_key(dict_keys[0]) + working_data = attribute_key_case_insensitive_extractor( + working_key, None, working_data + ) + if working_data is None: + # If at any point while following flatten JSON path see None, it means + # that all properties under are None as well + # https://github.com/Azure/msrest-for-python/issues/197 + return None + key = ".".join(dict_keys[1:]) + + if working_data: + return attribute_key_case_insensitive_extractor(key, None, working_data) + + +def last_rest_key_extractor(attr, attr_desc, data): + """Extract the attribute in "data" based on the last part of the JSON path key.""" + key = attr_desc["key"] + dict_keys = _FLATTEN.split(key) + return attribute_key_extractor(dict_keys[-1], None, data) + + +def last_rest_key_case_insensitive_extractor(attr, attr_desc, data): + """Extract the attribute in "data" based on the last part of the JSON path key. + + This is the case insensitive version of "last_rest_key_extractor" + """ + key = attr_desc["key"] + dict_keys = _FLATTEN.split(key) + return attribute_key_case_insensitive_extractor(dict_keys[-1], None, data) + + +def attribute_key_extractor(attr, _, data): + return data.get(attr) + + +def attribute_key_case_insensitive_extractor(attr, _, data): + found_key = None + lower_attr = attr.lower() + for key in data: + if lower_attr == key.lower(): + found_key = key + break + + return data.get(found_key) + + +def _extract_name_from_internal_type(internal_type): + """Given an internal type XML description, extract correct XML name with namespace. + + :param dict internal_type: An model type + :rtype: tuple + :returns: A tuple XML name + namespace dict + """ + internal_type_xml_map = getattr(internal_type, "_xml_map", {}) + xml_name = internal_type_xml_map.get("name", internal_type.__name__) + xml_ns = internal_type_xml_map.get("ns", None) + if xml_ns: + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + return xml_name + + +def xml_key_extractor(attr, attr_desc, data): + if isinstance(data, dict): + return None + + # Test if this model is XML ready first + if not isinstance(data, ET.Element): + return None + + xml_desc = attr_desc.get("xml", {}) + xml_name = xml_desc.get("name", attr_desc["key"]) + + # Look for a children + is_iter_type = attr_desc["type"].startswith("[") + is_wrapped = xml_desc.get("wrapped", False) + internal_type = attr_desc.get("internalType", None) + internal_type_xml_map = getattr(internal_type, "_xml_map", {}) + + # Integrate namespace if necessary + xml_ns = xml_desc.get("ns", internal_type_xml_map.get("ns", None)) + if xml_ns: + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + + # If it's an attribute, that's simple + if xml_desc.get("attr", False): + return data.get(xml_name) + + # If it's x-ms-text, that's simple too + if xml_desc.get("text", False): + return data.text + + # Scenario where I take the local name: + # - Wrapped node + # - Internal type is an enum (considered basic types) + # - Internal type has no XML/Name node + if is_wrapped or ( + internal_type + and (issubclass(internal_type, Enum) or "name" not in internal_type_xml_map) + ): + children = data.findall(xml_name) + # If internal type has a local name and it's not a list, I use that name + elif not is_iter_type and internal_type and "name" in internal_type_xml_map: + xml_name = _extract_name_from_internal_type(internal_type) + children = data.findall(xml_name) + # That's an array + else: + if ( + internal_type + ): # Complex type, ignore itemsName and use the complex type name + items_name = _extract_name_from_internal_type(internal_type) + else: + items_name = xml_desc.get("itemsName", xml_name) + children = data.findall(items_name) + + if len(children) == 0: + if is_iter_type: + if is_wrapped: + return None # is_wrapped no node, we want None + else: + return [] # not wrapped, assume empty list + return None # Assume it's not there, maybe an optional node. + + # If is_iter_type and not wrapped, return all found children + if is_iter_type: + if not is_wrapped: + return children + else: # Iter and wrapped, should have found one node only (the wrap one) + if len(children) != 1: + raise DeserializationError( + "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( + xml_name + ) + ) + return list(children[0]) # Might be empty list and that's ok. + + # Here it's not a itertype, we should have found one element only or empty + if len(children) > 1: + raise DeserializationError( + "Find several XML '{}' where it was not expected".format(xml_name) + ) + return children[0] + + +class Deserializer(object): + """Response object model deserializer. + + :param dict classes: Class type dictionary for deserializing complex types. + :ivar list key_extractors: Ordered list of extractors to be used by this deserializer. + """ + + basic_types = {str: "str", int: "int", bool: "bool", float: "float"} + + valid_date = re.compile( + r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?" + ) + + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + self.deserialize_type = { + "iso-8601": Deserializer.deserialize_iso, + "rfc-1123": Deserializer.deserialize_rfc, + "unix-time": Deserializer.deserialize_unix, + "duration": Deserializer.deserialize_duration, + "date": Deserializer.deserialize_date, + "time": Deserializer.deserialize_time, + "decimal": Deserializer.deserialize_decimal, + "long": Deserializer.deserialize_long, + "bytearray": Deserializer.deserialize_bytearray, + "base64": Deserializer.deserialize_base64, + "object": self.deserialize_object, + "[]": self.deserialize_iter, + "{}": self.deserialize_dict, + } + self.deserialize_expected_types = { + "duration": (isodate.Duration, datetime.timedelta), + "iso-8601": (datetime.datetime), + } + self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.key_extractors = [rest_key_extractor, xml_key_extractor] + # Additional properties only works if the "rest_key_extractor" is used to + # extract the keys. Making it to work whatever the key extractor is too much + # complicated, with no real scenario for now. + # So adding a flag to disable additional properties detection. This flag should be + # used if your expect the deserialization to NOT come from a JSON REST syntax. + # Otherwise, result are unexpected + self.additional_properties_detection = True + + def __call__(self, target_obj, response_data, content_type=None): + """Call the deserializer to process a REST response. + + :param str target_obj: Target data type to deserialize to. + :param requests.Response response_data: REST response object. + :param str content_type: Swagger "produces" if available. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + data = self._unpack_content(response_data, content_type) + return self._deserialize(target_obj, data) + + def _deserialize(self, target_obj, data): + """Call the deserializer on a model. + + Data needs to be already deserialized as JSON or XML ElementTree + + :param str target_obj: Target data type to deserialize to. + :param object data: Object to deserialize. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + # This is already a model, go recursive just in case + if hasattr(data, "_attribute_map"): + constants = [ + name + for name, config in getattr(data, "_validation", {}).items() + if config.get("constant") + ] + try: + for attr, mapconfig in data._attribute_map.items(): + if attr in constants: + continue + value = getattr(data, attr) + if value is None: + continue + local_type = mapconfig["type"] + internal_data_type = local_type.strip("[]{}") + if internal_data_type not in self.dependencies or isinstance( + internal_data_type, Enum + ): + continue + setattr(data, attr, self._deserialize(local_type, value)) + return data + except AttributeError: + return + + response, class_name = self._classify_target(target_obj, data) + + if isinstance(response, basestring): + return self.deserialize_data(data, response) + elif isinstance(response, type) and issubclass(response, Enum): + return self.deserialize_enum(data, response) + + if data is None: + return data + try: + attributes = response._attribute_map # type: ignore + d_attrs = {} + for attr, attr_desc in attributes.items(): + # Check empty string. If it's not empty, someone has a real "additionalProperties"... + if attr == "additional_properties" and attr_desc["key"] == "": + continue + raw_value = None + # Enhance attr_desc with some dynamic data + attr_desc = attr_desc.copy() # Do a copy, do not change the real one + internal_data_type = attr_desc["type"].strip("[]{}") + if internal_data_type in self.dependencies: + attr_desc["internalType"] = self.dependencies[internal_data_type] + + for key_extractor in self.key_extractors: + found_value = key_extractor(attr, attr_desc, data) + if found_value is not None: + if raw_value is not None and raw_value != found_value: + msg = ( + "Ignoring extracted value '%s' from %s for key '%s'" + " (duplicate extraction, follow extractors order)" + ) + _LOGGER.warning(msg, found_value, key_extractor, attr) + continue + raw_value = found_value + + value = self.deserialize_data(raw_value, attr_desc["type"]) + d_attrs[attr] = value + except (AttributeError, TypeError, KeyError) as err: + msg = "Unable to deserialize to object: " + class_name # type: ignore + raise_with_traceback(DeserializationError, msg, err) + else: + additional_properties = self._build_additional_properties(attributes, data) + return self._instantiate_model(response, d_attrs, additional_properties) + + def _build_additional_properties(self, attribute_map, data): + if not self.additional_properties_detection: + return None + if ( + "additional_properties" in attribute_map + and attribute_map.get("additional_properties", {}).get("key") != "" + ): + # Check empty string. If it's not empty, someone has a real "additionalProperties" + return None + if isinstance(data, ET.Element): + data = {el.tag: el.text for el in data} + + known_keys = { + _decode_attribute_map_key(_FLATTEN.split(desc["key"])[0]) + for desc in attribute_map.values() + if desc["key"] != "" + } + present_keys = set(data.keys()) + missing_keys = present_keys - known_keys + return {key: data[key] for key in missing_keys} + + def _classify_target(self, target, data): + """Check to see whether the deserialization target object can + be classified into a subclass. + Once classification has been determined, initialize object. + + :param str target: The target object type to deserialize to. + :param str/dict data: The response data to deserialize. + """ + if target is None: + return None, None + + if isinstance(target, basestring): + try: + target = self.dependencies[target] + except KeyError: + return target, target + + try: + target = target._classify(data, self.dependencies) + except AttributeError: + pass # Target is not a Model, no classify + return target, target.__class__.__name__ # type: ignore + + def failsafe_deserialize(self, target_obj, data, content_type=None): + """Ignores any errors encountered in deserialization, + and falls back to not deserializing the object. Recommended + for use in error deserialization, as we want to return the + HttpResponseError to users, and not have them deal with + a deserialization error. + + :param str target_obj: The target object type to deserialize to. + :param str/dict data: The response data to deserialize. + :param str content_type: Swagger "produces" if available. + """ + try: + return self(target_obj, data, content_type=content_type) + except: + _LOGGER.debug( + "Ran into a deserialization error. Ignoring since this is failsafe deserialization", + exc_info=True, + ) + return None + + @staticmethod + def _unpack_content(raw_data, content_type=None): + """Extract the correct structure for deserialization. + + If raw_data is a PipelineResponse, try to extract the result of RawDeserializer. + if we can't, raise. Your Pipeline should have a RawDeserializer. + + If not a pipeline response and raw_data is bytes or string, use content-type + to decode it. If no content-type, try JSON. + + If raw_data is something else, bypass all logic and return it directly. + + :param raw_data: Data to be processed. + :param content_type: How to parse if raw_data is a string/bytes. + :raises JSONDecodeError: If JSON is requested and parsing is impossible. + :raises UnicodeDecodeError: If bytes is not UTF8 + """ + # Assume this is enough to detect a Pipeline Response without importing it + context = getattr(raw_data, "context", {}) + if context: + if RawDeserializer.CONTEXT_NAME in context: + return context[RawDeserializer.CONTEXT_NAME] + raise ValueError( + "This pipeline didn't have the RawDeserializer policy; can't deserialize" + ) + + # Assume this is enough to recognize universal_http.ClientResponse without importing it + if hasattr(raw_data, "body"): + return RawDeserializer.deserialize_from_http_generics( + raw_data.text(), raw_data.headers + ) + + # Assume this enough to recognize requests.Response without importing it. + if hasattr(raw_data, "_content_consumed"): + return RawDeserializer.deserialize_from_http_generics( + raw_data.text, raw_data.headers + ) + + if isinstance(raw_data, (basestring, bytes)) or hasattr(raw_data, "read"): + return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore + return raw_data + + def _instantiate_model(self, response, attrs, additional_properties=None): + """Instantiate a response model passing in deserialized args. + + :param response: The response model class. + :param d_attrs: The deserialized response attributes. + """ + if callable(response): + subtype = getattr(response, "_subtype_map", {}) + try: + readonly = [ + k for k, v in response._validation.items() if v.get("readonly") + ] + const = [ + k for k, v in response._validation.items() if v.get("constant") + ] + kwargs = { + k: v + for k, v in attrs.items() + if k not in subtype and k not in readonly + const + } + response_obj = response(**kwargs) + for attr in readonly: + setattr(response_obj, attr, attrs.get(attr)) + if additional_properties: + response_obj.additional_properties = additional_properties + return response_obj + except TypeError as err: + msg = "Unable to deserialize {} into model {}. ".format(kwargs, response) # type: ignore + raise DeserializationError(msg + str(err)) + else: + try: + for attr, value in attrs.items(): + setattr(response, attr, value) + return response + except Exception as exp: + msg = "Unable to populate response model. " + msg += "Type: {}, Error: {}".format(type(response), exp) + raise DeserializationError(msg) + + def deserialize_data(self, data, data_type): + """Process data for deserialization according to data type. + + :param str data: The response string to be deserialized. + :param str data_type: The type to deserialize to. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + if data is None: + return data + + try: + if not data_type: + return data + if data_type in self.basic_types.values(): + return self.deserialize_basic(data, data_type) + if data_type in self.deserialize_type: + if isinstance( + data, self.deserialize_expected_types.get(data_type, tuple()) + ): + return data + + is_a_text_parsing_type = lambda x: x not in ["object", "[]", r"{}"] + if ( + isinstance(data, ET.Element) + and is_a_text_parsing_type(data_type) + and not data.text + ): + return None + data_val = self.deserialize_type[data_type](data) + return data_val + + iter_type = data_type[0] + data_type[-1] + if iter_type in self.deserialize_type: + return self.deserialize_type[iter_type](data, data_type[1:-1]) + + obj_type = self.dependencies[data_type] + if issubclass(obj_type, Enum): + if isinstance(data, ET.Element): + data = data.text + return self.deserialize_enum(data, obj_type) + + except (ValueError, TypeError, AttributeError) as err: + msg = "Unable to deserialize response data." + msg += " Data: {}, {}".format(data, data_type) + raise_with_traceback(DeserializationError, msg, err) + else: + return self._deserialize(obj_type, data) + + def deserialize_iter(self, attr, iter_type): + """Deserialize an iterable. + + :param list attr: Iterable to be deserialized. + :param str iter_type: The type of object in the iterable. + :rtype: list + """ + if attr is None: + return None + if isinstance( + attr, ET.Element + ): # If I receive an element here, get the children + attr = list(attr) + if not isinstance(attr, (list, set)): + raise DeserializationError( + "Cannot deserialize as [{}] an object of type {}".format( + iter_type, type(attr) + ) + ) + return [self.deserialize_data(a, iter_type) for a in attr] + + def deserialize_dict(self, attr, dict_type): + """Deserialize a dictionary. + + :param dict/list attr: Dictionary to be deserialized. Also accepts + a list of key, value pairs. + :param str dict_type: The object type of the items in the dictionary. + :rtype: dict + """ + if isinstance(attr, list): + return { + x["key"]: self.deserialize_data(x["value"], dict_type) for x in attr + } + + if isinstance(attr, ET.Element): + # Transform value into {"Key": "value"} + attr = {el.tag: el.text for el in attr} + return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()} + + def deserialize_object(self, attr, **kwargs): + """Deserialize a generic object. + This will be handled as a dictionary. + + :param dict attr: Dictionary to be deserialized. + :rtype: dict + :raises: TypeError if non-builtin datatype encountered. + """ + if attr is None: + return None + if isinstance(attr, ET.Element): + # Do no recurse on XML, just return the tree as-is + return attr + if isinstance(attr, basestring): + return self.deserialize_basic(attr, "str") + obj_type = type(attr) + if obj_type in self.basic_types: + return self.deserialize_basic(attr, self.basic_types[obj_type]) + if obj_type is _long_type: + return self.deserialize_long(attr) + + if obj_type == dict: + deserialized = {} + for key, value in attr.items(): + try: + deserialized[key] = self.deserialize_object(value, **kwargs) + except ValueError: + deserialized[key] = None + return deserialized + + if obj_type == list: + deserialized = [] + for obj in attr: + try: + deserialized.append(self.deserialize_object(obj, **kwargs)) + except ValueError: + pass + return deserialized + + else: + error = "Cannot deserialize generic object with type: " + raise TypeError(error + str(obj_type)) + + def deserialize_basic(self, attr, data_type): + """Deserialize basic builtin data type from string. + Will attempt to convert to str, int, float and bool. + This function will also accept '1', '0', 'true' and 'false' as + valid bool values. + + :param str attr: response string to be deserialized. + :param str data_type: deserialization data type. + :rtype: str, int, float or bool + :raises: TypeError if string format is not valid. + """ + # If we're here, data is supposed to be a basic type. + # If it's still an XML node, take the text + if isinstance(attr, ET.Element): + attr = attr.text + if not attr: + if data_type == "str": + # None or '', node is empty string. + return "" + else: + # None or '', node with a strong type is None. + # Don't try to model "empty bool" or "empty int" + return None + + if data_type == "bool": + if attr in [True, False, 1, 0]: + return bool(attr) + elif isinstance(attr, basestring): + if attr.lower() in ["true", "1"]: + return True + elif attr.lower() in ["false", "0"]: + return False + raise TypeError("Invalid boolean value: {}".format(attr)) + + if data_type == "str": + return self.deserialize_unicode(attr) + return eval(data_type)(attr) # nosec + + @staticmethod + def deserialize_unicode(data): + """Preserve unicode objects in Python 2, otherwise return data + as a string. + + :param str data: response string to be deserialized. + :rtype: str or unicode + """ + # We might be here because we have an enum modeled as string, + # and we try to deserialize a partial dict with enum inside + if isinstance(data, Enum): + return data + + # Consider this is real string + try: + if isinstance(data, unicode): # type: ignore + return data + except NameError: + return str(data) + else: + return str(data) + + @staticmethod + def deserialize_enum(data, enum_obj): + """Deserialize string into enum object. + + If the string is not a valid enum value it will be returned as-is + and a warning will be logged. + + :param str data: Response string to be deserialized. If this value is + None or invalid it will be returned as-is. + :param Enum enum_obj: Enum object to deserialize to. + :rtype: Enum + """ + if isinstance(data, enum_obj) or data is None: + return data + if isinstance(data, Enum): + data = data.value + if isinstance(data, int): + # Workaround. We might consider remove it in the future. + # https://github.com/Azure/azure-rest-api-specs/issues/141 + try: + return list(enum_obj.__members__.values())[data] + except IndexError: + error = "{!r} is not a valid index for enum {!r}" + raise DeserializationError(error.format(data, enum_obj)) + try: + return enum_obj(str(data)) + except ValueError: + for enum_value in enum_obj: + if enum_value.value.lower() == str(data).lower(): + return enum_value + # We don't fail anymore for unknown value, we deserialize as a string + _LOGGER.warning( + "Deserializer is not able to find %s as valid enum in %s", + data, + enum_obj, + ) + return Deserializer.deserialize_unicode(data) + + @staticmethod + def deserialize_bytearray(attr): + """Deserialize string into bytearray. + + :param str attr: response string to be deserialized. + :rtype: bytearray + :raises: TypeError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + return bytearray(b64decode(attr)) # type: ignore + + @staticmethod + def deserialize_base64(attr): + """Deserialize base64 encoded string into string. + + :param str attr: response string to be deserialized. + :rtype: bytearray + :raises: TypeError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + padding = "=" * (3 - (len(attr) + 3) % 4) # type: ignore + attr = attr + padding # type: ignore + encoded = attr.replace("-", "+").replace("_", "/") + return b64decode(encoded) + + @staticmethod + def deserialize_decimal(attr): + """Deserialize string into Decimal object. + + :param str attr: response string to be deserialized. + :rtype: Decimal + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + return decimal.Decimal(attr) # type: ignore + except decimal.DecimalException as err: + msg = "Invalid decimal {}".format(attr) + raise_with_traceback(DeserializationError, msg, err) + + @staticmethod + def deserialize_long(attr): + """Deserialize string into long (Py2) or int (Py3). + + :param str attr: response string to be deserialized. + :rtype: long or int + :raises: ValueError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + return _long_type(attr) # type: ignore + + @staticmethod + def deserialize_duration(attr): + """Deserialize ISO-8601 formatted string into TimeDelta object. + + :param str attr: response string to be deserialized. + :rtype: TimeDelta + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + duration = isodate.parse_duration(attr) + except (ValueError, OverflowError, AttributeError) as err: + msg = "Cannot deserialize duration object." + raise_with_traceback(DeserializationError, msg, err) + else: + return duration + + @staticmethod + def deserialize_date(attr): + """Deserialize ISO-8601 formatted string into Date object. + + :param str attr: response string to be deserialized. + :rtype: Date + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore + raise DeserializationError( + "Date must have only digits and -. Received: %s" % attr + ) + # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + + @staticmethod + def deserialize_time(attr): + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore + raise DeserializationError( + "Date must have only digits and -. Received: %s" % attr + ) + return isodate.parse_time(attr) + + @staticmethod + def deserialize_rfc(attr): + """Deserialize RFC-1123 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: Datetime + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + parsed_date = email.utils.parsedate_tz(attr) # type: ignore + date_obj = datetime.datetime( + *parsed_date[:6], + tzinfo=_FixedOffset( + datetime.timedelta(minutes=(parsed_date[9] or 0) / 60) + ) + ) + if not date_obj.tzinfo: + date_obj = date_obj.astimezone(tz=TZ_UTC) + except ValueError as err: + msg = "Cannot deserialize to rfc datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj + + @staticmethod + def deserialize_iso(attr): + """Deserialize ISO-8601 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: Datetime + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + attr = attr.upper() # type: ignore + match = Deserializer.valid_date.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + check_decimal = attr.split(".") + if len(check_decimal) > 1: + decimal_str = "" + for digit in check_decimal[1]: + if digit.isdigit(): + decimal_str += digit + else: + break + if len(decimal_str) > 6: + attr = attr.replace(decimal_str, decimal_str[0:6]) + + date_obj = isodate.parse_datetime(attr) + test_utc = date_obj.utctimetuple() + if test_utc.tm_year > 9999 or test_utc.tm_year < 1: + raise OverflowError("Hit max or min date") + except (ValueError, OverflowError, AttributeError) as err: + msg = "Cannot deserialize datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj + + @staticmethod + def deserialize_unix(attr): + """Serialize Datetime object into IntTime format. + This is represented as seconds. + + :param int attr: Object to be serialized. + :rtype: Datetime + :raises: DeserializationError if format invalid + """ + if isinstance(attr, ET.Element): + attr = int(attr.text) # type: ignore + try: + date_obj = datetime.datetime.fromtimestamp(attr, TZ_UTC) + except ValueError as err: + msg = "Cannot deserialize to unix datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_vendor.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_vendor.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_vendor.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/__init__.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/__init__.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/__init__.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py similarity index 87% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_client.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py index f81ce4181ad6..b094add0dc06 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py @@ -28,17 +28,25 @@ class EventGridPublisherClient( :paramtype api_version: str """ - def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__( + self, **kwargs: Any + ) -> None: # pylint: disable=missing-client-constructor-parameter-credential _endpoint = "https://{topicHostname}" self._config = EventGridPublisherClientConfiguration(**kwargs) - self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) + self._client: AsyncPipelineClient = AsyncPipelineClient( + base_url=_endpoint, config=self._config, **kwargs + ) - client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)} + client_models = { + k: v for k, v in _models.__dict__.items() if isinstance(v, type) + } self._serialize = Serializer(client_models) self._deserialize = Deserializer(client_models) self._serialize.client_side_validation = False - def send_request(self, request: HttpRequest, **kwargs: Any) -> Awaitable[AsyncHttpResponse]: + def send_request( + self, request: HttpRequest, **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: """Runs the network request through the client's chained policies. >>> from azure.core.rest import HttpRequest diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py similarity index 68% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_configuration.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py index 52c2f3551ad7..06deaef1eb5c 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py @@ -20,7 +20,9 @@ VERSION = "unknown" -class EventGridPublisherClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes +class EventGridPublisherClientConfiguration( + Configuration +): # pylint: disable=too-many-instance-attributes """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance @@ -40,12 +42,26 @@ def __init__(self, **kwargs: Any) -> None: self._configure(**kwargs) def _configure(self, **kwargs: Any) -> None: - self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.user_agent_policy = kwargs.get( + "user_agent_policy" + ) or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy( + **kwargs + ) self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) - self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs) + self.logging_policy = kwargs.get( + "logging_policy" + ) or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get( + "http_logging_policy" + ) or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy( + **kwargs + ) + self.custom_hook_policy = kwargs.get( + "custom_hook_policy" + ) or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get( + "redirect_policy" + ) or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get("authentication_policy") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/__init__.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/__init__.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/__init__.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py similarity index 86% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_operations.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py index 317fd4bfb161..fe65e0c6cf06 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py @@ -37,7 +37,9 @@ from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] +ClsType = Optional[ + Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any] +] class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @@ -67,7 +69,12 @@ async def publish_events( # pylint: disable=inconsistent-return-statements @overload async def publish_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: IO, + *, + content_type: str = "application/json", + **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -86,7 +93,10 @@ async def publish_events( # pylint: disable=inconsistent-return-statements @distributed_trace_async async def publish_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: Union[List[_models.EventGridEvent], IO], **kwargs: Any + self, + topic_hostname: str, + events: Union[List[_models.EventGridEvent], IO], + **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -114,7 +124,9 @@ async def publish_events( # pylint: disable=inconsistent-return-statements _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -134,7 +146,9 @@ async def publish_events( # pylint: disable=inconsistent-return-statements params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -146,7 +160,9 @@ async def publish_events( # pylint: disable=inconsistent-return-statements response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: @@ -179,7 +195,10 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop( - "content_type", _headers.pop("Content-Type", "application/cloudevents-batch+json; charset=utf-8") + "content_type", + _headers.pop( + "Content-Type", "application/cloudevents-batch+json; charset=utf-8" + ), ) cls: ClsType[None] = kwargs.pop("cls", None) @@ -193,7 +212,9 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -205,7 +226,9 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: @@ -213,7 +236,12 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta @overload async def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: List[JSON], *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: List[JSON], + *, + content_type: str = "application/json", + **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -232,7 +260,12 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st @overload async def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any + self, + topic_hostname: str, + events: IO, + *, + content_type: str = "application/json", + **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -279,7 +312,9 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + content_type: Optional[str] = kwargs.pop( + "content_type", _headers.pop("Content-Type", None) + ) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -299,7 +334,9 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), + "topicHostname": self._serialize.url( + "topic_hostname", topic_hostname, "str", skip_quote=True + ), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -311,7 +348,9 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st response = pipeline_response.http_response if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if cls: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py similarity index 84% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_patch.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py index f7dd32510333..d400d2d124e2 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py @@ -8,7 +8,9 @@ """ from typing import List -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level +__all__: List[ + str +] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py similarity index 84% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_patch.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py index f7dd32510333..d400d2d124e2 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py @@ -8,7 +8,9 @@ """ from typing import List -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level +__all__: List[ + str +] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_vendor.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/aio/_vendor.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_vendor.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/__init__.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/__init__.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/__init__.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py similarity index 99% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_models.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py index 1308cb0f76e1..5b7573872822 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py @@ -291,7 +291,9 @@ class SubscriptionValidationResponse(_serialization.Model): "validation_response": {"key": "validationResponse", "type": "str"}, } - def __init__(self, *, validation_response: Optional[str] = None, **kwargs: Any) -> None: + def __init__( + self, *, validation_response: Optional[str] = None, **kwargs: Any + ) -> None: """ :keyword validation_response: The validation response sent by the subscriber to Azure Event Grid to complete the validation of an event subscription. diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py new file mode 100644 index 000000000000..d400d2d124e2 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py @@ -0,0 +1,22 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[ + str +] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/py.typed b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/py.typed similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/py.typed rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/py.typed diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py similarity index 90% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py index e824426427d3..0e7f08461e26 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py @@ -11,7 +11,10 @@ from urllib.parse import quote from azure.core.pipeline.transport import HttpRequest -from azure.core.pipeline.policies import AzureKeyCredentialPolicy, BearerTokenCredentialPolicy +from azure.core.pipeline.policies import ( + AzureKeyCredentialPolicy, + BearerTokenCredentialPolicy, +) from azure.core.credentials import AzureKeyCredential, AzureSasCredential from ._generated._serialization import Serializer from ._signature_credential_policy import EventGridSasCredentialPolicy @@ -65,6 +68,7 @@ def generate_sas( signed_sas = "{}&s={}".format(unsigned_sas, signature) return signed_sas + def _generate_hmac(key, message): decoded_key = base64.b64decode(key) bytes_message = message.encode("ascii") @@ -73,14 +77,13 @@ def _generate_hmac(key, message): return base64.b64encode(hmac_new) -def _get_authentication_policy(credential, bearer_token_policy=BearerTokenCredentialPolicy): +def _get_authentication_policy( + credential, bearer_token_policy=BearerTokenCredentialPolicy +): if credential is None: raise ValueError("Parameter 'self._credential' must not be None.") if hasattr(credential, "get_token"): - return bearer_token_policy( - credential, - constants.DEFAULT_EVENTGRID_SCOPE - ) + return bearer_token_policy(credential, constants.DEFAULT_EVENTGRID_SCOPE) if isinstance(credential, AzureKeyCredential): return AzureKeyCredentialPolicy( credential=credential, name=constants.EVENTGRID_KEY_HEADER @@ -102,6 +105,7 @@ def _is_cloud_event(event): except TypeError: return False + def _is_eventgrid_event(event): # type: (Any) -> bool required = ("subject", "eventType", "data", "dataVersion", "id", "eventTime") @@ -123,6 +127,7 @@ def _eventgrid_data_typecheck(event): "https://docs.microsoft.com/en-us/azure/event-grid/event-schema" ) + def _cloud_event_to_generated(cloud_event, **kwargs): if isinstance(cloud_event.data, bytes): data_base64 = cloud_event.data @@ -156,11 +161,12 @@ def _from_cncf_events(event): # pylint: disable=inconsistent-return-statements """ try: from cloudevents.http import to_json + return json.loads(to_json(event)) except (AttributeError, ImportError): # means this is not a CNCF event return event - except Exception as err: # pylint: disable=broad-except + except Exception as err: # pylint: disable=broad-except msg = """Failed to serialize the event. Please ensure your CloudEvents is correctly formatted (https://pypi.org/project/cloudevents/)""" raise ValueError(msg) from err @@ -172,23 +178,20 @@ def _build_request(endpoint, content_type, events, *, channel_name=None, api_ver header_parameters['Content-Type'] = serialize.header("content_type", content_type, 'str') if channel_name: - header_parameters['aeg-channel-name'] = channel_name + header_parameters["aeg-channel-name"] = channel_name query_parameters: Dict[str, Any] = {} query_parameters['api-version'] = serialize.query("api_version", api_version, 'str') - body = serialize.body(events, '[object]') + body = serialize.body(events, "[object]") if body is None: data = None else: data = json.dumps(body) - header_parameters['Content-Length'] = str(len(data)) + header_parameters["Content-Length"] = str(len(data)) request = HttpRequest( - method="POST", - url=endpoint, - headers=header_parameters, - data=data + method="POST", url=endpoint, headers=header_parameters, data=data ) request.format_parameters(query_parameters) return request diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_messaging_shared.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py similarity index 99% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_messaging_shared.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py index 2ddd520a8648..c37971d694ff 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_messaging_shared.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py @@ -11,7 +11,6 @@ # ========================================================================== - import json def _get_json_content(obj): # pylint: disable=inconsistent-return-statements diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_models.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_models.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_policies.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py similarity index 99% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_policies.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py index 13a19d60bbcd..6feda49c6f36 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_policies.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py @@ -40,7 +40,6 @@ def on_request(self, request): == CloudEventDistributedTracingPolicy._CONTENT_TYPE and traceparent is not None ): - body = json.loads(request.http_request.body) for item in body: if "traceparent" not in item and "tracestate" not in item: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py similarity index 93% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py index a16b69e5bf13..409644f893dc 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py @@ -26,7 +26,7 @@ HttpResponseError, ResourceNotFoundError, ResourceExistsError, - map_error + map_error, ) from azure.core.messaging import CloudEvent @@ -71,7 +71,9 @@ ListEventType = Union[List[CloudEvent], List[EventGridEvent], List[Dict]] -class EventGridPublisherClient(object): # pylint: disable=client-accepts-api-version-keyword +class EventGridPublisherClient( + object +): # pylint: disable=client-accepts-api-version-keyword """EventGridPublisherClient publishes events to an EventGrid topic or domain. It can be used to publish either an EventGridEvent, a CloudEvent or a Custom Schema. @@ -140,12 +142,8 @@ def _policies(credential, **kwargs): @distributed_trace def send( - self, - events: SendType, - *, - channel_name: Optional[str] = None, - **kwargs: Any - ) -> None: + self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any + ) -> None: """Sends events to a topic or a domain specified during the client initialization. A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. @@ -219,14 +217,11 @@ def send( if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: events = [ - _cloud_event_to_generated(e, **kwargs) - for e in events # pylint: disable=protected-access - ] + _cloud_event_to_generated(e, **kwargs) for e in events + ] # pylint: disable=protected-access except AttributeError: ## this is either a dictionary or a CNCF cloud event - events = [ - _from_cncf_events(e) for e in events - ] + events = [_from_cncf_events(e) for e in events] content_type = "application/cloudevents-batch+json; charset=utf-8" elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): for event in events: @@ -236,9 +231,15 @@ def send( self._endpoint,content_type, events, channel_name=channel_name, api_version=self._api_version), **kwargs ) - error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + } if response.status_code != 200: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) def close(self): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_signature_credential_policy.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_signature_credential_policy.py similarity index 100% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_signature_credential_policy.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_signature_credential_policy.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_version.py new file mode 100644 index 000000000000..c9812c54f54c --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_version.py @@ -0,0 +1,12 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +VERSION = "4.10.0" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/__init__.py new file mode 100644 index 000000000000..0d2dce7aaea2 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/__init__.py @@ -0,0 +1,9 @@ +# coding=utf-8 +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from ._publisher_client_async import EventGridPublisherClient + +__all__ = ["EventGridPublisherClient"] diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py similarity index 93% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py index 69f6654ab145..692451987fd7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py @@ -29,7 +29,7 @@ HttpResponseError, ResourceNotFoundError, ResourceExistsError, - map_error + map_error, ) from .._policies import CloudEventDistributedTracingPolicy from .._models import EventGridEvent @@ -65,7 +65,7 @@ ListEventType = Union[List[CloudEvent], List[EventGridEvent], List[Dict]] -class EventGridPublisherClient: # pylint: disable=client-accepts-api-version-keyword +class EventGridPublisherClient: # pylint: disable=client-accepts-api-version-keyword """Asynchronous EventGridPublisherClient publishes events to an EventGrid topic or domain. It can be used to publish either an EventGridEvent, a CloudEvent or a Custom Schema. @@ -141,7 +141,9 @@ def _policies( return policies @distributed_trace_async - async def send(self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any) -> None: + async def send( + self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any + ) -> None: """Sends events to a topic or a domain specified during the client initialization. A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. @@ -215,14 +217,11 @@ async def send(self, events: SendType, *, channel_name: Optional[str] = None, ** if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: events = [ - _cloud_event_to_generated(e, **kwargs) - for e in events # pylint: disable=protected-access - ] + _cloud_event_to_generated(e, **kwargs) for e in events + ] # pylint: disable=protected-access except AttributeError: ## this is either a dictionary or a CNCF cloud event - events = [ - _from_cncf_events(e) for e in events - ] + events = [_from_cncf_events(e) for e in events] content_type = "application/cloudevents-batch+json; charset=utf-8" elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): for event in events: @@ -232,9 +231,15 @@ async def send(self, events: SendType, *, channel_name: Optional[str] = None, ** channel_name=channel_name, api_version=self._api_version), **kwargs ) - error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + } if response.status_code != 200: - map_error(status_code=response.status_code, response=response, error_map=error_map) + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) async def __aenter__(self) -> "EventGridPublisherClient": diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py new file mode 100644 index 000000000000..8d3005d8f692 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -0,0 +1,695 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: disable=protected-access, arguments-differ, signature-differs, broad-except +# pyright: reportGeneralTypeIssues=false + +import functools +import sys +import logging +import base64 +import re +import copy +import typing +from datetime import datetime, date, time, timedelta, timezone +from json import JSONEncoder +import isodate +from azure.core.exceptions import DeserializationError +from azure.core import CaseInsensitiveEnumMeta +from azure.core.pipeline import PipelineResponse +from azure.core.serialization import _Null # pylint: disable=protected-access + +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping + +_LOGGER = logging.getLogger(__name__) + +__all__ = ["AzureJSONEncoder", "Model", "rest_field", "rest_discriminator"] + + +TZ_UTC = timezone.utc + +def _timedelta_as_isostr(td: timedelta) -> str: + """Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S' + + Function adapted from the Tin Can Python project: https://github.com/RusticiSoftware/TinCanPython + + :param timedelta td: The timedelta to convert + :rtype: str + :return: ISO8601 version of this timedelta + """ + + # Split seconds to larger units + seconds = td.total_seconds() + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) + days, hours = divmod(hours, 24) + + days, hours, minutes = list(map(int, (days, hours, minutes))) + seconds = round(seconds, 6) + + # Build date + date_str = "" + if days: + date_str = "%sD" % days + + if hours or minutes or seconds: + # Build time + time_str = "T" + + # Hours + bigger_exists = date_str or hours + if bigger_exists: + time_str += "{:02}H".format(hours) + + # Minutes + bigger_exists = bigger_exists or minutes + if bigger_exists: + time_str += "{:02}M".format(minutes) + + # Seconds + try: + if seconds.is_integer(): + seconds_string = "{:02}".format(int(seconds)) + else: + # 9 chars long w/ leading 0, 6 digits after decimal + seconds_string = "%09.6f" % seconds + # Remove trailing zeros + seconds_string = seconds_string.rstrip("0") + except AttributeError: # int.is_integer() raises + seconds_string = "{:02}".format(seconds) + + time_str += "{}S".format(seconds_string) + else: + time_str = "" + + return "P" + date_str + time_str + + +def _datetime_as_isostr(dt: typing.Union[datetime, date, time, timedelta]) -> str: + """Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string + + :param timedelta dt: The date object to convert + :rtype: str + :return: ISO8601 version of this datetime + """ + # First try datetime.datetime + if hasattr(dt, "year") and hasattr(dt, "hour"): + dt = typing.cast(datetime, dt) + # astimezone() fails for naive times in Python 2.7, so make make sure dt is aware (tzinfo is set) + if not dt.tzinfo: + iso_formatted = dt.replace(tzinfo=TZ_UTC).isoformat() + else: + iso_formatted = dt.astimezone(TZ_UTC).isoformat() + # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) + return iso_formatted.replace("+00:00", "Z") + # Next try datetime.date or datetime.time + try: + dt = typing.cast(typing.Union[date, time], dt) + return dt.isoformat() + # Last, try datetime.timedelta + except AttributeError: + dt = typing.cast(timedelta, dt) + return _timedelta_as_isostr(dt) + +def _serialize_bytes(o) -> str: + return base64.b64encode(o).decode() + + +def _serialize_datetime(o): + if hasattr(o, "year") and hasattr(o, "hour"): + # astimezone() fails for naive times in Python 2.7, so make make sure o is aware (tzinfo is set) + if not o.tzinfo: + iso_formatted = o.replace(tzinfo=TZ_UTC).isoformat() + else: + iso_formatted = o.astimezone(TZ_UTC).isoformat() + # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) + return iso_formatted.replace("+00:00", "Z") + # Next try datetime.date or datetime.time + return o.isoformat() + + +def _is_readonly(p): + try: + return p._readonly # pylint: disable=protected-access + except AttributeError: + return False + + +class AzureJSONEncoder(JSONEncoder): + """A JSON encoder that's capable of serializing datetime objects and bytes.""" + + def default(self, o): # pylint: disable=too-many-return-statements + if _is_model(o): + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] # pylint: disable=protected-access + return {k: v for k, v in o.items() if k not in readonly_props} + if isinstance(o, (bytes, bytearray)): + return base64.b64encode(o).decode() + if isinstance(o, _Null): + return None + try: + return super(AzureJSONEncoder, self).default(o) + except TypeError: + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o) + try: + # First try datetime.datetime + return _serialize_datetime(o) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return super(AzureJSONEncoder, self).default(o) + + +_VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") + + +def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime: + """Deserialize ISO-8601 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + attr = attr.upper() + match = _VALID_DATE.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + check_decimal = attr.split(".") + if len(check_decimal) > 1: + decimal_str = "" + for digit in check_decimal[1]: + if digit.isdigit(): + decimal_str += digit + else: + break + if len(decimal_str) > 6: + attr = attr.replace(decimal_str, decimal_str[0:6]) + + date_obj = isodate.parse_datetime(attr) + test_utc = date_obj.utctimetuple() + if test_utc.tm_year > 9999 or test_utc.tm_year < 1: + raise OverflowError("Hit max or min date") + return date_obj + + +def _deserialize_date(attr: typing.Union[str, date]) -> date: + """Deserialize ISO-8601 formatted string into Date object. + :param str attr: response string to be deserialized. + :rtype: date + :returns: The date object from that input + """ + # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. + if isinstance(attr, date): + return attr + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + + +def _deserialize_time(attr: typing.Union[str, time]) -> time: + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :returns: The time object from that input + """ + if isinstance(attr, time): + return attr + return isodate.parse_time(attr) + + +def deserialize_bytes(attr): + if isinstance(attr, (bytes, bytearray)): + return attr + return bytes(base64.b64decode(attr)) + + +def deserialize_duration(attr): + if isinstance(attr, timedelta): + return attr + return isodate.parse_duration(attr) + + +_DESERIALIZE_MAPPING = { + datetime: _deserialize_datetime, + date: _deserialize_date, + time: _deserialize_time, + bytes: deserialize_bytes, + timedelta: deserialize_duration, + typing.Any: lambda x: x, +} + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + module_end = module_name.rsplit(".", 1)[0] + module = sys.modules[module_end] + models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + if isinstance(model_name, str): + model_name = model_name.split(".")[-1] + if model_name not in models: + return model_name + return models[model_name] + + +_UNSET = object() + + +class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object + def __init__(self, data: typing.Dict[str, typing.Any]) -> None: + self._data = copy.deepcopy(data) + + def __contains__(self, key: typing.Any) -> bool: + return key in self._data + + def __getitem__(self, key: str) -> typing.Any: + return self._data.__getitem__(key) + + def __setitem__(self, key: str, value: typing.Any) -> None: + self._data.__setitem__(key, value) + + def __delitem__(self, key: str) -> None: + self._data.__delitem__(key) + + def __iter__(self) -> typing.Iterator[typing.Any]: + return self._data.__iter__() + + def __len__(self) -> int: + return self._data.__len__() + + def __ne__(self, other: typing.Any) -> bool: + return not self.__eq__(other) + + def keys(self) -> typing.KeysView[str]: + return self._data.keys() + + def values(self) -> typing.ValuesView[typing.Any]: + return self._data.values() + + def items(self) -> typing.ItemsView[str, typing.Any]: + return self._data.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + try: + return self[key] + except KeyError: + return default + + @typing.overload # type: ignore + def pop(self, key: str) -> typing.Any: # pylint: disable=no-member + ... + + @typing.overload + def pop(self, key: str, default: typing.Any) -> typing.Any: + ... + + def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + if default is _UNSET: + return self._data.pop(key) + return self._data.pop(key, default) + + def popitem(self) -> typing.Tuple[str, typing.Any]: + return self._data.popitem() + + def clear(self) -> None: + self._data.clear() + + def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: + self._data.update(*args, **kwargs) + + @typing.overload # type: ignore + def setdefault(self, key: str) -> typing.Any: + ... + + @typing.overload + def setdefault(self, key: str, default: typing.Any) -> typing.Any: + ... + + def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + if default is _UNSET: + return self._data.setdefault(key) + return self._data.setdefault(key, default) + + def __eq__(self, other: typing.Any) -> bool: + try: + other_model = self.__class__(other) + except Exception: + return False + return self._data == other_model._data + + def __repr__(self) -> str: + return str(self._data) + + +def _is_model(obj: typing.Any) -> bool: + return getattr(obj, "_is_model", False) + + +def _serialize(o): + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o) + try: + # First try datetime.datetime + return _serialize_datetime(o) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return o + + +def _get_rest_field( + attr_to_rest_field: typing.Dict[str, "_RestField"], rest_name: str +) -> typing.Optional["_RestField"]: + try: + return next(rf for rf in attr_to_rest_field.values() if rf._rest_name == rest_name) + except StopIteration: + return None + + +def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any: + return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value) + + +class Model(_MyMutableMapping): + _is_model = True + + def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: + class_name = self.__class__.__name__ + if len(args) > 1: + raise TypeError(f"{class_name}.__init__() takes 2 positional arguments but {len(args) + 1} were given") + dict_to_pass = { + rest_field._rest_name: rest_field._default + for rest_field in self._attr_to_rest_field.values() + if rest_field._default is not _UNSET + } + if args: + dict_to_pass.update( + {k: _create_value(_get_rest_field(self._attr_to_rest_field, k), v) for k, v in args[0].items()} + ) + else: + non_attr_kwargs = [k for k in kwargs if k not in self._attr_to_rest_field] + if non_attr_kwargs: + # actual type errors only throw the first wrong keyword arg they see, so following that. + raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") + dict_to_pass.update({ + self._attr_to_rest_field[k]._rest_name: _serialize(v) + for k, v in kwargs.items() if v is not None + }) + super().__init__(dict_to_pass) + + def copy(self) -> "Model": + return Model(self.__dict__) + + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> "Model": # pylint: disable=unused-argument + # we know the last three classes in mro are going to be 'Model', 'dict', and 'object' + mros = cls.__mro__[:-3][::-1] # ignore model, dict, and object parents, and reverse the mro order + attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property + k: v for mro_class in mros for k, v in mro_class.__dict__.items() if k[0] != "_" and hasattr(v, "_type") + } + annotations = { + k: v + for mro_class in mros + if hasattr(mro_class, "__annotations__") # pylint: disable=no-member + for k, v in mro_class.__annotations__.items() # pylint: disable=no-member + } + for attr, rf in attr_to_rest_field.items(): + rf._module = cls.__module__ + if not rf._type: + rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None)) + if not rf._rest_name_input: + rf._rest_name_input = attr + cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items()) + + return super().__new__(cls) # pylint: disable=no-value-for-parameter + + def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: + for base in cls.__bases__: + if hasattr(base, "__mapping__"): # pylint: disable=no-member + base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member + + @classmethod + def _get_discriminator(cls) -> typing.Optional[str]: + for v in cls.__dict__.values(): + if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + return v._rest_name # pylint: disable=protected-access + return None + + @classmethod + def _deserialize(cls, data): + if not hasattr(cls, "__mapping__"): # pylint: disable=no-member + return cls(data) + discriminator = cls._get_discriminator() + mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member + if mapped_cls == cls: + return cls(data) + return mapped_cls._deserialize(data) # pylint: disable=protected-access + + +def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements + annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None + ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + if not annotation or annotation in [int, float]: + return None + + try: + if module and _is_model(_get_model(module, annotation)): + if rf: + rf._is_model = True + def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): + if _is_model(obj): + return obj + return _deserialize(model_deserializer, obj) + + return functools.partial(_deserialize_model, _get_model(module, annotation)) + except Exception: + pass + + # is it a literal? + try: + if sys.version_info >= (3, 8): + from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports + else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports + + if annotation.__origin__ == Literal: + return None + except AttributeError: + pass + + if getattr(annotation, "__origin__", None) is typing.Union: + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module) + except DeserializationError: + pass + raise DeserializationError() + return functools.partial(_deserialize_with_union, annotation) + + # is it optional? + try: + # right now, assuming we don't have unions, since we're getting rid of the only + # union we used to have in msrest models, which was union of str and enum + if any(a for a in annotation.__args__ if a == type(None)): + + if_obj_deserializer = _get_deserialize_callable_from_annotation( + next(a for a in annotation.__args__ if a != type(None)), module, rf + ) + + def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): + if obj is None: + return obj + return _deserialize_with_callable(if_obj_deserializer, obj) + + return functools.partial(_deserialize_with_optional, if_obj_deserializer) + except AttributeError: + pass + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + + try: + if annotation._name == "Dict": + key_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + value_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[1], module, rf) + + def _deserialize_dict( + key_deserializer: typing.Optional[typing.Callable], + value_deserializer: typing.Optional[typing.Callable], + obj: typing.Dict[typing.Any, typing.Any], + ): + if obj is None: + return obj + return { + _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) for k, v in obj.items() + } + + return functools.partial( + _deserialize_dict, + key_deserializer, + value_deserializer, + ) + except (AttributeError, IndexError): + pass + try: + if annotation._name in ["List", "Set", "Tuple", "Sequence"]: + if len(annotation.__args__) > 1: + + def _deserialize_multiple_sequence( + entry_deserializers: typing.List[typing.Optional[typing.Callable]], obj + ): + if obj is None: + return obj + return type(obj)( + _deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers) + ) + + entry_deserializers = [ + _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ + ] + return functools.partial(_deserialize_multiple_sequence, entry_deserializers) + deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + + def _deserialize_sequence( + deserializer: typing.Optional[typing.Callable], + obj, + ): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + + return functools.partial(_deserialize_sequence, deserializer) + except (TypeError, IndexError, AttributeError, SyntaxError): + pass + + def _deserialize_default( + annotation, + deserializer_from_mapping, + obj, + ): + if obj is None: + return obj + try: + return _deserialize_with_callable(annotation, obj) + except Exception: + pass + return _deserialize_with_callable(deserializer_from_mapping, obj) + + return functools.partial(_deserialize_default, annotation, _DESERIALIZE_MAPPING.get(annotation)) + + +def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], value: typing.Any): + try: + if value is None: + return None + if deserializer is None: + return value + if isinstance(deserializer, CaseInsensitiveEnumMeta): + try: + return deserializer(value) + except ValueError: + # for unknown value, return raw value + return value + if isinstance(deserializer, type) and issubclass(deserializer, Model): + return deserializer._deserialize(value) + return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) + except Exception as e: + raise DeserializationError() from e + + +def _deserialize(deserializer: typing.Any, value: typing.Any, module: typing.Optional[str] = None) -> typing.Any: + if isinstance(value, PipelineResponse): + value = value.http_response.json() + deserializer = _get_deserialize_callable_from_annotation(deserializer, module) + return _deserialize_with_callable(deserializer, value) + +class _RestField: + def __init__( + self, + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin + is_discriminator: bool = False, + readonly: bool = False, + default: typing.Any = _UNSET, + ): + self._type = type + self._rest_name_input = name + self._module: typing.Optional[str] = None + self._is_discriminator = is_discriminator + self._readonly = readonly + self._is_model = False + self._default = default + + @property + def _rest_name(self) -> str: + if self._rest_name_input is None: + raise ValueError("Rest name was never set") + return self._rest_name_input + + def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin + # by this point, type and rest_name will have a value bc we default + # them in __new__ of the Model class + item = obj.get(self._rest_name) + if item is None: + return item + return _deserialize(self._type, _serialize(item)) + + def __set__(self, obj: Model, value) -> None: + if value is None: + # we want to wipe out entries if users set attr to None + try: + obj.__delitem__(self._rest_name) + except KeyError: + pass + return + if self._is_model and not _is_model(value): + obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + obj.__setitem__(self._rest_name, _serialize(value)) + + def _get_deserialize_callable_from_annotation( + self, annotation: typing.Any + ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + return _get_deserialize_callable_from_annotation(annotation, self._module, self) + + +def rest_field( + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin + readonly: bool = False, + default: typing.Any = _UNSET, +) -> typing.Any: + return _RestField(name=name, type=type, readonly=readonly, default=default) + + +def rest_discriminator( + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin +) -> typing.Any: + return _RestField(name=name, type=type, is_discriminator=True) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py new file mode 100644 index 000000000000..c166e5de9c64 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -0,0 +1,18 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import EventGridClientOperationsMixin + +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk +__all__ = [ + 'EventGridClientOperationsMixin', +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py new file mode 100644 index 000000000000..71a965588424 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -0,0 +1,739 @@ +# pylint: disable=too-many-lines +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import json +from typing import Any, Callable, Dict, List, Optional, TypeVar + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpResponse +from azure.core.rest import HttpRequest +from azure.core.tracing.decorator import distributed_trace +from azure.core.utils import case_insensitive_dict + +from .. import models as _models +from .._model_base import AzureJSONEncoder, _deserialize +from .._serialization import Serializer +from .._vendor import EventGridClientMixinABC, _format_url_section +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +_SERIALIZER = Serializer() +_SERIALIZER.client_side_validation = False + + +def build_event_grid_publish_cloud_event_request( + topic_name: str, + *, + content: _models._models.CloudEvent, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop('content_type') + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + # Construct URL + _url = "/topics/{topicName}:publish" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=content, + **kwargs + ) + + +def build_event_grid_publish_cloud_events_request( + topic_name: str, + *, + content: List[_models._models.CloudEvent], + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop('content_type') + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + # Construct URL + _url = "/topics/{topicName}:publish" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=content, + **kwargs + ) + + +def build_event_grid_receive_cloud_events_request( + topic_name: str, + event_subscription_name: str, + *, + max_events: Optional[int] = None, + max_wait_time: Optional[int] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:receive" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + if max_events is not None: + _params['maxEvents'] = _SERIALIZER.query("max_events", max_events, 'int') + if max_wait_time is not None: + _params['maxWaitTime'] = _SERIALIZER.query("max_wait_time", max_wait_time, 'int') + + # Construct headers + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + **kwargs + ) + + +def build_event_grid_acknowledge_cloud_events_request( + topic_name: str, + event_subscription_name: str, + *, + content: _models.AcknowledgeOptions, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop('content_type') + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=content, + **kwargs + ) + + +def build_event_grid_release_cloud_events_request( + topic_name: str, + event_subscription_name: str, + *, + content: _models.ReleaseOptions, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop('content_type') + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=content, + **kwargs + ) + + +def build_event_grid_reject_cloud_events_request( + topic_name: str, + event_subscription_name: str, + *, + content: _models.RejectOptions, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop('content_type') + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:reject" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + } + + _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=content, + **kwargs + ) + +class EventGridClientOperationsMixin(EventGridClientMixinABC): + + @distributed_trace + def _publish_cloud_event( # pylint: disable=inconsistent-return-statements + self, + topic_name: str, + event: _models._models.CloudEvent, + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event: Single Cloud Event being published. Required. + :type event: ~azure.eventgrid.models.CloudEvent + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + cls: ClsType[None] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(event, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_publish_cloud_event_request( + topic_name=topic_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + + + @distributed_trace + def _publish_cloud_events( # pylint: disable=inconsistent-return-statements + self, + topic_name: str, + events: List[_models._models.CloudEvent], + **kwargs: Any + ) -> None: + """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param events: Array of Cloud Events being published. Required. + :type events: list[~azure.eventgrid.models.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents-batch+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) + cls: ClsType[None] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(events, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_publish_cloud_events_request( + topic_name=topic_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + + + @distributed_trace + def _receive_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + *, + max_events: Optional[int] = None, + max_wait_time: Optional[int] = None, + **kwargs: Any + ) -> _models._models.ReceiveResult: + """Receive Batch of Cloud Events from the Event Subscription. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value + is 100 events. If not specified, the default value is 1. Default value is None. + :paramtype max_events: int + :keyword max_wait_time: Max wait time value for receive operation in Seconds. It is the time in + seconds that the server approximately waits for the availability of an event and responds to + the request. If an event is available, the broker responds immediately to the client. Minimum + value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is + 60 seconds. Default value is None. + :paramtype max_wait_time: int + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReceiveResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models._models.ReceiveResult] = kwargs.pop( # pylint: disable=protected-access + 'cls', None + ) + + + request = build_event_grid_receive_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + max_events=max_events, + max_wait_time=max_wait_time, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.ReceiveResult, # pylint: disable=protected-access + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace + def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.AcknowledgeOptions, + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_acknowledge_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.AcknowledgeResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace + def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.ReleaseOptions, + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.ReleaseResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_release_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.ReleaseResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace + def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.RejectOptions, + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.RejectOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.RejectResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_reject_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.RejectResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py new file mode 100644 index 000000000000..93482173865e --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -0,0 +1,186 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +import base64 +from typing import List, overload, Union, Any, Optional +from azure.core.messaging import CloudEvent +from azure.core.tracing.decorator import distributed_trace +from ._operations import EventGridClientOperationsMixin as OperationsMixin +from ..models._models import CloudEvent as InternalCloudEvent +from ..models._patch import ReceiveResult, ReceiveDetails + + +def _cloud_event_to_generated(cloud_event, **kwargs): + data_kwargs = {} + + if isinstance(cloud_event.data, bytes): + data_kwargs["data_base64"] = base64.b64encode( + cloud_event.data + ) # base64 encode double check + else: + data_kwargs["data"] = cloud_event.data + + internal_event = InternalCloudEvent( + id=cloud_event.id, + source=cloud_event.source, + type=cloud_event.type, + specversion=cloud_event.specversion, + time=cloud_event.time, + dataschema=cloud_event.dataschema, + datacontenttype=cloud_event.datacontenttype, + subject=cloud_event.subject, + **data_kwargs, + **kwargs + ) + if cloud_event.extensions: + internal_event.update(cloud_event.extensions) + return internal_event + + +class EventGridClientOperationsMixin(OperationsMixin): + @overload + def publish_cloud_events( + self, + topic_name: str, + body: List[CloudEvent], + *, + content_type: str = "application/cloudevents-batch+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Batch of Cloud Events to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Array of Cloud Events being published. Required. + :type body: list[~azure.core.messaging.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents-batch+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def publish_cloud_events( + self, + topic_name: str, + body: CloudEvent, + *, + content_type: str = "application/cloudevents+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event being published. Required. + :type body: ~azure.core.messaging.CloudEvent + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def publish_cloud_events( + self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs + ) -> None: + """Publish Cloud Events to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event or list of Cloud Events being published. Required. + :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + if isinstance(body, CloudEvent): + kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" + internal_body = _cloud_event_to_generated(body) + self._publish_cloud_event(topic_name, internal_body, **kwargs) + else: + kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" + internal_body_list = [] + for item in body: + internal_body_list.append(_cloud_event_to_generated(item)) + self._publish_cloud_events(topic_name, internal_body_list, **kwargs) + + @distributed_trace + def receive_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + *, + max_events: Optional[int] = None, + max_wait_time: Optional[int] = None, + **kwargs: Any + ) -> ReceiveResult: + """Receive Batch of Cloud Events from the Event Subscription. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value + is 100 events. If not specified, the default value is 1. Default value is None. + :paramtype max_events: int + :keyword max_wait_time: Max wait time value for receive operation in Seconds. It is the time in + seconds that the server approximately waits for the availability of an event and responds to + the request. If an event is available, the broker responds immediately to the client. Minimum + value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is + 60 seconds. Default value is None. + :paramtype max_wait_time: int + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReceiveResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + detail_items = [] + received_result = self._receive_cloud_events( + topic_name, + event_subscription_name, + max_events=max_events, + max_wait_time=max_wait_time, + **kwargs + ) + for detail_item in received_result.value: + deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) + detail_item.event = deserialized_cloud_event + detail_items.append( + ReceiveDetails( + broker_properties=detail_item.broker_properties, + event=detail_item.event, + ) + ) + receive_result_deserialized = ReceiveResult(value=detail_items) + return receive_result_deserialized + + +__all__: List[str] = [ + "EventGridClientOperationsMixin" +] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py new file mode 100644 index 000000000000..4ead1bf7ec05 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -0,0 +1,71 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" + +from typing import List +from azure.core.pipeline.policies import SansIOHTTPPolicy +from azure.core.credentials import AzureKeyCredential +from ._client import EventGridClient as ServiceClientGenerated +from ._legacy import ( + EventGridPublisherClient, + SystemEventNames, + EventGridEvent, + generate_sas, +) + + +class EventGridSharedAccessKeyPolicy(SansIOHTTPPolicy): + def __init__( + self, credential: "AzureKeyCredential", **kwargs + ) -> None: # pylint: disable=unused-argument + super(EventGridSharedAccessKeyPolicy, self).__init__() + self._credential = credential + + def on_request(self, request): + request.http_request.headers["Authorization"] = ( + "SharedAccessKey " + self._credential.key + ) + + +class EventGridClient(ServiceClientGenerated): + """Azure Messaging EventGrid Client. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs) -> None: + if isinstance(credential, AzureKeyCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = EventGridSharedAccessKeyPolicy( + credential + ) + super().__init__(endpoint=endpoint, credential=credential, **kwargs) + + +def patch_sdk(): + """Do not remove from this file. + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ + + +__all__: List[str] = [ + "EventGridClient", + "EventGridPublisherClient", + "SystemEventNames", + "EventGridEvent", + "generate_sas", +] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py similarity index 99% rename from sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_serialization.py rename to sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index 842ae727fbbc..e3cc6ce6ed6f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_generated/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -356,7 +356,9 @@ def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: def as_dict( self, keep_readonly: bool = True, - key_transformer: Callable[[str, Dict[str, Any], Any], Any] = attribute_transformer, + key_transformer: Callable[ + [str, Dict[str, Any], Any], Any + ] = attribute_transformer, **kwargs: Any ) -> JSON: """Return a dict that can be serialized using json.dump. @@ -545,7 +547,7 @@ class Serializer(object): "multiple": lambda x, y: x % y != 0, } - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): self.serialize_type = { "iso-8601": Serializer.serialize_iso, "rfc-1123": Serializer.serialize_rfc, @@ -1361,7 +1363,7 @@ class Deserializer(object): valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): self.deserialize_type = { "iso-8601": Deserializer.deserialize_iso, "rfc-1123": Deserializer.deserialize_rfc, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py new file mode 100644 index 000000000000..3aae9cfccf6b --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from abc import ABC +from typing import List, TYPE_CHECKING, cast + +from ._configuration import EventGridClientConfiguration + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core import PipelineClient + + from ._serialization import Deserializer, Serializer + + +def _format_url_section(template, **kwargs): + components = template.split("/") + while components: + try: + return template.format(**kwargs) + except KeyError as key: + # Need the cast, as for some reasons "split" is typed as list[str | Any] + formatted_components = cast(List[str], template.split("/")) + components = [ + c for c in formatted_components if "{}".format(key.args[0]) not in c + ] + template = "/".join(components) + +class EventGridClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + _client: "PipelineClient" + _config: EventGridClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index 5834df1ac978..4c7f8043b9d7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -1,12 +1,9 @@ # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is -# regenerated. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- VERSION = "4.19.1" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py index 0d2dce7aaea2..6c53eb888303 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py @@ -1,9 +1,22 @@ # coding=utf-8 -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -from ._publisher_client_async import EventGridPublisherClient +from ._client import EventGridClient -__all__ = ["EventGridPublisherClient"] +try: + from ._patch import __all__ as _patch_all + from ._patch import * # pylint: disable=unused-wildcard-import +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk +__all__ = [ + 'EventGridClient', +] +__all__.extend([p for p in _patch_all if p not in __all__]) + +_patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py new file mode 100644 index 000000000000..d5e929121bc0 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py @@ -0,0 +1,87 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from copy import deepcopy +from typing import Any, Awaitable + +from azure.core import AsyncPipelineClient +from azure.core.credentials import AzureKeyCredential +from azure.core.rest import AsyncHttpResponse, HttpRequest + +from .._serialization import Deserializer, Serializer +from ._configuration import EventGridClientConfiguration +from ._operations import EventGridClientOperationsMixin + +class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + """Azure Messaging EventGrid Client. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: AzureKeyCredential, + **kwargs: Any + ) -> None: + _endpoint = '{endpoint}' + self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + + def send_request( + self, + request: HttpRequest, + **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = await client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.AsyncHttpResponse + """ + + request_copy = deepcopy(request) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, **kwargs) + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "EventGridClient": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py new file mode 100644 index 000000000000..d2308d4f626d --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py @@ -0,0 +1,70 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any + +from azure.core.configuration import Configuration +from azure.core.credentials import AzureKeyCredential +from azure.core.pipeline import policies + +from .._version import VERSION + + +class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + """Configuration for EventGridClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: AzureKeyCredential, + **kwargs: Any + ) -> None: + super(EventGridClientConfiguration, self).__init__(**kwargs) + api_version: str = kwargs.pop('api_version', "2023-06-01-preview") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + + self.endpoint = endpoint + self.credential = credential + self.api_version = api_version + kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self._configure(**kwargs) + + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AzureKeyCredentialPolicy(self.credential, "SharedAccessKey", **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py new file mode 100644 index 000000000000..c166e5de9c64 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -0,0 +1,18 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import EventGridClientOperationsMixin + +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk +__all__ = [ + 'EventGridClientOperationsMixin', +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py new file mode 100644 index 000000000000..deb44505d8a2 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -0,0 +1,504 @@ +# pylint: disable=too-many-lines +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import json +from typing import Any, Callable, Dict, List, Optional, TypeVar + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse +from azure.core.rest import HttpRequest +from azure.core.tracing.decorator_async import distributed_trace_async +from azure.core.utils import case_insensitive_dict + +from ... import models as _models +from ..._model_base import AzureJSONEncoder, _deserialize +from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request +from .._vendor import EventGridClientMixinABC +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class EventGridClientOperationsMixin(EventGridClientMixinABC): + + @distributed_trace_async + async def _publish_cloud_event( # pylint: disable=inconsistent-return-statements + self, + topic_name: str, + event: _models._models.CloudEvent, + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event: Single Cloud Event being published. Required. + :type event: ~azure.eventgrid.models.CloudEvent + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + cls: ClsType[None] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(event, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_publish_cloud_event_request( + topic_name=topic_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + + + @distributed_trace_async + async def _publish_cloud_events( # pylint: disable=inconsistent-return-statements + self, + topic_name: str, + events: List[_models._models.CloudEvent], + **kwargs: Any + ) -> None: + """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param events: Array of Cloud Events being published. Required. + :type events: list[~azure.eventgrid.models.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents-batch+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) + cls: ClsType[None] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(events, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_publish_cloud_events_request( + topic_name=topic_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + + + @distributed_trace_async + async def _receive_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + *, + max_events: Optional[int] = None, + max_wait_time: Optional[int] = None, + **kwargs: Any + ) -> _models._models.ReceiveResult: + """Receive Batch of Cloud Events from the Event Subscription. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value + is 100 events. If not specified, the default value is 1. Default value is None. + :paramtype max_events: int + :keyword max_wait_time: Max wait time value for receive operation in Seconds. It is the time in + seconds that the server approximately waits for the availability of an event and responds to + the request. If an event is available, the broker responds immediately to the client. Minimum + value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is + 60 seconds. Default value is None. + :paramtype max_wait_time: int + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReceiveResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models._models.ReceiveResult] = kwargs.pop( # pylint: disable=protected-access + 'cls', None + ) + + + request = build_event_grid_receive_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + max_events=max_events, + max_wait_time=max_wait_time, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.ReceiveResult, # pylint: disable=protected-access + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace_async + async def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.AcknowledgeOptions, + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_acknowledge_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.AcknowledgeResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace_async + async def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.ReleaseOptions, + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.ReleaseResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_release_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.ReleaseResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + + + @distributed_trace_async + async def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: _models.RejectOptions, + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: ~azure.eventgrid.models.RejectOptions + :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + cls: ClsType[_models.RejectResult] = kwargs.pop( + 'cls', None + ) + + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + + request = build_event_grid_reject_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.RejectResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py new file mode 100644 index 000000000000..7a864a599c65 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -0,0 +1,157 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List, overload, Union, Any, Optional +from azure.core.messaging import CloudEvent +from azure.core.tracing.decorator_async import distributed_trace_async +from ...models._patch import ReceiveResult, ReceiveDetails +from ..._operations._patch import _cloud_event_to_generated +from ._operations import EventGridClientOperationsMixin as OperationsMixin + + +class EventGridClientOperationsMixin(OperationsMixin): + @overload + async def publish_cloud_events( + self, + topic_name: str, + body: List[CloudEvent], + *, + content_type: str = "application/cloudevents-batch+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Batch of Cloud Events to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Array of Cloud Events being published. Required. + :type body: list[~azure.core.messaging.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents-batch+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def publish_cloud_events( + self, + topic_name: str, + body: CloudEvent, + *, + content_type: str = "application/cloudevents+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event being published. Required. + :type body: ~azure.core.messaging.CloudEvent + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def publish_cloud_events( + self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs + ) -> None: + """Publish Cloud Events to namespace topic. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event or list of Cloud Events being published. Required. + :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + if isinstance(body, CloudEvent): + kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" + internal_body = _cloud_event_to_generated(body) + await self._publish_cloud_event(topic_name, internal_body, **kwargs) + else: + kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" + internal_body_list = [] + for item in body: + internal_body_list.append(_cloud_event_to_generated(item)) + await self._publish_cloud_events(topic_name, internal_body_list, **kwargs) + + @distributed_trace_async + async def receive_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + *, + max_events: Optional[int] = None, + max_wait_time: Optional[int] = None, + **kwargs: Any + ) -> ReceiveResult: + """Receive Batch of Cloud Events from the Event Subscription. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value + is 100 events. If not specified, the default value is 1. Default value is None. + :paramtype max_events: int + :keyword max_wait_time: Max wait time value for receive operation in Seconds. It is the time in + seconds that the server approximately waits for the availability of an event and responds to + the request. If an event is available, the broker responds immediately to the client. Minimum + value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is + 60 seconds. Default value is None. + :paramtype max_wait_time: int + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReceiveResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + detail_items = [] + receive_result = await self._receive_cloud_events( + topic_name, + event_subscription_name, + max_events=max_events, + max_wait_time=max_wait_time, + **kwargs + ) + for detail_item in receive_result.value: + deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) + detail_item.event = deserialized_cloud_event + detail_items.append( + ReceiveDetails( + broker_properties=detail_item.broker_properties, + event=detail_item.event, + ) + ) + receive_result_deserialized = ReceiveResult(value=detail_items) + return receive_result_deserialized + + +__all__: List[str] = [ + "EventGridClientOperationsMixin" +] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py new file mode 100644 index 000000000000..1b19aa235f57 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -0,0 +1,50 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" + +from typing import List +from azure.core.credentials import AzureKeyCredential +from .._patch import EventGridSharedAccessKeyPolicy +from ._client import EventGridClient as ServiceClientGenerated +from .._legacy.aio import EventGridPublisherClient + + +class EventGridClient(ServiceClientGenerated): + """Azure Messaging EventGrid Client. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential + :keyword api_version: The API version to use for this operation. Default value is + "2023-06-01-preview". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs) -> None: + if isinstance(credential, AzureKeyCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = EventGridSharedAccessKeyPolicy( + credential + ) + super().__init__(endpoint=endpoint, credential=credential, **kwargs) + + +def patch_sdk(): + """Do not remove from this file. + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ + + +__all__: List[str] = [ + "EventGridClient", + "EventGridPublisherClient", +] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py new file mode 100644 index 000000000000..67626c5adc66 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py @@ -0,0 +1,25 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from abc import ABC +from typing import TYPE_CHECKING + +from ._configuration import EventGridClientConfiguration + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core import AsyncPipelineClient + + from .._serialization import Deserializer, Serializer + + +class EventGridClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + _client: "AsyncPipelineClient" + _config: EventGridClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py new file mode 100644 index 000000000000..bb787a2e0c74 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py @@ -0,0 +1,29 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._models import AcknowledgeOptions +from ._models import AcknowledgeResult +from ._models import FailedLockToken +from ._models import RejectOptions +from ._models import RejectResult +from ._models import ReleaseOptions +from ._models import ReleaseResult +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk +__all__ = [ + 'AcknowledgeOptions', + 'AcknowledgeResult', + 'FailedLockToken', + 'RejectOptions', + 'RejectResult', + 'ReleaseOptions', + 'ReleaseResult', +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py new file mode 100644 index 000000000000..3fda23b49841 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -0,0 +1,383 @@ +# coding=utf-8 +# pylint: disable=too-many-lines +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import datetime +from typing import Any, List, Mapping, Optional, TYPE_CHECKING, overload + +from .. import _model_base +from .._model_base import rest_field + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from .. import models as _models + + +class AcknowledgeOptions(_model_base.Model): + """Array of lock token strings for the corresponding received Cloud Events to be acknowledged. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_tokens: String array of lock tokens. Required. + :vartype lock_tokens: list[str] + """ + + lock_tokens: List[str] = rest_field(name="lockTokens") + """String array of lock tokens. Required.""" + + @overload + def __init__( + self, + *, + lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class AcknowledgeResult(_model_base.Model): + """The result of the Acknowledge operation. + + All required parameters must be populated in order to send to Azure. + + :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken + includes the lock token value along with the related error information (namely, the error code + and description). Required. + :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] + :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully acknowledged + cloud events. Required. + :vartype succeeded_lock_tokens: list[str] + """ + + failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") + """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + along with the related error information (namely, the error code and description). Required.""" + succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") + """Array of lock tokens values for the successfully acknowledged cloud events. Required.""" + + @overload + def __init__( + self, + *, + failed_lock_tokens: List["_models.FailedLockToken"], + succeeded_lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class BrokerProperties(_model_base.Model): + """Properties of the Event Broker operation. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_token: The token used to lock the event. Required. + :vartype lock_token: str + :ivar delivery_count: The attempt count for delivering the event. Required. + :vartype delivery_count: int + """ + + lock_token: str = rest_field(name="lockToken") + """The token used to lock the event. Required.""" + delivery_count: int = rest_field(name="deliveryCount") + """The attempt count for delivering the event. Required.""" + + + +class CloudEvent(_model_base.Model): + """Properties of an event published to an Azure Messaging EventGrid Namespace topic using the + CloudEvent 1.0 Schema. + + All required parameters must be populated in order to send to Azure. + + :ivar id: An identifier for the event. The combination of id and source must be unique for each + distinct event. Required. + :vartype id: str + :ivar source: Identifies the context in which an event happened. The combination of id and + source must be unique for each distinct event. Required. + :vartype source: str + :ivar data: Event data specific to the event type. + :vartype data: any + :ivar data_base64: Event data specific to the event type, encoded as a base64 string. + :vartype data_base64: bytes + :ivar type: Type of event related to the originating occurrence. Required. + :vartype type: str + :ivar time: The time (in UTC) the event was generated, in RFC3339 format. + :vartype time: ~datetime.datetime + :ivar specversion: The version of the CloudEvents specification which the event uses. Required. + :vartype specversion: str + :ivar dataschema: Identifies the schema that data adheres to. + :vartype dataschema: str + :ivar datacontenttype: Content type of data value. + :vartype datacontenttype: str + :ivar subject: This describes the subject of the event in the context of the event producer + (identified by source). + :vartype subject: str + """ + + id: str = rest_field() + """An identifier for the event. The combination of id and source must be unique for each distinct + event. Required.""" + source: str = rest_field() + """Identifies the context in which an event happened. The combination of id and source must be + unique for each distinct event. Required.""" + data: Optional[Any] = rest_field() + """Event data specific to the event type.""" + data_base64: Optional[bytes] = rest_field() + """Event data specific to the event type, encoded as a base64 string.""" + type: str = rest_field() + """Type of event related to the originating occurrence. Required.""" + time: Optional[datetime.datetime] = rest_field() + """The time (in UTC) the event was generated, in RFC3339 format.""" + specversion: str = rest_field() + """The version of the CloudEvents specification which the event uses. Required.""" + dataschema: Optional[str] = rest_field() + """Identifies the schema that data adheres to.""" + datacontenttype: Optional[str] = rest_field() + """Content type of data value.""" + subject: Optional[str] = rest_field() + """This describes the subject of the event in the context of the event producer (identified by + source).""" + + + +class FailedLockToken(_model_base.Model): + """Failed LockToken information. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_token: LockToken value. Required. + :vartype lock_token: str + :ivar error_code: Error code related to the token. Example of such error codes are BadToken: + which indicates the Token is not formatted correctly, TokenLost: which indicates that token is + not found, and InternalServerError: For any internal server errors. Required. + :vartype error_code: str + :ivar error_description: Description of the token error. Required. + :vartype error_description: str + """ + + lock_token: str = rest_field(name="lockToken") + """LockToken value. Required.""" + error_code: str = rest_field(name="errorCode") + """Error code related to the token. Example of such error codes are BadToken: which indicates the + Token is not formatted correctly, TokenLost: which indicates that token is not found, and + InternalServerError: For any internal server errors. Required.""" + error_description: str = rest_field(name="errorDescription") + """Description of the token error. Required.""" + + @overload + def __init__( + self, + *, + lock_token: str, + error_code: str, + error_description: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ReceiveDetails(_model_base.Model): + """Receive operation details per Cloud Event. + + All required parameters must be populated in order to send to Azure. + + :ivar broker_properties: The Event Broker details. Required. + :vartype broker_properties: ~azure.eventgrid.models.BrokerProperties + :ivar event: Cloud Event details. Required. + :vartype event: ~azure.eventgrid.models.CloudEvent + """ + + broker_properties: "_models._models.BrokerProperties" = rest_field(name="brokerProperties") + """The Event Broker details. Required.""" + event: "_models._models.CloudEvent" = rest_field() + """Cloud Event details. Required.""" + + + +class ReceiveResult(_model_base.Model): + """Details of the Receive operation response. + + All required parameters must be populated in order to send to Azure. + + :ivar value: Array of receive responses, one per cloud event. Required. + :vartype value: list[~azure.eventgrid.models.ReceiveDetails] + """ + + value: List["_models._models.ReceiveDetails"] = rest_field() + """Array of receive responses, one per cloud event. Required.""" + + + +class RejectOptions(_model_base.Model): + """Array of lock token strings for the corresponding received Cloud Events to be rejected. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_tokens: String array of lock tokens. Required. + :vartype lock_tokens: list[str] + """ + + lock_tokens: List[str] = rest_field(name="lockTokens") + """String array of lock tokens. Required.""" + + @overload + def __init__( + self, + *, + lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class RejectResult(_model_base.Model): + """The result of the Reject operation. + + All required parameters must be populated in order to send to Azure. + + :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken + includes the lock token value along with the related error information (namely, the error code + and description). Required. + :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] + :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully rejected cloud + events. Required. + :vartype succeeded_lock_tokens: list[str] + """ + + failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") + """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + along with the related error information (namely, the error code and description). Required.""" + succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") + """Array of lock tokens values for the successfully rejected cloud events. Required.""" + + @overload + def __init__( + self, + *, + failed_lock_tokens: List["_models.FailedLockToken"], + succeeded_lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ReleaseOptions(_model_base.Model): + """Array of lock token strings for the corresponding received Cloud Events to be released. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_tokens: String array of lock tokens. Required. + :vartype lock_tokens: list[str] + """ + + lock_tokens: List[str] = rest_field(name="lockTokens") + """String array of lock tokens. Required.""" + + @overload + def __init__( + self, + *, + lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ReleaseResult(_model_base.Model): + """The result of the Release operation. + + All required parameters must be populated in order to send to Azure. + + :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken + includes the lock token value along with the related error information (namely, the error code + and description). Required. + :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] + :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully released cloud + events. Required. + :vartype succeeded_lock_tokens: list[str] + """ + + failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") + """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + along with the related error information (namely, the error code and description). Required.""" + succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") + """Array of lock tokens values for the successfully released cloud events. Required.""" + + @overload + def __init__( + self, + *, + failed_lock_tokens: List["_models.FailedLockToken"], + succeeded_lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py new file mode 100644 index 000000000000..ff93f72c6f87 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py @@ -0,0 +1,127 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List, overload, Mapping, Any +from azure.core.messaging import CloudEvent +from .. import _model_base +from ._models import ( + ReceiveDetails as InternalReceiveDetails, + ReceiveResult as InternalReceiveResult, + BrokerProperties as InternalBrokerProperties, +) + +class ReceiveDetails(InternalReceiveDetails): + """Receive operation details per Cloud Event. + + All required parameters must be populated in order to send to Azure. + + :ivar broker_properties: The Event Broker details. Required. + :vartype broker_properties: ~azure.eventgrid.models.BrokerProperties + :ivar event: Cloud Event details. Required. + :vartype event: ~azure.core.messaging.CloudEvent + """ + + @overload + def __init__( + self, + *, + broker_properties: "BrokerProperties", + event: "CloudEvent", + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__( + self, *args: Any, **kwargs: Any + ) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ReceiveResult(InternalReceiveResult): + """Details of the Receive operation response. + + All required parameters must be populated in order to send to Azure. + + :ivar value: Array of receive responses, one per cloud event. Required. + :vartype value: list[~azure.eventgrid.models.ReceiveDetails] + """ + + @overload + def __init__( + self, + *, + value: List["ReceiveDetails"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__( + self, *args: Any, **kwargs: Any + ) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class BrokerProperties(InternalBrokerProperties): + """Properties of the Event Broker operation. + + All required parameters must be populated in order to send to Azure. + + :ivar lock_token: The token used to lock the event. Required. + :vartype lock_token: str + :ivar delivery_count: The attempt count for deliverying the event. Required. + :vartype delivery_count: int + """ + + @overload + def __init__( + self, + *, + lock_token: str, + delivery_count: int, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__( + self, *args: Any, **kwargs: Any + ) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +__all__: List[str] = [ + "ReceiveDetails", + "ReceiveResult", + "BrokerProperties", +] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/py.typed b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/py.typed index e69de29bb2d1..e5aff4f83af8 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/py.typed +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/mypy.ini b/sdk/eventgrid/azure-eventgrid/mypy.ini index b8d3b2b62839..83bbdffd443c 100644 --- a/sdk/eventgrid/azure-eventgrid/mypy.ini +++ b/sdk/eventgrid/azure-eventgrid/mypy.ini @@ -1,12 +1,18 @@ [mypy] python_version = 3.7 -warn_return_any = True +warn_return_any = False warn_unused_configs = True ignore_missing_imports = True # Per-module options: -[mypy-azure.eventgrid._generated.*] +[mypy-azure.eventgrid._legacy.*] +ignore_errors = True + +[mypy-azure.eventgrid._operations.*] +ignore_errors = True + +[mypy-azure.eventgrid.aio._operations.*] ignore_errors = True [mypy-azure.core.*] diff --git a/sdk/eventgrid/azure-eventgrid/pyproject.toml b/sdk/eventgrid/azure-eventgrid/pyproject.toml index 57f5387d00e3..fdde94224048 100644 --- a/sdk/eventgrid/azure-eventgrid/pyproject.toml +++ b/sdk/eventgrid/azure-eventgrid/pyproject.toml @@ -2,4 +2,4 @@ pyright = false type_check_samples = false verifytypes = false -strict_sphinx = true \ No newline at end of file +strict_sphinx = true diff --git a/sdk/eventgrid/azure-eventgrid/samples/README.md b/sdk/eventgrid/azure-eventgrid/samples/README.md index 226c849d8d08..47e05c588b2a 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/README.md +++ b/sdk/eventgrid/azure-eventgrid/samples/README.md @@ -74,3 +74,6 @@ To publish events, dict representation of the models could also be used as follo [python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts + +[python-eg-client-sync-samples]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples +[python-eg-client-async-samples]:https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py new file mode 100644 index 000000000000..79d2d4f9631e --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + # Acknowledge a batch of CloudEvents + try: + async with client: + lock_tokens = AcknowledgeOptions(lock_tokens=["token"]) + ack_events = await client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, + ) + print(ack_events) + except HttpResponseError: + raise + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py new file mode 100644 index 000000000000..47d1615d7656 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -0,0 +1,126 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError +from azure.eventgrid.aio import EventGridClient + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +cloud_event_reject = CloudEvent( + data="reject", source="https://example.com", type="example" +) +cloud_event_release = CloudEvent( + data="release", source="https://example.com", type="example" +) +cloud_event_ack = CloudEvent( + data="acknowledge", source="https://example.com", type="example" +) + + +async def main(): + async with client: + # Publish a CloudEvent + try: + await client.publish_cloud_events( + topic_name=TOPIC_NAME, body=cloud_event_reject + ) + except HttpResponseError: + raise + + # Publish a list of CloudEvents + try: + list_of_cloud_events = [cloud_event_release, cloud_event_ack] + await client.publish_cloud_events( + topic_name=TOPIC_NAME, body=list_of_cloud_events + ) + except HttpResponseError: + raise + + # Receive Published Cloud Events + try: + receive_results = await client.receive_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + max_events=10, + max_wait_time=10, + ) + except HttpResponseError: + raise + + # Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject: + + release_events = [] + acknowledge_events = [] + reject_events = [] + + for detail in receive_results.value: + data = detail.event.data + broker_properties = detail.broker_properties + if data == "release": + release_events.append(broker_properties.lock_token) + elif data == "acknowledge": + acknowledge_events.append(broker_properties.lock_token) + else: + reject_events.append(broker_properties.lock_token) + + # Release/Acknowledge/Reject events + + if len(release_events) > 0: + try: + release_tokens = ReleaseOptions(lock_tokens=release_events) + release_result = await client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=release_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in release_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + if len(acknowledge_events) > 0: + try: + ack_tokens = AcknowledgeOptions(lock_tokens=acknowledge_events) + ack_result = await client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=ack_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in ack_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + if len(reject_events) > 0: + try: + reject_tokens = RejectOptions(lock_tokens=reject_events) + reject_result = await client.reject_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=reject_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in reject_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + +asyncio.run(main()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py new file mode 100644 index 000000000000..21966b77dc55 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -0,0 +1,46 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + async with client: + # Publish a CloudEvent + try: + cloud_event = CloudEvent( + data="HI", source="https://example.com", type="example" + ) + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + except HttpResponseError: + raise + + # Publish a list of CloudEvents + try: + list_of_cloud_events = [cloud_event, cloud_event] + await client.publish_cloud_events( + topic_name=TOPIC_NAME, body=list_of_cloud_events + ) + except HttpResponseError: + raise + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py new file mode 100644 index 000000000000..0d0a94876bfe --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + # Receive CloudEvents + try: + async with client: + receive_result = await client.receive_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + max_events=10, + max_wait_time=10, + ) + print(receive_result) + except HttpResponseError: + raise + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py new file mode 100644 index 000000000000..c9de1fbd4817 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + # Release a LockToken + try: + async with client: + tokens = RejectOptions(lock_tokens=["token"]) + reject_events = await client.reject_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=tokens, + ) + print(reject_events) + except HttpResponseError: + raise + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py new file mode 100644 index 000000000000..eb423e2f5827 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + # Release a LockToken + try: + async with client: + tokens = ReleaseOptions(lock_tokens=["token"]) + release_events = await client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=tokens, + ) + print(release_events) + except HttpResponseError: + raise + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py index cc1ccb15c6f2..a26411bb95ed 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py @@ -48,10 +48,10 @@ data={"team": "azure-sdk"}, subject="Door1", event_type="Azure.Sdk.Demo", - data_version="2.0" + data_version="2.0", ) default_az_credential = DefaultAzureCredential() endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] client = EventGridPublisherClient(endpoint, default_az_credential) -# [END client_auth_with_token_cred_async] \ No newline at end of file +# [END client_auth_with_token_cred_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py index d46585fac3e9..d6737c21420d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py @@ -24,25 +24,27 @@ topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] + async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) # [START publish_cloud_event_dict_async] async with client: - await client.send([ - { - "type": "Contoso.Items.ItemReceived", - "source": "/contoso/items", - "data": { - "itemSku": "Contoso Item SKU #1" - }, - "subject": "Door1", - "specversion": "1.0", - "id": "randomclouduuid11" - } - ]) + await client.send( + [ + { + "type": "Contoso.Items.ItemReceived", + "source": "/contoso/items", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "specversion": "1.0", + "id": "randomclouduuid11", + } + ] + ) # [END publish_cloud_event_dict_async] -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py index e2036f141e63..f755c9724c46 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py @@ -25,19 +25,21 @@ async def publish(): - credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) - await client.send([ - CloudEvent( - attributes={ - "type": "cloudevent", - "source": "/cncf/cloud/event/1.0", - "subject": "testing-cncf-event" - }, - data=b'This is a cncf cloud event.', - ) - ]) + await client.send( + [ + CloudEvent( + attributes={ + "type": "cloudevent", + "source": "/cncf/cloud/event/1.0", + "subject": "testing-cncf-event", + }, + data=b"This is a cncf cloud event.", + ) + ] + ) -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py index 9c6001e4afae..2d7ccbb8cbcf 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py @@ -28,6 +28,7 @@ key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] + async def publish_event(): # authenticate client # [START publish_custom_schema_async] @@ -40,13 +41,14 @@ async def publish_event(): "customDataVersion": "2.0", "customId": uuid.uuid4(), "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" + "customData": "sample data", } async with client: # publish list of events await client.send(custom_schema_event) - + # [END publish_custom_schema_async] -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(publish_event()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py index a175bfec0d75..8909b5717b2b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py @@ -26,35 +26,33 @@ topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] + async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) # [START publish_eg_event_dict_async] - event0 = { - "eventType": "Contoso.Items.ItemReceived", - "data": { - "itemSku": "Contoso Item SKU #1" - }, - "subject": "Door1", - "dataVersion": "2.0", - "id": "randomuuid11", - "eventTime": datetime.utcnow() - } - event1 = { - "eventType": "Contoso.Items.ItemReceived", - "data": { - "itemSku": "Contoso Item SKU #2" - }, - "subject": "Door1", - "dataVersion": "2.0", - "id": "randomuuid12", - "eventTime": datetime.utcnow() + event0 = { + "eventType": "Contoso.Items.ItemReceived", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "dataVersion": "2.0", + "id": "randomuuid11", + "eventTime": datetime.utcnow(), + } + event1 = { + "eventType": "Contoso.Items.ItemReceived", + "data": {"itemSku": "Contoso Item SKU #2"}, + "subject": "Door1", + "dataVersion": "2.0", + "id": "randomuuid12", + "eventTime": datetime.utcnow(), } - async with client: + async with client: await client.send([event0, event1]) # [END publish_eg_event_dict_async] -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py index 2973273fb180..48272cb30166 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py @@ -24,30 +24,30 @@ domain_key = os.environ["EVENTGRID_DOMAIN_KEY"] domain_hostname = os.environ["EVENTGRID_DOMAIN_ENDPOINT"] + async def publish(): credential = AzureKeyCredential(domain_key) client = EventGridPublisherClient(domain_hostname, credential) - await client.send([ - EventGridEvent( - topic="MyCustomDomainTopic1", - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ), - EventGridEvent( - topic="MyCustomDomainTopic2", - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #2" - }, - subject="Door1", - data_version="2.0" - ) - ]) + await client.send( + [ + EventGridEvent( + topic="MyCustomDomainTopic1", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ), + EventGridEvent( + topic="MyCustomDomainTopic2", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #2"}, + subject="Door1", + data_version="2.0", + ), + ] + ) + -if __name__ == '__main__': +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py index f1924f54f66d..4ab76f2a81fa 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py @@ -24,21 +24,24 @@ topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] + async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) - await client.send([ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ) - ]) + await client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] + ) + + # [END publish_eg_event_to_topic_async] -if __name__ == '__main__': +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py index 26e4c745ddaf..c70bfd11aef4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py @@ -23,21 +23,23 @@ sas = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] + async def publish(): credential = AzureSasCredential(sas) client = EventGridPublisherClient(endpoint, credential) async with client: - await client.send([ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ) - ]) + await client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] + ) + -if __name__ == '__main__': +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py index 8e238dfee5a1..1d3ea0337e33 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py @@ -24,21 +24,24 @@ topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] + async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) - await client.send([ - CloudEvent( - type="Contoso.Items.ItemReceived", - source="/contoso/items", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1" - ) - ]) + await client.send( + [ + CloudEvent( + type="Contoso.Items.ItemReceived", + source="/contoso/items", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + ) + ] + ) + + # [END publish_cloud_event_to_topic_async] -if __name__ == '__main__': +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py index 15a6526f0088..f12070c35a1e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py @@ -22,26 +22,28 @@ from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -topic_key = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY'] -endpoint = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT'] +topic_key = os.environ["EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY"] +endpoint = os.environ["EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT"] + +channel_name = os.environ["EVENTGRID_PARTNER_CHANNEL_NAME"] -channel_name = os.environ['EVENTGRID_PARTNER_CHANNEL_NAME'] async def publish(): credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) async with client: - await client.send([ - CloudEvent( - type="Contoso.Items.ItemReceived", - source="/contoso/items", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1" - ) - ], - channel_name=channel_name) + await client.send( + [ + CloudEvent( + type="Contoso.Items.ItemReceived", + source="/contoso/items", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + ) + ], + channel_name=channel_name, + ) + -if __name__ == '__main__': +if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py index 613794f04f20..5dca03859841 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py @@ -24,13 +24,16 @@ CONNECTION_STR = os.environ["EVENT_HUB_CONN_STR"] EVENTHUB_NAME = os.environ["EVENT_HUB_NAME"] + + def on_event(partition_context, event): dict_event: CloudEvent = CloudEvent.from_json(event) print("data: {}\n".format(dict_event.data)) + consumer_client = EventHubConsumerClient.from_connection_string( conn_str=CONNECTION_STR, - consumer_group='$Default', + consumer_group="$Default", eventhub_name=EVENTHUB_NAME, ) @@ -38,5 +41,5 @@ def on_event(partition_context, event): event_list = consumer_client.receive( on_event=on_event, starting_position="-1", # "-1" is from the beginning of the partition. - prefetch=5 + prefetch=5, ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py index f8975d603a63..17e110122a95 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py @@ -20,17 +20,16 @@ import json # all types of CloudEvents below produce same DeserializedEvent -connection_str = os.environ['AZURE_STORAGE_CONNECTION_STRING'] -queue_name = os.environ['STORAGE_QUEUE_NAME'] +connection_str = os.environ["AZURE_STORAGE_CONNECTION_STRING"] +queue_name = os.environ["STORAGE_QUEUE_NAME"] with QueueServiceClient.from_connection_string(connection_str) as qsc: - payload = qsc.get_queue_client( - queue=queue_name, - message_decode_policy=BinaryBase64DecodePolicy() - ).peek_messages(max_messages=32) + payload = qsc.get_queue_client( + queue=queue_name, message_decode_policy=BinaryBase64DecodePolicy() + ).peek_messages(max_messages=32) ## deserialize payload into a list of typed Events events: List[CloudEvent] = [CloudEvent.from_json(msg) for msg in payload] for event in events: - print(type(event)) ## CloudEvent + print(type(event)) ## CloudEvent diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py index 9889ea87c112..25c6a3b49d05 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_eventgrid_events_from_service_bus_queue.py @@ -23,14 +23,14 @@ import json # all types of EventGridEvents below produce same DeserializedEvent -connection_str = os.environ['SERVICE_BUS_CONNECTION_STR'] -queue_name = os.environ['SERVICE_BUS_QUEUE_NAME'] +connection_str = os.environ["SERVICE_BUS_CONNECTION_STR"] +queue_name = os.environ["SERVICE_BUS_QUEUE_NAME"] with ServiceBusClient.from_connection_string(connection_str) as sb_client: - payload = sb_client.get_queue_receiver(queue_name).receive_messages() + payload = sb_client.get_queue_receiver(queue_name).receive_messages() ## deserialize payload into a list of typed Events events = [EventGridEvent.from_json(msg) for msg in payload] for event in events: - print(type(event)) ## EventGridEvent + print(type(event)) ## EventGridEvent diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/functionsapp/EventGridTrigger1/__init__.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/functionsapp/EventGridTrigger1/__init__.py index b7a38ab6b5b3..56c82506fc64 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/functionsapp/EventGridTrigger1/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/functionsapp/EventGridTrigger1/__init__.py @@ -5,16 +5,19 @@ import azure.functions as func from azure.eventgrid import EventGridEvent + def main(event: func.EventGridEvent): logging.info(sys.version) logging.info(event) - result = json.dumps({ - 'id': event.id, - 'data': event.get_json(), - 'topic': event.topic, - 'subject': event.subject, - 'event_type': event.event_type - }) + result = json.dumps( + { + "id": event.id, + "data": event.get_json(), + "topic": event.topic, + "subject": event.subject, + "event_type": event.event_type, + } + ) logging.info(result) deserialized_event = EventGridEvent.from_dict(json.loads(result)) ## can only be EventGridEvent diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py index 45eccfc14c91..bb6b7420cef1 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py @@ -30,21 +30,29 @@ credential = AzureKeyCredential(key) client = EventGridPublisherClient(endpoint, credential) -services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field +services = [ + "EventGrid", + "ServiceBus", + "EventHubs", + "Storage", +] # possible values for data field + def publish_event(): # publish events for _ in range(3): - event_list = [] # list of events to publish + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 1)): - sample_members = sample(services, k=randint(1, 4)) # select random subset of team members + sample_members = sample( + services, k=randint(1, 4) + ) # select random subset of team members data_dict = {"team": sample_members} event = CloudEvent( - type="Azure.Sdk.Sample", - source="https://egsample.dev/sampleevent", - data={"team": sample_members} - ) + type="Azure.Sdk.Sample", + source="https://egsample.dev/sampleevent", + data={"team": sample_members}, + ) event_list.append(event) # publish list of events @@ -52,5 +60,6 @@ def publish_event(): print("Batch of size {} published".format(len(event_list))) time.sleep(randint(1, 5)) + if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py index 4deab71ad6b5..b12784c078b7 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py @@ -32,21 +32,28 @@ credential = AzureKeyCredential(domain_key) client = EventGridPublisherClient(domain_endpoint, credential) + def publish_event(): # publish events for _ in range(3): - - event_list = [] # list of events to publish - services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field + event_list = [] # list of events to publish + services = [ + "EventGrid", + "ServiceBus", + "EventHubs", + "Storage", + ] # possible values for data field # create events and append to list for j in range(randint(1, 3)): - sample_members = sample(services, k=randint(1, 4)) # select random subset of team members + sample_members = sample( + services, k=randint(1, 4) + ) # select random subset of team members event = CloudEvent( - type="Azure.Sdk.Demo", - source='domainname', - data={"team": sample_members} - ) + type="Azure.Sdk.Demo", + source="domainname", + data={"team": sample_members}, + ) event_list.append(event) # publish list of events @@ -54,5 +61,6 @@ def publish_event(): print("Batch of size {} published".format(len(event_list))) time.sleep(randint(1, 5)) -if __name__ == '__main__': + +if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py index c24b7c3fddb4..4f51f1b6990c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py @@ -27,6 +27,7 @@ key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] + def publish_event(): # authenticate client credential = AzureKeyCredential(key) @@ -38,13 +39,12 @@ def publish_event(): "customDataVersion": "2.0", "customId": uuid.uuid4(), "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" + "customData": "sample data", } # publish events - for _ in range(3): - - event_list = [] # list of events to publish + for _ in range(3): + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): event_list.append(custom_schema_event) @@ -55,5 +55,5 @@ def publish_event(): time.sleep(randint(1, 5)) -if __name__ == '__main__': +if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py index 209d3ca48582..075dc12fdfdf 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py @@ -28,22 +28,29 @@ # authenticate client credential = AzureKeyCredential(key) client = EventGridPublisherClient(endpoint, credential) -services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field +services = [ + "EventGrid", + "ServiceBus", + "EventHubs", + "Storage", +] # possible values for data field + def publish_event(): # publish events for _ in range(3): - - event_list = [] # list of events to publish + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): - sample_members = sample(services, k=randint(1, 4)) # select random subset of team members + sample_members = sample( + services, k=randint(1, 4) + ) # select random subset of team members event = EventGridEvent( - subject="Door1", - data={"team": sample_members}, - event_type="Azure.Sdk.Demo", - data_version="2.0" - ) + subject="Door1", + data={"team": sample_members}, + event_type="Azure.Sdk.Demo", + data_version="2.0", + ) event_list.append(event) # publish list of events @@ -51,5 +58,6 @@ def publish_event(): print("Batch of size {} published".format(len(event_list))) time.sleep(randint(1, 5)) -if __name__ == '__main__': + +if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py index 9e0c02c15914..dea31e7b7ae0 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py @@ -34,21 +34,28 @@ credential = AzureSasCredential(signature) client = EventGridPublisherClient(endpoint, credential) -services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field +services = [ + "EventGrid", + "ServiceBus", + "EventHubs", + "Storage", +] # possible values for data field + def publish_event(): # publish events for _ in range(3): - - event_list = [] # list of events to publish + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): - sample_members = sample(services, k=randint(1, 4)) # select random subset of team members + sample_members = sample( + services, k=randint(1, 4) + ) # select random subset of team members event = CloudEvent( - type="Azure.Sdk.Demo", - source="https://egdemo.dev/demowithsignature", - data={"team": sample_members} - ) + type="Azure.Sdk.Demo", + source="https://egdemo.dev/demowithsignature", + data={"team": sample_members}, + ) event_list.append(event) # publish list of events @@ -56,5 +63,6 @@ def publish_event(): print("Batch of size {} published".format(len(event_list))) time.sleep(randint(1, 5)) -if __name__ == '__main__': + +if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py new file mode 100644 index 000000000000..96cb87dc59eb --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +# Acknowledge a batch of CloudEvents +try: + lock_tokens = AcknowledgeOptions(lock_tokens=["token"]) + ack_events = client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, + ) + print(ack_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py new file mode 100644 index 000000000000..9237729b12fd --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -0,0 +1,116 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError +from azure.eventgrid import EventGridClient + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +cloud_event_reject = CloudEvent( + data="reject", source="https://example.com", type="example" +) +cloud_event_release = CloudEvent( + data="release", source="https://example.com", type="example" +) +cloud_event_ack = CloudEvent( + data="acknowledge", source="https://example.com", type="example" +) + +# Publish a CloudEvent +try: + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_reject) +except HttpResponseError: + raise + +# Publish a list of CloudEvents +try: + list_of_cloud_events = [cloud_event_release, cloud_event_ack] + client.publish_cloud_events(topic_name=TOPIC_NAME, body=list_of_cloud_events) +except HttpResponseError: + raise + +# Receive Published Cloud Events +try: + receive_results = client.receive_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + max_events=10, + max_wait_time=10, + ) +except HttpResponseError: + raise + +# Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject: + +release_events = [] +acknowledge_events = [] +reject_events = [] + +for detail in receive_results.value: + data = detail.event.data + broker_properties = detail.broker_properties + if data == "release": + release_events.append(broker_properties.lock_token) + elif data == "acknowledge": + acknowledge_events.append(broker_properties.lock_token) + else: + reject_events.append(broker_properties.lock_token) + +# Release/Acknowledge/Reject events + +if len(release_events) > 0: + try: + release_tokens = ReleaseOptions(lock_tokens=release_events) + release_result = client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=release_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in release_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + +if len(acknowledge_events) > 0: + try: + ack_tokens = AcknowledgeOptions(lock_tokens=acknowledge_events) + ack_result = client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=ack_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in ack_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + +if len(reject_events) > 0: + try: + reject_tokens = RejectOptions(lock_tokens=reject_events) + reject_result = client.reject_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=reject_tokens, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in reject_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py new file mode 100644 index 000000000000..f44b6d76f7c3 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py @@ -0,0 +1,27 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +""" +FILE: sample_eg_client_authentication.py +DESCRIPTION: + These samples demonstrate authenticating an EventGridClient. +USAGE: + python sample_eg_client_authentication.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace hostname. Typically it exists in the format + "https://..eventgrid.azure.net". +""" +# [START client_auth_with_key_cred] +import os +from azure.eventgrid import EventGridClient +from azure.core.credentials import AzureKeyCredential + +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] + +credential = AzureKeyCredential(key) +client = EventGridClient(endpoint, credential) +# [END client_auth_with_key_cred] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py new file mode 100644 index 000000000000..10bfb8e0ffe8 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py @@ -0,0 +1,35 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +# Publish a CloudEvent +try: + cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) +except HttpResponseError: + raise + +# Publish a list of CloudEvents +try: + list_of_cloud_events = [cloud_event, cloud_event] + client.publish_cloud_events(topic_name=TOPIC_NAME, body=list_of_cloud_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py new file mode 100644 index 000000000000..222772002bd0 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +# Receive CloudEvents +try: + receive_result = client.receive_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + max_events=10, + max_wait_time=10, + ) + print(receive_result) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py new file mode 100644 index 000000000000..d65066e52b44 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + +# Release a LockToken +try: + lock_tokens = RejectOptions(lock_tokens=["token"]) + reject_events = client.reject_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, + ) + print(reject_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py new file mode 100644 index 000000000000..dfea2e9489a4 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") +EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") +TOPIC_NAME = os.environ.get("TOPIC_NAME") +EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + +# Release a LockToken +try: + lock_tokens = ReleaseOptions(lock_tokens=["token"]) + release_events = client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, + ) + print(release_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py index ea3e5b30522c..eb54049d0925 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py @@ -46,4 +46,4 @@ default_az_credential = DefaultAzureCredential() endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] client = EventGridPublisherClient(endpoint, default_az_credential) -# [END client_auth_with_token_cred] \ No newline at end of file +# [END client_auth_with_token_cred] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py index 4c8eb1141a91..deb0d72d6649 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py @@ -22,11 +22,11 @@ topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -#represents the expiration date for sas +# represents the expiration date for sas expiration_date_utc = datetime.utcnow() + timedelta(hours=10) signature = generate_sas(endpoint, topic_key, expiration_date_utc) # [END generate_sas] -print(signature) \ No newline at end of file +print(signature) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py index 25be49359a50..0630d409ebd6 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py @@ -26,16 +26,16 @@ client = EventGridPublisherClient(endpoint, credential) # [START publish_cloud_event_dict] -client.send([ - { - "type": "Contoso.Items.ItemReceived", - "source": "/contoso/items", - "data": { - "itemSku": "Contoso Item SKU #1" - }, - "subject": "Door1", - "specversion": "1.0", - "id": "randomclouduuid11" - } -]) +client.send( + [ + { + "type": "Contoso.Items.ItemReceived", + "source": "/contoso/items", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "specversion": "1.0", + "id": "randomclouduuid11", + } + ] +) # [END publish_cloud_event_dict] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py index a54a7442a15a..83432366aa74 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py @@ -25,13 +25,15 @@ credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) -client.send([ - CloudEvent( - attributes={ - "type": "cloudevent", - "source": "/cncf/cloud/event/1.0", - "subject": "testing-cncf-event" - }, - data=b'This is a cncf cloud event.', - ) -]) +client.send( + [ + CloudEvent( + attributes={ + "type": "cloudevent", + "source": "/cncf/cloud/event/1.0", + "subject": "testing-cncf-event", + }, + data=b"This is a cncf cloud event.", + ) + ] +) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py index abfaba2c0083..4650aae15d61 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py @@ -27,6 +27,7 @@ key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] + def publish_event(): # authenticate client credential = AzureKeyCredential(key) @@ -39,11 +40,12 @@ def publish_event(): "customDataVersion": "2.0", "customId": uuid.uuid4(), "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" + "customData": "sample data", } client.send(custom_schema_event) # [END publish_custom_schema] -if __name__ == '__main__': + +if __name__ == "__main__": publish_event() diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py index 97b84b922592..b7154a0e07b8 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py @@ -25,33 +25,31 @@ topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] + def publish(): # [START publish_eg_event_dict] credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) - event0 = { - "eventType": "Contoso.Items.ItemReceived", - "data": { - "itemSku": "Contoso Item SKU #1" - }, - "subject": "Door1", - "dataVersion": "2.0", - "id": "randomuuid11", - "eventTime": datetime.now(UTC()) - } - event1 = { - "eventType": "Contoso.Items.ItemReceived", - "data": { - "itemSku": "Contoso Item SKU #2" - }, - "subject": "Door1", - "dataVersion": "2.0", - "id": "randomuuid12", - "eventTime": datetime.now(UTC()) - } + event0 = { + "eventType": "Contoso.Items.ItemReceived", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "dataVersion": "2.0", + "id": "randomuuid11", + "eventTime": datetime.now(UTC()), + } + event1 = { + "eventType": "Contoso.Items.ItemReceived", + "data": {"itemSku": "Contoso Item SKU #2"}, + "subject": "Door1", + "dataVersion": "2.0", + "id": "randomuuid12", + "eventTime": datetime.now(UTC()), + } client.send([event0, event1]) # [END publish_eg_event_dict] -if __name__ == '__main__': + +if __name__ == "__main__": publish() diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py index e66d26c7a36a..960f91aeae70 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py @@ -24,23 +24,21 @@ credential = AzureKeyCredential(domain_key) client = EventGridPublisherClient(domain_hostname, credential) -client.send([ - EventGridEvent( - topic="MyCustomDomainTopic1", - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ), - EventGridEvent( - topic="MyCustomDomainTopic2", - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #2" - }, - subject="Door1", - data_version="2.0" - ) -]) +client.send( + [ + EventGridEvent( + topic="MyCustomDomainTopic1", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ), + EventGridEvent( + topic="MyCustomDomainTopic2", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #2"}, + subject="Door1", + data_version="2.0", + ), + ] +) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py index 9138a8ab1899..a0e3ab58b6dc 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py @@ -25,14 +25,14 @@ credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) -client.send([ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ) -]) +client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] +) # [END publish_eg_event_to_topic] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py index 78ad100c40f9..6051d883fbd4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py @@ -25,13 +25,13 @@ credential = AzureSasCredential(sas) client = EventGridPublisherClient(endpoint, credential) -client.send([ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1", - data_version="2.0" - ) -]) +client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] +) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py index 9544f3fcd209..a0297f9950a3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py @@ -26,14 +26,14 @@ credential = AzureKeyCredential(topic_key) client = EventGridPublisherClient(endpoint, credential) -client.send([ - CloudEvent( - type="Contoso.Items.ItemReceived", - source="/contoso/items", - data={ - "itemSku": "Contoso Item SKU #1" - }, - subject="Door1" - ) -]) +client.send( + [ + CloudEvent( + type="Contoso.Items.ItemReceived", + source="/contoso/items", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + ) + ] +) # [END publish_cloud_event_to_topic] diff --git a/sdk/eventgrid/azure-eventgrid/setup.py b/sdk/eventgrid/azure-eventgrid/setup.py index 3a1acfc1aea8..7a861fa486eb 100644 --- a/sdk/eventgrid/azure-eventgrid/setup.py +++ b/sdk/eventgrid/azure-eventgrid/setup.py @@ -1,51 +1,41 @@ -#!/usr/bin/env python - -#------------------------------------------------------------------------- +# coding=utf-8 +# -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -#-------------------------------------------------------------------------- +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# coding: utf-8 +import os import re -import os.path -from io import open -from setuptools import find_packages, setup +from setuptools import setup, find_packages + -# Change the PACKAGE_NAME only to change folder and different name PACKAGE_NAME = "azure-eventgrid" -PACKAGE_PPRINT_NAME = "Event Grid" +PACKAGE_PPRINT_NAME = "Azure Event Grid" # a-b-c => a/b/c -package_folder_path = PACKAGE_NAME.replace('-', '/') -# a-b-c => a.b.c -namespace_name = PACKAGE_NAME.replace('-', '.') +package_folder_path = PACKAGE_NAME.replace("-", "/") # Version extraction inspired from 'requests' -with open(os.path.join(package_folder_path, 'version.py') - if os.path.exists(os.path.join(package_folder_path, 'version.py')) - else os.path.join(package_folder_path, '_version.py'), 'r') as fd: - version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', - fd.read(), re.MULTILINE).group(1) +with open(os.path.join(package_folder_path, "_version.py"), "r") as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) if not version: - raise RuntimeError('Cannot find version information') + raise RuntimeError("Cannot find version information") -with open('README.md', encoding='utf-8') as f: - readme = f.read() -with open('CHANGELOG.md', encoding='utf-8') as f: - changelog = f.read() setup( name=PACKAGE_NAME, version=version, - include_package_data=True, - description='Microsoft Azure {} Client Library for Python'.format(PACKAGE_PPRINT_NAME), - long_description=readme + '\n\n' + changelog, - long_description_content_type='text/markdown', - license='MIT License', - author='Microsoft Corporation', - author_email='azpysdkhelp@microsoft.com', - url='https://github.com/Azure/azure-sdk-for-python', + description="Microsoft {} Client Library for Python".format(PACKAGE_PPRINT_NAME), + long_description=open("README.md", "r").read(), + long_description_content_type="text/markdown", + license="MIT License", + author="Microsoft Corporation", + author_email="azpysdkhelp@microsoft.com", + url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk", keywords="azure, azure sdk", classifiers=[ "Development Status :: 5 - Production/Stable", @@ -61,14 +51,20 @@ ], python_requires=">=3.8", zip_safe=False, - packages=find_packages(exclude=[ - 'tests', - 'samples', - # Exclude packages that will be covered by PEP420 or nspkg - 'azure', - ]), + packages=find_packages( + exclude=[ + "tests", + # Exclude packages that will be covered by PEP420 or nspkg + "azure", + ] + ), + include_package_data=True, + package_data={ + "pytyped": ["py.typed"], + }, install_requires=[ "isodate>=0.6.1", 'azure-core>=1.24.0', ], + python_requires=">=3.7", ) diff --git a/sdk/eventgrid/azure-eventgrid/swagger/_constants.py b/sdk/eventgrid/azure-eventgrid/swagger/_constants.py index c6a89faa3626..b9ba703da2e4 100644 --- a/sdk/eventgrid/azure-eventgrid/swagger/_constants.py +++ b/sdk/eventgrid/azure-eventgrid/swagger/_constants.py @@ -36,32 +36,32 @@ ### Used for backward compatibility. Don't change this ####################################################### backward_compat = { - 'AcsChatMemberAddedToThreadWithUserEventName': "Microsoft.Communication.ChatMemberAddedToThreadWithUser", - 'ResourceWriteFailureEventName': "Microsoft.Resources.ResourceWriteFailure", - 'IoTHubDeviceDeletedEventName': "Microsoft.Devices.DeviceDeleted", - 'IoTHubDeviceDisconnectedEventName': "Microsoft.Devices.DeviceDisconnected", - 'ResourceDeleteFailureEventName': "Microsoft.Resources.ResourceDeleteFailure", - 'ResourceDeleteCancelEventName': "Microsoft.Resources.ResourceDeleteCancel", - 'AcsChatThreadParticipantAddedEventName': "Microsoft.Communication.ChatThreadParticipantAdded", - 'ResourceDeleteSuccessEventName': "Microsoft.Resources.ResourceDeleteSuccess", - 'EventGridSubscriptionValidationEventName': "Microsoft.EventGrid.SubscriptionValidationEvent", - 'ResourceWriteSuccessEventName': "Microsoft.Resources.ResourceWriteSuccess", - 'ResourceActionSuccessEventName': "Microsoft.Resources.ResourceActionSuccess", - 'ResourceWriteCancelEventName': "Microsoft.Resources.ResourceWriteCancel", - 'ResourceActionFailureEventName': "Microsoft.Resources.ResourceActionFailure", - 'AcsChatMemberRemovedFromThreadWithUserEventName': "Microsoft.Communication.ChatMemberRemovedFromThreadWithUser", - 'IoTHubDeviceConnectedEventName': "Microsoft.Devices.DeviceConnected", - 'EventGridSubscriptionDeletedEventName': "Microsoft.EventGrid.SubscriptionDeletedEvent", - 'AcsChatThreadParticipantRemovedEventName': "Microsoft.Communication.ChatThreadParticipantRemoved", - 'ResourceActionCancelEventName': "Microsoft.Resources.ResourceActionCancel", - 'IoTHubDeviceCreatedEventName': "Microsoft.Devices.DeviceCreated", + "AcsChatMemberAddedToThreadWithUserEventName": "Microsoft.Communication.ChatMemberAddedToThreadWithUser", + "ResourceWriteFailureEventName": "Microsoft.Resources.ResourceWriteFailure", + "IoTHubDeviceDeletedEventName": "Microsoft.Devices.DeviceDeleted", + "IoTHubDeviceDisconnectedEventName": "Microsoft.Devices.DeviceDisconnected", + "ResourceDeleteFailureEventName": "Microsoft.Resources.ResourceDeleteFailure", + "ResourceDeleteCancelEventName": "Microsoft.Resources.ResourceDeleteCancel", + "AcsChatThreadParticipantAddedEventName": "Microsoft.Communication.ChatThreadParticipantAdded", + "ResourceDeleteSuccessEventName": "Microsoft.Resources.ResourceDeleteSuccess", + "EventGridSubscriptionValidationEventName": "Microsoft.EventGrid.SubscriptionValidationEvent", + "ResourceWriteSuccessEventName": "Microsoft.Resources.ResourceWriteSuccess", + "ResourceActionSuccessEventName": "Microsoft.Resources.ResourceActionSuccess", + "ResourceWriteCancelEventName": "Microsoft.Resources.ResourceWriteCancel", + "ResourceActionFailureEventName": "Microsoft.Resources.ResourceActionFailure", + "AcsChatMemberRemovedFromThreadWithUserEventName": "Microsoft.Communication.ChatMemberRemovedFromThreadWithUser", + "IoTHubDeviceConnectedEventName": "Microsoft.Devices.DeviceConnected", + "EventGridSubscriptionDeletedEventName": "Microsoft.EventGrid.SubscriptionDeletedEvent", + "AcsChatThreadParticipantRemovedEventName": "Microsoft.Communication.ChatThreadParticipantRemoved", + "ResourceActionCancelEventName": "Microsoft.Resources.ResourceActionCancel", + "IoTHubDeviceCreatedEventName": "Microsoft.Devices.DeviceCreated", } additional_events = { - 'ContainerRegistryArtifactEventName': 'Microsoft.AppConfiguration.KeyValueModified', - 'KeyVaultAccessPolicyChangedEventName': 'Microsoft.KeyVault.VaultAccessPolicyChanged', - 'ContainerRegistryEventName': 'Microsoft.ContainerRegistry.ChartPushed', - 'ServiceBusDeadletterMessagesAvailableWithNoListenerEventName': 'Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners' + "ContainerRegistryArtifactEventName": "Microsoft.AppConfiguration.KeyValueModified", + "KeyVaultAccessPolicyChangedEventName": "Microsoft.KeyVault.VaultAccessPolicyChanged", + "ContainerRegistryEventName": "Microsoft.ContainerRegistry.ChartPushed", + "ServiceBusDeadletterMessagesAvailableWithNoListenerEventName": "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners", } EXCEPTIONS = ['ContainerRegistryArtifactEventData', 'ContainerRegistryEventData', 'ContainerServiceClusterSupportEventData', 'ContainerServiceNodePoolRollingEventData', diff --git a/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py b/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py index 5e96e2c8cd62..f1a2cd34d400 100644 --- a/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py +++ b/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py @@ -6,6 +6,7 @@ from azure.eventgrid._generated import models from _constants import files, backward_compat, additional_events, EXCEPTIONS, NAMING_CHANGES + def extract(definitions): if not definitions: return @@ -29,8 +30,11 @@ def extract(definitions): sys.exit(1) return tups + def generate_enum_content(tuples): - print("# These names at the top are 'corrected' aliases of duplicate values that appear below, which are") + print( + "# These names at the top are 'corrected' aliases of duplicate values that appear below, which are" + ) print("# deprecated but maintained for backwards compatibility.") for k, v in backward_compat.items(): print(k + " = '" + v + "'\n") @@ -40,10 +44,11 @@ def generate_enum_content(tuples): for k, v in additional_events.items(): print(k + " = '" + v + "'\n") + definitions = {} for fp in files: data = json.loads(urlopen(fp).read()) - definitions.update(data.get('definitions')) + definitions.update(data.get("definitions")) tup_list = extract(definitions) tup_list.sort(key=lambda tup: tup[0]) generate_enum_content(tup_list) diff --git a/sdk/eventgrid/azure-eventgrid/tests/_mocks.py b/sdk/eventgrid/azure-eventgrid/tests/_mocks.py index d06c77a30a89..eb4ebc6f19ce 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/_mocks.py +++ b/sdk/eventgrid/azure-eventgrid/tests/_mocks.py @@ -3,35 +3,35 @@ # storage cloud event cloud_storage_dict = { - "id":"a0517898-9fa4-4e70-b4a3-afda1dd68672", - "source":"/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account}", - "data":{ - "api":"PutBlockList", - "client_request_id":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", - "request_id":"831e1650-001e-001b-66ab-eeb76e000000", - "e_tag":"0x8D4BCC2E4835CD0", - "content_type":"application/octet-stream", - "content_length":524288, - "blob_type":"BlockBlob", - "url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", - "sequencer":"00000000000004420000000000028963", - "storage_diagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} + "id": "a0517898-9fa4-4e70-b4a3-afda1dd68672", + "source": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account}", + "data": { + "api": "PutBlockList", + "client_request_id": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", + "request_id": "831e1650-001e-001b-66ab-eeb76e000000", + "e_tag": "0x8D4BCC2E4835CD0", + "content_type": "application/octet-stream", + "content_length": 524288, + "blob_type": "BlockBlob", + "url": "https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", + "sequencer": "00000000000004420000000000028963", + "storage_diagnostics": {"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"}, }, - "type":"Microsoft.Storage.BlobCreated", - "time":"2020-08-07T01:11:49.765846Z", - "specversion":"1.0" + "type": "Microsoft.Storage.BlobCreated", + "time": "2020-08-07T01:11:49.765846Z", + "specversion": "1.0", } cloud_storage_string = json.dumps(cloud_storage_dict) cloud_storage_bytes = cloud_storage_string.encode("utf-8") # custom cloud event cloud_custom_dict = { - "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", - "source":"https://egtest.dev/cloudcustomevent", - "data":{"team": "event grid squad"}, - "type":"Azure.Sdk.Sample", - "time":"2020-08-07T02:06:08.11969Z", - "specversion":"1.0" + "id": "de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "source": "https://egtest.dev/cloudcustomevent", + "data": {"team": "event grid squad"}, + "type": "Azure.Sdk.Sample", + "time": "2020-08-07T02:06:08.11969Z", + "specversion": "1.0", } cloud_custom_string = json.dumps(cloud_custom_dict) cloud_custom_bytes = cloud_custom_string.encode("utf-8") @@ -39,25 +39,25 @@ # storage eg event # spell-checker:ignore swpill eventgridegsub egtopicsamplesub eg_storage_dict = { - "id":"bbab6625-dc56-4b22-abeb-afcc72e5290c", - "subject":"/blobServices/default/containers/oc2d2817345i200097container/blobs/oc2d2817345i20002296blob", - "data":{ - "api":"PutBlockList", - "clientRequestId":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", - "requestId":"831e1650-001e-001b-66ab-eeb76e000000", - "eTag":"0x8D4BCC2E4835CD0", - "contentType":"application/octet-stream", - "contentLength":524288, - "blobType":"BlockBlob", - "url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", - "sequencer":"00000000000004420000000000028963", - "storageDiagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} + "id": "bbab6625-dc56-4b22-abeb-afcc72e5290c", + "subject": "/blobServices/default/containers/oc2d2817345i200097container/blobs/oc2d2817345i20002296blob", + "data": { + "api": "PutBlockList", + "clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", + "requestId": "831e1650-001e-001b-66ab-eeb76e000000", + "eTag": "0x8D4BCC2E4835CD0", + "contentType": "application/octet-stream", + "contentLength": 524288, + "blobType": "BlockBlob", + "url": "https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", + "sequencer": "00000000000004420000000000028963", + "storageDiagnostics": {"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"}, }, - "eventType":"Microsoft.Storage.BlobCreated", - "dataVersion":"2.0", - "metadataVersion":"1", - "eventTime":"2020-08-07T02:28:23.867525Z", - "topic":"/subscriptions/faa080af-c1d8-40ad-9cce-e1a450ca5b57/resourceGroups/t-swpill-test/providers/Microsoft.EventGrid/topics/eventgridegsub" + "eventType": "Microsoft.Storage.BlobCreated", + "dataVersion": "2.0", + "metadataVersion": "1", + "eventTime": "2020-08-07T02:28:23.867525Z", + "topic": "/subscriptions/faa080af-c1d8-40ad-9cce-e1a450ca5b57/resourceGroups/t-swpill-test/providers/Microsoft.EventGrid/topics/eventgridegsub", } eg_storage_string = json.dumps(eg_storage_dict) @@ -65,14 +65,14 @@ # custom eg event eg_custom_dict = { - "id":"3a30afef-b604-4b67-973e-7dfff7e178a7", - "subject":"Test EG Custom Event", - "data":{"team":"event grid squad"}, - "eventType":"Azure.Sdk.Sample", - "dataVersion":"2.0", - "metadataVersion":"1", - "eventTime":"2020-08-07T02:19:05.16916Z", - "topic":"/subscriptions/f8aa80ae-d1c8-60ad-9bce-e1a850ba5b67/resourceGroups/sample-resource-group-test/providers/Microsoft.EventGrid/topics/egtopicsamplesub" + "id": "3a30afef-b604-4b67-973e-7dfff7e178a7", + "subject": "Test EG Custom Event", + "data": {"team": "event grid squad"}, + "eventType": "Azure.Sdk.Sample", + "dataVersion": "2.0", + "metadataVersion": "1", + "eventTime": "2020-08-07T02:19:05.16916Z", + "topic": "/subscriptions/f8aa80ae-d1c8-60ad-9bce-e1a850ba5b67/resourceGroups/sample-resource-group-test/providers/Microsoft.EventGrid/topics/egtopicsamplesub", } eg_custom_string = json.dumps(eg_custom_dict) eg_custom_bytes = eg_custom_string.encode("utf-8") diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index c26a3608ff0b..4f8ea9e61368 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -27,7 +27,11 @@ import sys import pytest from devtools_testutils import test_proxy -from devtools_testutils.sanitizers import add_remove_header_sanitizer, add_general_regex_sanitizer, set_custom_default_matcher +from devtools_testutils.sanitizers import ( + add_remove_header_sanitizer, + add_general_regex_sanitizer, + set_custom_default_matcher, +) # Ignore async tests for Python < 3.5 collect_ignore_glob = [] @@ -35,14 +39,16 @@ collect_ignore_glob.append("*_async.py") collect_ignore_glob.append("test_cncf*") + @pytest.fixture(scope="session", autouse=True) def add_aeg_sanitizer(test_proxy): # this can be reverted to set_bodiless_matcher() after tests are re-recorded and don't contain these headers set_custom_default_matcher( - compare_bodies=False, excluded_headers="Authorization,Content-Length,x-ms-client-request-id,x-ms-request-id" + compare_bodies=False, + excluded_headers="Authorization,Content-Length,x-ms-client-request-id,x-ms-request-id", ) add_remove_header_sanitizer(headers="aeg-sas-key, aeg-sas-token") add_general_regex_sanitizer( value="fakeresource", - regex="(?<=\\/\\/)[a-z-]+(?=\\.westus2-1\\.eventgrid\\.azure\\.net/api/events)" + regex="(?<=\\/\\/)[a-z-]+(?=\\.westus2-1\\.eventgrid\\.azure\\.net/api/events)", ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py index 546442b29b5d..a1236092d58a 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py +++ b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py @@ -1,24 +1,45 @@ import functools from devtools_testutils import PowerShellPreparer -from azure.mgmt.eventgrid.models import Topic, InputSchema, JsonInputSchemaMapping, JsonField, JsonFieldWithDefault +from azure.mgmt.eventgrid.models import ( + Topic, + InputSchema, + JsonInputSchemaMapping, + JsonField, + JsonFieldWithDefault, +) +from azure_devtools.scenario_tests.exceptions import AzureTestError from devtools_testutils.resource_testcase import RESOURCE_GROUP_PARAM -EVENTGRID_TOPIC_PARAM = 'eventgrid_topic' -EVENTGRID_TOPIC_LOCATION = 'westus' +EVENTGRID_TOPIC_PARAM = "eventgrid_topic" +EVENTGRID_TOPIC_LOCATION = "westus" CLOUD_EVENT_SCHEMA = InputSchema.cloud_event_schema_v1_0 CUSTOM_EVENT_SCHEMA = InputSchema.custom_event_schema -ID_JSON_FIELD = JsonField(source_field='customId') -TOPIC_JSON_FIELD = JsonField(source_field='customTopic') -EVENT_TIME_JSON_FIELD = JsonField(source_field='customEventTime') -EVENT_TYPE_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field='customEventType', default_value='') -SUBJECT_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field='customSubject', default_value='') -DATA_VERSION_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field='customDataVersion', default_value='') -CUSTOM_JSON_INPUT_SCHEMA_MAPPING = JsonInputSchemaMapping(id=ID_JSON_FIELD, topic=TOPIC_JSON_FIELD, event_time=EVENT_TIME_JSON_FIELD, event_type=EVENT_TYPE_JSON_FIELD_WITH_DEFAULT, subject=SUBJECT_JSON_FIELD_WITH_DEFAULT, data_version=DATA_VERSION_JSON_FIELD_WITH_DEFAULT) +ID_JSON_FIELD = JsonField(source_field="customId") +TOPIC_JSON_FIELD = JsonField(source_field="customTopic") +EVENT_TIME_JSON_FIELD = JsonField(source_field="customEventTime") +EVENT_TYPE_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( + source_field="customEventType", default_value="" +) +SUBJECT_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( + source_field="customSubject", default_value="" +) +DATA_VERSION_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( + source_field="customDataVersion", default_value="" +) +CUSTOM_JSON_INPUT_SCHEMA_MAPPING = JsonInputSchemaMapping( + id=ID_JSON_FIELD, + topic=TOPIC_JSON_FIELD, + event_time=EVENT_TIME_JSON_FIELD, + event_type=EVENT_TYPE_JSON_FIELD_WITH_DEFAULT, + subject=SUBJECT_JSON_FIELD_WITH_DEFAULT, + data_version=DATA_VERSION_JSON_FIELD_WITH_DEFAULT, +) EventGridPreparer = functools.partial( - PowerShellPreparer, "eventgrid", + PowerShellPreparer, + "eventgrid", eventgrid_topic_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", eventgrid_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", eventgrid_domain_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", diff --git a/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py b/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py index 743046cc1edb..5ad2958c9b8c 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py +++ b/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py @@ -1,17 +1,21 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import asyncio from devtools_testutils.perfstress_tests import PerfStressTest -from azure.eventgrid import EventGridPublisherClient as SyncPublisherClient, EventGridEvent +from azure.eventgrid import ( + EventGridPublisherClient as SyncPublisherClient, + EventGridEvent, +) from azure.eventgrid.aio import EventGridPublisherClient as AsyncPublisherClient from azure.core.credentials import AzureKeyCredential + class EventGridPerfTest(PerfStressTest): def __init__(self, arguments): super().__init__(arguments) @@ -22,28 +26,28 @@ def __init__(self, arguments): # Create clients self.publisher_client = SyncPublisherClient( - endpoint=endpoint, - credential=AzureKeyCredential(topic_key) + endpoint=endpoint, credential=AzureKeyCredential(topic_key) ) self.async_publisher_client = AsyncPublisherClient( - endpoint=endpoint, - credential=AzureKeyCredential(topic_key) + endpoint=endpoint, credential=AzureKeyCredential(topic_key) ) self.event_list = [] for _ in range(self.args.num_events): - self.event_list.append(EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={ - "services": ["EventGrid", "ServiceBus", "EventHubs", "Storage"] - }, - subject="Door1", - data_version="2.0" - )) + self.event_list.append( + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={ + "services": ["EventGrid", "ServiceBus", "EventHubs", "Storage"] + }, + subject="Door1", + data_version="2.0", + ) + ) async def close(self): """This is run after cleanup. - + Use this to close any open handles or clients. """ await self.async_publisher_client.close() @@ -51,7 +55,7 @@ async def close(self): def run_sync(self): """The synchronous perf test. - + Try to keep this minimal and focused. Using only a single client API. Avoid putting any ancillary logic (e.g. generating UUIDs), and put this in the setup/init instead so that we're only measuring the client API call. @@ -60,7 +64,7 @@ def run_sync(self): async def run_async(self): """The asynchronous perf test. - + Try to keep this minimal and focused. Using only a single client API. Avoid putting any ancillary logic (e.g. generating UUIDs), and put this in the setup/init instead so that we're only measuring the client API call. @@ -70,4 +74,11 @@ async def run_async(self): @staticmethod def add_arguments(parser): super(EventGridPerfTest, EventGridPerfTest).add_arguments(parser) - parser.add_argument('-n', '--num-events', nargs='?', type=int, help='Number of events to be sent. Defaults to 100', default=100) + parser.add_argument( + "-n", + "--num-events", + nargs="?", + type=int, + help="Number of events to be sent. Defaults to 100", + default=100, + ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py index 0aad89a0d898..87d08b9fdbc7 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py @@ -1,67 +1,65 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import pytest import json -from azure.core.pipeline import ( - PipelineRequest, - PipelineContext -) +from azure.core.pipeline import PipelineRequest, PipelineContext from azure.core.pipeline.transport import HttpRequest from azure.core.messaging import CloudEvent -from azure.eventgrid._policies import CloudEventDistributedTracingPolicy -from _mocks import ( - cloud_storage_dict -) +from azure.eventgrid._legacy._policies import CloudEventDistributedTracingPolicy +from _mocks import cloud_storage_dict + # spell-checker:disable _content_type = "application/cloudevents-batch+json; charset=utf-8" _traceparent_value = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" _tracestate_value = "rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01,congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4" # spell-chcker:enable -class EventGridSerializationTests(object): +class EventGridSerializationTests(object): def test_cloud_event_policy_copies(self): policy = CloudEventDistributedTracingPolicy() body = json.dumps([cloud_storage_dict]) - universal_request = HttpRequest('POST', 'http://127.0.0.1/', data=body) - universal_request.headers['content-type'] = _content_type - universal_request.headers['traceparent'] = _traceparent_value - universal_request.headers['tracestate'] = _tracestate_value + universal_request = HttpRequest("POST", "http://127.0.0.1/", data=body) + universal_request.headers["content-type"] = _content_type + universal_request.headers["traceparent"] = _traceparent_value + universal_request.headers["tracestate"] = _tracestate_value request = PipelineRequest(universal_request, PipelineContext(None)) resp = policy.on_request(request) body = json.loads(request.http_request.body) - + for item in body: - assert 'traceparent' in item - assert 'tracestate' in item + assert "traceparent" in item + assert "tracestate" in item def test_cloud_event_policy_no_copy_if_trace_exists(self): policy = CloudEventDistributedTracingPolicy() - cloud_storage_dict.update({'traceparent': 'exists', 'tracestate': 'state_exists'}) + cloud_storage_dict.update( + {"traceparent": "exists", "tracestate": "state_exists"} + ) body = json.dumps([cloud_storage_dict]) - universal_request = HttpRequest('POST', 'http://127.0.0.1/', data=body) - universal_request.headers['content-type'] = _content_type - universal_request.headers['traceparent'] = _traceparent_value - universal_request.headers['tracestate'] = _tracestate_value + universal_request = HttpRequest("POST", "http://127.0.0.1/", data=body) + universal_request.headers["content-type"] = _content_type + universal_request.headers["traceparent"] = _traceparent_value + universal_request.headers["tracestate"] = _tracestate_value request = PipelineRequest(universal_request, PipelineContext(None)) resp = policy.on_request(request) body = json.loads(request.http_request.body) - + for item in body: - assert 'traceparent' in item - assert 'tracestate' in item - assert item['traceparent'] == 'exists' - assert item['tracestate'] == 'state_exists' + assert "traceparent" in item + assert "tracestate" in item + assert item["traceparent"] == "exists" + assert item["tracestate"] == "state_exists" diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py index 377838160d01..0319fcf50f6b 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py @@ -1,4 +1,3 @@ - import json from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy @@ -10,10 +9,13 @@ EventGridPreparer, ) + class TestEventGridPublisherClientCncf(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -26,13 +28,14 @@ def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): } data = {"message": "Hello World!"} cloud_event = CloudEvent(attributes, data) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data") is not None assert isinstance(req[0], dict) assert req[0].get("type") == "com.example.sampletype1" assert req[0].get("source") == "https://example.com/event-producer" - + client.send(cloud_event, raw_request_hook=callback) @EventGridPreparer() @@ -43,13 +46,14 @@ def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_top "type": "com.example.sampletype1", "source": "https://example.com/event-producer", } - data = b'hello world' + data = b"hello world" cloud_event = CloudEvent(attributes, data) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data_base64") is not None assert req[0].get("data") is None - + client.send(cloud_event, raw_request_hook=callback) @EventGridPreparer() @@ -73,10 +77,12 @@ def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): "source": "https://example.com/event-producer", } data = "hello world" + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data_base64") is None assert req[0].get("data") is not None + cloud_event = CloudEvent(attributes, data) client.send(cloud_event, raw_request_hook=callback) @@ -99,8 +105,8 @@ def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic attributes = { "type": "com.example.sampletype1", "source": "https://example.com/event-producer", - "ext1": "extension" + "ext1": "extension", } data = "hello world" cloud_event = CloudEvent(attributes, data) - client.send([cloud_event]) \ No newline at end of file + client.send([cloud_event]) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py index c9903da23b2f..4c65b623316d 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py @@ -1,4 +1,3 @@ - import json import pytest from devtools_testutils import AzureRecordedTestCase, CachedResourceGroupPreparer @@ -12,10 +11,13 @@ EventGridPreparer, ) + class TestEventGridPublisherClientCncf(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -29,13 +31,14 @@ async def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endp } data = {"message": "Hello World!"} cloud_event = CloudEvent(attributes, data) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data") is not None assert isinstance(req[0], dict) assert req[0].get("type") == "com.example.sampletype1" assert req[0].get("source") == "https://example.com/event-producer" - + await client.send(cloud_event, raw_request_hook=callback) @EventGridPreparer() @@ -47,13 +50,14 @@ async def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_eve "type": "com.example.sampletype1", "source": "https://example.com/event-producer", } - data = b'hello world' + data = b"hello world" cloud_event = CloudEvent(attributes, data) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data_base64") is not None assert req[0].get("data") is None - + await client.send(cloud_event, raw_request_hook=callback) @EventGridPreparer() @@ -80,11 +84,12 @@ async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpo } data = "hello world" cloud_event = CloudEvent(attributes, data) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data_base64") is None assert req[0].get("data") is not None - + await client.send(cloud_event, raw_request_hook=callback) @EventGridPreparer() @@ -108,7 +113,7 @@ async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event attributes = { "type": "com.example.sampletype1", "source": "https://example.com/event-producer", - "ext1": "extension" + "ext1": "extension", } data = "hello world" cloud_event = CloudEvent(attributes, data) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py new file mode 100644 index 000000000000..7786a955966d --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -0,0 +1,240 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +import os +import time +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError + + +class TestEGClientExceptions: + def create_eg_client(self, endpoint): + eventgrid_key = os.environ["EVENTGRID_KEY"] + client = EventGridClient( + endpoint=endpoint, credential=AzureKeyCredential(eventgrid_key) + ) + return client + + @pytest.mark.live_test_only + def test_publish_cloud_event_bad_request(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source=None, + subject="MySubject", + data={"itemSku": "Contoso Item SKU #1"}, + ) + + with pytest.raises(HttpResponseError): + client.publish_cloud_events(topic_name, [event]) + + @pytest.mark.live_test_only + def test_publish_cloud_event_not_found(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + + client = self.create_eg_client(eventgrid_endpoint) + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source=None, + subject="MySubject", + data={"itemSku": "Contoso Item SKU #1"}, + ) + + with pytest.raises(ResourceNotFoundError): + client.publish_cloud_events("faketopic", [event]) + + @pytest.mark.live_test_only + def test_receive_cloud_event_not_found(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(ResourceNotFoundError): + client.receive_cloud_events("faketopic", event_subscription_name) + + @pytest.mark.live_test_only + def test_receive_cloud_event_max_events_negative(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(HttpResponseError): + client.receive_cloud_events( + topic_name, event_subscription_name, max_events=-20 + ) + + @pytest.mark.live_test_only + def test_receive_cloud_event_timeout_negative(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(HttpResponseError): + client.receive_cloud_events( + topic_name, event_subscription_name, max_wait_time=-20 + ) + + @pytest.mark.live_test_only + def test_receive_cloud_event_timeout_max_value(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(HttpResponseError): + client.receive_cloud_events( + topic_name, event_subscription_name, max_wait_time=121 + ) + + @pytest.mark.live_test_only + def test_receive_cloud_event_timeout_min_value(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(HttpResponseError): + client.receive_cloud_events( + topic_name, event_subscription_name, max_wait_time=9 + ) + + @pytest.mark.live_test_only + def test_acknowledge_cloud_event_not_found(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(ResourceNotFoundError): + lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) + client.acknowledge_cloud_events( + "faketopic", event_subscription_name, lock_tokens=lock_tokens + ) + + @pytest.mark.live_test_only + def test_release_cloud_event_not_found(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + with pytest.raises(ResourceNotFoundError): + lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) + client.release_cloud_events( + "faketopic", event_subscription_name, lock_tokens=lock_tokens + ) + + @pytest.mark.live_test_only + def test_reject_cloud_event_not_found(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + lock_tokens = RejectOptions(lock_tokens=["faketoken"]) + + with pytest.raises(ResourceNotFoundError): + client.reject_cloud_events( + "faketopic", event_subscription_name, lock_tokens=lock_tokens + ) + + @pytest.mark.live_test_only + def test_acknowledge_cloud_event_invalid_token(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) + ack = client.acknowledge_cloud_events( + topic_name, event_subscription_name, lock_tokens=lock_tokens + ) + assert type(ack) == AcknowledgeResult + assert ack.succeeded_lock_tokens == [] + assert type(ack.failed_lock_tokens[0]) == FailedLockToken + assert ack.failed_lock_tokens[0].lock_token == "faketoken" + + @pytest.mark.live_test_only + def test_release_cloud_event_invalid_token(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + + lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) + release = client.release_cloud_events( + topic_name, event_subscription_name, lock_tokens=lock_tokens + ) + assert type(release) == ReleaseResult + assert release.succeeded_lock_tokens == [] + assert type(release.failed_lock_tokens[0]) == FailedLockToken + assert release.failed_lock_tokens[0].lock_token == "faketoken" + + @pytest.mark.live_test_only + def test_reject_cloud_event_invalid_token(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + lock_tokens = RejectOptions(lock_tokens=["faketoken"]) + + reject = client.reject_cloud_events( + topic_name, event_subscription_name, lock_tokens=lock_tokens + ) + assert type(reject) == RejectResult + assert reject.succeeded_lock_tokens == [] + assert type(reject.failed_lock_tokens[0]) == FailedLockToken + assert reject.failed_lock_tokens[0].lock_token == "faketoken" + + @pytest.mark.live_test_only + def test_release_cloud_event_event_delivery_time(self): + eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_name = os.environ["TOPIC_NAME"] + event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] + + client = self.create_eg_client(eventgrid_endpoint) + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="l", + subject="MySubject", + data={"itemSku": "Contoso Item SKU #1"}, + ) + + client.publish_cloud_events(topic_name, event) + time.sleep(10) + + event = client.receive_cloud_events( + topic_name, event_subscription_name, max_events=1 + ) + lock_token = event.value[0].broker_properties.lock_token + lock_tokens = ReleaseOptions(lock_tokens=[lock_token]) + start = time.time() + + client.release_cloud_events( + topic_name, event_subscription_name, lock_tokens=lock_tokens + ) + event_receive_again = client.release_cloud_events( + topic_name, event_subscription_name, lock_tokens=lock_tokens + ) + if time.time() - start <= 1000: + assert event_receive_again.failed_lock_tokens[0].lock_token == lock_token + else: + assert True diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py index 1ae80ecde2c9..4e1910b1bbad 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py @@ -6,9 +6,10 @@ import pytest import uuid from msrest.serialization import UTC -from azure.eventgrid._messaging_shared import _get_json_content +from azure.eventgrid._legacy._messaging_shared import _get_json_content from azure.eventgrid import EventGridEvent + class MockQueueMessage(object): def __init__(self, content=None): self.id = uuid.uuid4() @@ -19,31 +20,33 @@ def __init__(self, content=None): self.pop_receipt = None self.next_visible_on = None + class MockServiceBusReceivedMessage(object): def __init__(self, body=None, **kwargs): - self.body=body - self.application_properties=None - self.session_id=None - self.message_id='3f6c5441-5be5-4f33-80c3-3ffeb6a090ce' - self.content_type='application/cloudevents+json; charset=utf-8' - self.correlation_id=None - self.to=None - self.reply_to=None - self.reply_to_session_id=None - self.subject=None - self.time_to_live=datetime.timedelta(days=14) - self.partition_key=None - self.scheduled_enqueue_time_utc=None - self.auto_renew_error=None, - self.dead_letter_error_description=None - self.dead_letter_reason=None - self.dead_letter_source=None - self.delivery_count=13 - self.enqueued_sequence_number=0 - self.enqueued_time_utc=datetime.datetime(2021, 7, 22, 22, 27, 41, 236000) - self.expires_at_utc=datetime.datetime(2021, 8, 5, 22, 27, 41, 236000) - self.sequence_number=11219 - self.lock_token='233146e3-d5a6-45eb-826f-691d82fb8b13' + self.body = body + self.application_properties = None + self.session_id = None + self.message_id = "3f6c5441-5be5-4f33-80c3-3ffeb6a090ce" + self.content_type = "application/cloudevents+json; charset=utf-8" + self.correlation_id = None + self.to = None + self.reply_to = None + self.reply_to_session_id = None + self.subject = None + self.time_to_live = datetime.timedelta(days=14) + self.partition_key = None + self.scheduled_enqueue_time_utc = None + self.auto_renew_error = (None,) + self.dead_letter_error_description = None + self.dead_letter_reason = None + self.dead_letter_source = None + self.delivery_count = 13 + self.enqueued_sequence_number = 0 + self.enqueued_time_utc = datetime.datetime(2021, 7, 22, 22, 27, 41, 236000) + self.expires_at_utc = datetime.datetime(2021, 8, 5, 22, 27, 41, 236000) + self.sequence_number = 11219 + self.lock_token = "233146e3-d5a6-45eb-826f-691d82fb8b13" + class MockEventhubData(object): def __init__(self, body=None): @@ -53,7 +56,7 @@ def __init__(self, body=None): raise ValueError("EventData cannot be None.") # Internal usage only for transforming AmqpAnnotatedMessage to outgoing EventData - self.body=body + self.body = body self._raw_amqp_message = "some amqp data" self.message_id = None self.content_type = None @@ -66,7 +69,7 @@ def __init__(self, data=None): def __iter__(self): return self - + def __next__(self): if not self.data: return """{"id":"f208feff-099b-4bda-a341-4afd0fa02fef","subject":"https://egsample.dev/sampleevent","data":"ServiceBus","event_type":"Azure.Sdk.Sample","event_time":"2021-07-22T22:27:38.960209Z","data_version":"1.0"}""" @@ -81,14 +84,15 @@ def __init__(self, data=None): def __iter__(self): return self - + def __next__(self): if not self.data: return b'[{"id":"f208feff-099b-4bda-a341-4afd0fa02fef","subject":"https://egsample.dev/sampleevent","data":"Eventhub","event_type":"Azure.Sdk.Sample","event_time":"2021-07-22T22:27:38.960209Z","data_version":"1.0"}]' return self.data - + next = __next__ + def test_get_bytes_storage_queue(): cloud_storage_dict = """{ "id":"a0517898-9fa4-4e70-b4a3-afda1dd68672", @@ -112,117 +116,124 @@ def test_get_bytes_storage_queue(): obj = MockQueueMessage(content=cloud_storage_dict) dict = _get_json_content(obj) - assert dict.get('data') == { - "api":"PutBlockList", - "client_request_id":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", - "request_id":"831e1650-001e-001b-66ab-eeb76e000000", - "e_tag":"0x8D4BCC2E4835CD0", - "content_type":"application/octet-stream", - "content_length":524288, - "blob_type":"BlockBlob", - "url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", - "sequencer":"00000000000004420000000000028963", - "storage_diagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} - } - assert dict.get('data_version') == "1.0" + assert dict.get("data") == { + "api": "PutBlockList", + "client_request_id": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", + "request_id": "831e1650-001e-001b-66ab-eeb76e000000", + "e_tag": "0x8D4BCC2E4835CD0", + "content_type": "application/octet-stream", + "content_length": 524288, + "blob_type": "BlockBlob", + "url": "https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", + "sequencer": "00000000000004420000000000028963", + "storage_diagnostics": {"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"}, + } + assert dict.get("data_version") == "1.0" + def test_get_bytes_storage_queue_wrong_content(): - string = u'This is a random string which must fail' + string = "This is a random string which must fail" obj = MockQueueMessage(content=string) - with pytest.raises(ValueError, match="Failed to load JSON content from the object."): + with pytest.raises( + ValueError, match="Failed to load JSON content from the object." + ): _get_json_content(obj) + def test_get_bytes_servicebus(): obj = MockServiceBusReceivedMessage( body=MockBody(), - message_id='3f6c5441-5be5-4f33-80c3-3ffeb6a090ce', - content_type='application/cloudevents+json; charset=utf-8', + message_id="3f6c5441-5be5-4f33-80c3-3ffeb6a090ce", + content_type="application/cloudevents+json; charset=utf-8", time_to_live=datetime.timedelta(days=14), delivery_count=13, enqueued_sequence_number=0, enqueued_time_utc=datetime.datetime(2021, 7, 22, 22, 27, 41, 236000), expires_at_utc=datetime.datetime(2021, 8, 5, 22, 27, 41, 236000), sequence_number=11219, - lock_token='233146e3-d5a6-45eb-826f-691d82fb8b13' + lock_token="233146e3-d5a6-45eb-826f-691d82fb8b13", ) dict = _get_json_content(obj) - assert dict.get('data') == "ServiceBus" - assert dict.get('data_version') == '1.0' + assert dict.get("data") == "ServiceBus" + assert dict.get("data_version") == "1.0" + def test_get_bytes_servicebus_wrong_content(): obj = MockServiceBusReceivedMessage( - body=MockBody(data='random'), - message_id='3f6c5441-5be5-4f33-80c3-3ffeb6a090ce', - content_type='application/json; charset=utf-8', + body=MockBody(data="random"), + message_id="3f6c5441-5be5-4f33-80c3-3ffeb6a090ce", + content_type="application/json; charset=utf-8", time_to_live=datetime.timedelta(days=14), delivery_count=13, enqueued_sequence_number=0, enqueued_time_utc=datetime.datetime(2021, 7, 22, 22, 27, 41, 236000), expires_at_utc=datetime.datetime(2021, 8, 5, 22, 27, 41, 236000), sequence_number=11219, - lock_token='233146e3-d5a6-45eb-826f-691d82fb8b13' + lock_token="233146e3-d5a6-45eb-826f-691d82fb8b13", ) - with pytest.raises(ValueError, match="Failed to load JSON content from the object."): + with pytest.raises( + ValueError, match="Failed to load JSON content from the object." + ): dict = _get_json_content(obj) def test_get_bytes_eventhubs(): - obj = MockEventhubData( - body=MockEhBody() - ) + obj = MockEventhubData(body=MockEhBody()) dict = _get_json_content(obj) - assert dict.get('data') == 'Eventhub' - assert dict.get('data_version') == '1.0' + assert dict.get("data") == "Eventhub" + assert dict.get("data_version") == "1.0" + def test_get_bytes_eventhubs_wrong_content(): - obj = MockEventhubData( - body=MockEhBody(data='random string') - ) + obj = MockEventhubData(body=MockEhBody(data="random string")) - with pytest.raises(ValueError, match="Failed to load JSON content from the object."): + with pytest.raises( + ValueError, match="Failed to load JSON content from the object." + ): dict = _get_json_content(obj) def test_get_bytes_random_obj(): json_str = '{"id": "de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", "subject": "https://egtest.dev/cloudcustomevent", "data": {"team": "event grid squad"}, "event_type": "Azure.Sdk.Sample", "event_time": "2020-08-07T02:06:08.11969Z", "data_version": "1.0"}' - random_obj = { - "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", - "subject":"https://egtest.dev/cloudcustomevent", - "data":{"team": "event grid squad"}, - "event_type":"Azure.Sdk.Sample", - "event_time":"2020-08-07T02:06:08.11969Z", - "data_version":"1.0", + random_obj = { + "id": "de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "subject": "https://egtest.dev/cloudcustomevent", + "data": {"team": "event grid squad"}, + "event_type": "Azure.Sdk.Sample", + "event_time": "2020-08-07T02:06:08.11969Z", + "data_version": "1.0", } assert _get_json_content(json_str) == random_obj + def test_from_json_sb(): obj = MockServiceBusReceivedMessage( body=MockBody(), - message_id='3f6c5441-5be5-4f33-80c3-3ffeb6a090ce', - content_type='application/cloudevents+json; charset=utf-8', + message_id="3f6c5441-5be5-4f33-80c3-3ffeb6a090ce", + content_type="application/cloudevents+json; charset=utf-8", time_to_live=datetime.timedelta(days=14), delivery_count=13, enqueued_sequence_number=0, enqueued_time_utc=datetime.datetime(2021, 7, 22, 22, 27, 41, 236000), expires_at_utc=datetime.datetime(2021, 8, 5, 22, 27, 41, 236000), sequence_number=11219, - lock_token='233146e3-d5a6-45eb-826f-691d82fb8b13' + lock_token="233146e3-d5a6-45eb-826f-691d82fb8b13", ) event = EventGridEvent.from_json(obj) assert event.id == "f208feff-099b-4bda-a341-4afd0fa02fef" assert event.data == "ServiceBus" + def test_from_json_eh(): - obj = MockEventhubData( - body=MockEhBody() - ) + obj = MockEventhubData(body=MockEhBody()) event = EventGridEvent.from_json(obj) assert event.id == "f208feff-099b-4bda-a341-4afd0fa02fef" assert event.data == "Eventhub" + def test_from_json_storage(): eg_storage_dict = """{ "id":"a0517898-9fa4-4e70-b4a3-afda1dd68672", @@ -246,17 +257,17 @@ def test_from_json_storage(): obj = MockQueueMessage(content=eg_storage_dict) event = EventGridEvent.from_json(obj) assert event.data == { - "api":"PutBlockList", - "client_request_id":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", - "request_id":"831e1650-001e-001b-66ab-eeb76e000000", - "e_tag":"0x8D4BCC2E4835CD0", - "content_type":"application/octet-stream", - "content_length":524288, - "blob_type":"BlockBlob", - "url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", - "sequencer":"00000000000004420000000000028963", - "storage_diagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} - } + "api": "PutBlockList", + "client_request_id": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", + "request_id": "831e1650-001e-001b-66ab-eeb76e000000", + "e_tag": "0x8D4BCC2E4835CD0", + "content_type": "application/octet-stream", + "content_length": 524288, + "blob_type": "BlockBlob", + "url": "https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", + "sequencer": "00000000000004420000000000028963", + "storage_diagnostics": {"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"}, + } def test_from_json(): diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 77ab8fa7a039..60a8837785f4 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -1,8 +1,8 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import logging import sys @@ -19,22 +19,25 @@ except ImportError: from urlparse import urlparse -from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy +from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas -from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from eventgrid_preparer import ( EventGridPreparer, ) + class TestEventGridPublisherClient(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -42,11 +45,11 @@ def create_eg_publisher_client(self, endpoint): def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) client.send(eg_event) @EventGridPreparer() @@ -56,11 +59,11 @@ def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, akc_credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(ValueError): client.send(eg_event) @@ -69,17 +72,17 @@ def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event1 = EventGridEvent( - subject="sample", - data=u"eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data="eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) eg_event2 = EventGridEvent( - subject="sample2", - data=u"eventgridevent2", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample2", + data="eventgridevent2", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) client.send([eg_event1, eg_event2]) @EventGridPreparer() @@ -87,11 +90,11 @@ def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint): def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data=u"eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data="eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) client.send(eg_event) @EventGridPreparer() @@ -99,11 +102,11 @@ def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data=b"eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data=b"eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(TypeError, match="Data in EventGridEvent cannot be bytes*"): client.send(eg_event) @@ -112,12 +115,12 @@ def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { - "subject":"sample", - "data":b"eventgridevent", - "eventType":"Sample.EventGrid.Event", - "dataVersion":"2.0", - "id": uuid.uuid4(), - "eventTime": datetime.now() + "subject": "sample", + "data": b"eventgridevent", + "eventType": "Sample.EventGrid.Event", + "dataVersion": "2.0", + "id": uuid.uuid4(), + "eventTime": datetime.now(), } with pytest.raises(TypeError, match="Data in EventGridEvent cannot be bytes*"): client.send(eg_event) @@ -127,16 +130,15 @@ def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { - "subject":"sample", - "data":{"key1": "Sample.EventGrid.Event"}, - "eventType":"Sample.EventGrid.Event", - "dataVersion":"2.0", - "id": uuid.uuid4(), - "eventTime": datetime.now() + "subject": "sample", + "data": {"key1": "Sample.EventGrid.Event"}, + "eventType": "Sample.EventGrid.Event", + "dataVersion": "2.0", + "id": uuid.uuid4(), + "eventTime": datetime.now(), } client.send(eg_event) - ### CLOUD EVENT TESTS @EventGridPreparer() @@ -144,10 +146,10 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = {"sample": "cloudevent"}, - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) client.send(cloud_event) @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @@ -156,11 +158,9 @@ def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = NULL, - type="Sample.Cloud.Event" - ) - + source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" + ) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data") is None @@ -172,10 +172,10 @@ def callback(request): def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = b'cloudevent', - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data=b"cloudevent", + type="Sample.Cloud.Event", + ) def callback(request): req = json.loads(request.http_request.body) @@ -185,23 +185,23 @@ def callback(request): client.send(cloud_event, raw_response_hook=callback) def test_send_cloud_event_fails_on_providing_data_and_b64(self): - with pytest.raises(ValueError, match="Unexpected keyword arguments data_base64.*"): + with pytest.raises( + ValueError, match="Unexpected keyword arguments data_base64.*" + ): cloud_event = CloudEvent( - source = "http://samplesource.dev", - data_base64 = b'cloudevent', - data = "random data", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data_base64=b"cloudevent", + data="random data", + type="Sample.Cloud.Event", + ) @EventGridPreparer() @recorded_by_proxy def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = None, - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" + ) client.send(cloud_event) @EventGridPreparer() @@ -209,10 +209,10 @@ def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) client.send(cloud_event) @EventGridPreparer() @@ -220,10 +220,10 @@ def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = b"cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data=b"cloudevent", + type="Sample.Cloud.Event", + ) client.send(cloud_event) @EventGridPreparer() @@ -231,10 +231,10 @@ def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint) def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) client.send([cloud_event]) @EventGridPreparer() @@ -242,30 +242,27 @@ def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoin def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event", - extensions={ - 'reasoncode':204, - 'extension':'hello' - } - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + extensions={"reasoncode": 204, "extension": "hello"}, + ) client.send([cloud_event]) internal = _cloud_event_to_generated(cloud_event).serialize() - assert 'reasoncode' in internal - assert 'extension' in internal - assert internal['reasoncode'] == 204 + assert "reasoncode" in internal + assert "extension" in internal + assert internal["reasoncode"] == 204 @EventGridPreparer() @recorded_by_proxy def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { - "id": "1234", - "source": "http://samplesource.dev", - "specversion": "1.0", - "data": "cloudevent", - "type": "Sample.Cloud.Event" + "id": "1234", + "source": "http://samplesource.dev", + "specversion": "1.0", + "data": "cloudevent", + "type": "Sample.Cloud.Event", } client.send(cloud_event1) @@ -273,15 +270,17 @@ def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): @recorded_by_proxy def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_endpoint): expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) - signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) + signature = generate_sas( + eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc + ) credential = AzureSasCredential(signature) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) client.send(eg_event) @EventGridPreparer() @@ -289,19 +288,19 @@ def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_en def test_send_NONE_credential(self, eventgrid_topic_endpoint): with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) - + @EventGridPreparer() @recorded_by_proxy def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { - "customSubject": "sample", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "1234", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" - } + "customSubject": "sample", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "1234", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data", + } client.send(custom_event) @EventGridPreparer() @@ -309,26 +308,29 @@ def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { - "customSubject": "sample", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "1234", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" - } + "customSubject": "sample", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "1234", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data", + } custom_event2 = { - "customSubject": "sample2", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "12345", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data 2" - } + "customSubject": "sample2", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "12345", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data 2", + } client.send([custom_event1, custom_event2]) def test_send_throws_with_bad_credential(self): bad_credential = "I am a bad credential" - with pytest.raises(ValueError, match="The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential"): + with pytest.raises( + ValueError, + match="The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential", + ): client = EventGridPublisherClient("eventgrid_endpoint", bad_credential) @pytest.mark.live_test_only @@ -338,11 +340,11 @@ def test_send_token_credential(self, eventgrid_topic_endpoint): credential = self.get_credential(EventGridPublisherClient) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) client.send(eg_event) @pytest.mark.live_test_only @@ -353,11 +355,11 @@ def test_send_partner_namespace(self): credential = AzureKeyCredential(eventgrid_partner_namespace_key) client = EventGridPublisherClient(eventgrid_partner_namespace_endpoint, credential) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) - + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) + def callback(request): req = request.http_request.headers assert req.get("aeg-channel-name") == channel_name diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index ec225dfea98c..f00c9af4f0b0 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -1,8 +1,8 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import logging import asyncio @@ -23,17 +23,17 @@ from azure.core.serialization import NULL from azure.eventgrid import EventGridEvent, generate_sas from azure.eventgrid.aio import EventGridPublisherClient -from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid._legacy._helpers import _cloud_event_to_generated -from eventgrid_preparer import ( - EventGridPreparer -) +from eventgrid_preparer import EventGridPreparer class TestEventGridPublisherClient(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -42,31 +42,30 @@ def create_eg_publisher_client(self, endpoint): async def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) await client.send(eg_event) - @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio async def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event1 = EventGridEvent( - subject="sample", - data="eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data="eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) eg_event2 = EventGridEvent( - subject="sample2", - data="eventgridevent2", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample2", + data="eventgridevent2", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) await client.send([eg_event1, eg_event2]) @EventGridPreparer() @@ -77,11 +76,11 @@ async def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topi parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, akc_credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(ValueError): await client.send(eg_event) @@ -91,11 +90,11 @@ async def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topi async def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data="eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data="eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) await client.send(eg_event) @EventGridPreparer() @@ -104,11 +103,11 @@ async def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): async def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( - subject="sample", - data=b"eventgridevent", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data=b"eventgridevent", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(TypeError, match="Data in EventGridEvent cannot be bytes*"): await client.send(eg_event) @@ -118,12 +117,12 @@ async def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { - "subject":"sample", - "data":b"eventgridevent", - "eventType":"Sample.EventGrid.Event", - "dataVersion":"2.0", - "id": "123-ddf-133-324255ffd", - "eventTime": dt.datetime.utcnow() + "subject": "sample", + "data": b"eventgridevent", + "eventType": "Sample.EventGrid.Event", + "dataVersion": "2.0", + "id": "123-ddf-133-324255ffd", + "eventTime": dt.datetime.utcnow(), } with pytest.raises(TypeError, match="Data in EventGridEvent cannot be bytes*"): await client.send(eg_event) @@ -159,10 +158,10 @@ async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpo async def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = b"cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) await client.send(cloud_event) @EventGridPreparer() @@ -171,12 +170,25 @@ async def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_end async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) - await client.send([cloud_event]) + source="http://samplesource.dev", + data=b"cloudevent", + type="Sample.Cloud.Event", + ) + await client.send(cloud_event) + @EventGridPreparer() + @recorded_by_proxy_async + @pytest.mark.asyncio + async def test_send_cloud_event_data_as_list( + self, variables, eventgrid_cloud_event_topic_endpoint + ): + client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) + await client.send([cloud_event]) @EventGridPreparer() @recorded_by_proxy_async @@ -184,20 +196,16 @@ async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_e async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event", - extensions={ - 'reasoncode':204, - 'extension':'hello' - } - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + extensions={"reasoncode": 204, "extension": "hello"}, + ) await client.send([cloud_event]) internal = _cloud_event_to_generated(cloud_event).serialize() - assert 'reasoncode' in internal - assert 'extension' in internal - assert internal['reasoncode'] == 204 - + assert "reasoncode" in internal + assert "extension" in internal + assert internal["reasoncode"] == 204 @EventGridPreparer() @recorded_by_proxy_async @@ -205,11 +213,11 @@ async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { - "id": "1234", - "source": "http://samplesource.dev", - "specversion": "1.0", - "data": "cloudevent", - "type": "Sample.Cloud.Event" + "id": "1234", + "source": "http://samplesource.dev", + "specversion": "1.0", + "data": "cloudevent", + "type": "Sample.Cloud.Event", } await client.send(cloud_event1) @@ -219,10 +227,8 @@ async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint) async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = None, - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" + ) await client.send(cloud_event) @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @@ -232,10 +238,9 @@ async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endp async def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = NULL, - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" + ) + def callback(request): req = json.loads(request.http_request.body) assert req[0].get("data") is None @@ -247,55 +252,55 @@ def callback(request): @pytest.mark.asyncio async def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_endpoint): expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) - signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) + signature = generate_sas( + eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc + ) credential = AzureSasCredential(signature) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) await client.send(eg_event) - @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio async def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { - "customSubject": "sample", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "1234", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" - } + "customSubject": "sample", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "1234", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data", + } await client.send(custom_event) - @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio async def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { - "customSubject": "sample", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "1234", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" - } + "customSubject": "sample", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "1234", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data", + } custom_event2 = { - "customSubject": "sample2", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": "12345", - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data 2" - } + "customSubject": "sample2", + "customEventType": "sample.event", + "customDataVersion": "2.0", + "customId": "12345", + "customEventTime": dt.datetime.now(UTC()).isoformat(), + "customData": "sample data 2", + } await client.send([custom_event1, custom_event2]) @EventGridPreparer() @@ -303,12 +308,12 @@ async def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_top @pytest.mark.asyncio async def test_send_and_close_async_session(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - async with client: # this throws if client can't close + async with client: # this throws if client can't close cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) await client.send(cloud_event) @pytest.mark.skip() @@ -326,11 +331,11 @@ async def test_send_token_credential(self, eventgrid_topic_endpoint): credential = self.get_credential(EventGridPublisherClient) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) await client.send(eg_event) @pytest.mark.live_test_only @@ -341,12 +346,15 @@ async def test_send_partner_namespace(self): credential = AzureKeyCredential(eventgrid_partner_namespace_key) client = EventGridPublisherClient(eventgrid_partner_namespace_endpoint, credential) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) + def callback(request): req = request.http_request.headers assert req.get("aeg-channel-name") == channel_name - await client.send(cloud_event, channel_name=channel_name, raw_request_hook=callback) + await client.send( + cloud_event, channel_name=channel_name, raw_request_hook=callback + ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index d3bdf37efe72..49effd2ccf06 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -1,8 +1,8 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import logging import sys @@ -14,7 +14,7 @@ from azure.core.exceptions import ( HttpResponseError, ClientAuthenticationError, - ServiceRequestError + ServiceRequestError, ) from msrest.serialization import UTC import datetime as dt @@ -30,16 +30,19 @@ from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas -from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from eventgrid_preparer import ( EventGridPreparer, ) + class TestEventGridPublisherClientExceptions(AzureMgmtRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -48,12 +51,15 @@ def test_raise_on_auth_error(self, eventgrid_topic_endpoint): akc_credential = AzureKeyCredential("bad credential") client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) - with pytest.raises(ClientAuthenticationError, match="The request authorization key is not authorized for*"): + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) + with pytest.raises( + ClientAuthenticationError, + match="The request authorization key is not authorized for*", + ): client.send(eg_event) @pytest.mark.skip("Fix during MQ - skip to unblock pipeline") @@ -61,13 +67,16 @@ def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @EventGridPreparer() def test_raise_on_bad_resource(self, eventgrid_topic_key): akc_credential = AzureKeyCredential(eventgrid_topic_key) - client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) + client = EventGridPublisherClient( + "https://bad-resource.westus-1.eventgrid.azure.net/api/events", + akc_credential, + ) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(HttpResponseError): client.send(eg_event) @@ -76,15 +85,17 @@ def test_raise_on_bad_resource(self, eventgrid_topic_key): def test_raise_on_large_payload(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) - path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./large_data.json")) + path = os.path.abspath( + os.path.join(os.path.abspath(__file__), "..", "./large_data.json") + ) with open(path) as json_file: data = json.load(json_file) eg_event = EventGridEvent( - subject="sample", - data=data, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data=data, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(HttpResponseError) as err: client.send(eg_event) assert "The maximum size (1536000) has been exceeded." in err.value.message diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index 339ed7bda1f0..0c26df470fcb 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -1,8 +1,8 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import logging import sys @@ -11,7 +11,11 @@ import pytest import uuid from datetime import datetime, timedelta -from azure.core.exceptions import HttpResponseError, ClientAuthenticationError, ServiceRequestError +from azure.core.exceptions import ( + HttpResponseError, + ClientAuthenticationError, + ServiceRequestError, +) from msrest.serialization import UTC import datetime as dt @@ -28,16 +32,19 @@ from azure.core.serialization import NULL from azure.eventgrid import EventGridEvent, generate_sas from azure.eventgrid.aio import EventGridPublisherClient -from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from eventgrid_preparer import ( EventGridPreparer, ) + class TestEventGridPublisherClientExceptionsAsync(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint + ) return client @EventGridPreparer() @@ -47,12 +54,15 @@ async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): akc_credential = AzureKeyCredential("bad credential") client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) - with pytest.raises(ClientAuthenticationError, match="The request authorization key is not authorized for*"): + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) + with pytest.raises( + ClientAuthenticationError, + match="The request authorization key is not authorized for*", + ): await client.send(eg_event) @pytest.mark.skip("Fix during MQ - skip to unblock pipeline") @@ -61,13 +71,16 @@ async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.asyncio async def test_raise_on_bad_resource(self, eventgrid_topic_key): akc_credential = AzureKeyCredential(eventgrid_topic_key) - client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) + client = EventGridPublisherClient( + "https://bad-resource.westus-1.eventgrid.azure.net/api/events", + akc_credential, + ) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(HttpResponseError): await client.send(eg_event) @@ -77,15 +90,17 @@ async def test_raise_on_bad_resource(self, eventgrid_topic_key): async def test_raise_on_large_payload(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) - path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./large_data.json")) + path = os.path.abspath( + os.path.join(os.path.abspath(__file__), "..", "./large_data.json") + ) with open(path) as json_file: data = json.load(json_file) eg_event = EventGridEvent( - subject="sample", - data=data, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + data=data, + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) with pytest.raises(HttpResponseError) as err: await client.send(eg_event) assert "The maximum size (1536000) has been exceeded." in err.value.message diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py index 6c7fc1d79913..e40e9c93e874 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py @@ -1,8 +1,8 @@ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import sys import pytest @@ -15,96 +15,99 @@ cloud_storage_dict, cloud_storage_string, cloud_storage_bytes, - ) +) + class EventGridSerializationTests: def _assert_cloud_event_serialized(self, expected, actual): - assert expected['source'] == actual['source'] - assert expected['type'] == actual['type'] - assert actual['specversion'] == '1.0' - assert 'id' in actual - assert 'time' in actual + assert expected["source"] == actual["source"] + assert expected["type"] == actual["type"] + assert actual["specversion"] == "1.0" + assert "id" in actual + assert "time" in actual # Cloud Event tests def test_cloud_event_serialization_extension_bytes(self, **kwargs): data = b"cloudevent" cloud_event = CloudEvent( - source="http://samplesource.dev", - data=data, - type="Sample.Cloud.Event", - extensions={'e1':1, 'e2':2} - ) - - cloud_event.subject = "subject" # to test explicit setting of prop - encoded = base64.b64encode(data).decode('utf-8') + source="http://samplesource.dev", + data=data, + type="Sample.Cloud.Event", + extensions={"e1": 1, "e2": 2}, + ) + + cloud_event.subject = "subject" # to test explicit setting of prop + encoded = base64.b64encode(data).decode("utf-8") internal = _cloud_event_to_generated(cloud_event) assert internal.additional_properties is not None - assert 'e1' in internal.additional_properties + assert "e1" in internal.additional_properties - json = internal.serialize() + json = internal.serialize() expected = { - 'source':'http://samplesource.dev', - 'data_base64': encoded, - 'type':'Sample.Cloud.Event', - 'reason_code':204, - 'e1':1, - 'e2':2 + "source": "http://samplesource.dev", + "data_base64": encoded, + "type": "Sample.Cloud.Event", + "reason_code": 204, + "e1": 1, + "e2": 2, } self._assert_cloud_event_serialized(expected, json) - assert expected['data_base64'] == json['data_base64'] - + assert expected["data_base64"] == json["data_base64"] def test_cloud_event_serialization_extension_string(self, **kwargs): data = "cloudevent" cloud_event = CloudEvent( - source="http://samplesource.dev", - data=data, - type="Sample.Cloud.Event", - extensions={'e1':1, 'e2':2} - ) - - cloud_event.subject = "subject" # to test explicit setting of prop + source="http://samplesource.dev", + data=data, + type="Sample.Cloud.Event", + extensions={"e1": 1, "e2": 2}, + ) + + cloud_event.subject = "subject" # to test explicit setting of prop internal = _cloud_event_to_generated(cloud_event) assert internal.additional_properties is not None - assert 'e1' in internal.additional_properties + assert "e1" in internal.additional_properties - json = internal.serialize() + json = internal.serialize() expected = { - 'source':'http://samplesource.dev', - 'data': data, - 'type':'Sample.Cloud.Event', - 'reason_code':204, - 'e1':1, - 'e2':2 + "source": "http://samplesource.dev", + "data": data, + "type": "Sample.Cloud.Event", + "reason_code": 204, + "e1": 1, + "e2": 2, } self._assert_cloud_event_serialized(expected, json) if sys.version_info > (3, 5): - assert expected['data'] == json['data'] + assert expected["data"] == json["data"] else: - encoded = base64.b64encode(data).decode('utf-8') - expected['data_base64'] = encoded - assert expected['data_base64'] == json['data_base64'] - assert 'data' not in json + encoded = base64.b64encode(data).decode("utf-8") + expected["data_base64"] = encoded + assert expected["data_base64"] == json["data_base64"] + assert "data" not in json def test_event_grid_event_raises_on_no_data(self): with pytest.raises(TypeError): eg_event = EventGridEvent( - subject="sample", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) def test_import_from_system_events(self): - var = SystemEventNames.AcsChatMemberAddedToThreadWithUserEventName + var = SystemEventNames.AcsChatMemberAddedToThreadWithUserEventName assert var == "Microsoft.Communication.ChatMemberAddedToThreadWithUser" - assert SystemEventNames.KeyVaultKeyNearExpiryEventName == "Microsoft.KeyVault.KeyNearExpiry" + assert ( + SystemEventNames.KeyVaultKeyNearExpiryEventName + == "Microsoft.KeyVault.KeyNearExpiry" + ) var = SystemEventNames.ServiceBusActiveMessagesAvailableWithNoListenersEventName assert var == "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners" var = SystemEventNames.AcsChatThreadParticipantAddedEventName @@ -114,20 +117,37 @@ def test_import_from_system_events(self): def test_eg_event_repr(self): event = EventGridEvent( - subject="sample2", - data="eventgridevent2", - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) - + subject="sample2", + data="eventgridevent2", + event_type="Sample.EventGrid.Event", + data_version="2.0", + ) + assert "EventGridEvent(subject=sample2" in event.__repr__() def test_servicebus_system_events_alias(self): val = "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners" - assert SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName - assert SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName == val - assert SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName == val - assert SystemEventNames(val) == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName - assert SystemEventNames(val) == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName + assert ( + SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName + == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName + ) + assert ( + SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName + == val + ) + assert ( + SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName + == val + ) + assert ( + SystemEventNames(val) + == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName + ) + assert ( + SystemEventNames(val) + == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName + ) with pytest.raises(ValueError): - SystemEventNames("Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener") + SystemEventNames( + "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener" + ) diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml new file mode 100644 index 000000000000..adaa6c9354c8 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -0,0 +1,4 @@ +cleanup: false +commit: c07d9898ed901330e5ac4996b1bc641adac2e6fd +directory: specification/eventgrid/Azure.Messaging.EventGrid +repo: Azure/azure-rest-api-specs \ No newline at end of file From 0cf20d1a40f178c5ab1f2332841341a9fd31ccc3 Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Mon, 22 May 2023 07:34:03 -0700 Subject: [PATCH 02/43] link to samples --- sdk/eventgrid/azure-eventgrid/samples/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/eventgrid/azure-eventgrid/samples/README.md b/sdk/eventgrid/azure-eventgrid/samples/README.md index 47e05c588b2a..fff007e9966e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/README.md +++ b/sdk/eventgrid/azure-eventgrid/samples/README.md @@ -29,6 +29,8 @@ To publish events, dict representation of the models could also be used as follo * Consume a Custom Payload of raw cloudevent data: [sample_consume_custom_payload.py][python-eg-sample-consume-custom-payload] +EventGridClient operation samples: [EventGridClient samples][python-eg-client-sync-samples] + ## Async samples These code samples show common champion scenario operations with the Azure Event Grid client library using the async client. @@ -44,6 +46,8 @@ To publish events, dict representation of the models could also be used as follo * Publish EventGridEvent as dict like representation: [sample_publish_eg_event_using_dict_async.py][python-eg-sample-send-eg-as-dict-async] * Publish CloudEvent as dict like representation: [sample_publish_cloud_event_using_dict_async.py][python-eg-sample-send-cloudevent-as-dict-async] +EventGridClient operation samples: [EventGridClient samples][python-eg-client-async-samples] + ## More Samples * More samples related to the send scenario can be seen [here][python-eg-publish-samples]. From 9f2feda9e73260ad687df655cb9ac610dc1f9dce Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Mon, 22 May 2023 07:46:03 -0700 Subject: [PATCH 03/43] remove comment --- .../azure-eventgrid/azure/eventgrid/_operations/_patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 93482173865e..611a4e815c5f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -20,7 +20,7 @@ def _cloud_event_to_generated(cloud_event, **kwargs): if isinstance(cloud_event.data, bytes): data_kwargs["data_base64"] = base64.b64encode( cloud_event.data - ) # base64 encode double check + ) else: data_kwargs["data"] = cloud_event.data From 626393c69d85acda160066276950187bcbeb1324 Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Mon, 22 May 2023 09:05:37 -0700 Subject: [PATCH 04/43] remove uneeded test --- .../tests/test_eg_client_exceptions.py | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index 7786a955966d..e385f206653e 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -203,38 +203,3 @@ def test_reject_cloud_event_invalid_token(self): assert reject.succeeded_lock_tokens == [] assert type(reject.failed_lock_tokens[0]) == FailedLockToken assert reject.failed_lock_tokens[0].lock_token == "faketoken" - - @pytest.mark.live_test_only - def test_release_cloud_event_event_delivery_time(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="l", - subject="MySubject", - data={"itemSku": "Contoso Item SKU #1"}, - ) - - client.publish_cloud_events(topic_name, event) - time.sleep(10) - - event = client.receive_cloud_events( - topic_name, event_subscription_name, max_events=1 - ) - lock_token = event.value[0].broker_properties.lock_token - lock_tokens = ReleaseOptions(lock_tokens=[lock_token]) - start = time.time() - - client.release_cloud_events( - topic_name, event_subscription_name, lock_tokens=lock_tokens - ) - event_receive_again = client.release_cloud_events( - topic_name, event_subscription_name, lock_tokens=lock_tokens - ) - if time.time() - start <= 1000: - assert event_receive_again.failed_lock_tokens[0].lock_token == lock_token - else: - assert True From 0d92b59ca499e39e9bfe1f032688c5070e8934d5 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 22 May 2023 09:50:27 -0700 Subject: [PATCH 05/43] [EGv2] doc updates (#30483) * doc updates * doc update * doc --- .../azure/eventgrid/_operations/_patch.py | 29 ++++++++++++++----- .../azure/eventgrid/aio/_operations/_patch.py | 29 ++++++++++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 611a4e815c5f..dc841427df53 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -51,7 +51,12 @@ def publish_cloud_events( content_type: str = "application/cloudevents-batch+json; charset=utf-8", **kwargs: Any ) -> None: - """Publish Batch of Cloud Events to namespace topic. + """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str :param body: Array of Cloud Events being published. Required. @@ -62,7 +67,7 @@ def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ @@ -75,7 +80,12 @@ def publish_cloud_events( content_type: str = "application/cloudevents+json; charset=utf-8", **kwargs: Any ) -> None: - """Publish Single Cloud Event to namespace topic. + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str :param body: Single Cloud Event being published. Required. @@ -86,7 +96,7 @@ def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ @@ -94,10 +104,15 @@ def publish_cloud_events( def publish_cloud_events( self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs ) -> None: - """Publish Cloud Events to namespace topic. + """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str - :param body: Single Cloud Event or list of Cloud Events being published. Required. + :param body: Cloud Event or array of Cloud Events being published. Required. :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". @@ -105,7 +120,7 @@ def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 7a864a599c65..4b940f11020d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -23,7 +23,12 @@ async def publish_cloud_events( content_type: str = "application/cloudevents-batch+json; charset=utf-8", **kwargs: Any ) -> None: - """Publish Batch of Cloud Events to namespace topic. + """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str :param body: Array of Cloud Events being published. Required. @@ -34,7 +39,7 @@ async def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ @@ -47,7 +52,12 @@ async def publish_cloud_events( content_type: str = "application/cloudevents+json; charset=utf-8", **kwargs: Any ) -> None: - """Publish Single Cloud Event to namespace topic. + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str :param body: Single Cloud Event being published. Required. @@ -58,7 +68,7 @@ async def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ @@ -66,10 +76,15 @@ async def publish_cloud_events( async def publish_cloud_events( self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs ) -> None: - """Publish Cloud Events to namespace topic. + """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. :type topic_name: str - :param body: Single Cloud Event or list of Cloud Events being published. Required. + :param body: Cloud Event or Array of Cloud Events being published. Required. :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". @@ -77,7 +92,7 @@ async def publish_cloud_events( :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. :return: None - :rtype: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ if isinstance(body, CloudEvent): From 4487000dd3a880f61f03a3a154356d81d0d3aa05 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 23 May 2023 14:50:17 -0700 Subject: [PATCH 06/43] [EGv2] Eg typing/formatting (#30492) * mypy pylint * update samples * remove version disclaimer --- .../eventgrid/_operations/_operations.py | 19 ++----------------- .../eventgrid/aio/_operations/_operations.py | 4 ++-- .../sample_acknowledge_operation_async.py | 2 +- .../sample_all_operations_async.py | 5 +++-- .../sample_publish_operation_async.py | 2 +- .../sample_receive_operation_async.py | 2 +- .../sample_reject_operation_async.py | 2 +- .../sample_release_operation_async.py | 2 +- 8 files changed, 12 insertions(+), 26 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 71a965588424..63e9753a018b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -29,8 +29,6 @@ def build_event_grid_publish_cloud_event_request( topic_name: str, - *, - content: _models._models.CloudEvent, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -57,15 +55,12 @@ def build_event_grid_publish_cloud_event_request( url=_url, params=_params, headers=_headers, - content=content, **kwargs ) def build_event_grid_publish_cloud_events_request( topic_name: str, - *, - content: List[_models._models.CloudEvent], **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -92,7 +87,6 @@ def build_event_grid_publish_cloud_events_request( url=_url, params=_params, headers=_headers, - content=content, **kwargs ) @@ -142,8 +136,6 @@ def build_event_grid_receive_cloud_events_request( def build_event_grid_acknowledge_cloud_events_request( topic_name: str, event_subscription_name: str, - *, - content: _models.AcknowledgeOptions, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -174,7 +166,6 @@ def build_event_grid_acknowledge_cloud_events_request( url=_url, params=_params, headers=_headers, - content=content, **kwargs ) @@ -182,8 +173,6 @@ def build_event_grid_acknowledge_cloud_events_request( def build_event_grid_release_cloud_events_request( topic_name: str, event_subscription_name: str, - *, - content: _models.ReleaseOptions, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -214,7 +203,6 @@ def build_event_grid_release_cloud_events_request( url=_url, params=_params, headers=_headers, - content=content, **kwargs ) @@ -222,8 +210,6 @@ def build_event_grid_release_cloud_events_request( def build_event_grid_reject_cloud_events_request( topic_name: str, event_subscription_name: str, - *, - content: _models.RejectOptions, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -254,14 +240,13 @@ def build_event_grid_reject_cloud_events_request( url=_url, params=_params, headers=_headers, - content=content, **kwargs ) class EventGridClientOperationsMixin(EventGridClientMixinABC): @distributed_trace - def _publish_cloud_event( # pylint: disable=inconsistent-return-statements + def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,protected-access self, topic_name: str, event: _models._models.CloudEvent, @@ -405,7 +390,7 @@ def _publish_cloud_events( # pylint: disable=inconsistent-return-statements @distributed_trace - def _receive_cloud_events( + def _receive_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index deb44505d8a2..9a15d090bd8b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -26,7 +26,7 @@ class EventGridClientOperationsMixin(EventGridClientMixinABC): @distributed_trace_async - async def _publish_cloud_event( # pylint: disable=inconsistent-return-statements + async def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,protected-access self, topic_name: str, event: _models._models.CloudEvent, @@ -170,7 +170,7 @@ async def _publish_cloud_events( # pylint: disable=inconsistent-return-statemen @distributed_trace_async - async def _receive_cloud_events( + async def _receive_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py index 79d2d4f9631e..d858b811d1f9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -35,4 +35,4 @@ async def run(): if __name__ == "__main__": - asyncio.run(run()) + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index 47d1615d7656..61d089485bf4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -32,7 +32,7 @@ ) -async def main(): +async def run(): async with client: # Publish a CloudEvent try: @@ -123,4 +123,5 @@ async def main(): print(f"Succeeded Lock Token:{succeeded_lock_token}") -asyncio.run(main()) +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py index 21966b77dc55..c8b321fd7f12 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -43,4 +43,4 @@ async def run(): if __name__ == "__main__": - asyncio.run(run()) + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py index 0d0a94876bfe..b483a2f0abed 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -35,4 +35,4 @@ async def run(): if __name__ == "__main__": - asyncio.run(run()) + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py index c9de1fbd4817..d493e9055736 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -35,4 +35,4 @@ async def run(): if __name__ == "__main__": - asyncio.run(run()) + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index eb423e2f5827..df57e7474b61 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -35,4 +35,4 @@ async def run(): if __name__ == "__main__": - asyncio.run(run()) + asyncio.get_event_loop().run_until_complete(run()) From 66cb39d9abf8a9220d9998a63cd8dfa42e9bea1f Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 25 Aug 2023 08:45:08 -0700 Subject: [PATCH 07/43] Beta LiveTests (#30728) * add bicep file for tests * update output * update test * secret sanitization * refactor failing test * update conftest * update assets and sanitizers * update preparer loc * update conftest * conftest * update conftest * remove variables for now * update assets * update tests * try to update regex * update recordings * update conftest * update preparer * update test * update exception test * update tests * update asset * update conftest * pr comments * default needs to be eastus * import --- sdk/eventgrid/azure-eventgrid/assets.json | 2 +- .../azure-eventgrid/tests/conftest.py | 44 +++-- .../tests/eventgrid_preparer.py | 26 +-- .../azure-eventgrid/tests/test_cncf_events.py | 24 ++- .../tests/test_cncf_events_async.py | 24 ++- .../azure-eventgrid/tests/test_eg_client.py | 78 ++++++++ .../tests/test_eg_client_exceptions.py | 170 ++++++++---------- .../tests/test_eg_publisher_client.py | 77 +++++--- .../tests/test_eg_publisher_client_async.py | 95 +++++++--- .../azure-eventgrid/tests/test_exceptions.py | 18 +- .../tests/test_exceptions_async.py | 6 +- sdk/eventgrid/test-resources.json | 83 +++++++++ 12 files changed, 445 insertions(+), 202 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py diff --git a/sdk/eventgrid/azure-eventgrid/assets.json b/sdk/eventgrid/azure-eventgrid/assets.json index 884eb4ab595a..a00be8330ac3 100644 --- a/sdk/eventgrid/azure-eventgrid/assets.json +++ b/sdk/eventgrid/azure-eventgrid/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/eventgrid/azure-eventgrid", - "Tag": "python/eventgrid/azure-eventgrid_d176c3a3b4" + "Tag": "python/eventgrid/azure-eventgrid_6f56978914" } diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index 4f8ea9e61368..c69c75af758e 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -23,32 +23,50 @@ # IN THE SOFTWARE. # # -------------------------------------------------------------------------- -import platform -import sys +import os import pytest -from devtools_testutils import test_proxy +from urllib.parse import urlparse +from devtools_testutils import add_general_string_sanitizer, test_proxy, add_body_key_sanitizer, add_header_regex_sanitizer, add_oauth_response_sanitizer, add_body_regex_sanitizer from devtools_testutils.sanitizers import ( add_remove_header_sanitizer, add_general_regex_sanitizer, set_custom_default_matcher, ) -# Ignore async tests for Python < 3.5 -collect_ignore_glob = [] -if sys.version_info < (3, 5): - collect_ignore_glob.append("*_async.py") - collect_ignore_glob.append("test_cncf*") - - @pytest.fixture(scope="session", autouse=True) -def add_aeg_sanitizer(test_proxy): +def add_sanitizers(test_proxy): # this can be reverted to set_bodiless_matcher() after tests are re-recorded and don't contain these headers set_custom_default_matcher( compare_bodies=False, excluded_headers="Authorization,Content-Length,x-ms-client-request-id,x-ms-request-id", ) - add_remove_header_sanitizer(headers="aeg-sas-key, aeg-sas-token") + add_remove_header_sanitizer(headers="aeg-sas-key, aeg-sas-token, aeg-channel-name") add_general_regex_sanitizer( value="fakeresource", - regex="(?<=\\/\\/)[a-z-]+(?=\\.westus2-1\\.eventgrid\\.azure\\.net/api/events)", + regex="(?<=\\/\\/)[.*]+(?=\\.eastus-1\\.eventgrid\\.azure\\.net/api/events)", ) + + add_oauth_response_sanitizer() + add_header_regex_sanitizer(key="Set-Cookie", value="[set-cookie;]") + add_header_regex_sanitizer(key="Cookie", value="cookie;") + + add_body_key_sanitizer(json_path="$..id", value="id") + + client_id = os.getenv("AZURE_CLIENT_ID", "sanitized") + client_secret = os.getenv("AZURE_CLIENT_SECRET", "sanitized") + eventgrid_client_id = os.getenv("EVENTGRID_CLIENT_ID", "sanitized") + eventgrid_client_secret = os.getenv("EVENTGRID_CLIENT_SECRET", "sanitized") + tenant_id = os.getenv("AZURE_TENANT_ID", "sanitized") + eventgrid_topic_endpoint = os.getenv("EVENTGRID_TOPIC_ENDPOINT", "sanitized") + # Need to santize namespace for eventgrid_topic: + try: + eventgrid_hostname = urlparse(eventgrid_topic_endpoint).hostname + add_general_string_sanitizer(target=eventgrid_hostname.upper(), value="sanitized.eastus-1.eventgrid.azure.net") + except: + pass + add_general_string_sanitizer(target=client_id, value="00000000-0000-0000-0000-000000000000") + add_general_string_sanitizer(target=client_secret, value="sanitized") + add_general_string_sanitizer(target=eventgrid_client_id, value="00000000-0000-0000-0000-000000000000") + add_general_string_sanitizer(target=eventgrid_client_secret, value="sanitized") + add_general_string_sanitizer(target=tenant_id, value="00000000-0000-0000-0000-000000000000") + diff --git a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py index a1236092d58a..1343179da503 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py +++ b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py @@ -1,5 +1,5 @@ import functools -from devtools_testutils import PowerShellPreparer +from devtools_testutils import PowerShellPreparer, EnvironmentVariableLoader from azure.mgmt.eventgrid.models import ( Topic, @@ -8,12 +8,9 @@ JsonField, JsonFieldWithDefault, ) -from azure_devtools.scenario_tests.exceptions import AzureTestError - -from devtools_testutils.resource_testcase import RESOURCE_GROUP_PARAM EVENTGRID_TOPIC_PARAM = "eventgrid_topic" -EVENTGRID_TOPIC_LOCATION = "westus" +EVENTGRID_TOPIC_LOCATION = "eastus" CLOUD_EVENT_SCHEMA = InputSchema.cloud_event_schema_v1_0 CUSTOM_EVENT_SCHEMA = InputSchema.custom_event_schema ID_JSON_FIELD = JsonField(source_field="customId") @@ -40,14 +37,21 @@ EventGridPreparer = functools.partial( PowerShellPreparer, "eventgrid", - eventgrid_topic_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", + eventgrid_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", - eventgrid_domain_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", + eventgrid_domain_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_domain_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", - eventgrid_cloud_event_topic_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", + eventgrid_cloud_event_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_cloud_event_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", - eventgrid_cloud_event_domain_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", + eventgrid_cloud_event_domain_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_cloud_event_domain_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", - eventgrid_custom_event_topic_endpoint="https://fakeresource.westus2-1.eventgrid.azure.net/api/events", + eventgrid_custom_event_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_custom_event_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", -) + eventgrid_partner_channel_name="fakechannel", + eventgrid_partner_namespace_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", + eventgrid_partner_namespace_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", + eventgrid_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", + eventgrid_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", + eventgrid_topic_name="faketopic", + eventgrid_event_subscription_name="fakesub", +) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py index 0319fcf50f6b..dca0af806cb3 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py @@ -20,7 +20,9 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_dict( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -40,7 +42,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_base64_using_data( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -58,7 +62,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_none( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -70,7 +76,9 @@ def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_str( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -88,7 +96,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_as_list( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -100,7 +110,9 @@ def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoin @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cncf_data_with_extensions( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py index 4c65b623316d..a421181f4d82 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py @@ -23,7 +23,9 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_dict_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -44,7 +46,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_base64_using_data_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -63,7 +67,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_none_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -76,7 +82,9 @@ async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endp @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_str_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -95,7 +103,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_as_list_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -108,7 +118,9 @@ async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_e @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cncf_data_with_extensions_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py new file mode 100644 index 000000000000..6f848c7c28a0 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -0,0 +1,78 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +import os +import time +from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential + +from eventgrid_preparer import EventGridPreparer + + +class TestEGClientExceptions(AzureRecordedTestCase): + def create_eg_client(self, endpoint, key): + client = EventGridClient( + endpoint=endpoint, credential=AzureKeyCredential(key) + ) + return client + + @pytest.mark.skip("need to update conftest") + @EventGridPreparer() + @recorded_by_proxy + def test_publish_receive_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b'this is binary data', + ) + + client.publish_cloud_events( + eventgrid_topic_name, body=[event] + ) + + time.sleep(5) + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + lock_token = events.value[0].broker_properties.lock_token + + ack = client.acknowledge_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=AcknowledgeOptions(lock_tokens=[lock_token])) + assert len(ack.succeeded_lock_tokens) == 1 + assert len(ack.failed_lock_tokens) == 0 + + @pytest.mark.skip("need to update conftest") + @EventGridPreparer() + @recorded_by_proxy + def test_publish_release_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b'this is binary data', + ) + + client.publish_cloud_events( + eventgrid_topic_name, body=[event] + ) + + time.sleep(5) + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + lock_token = events.value[0].broker_properties.lock_token + + ack = client.release_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=ReleaseOptions(lock_tokens=[lock_token])) + assert len(ack.succeeded_lock_tokens) == 1 + assert len(ack.failed_lock_tokens) == 0 + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + assert events.value[0].broker_properties.delivery_count > 1 \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index e385f206653e..7f5f8ffa4a91 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -6,27 +6,27 @@ import pytest import os import time +from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy from azure.eventgrid import EventGridClient from azure.eventgrid.models import * from azure.core.messaging import CloudEvent from azure.core.credentials import AzureKeyCredential from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from eventgrid_preparer import EventGridPreparer -class TestEGClientExceptions: - def create_eg_client(self, endpoint): - eventgrid_key = os.environ["EVENTGRID_KEY"] + +class TestEGClientExceptions(AzureRecordedTestCase): + def create_eg_client(self, endpoint, key): client = EventGridClient( - endpoint=endpoint, credential=AzureKeyCredential(eventgrid_key) + endpoint=endpoint, credential=AzureKeyCredential(key) ) return client - @pytest.mark.live_test_only - def test_publish_cloud_event_bad_request(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", source=None, @@ -35,13 +35,12 @@ def test_publish_cloud_event_bad_request(self): ) with pytest.raises(HttpResponseError): - client.publish_cloud_events(topic_name, [event]) + client.publish_cloud_events("testtopic1", [event]) - @pytest.mark.live_test_only - def test_publish_cloud_event_not_found(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_publish_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", source=None, @@ -52,152 +51,123 @@ def test_publish_cloud_event_not_found(self): with pytest.raises(ResourceNotFoundError): client.publish_cloud_events("faketopic", [event]) - @pytest.mark.live_test_only - def test_receive_cloud_event_not_found(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_receive_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): - client.receive_cloud_events("faketopic", event_subscription_name) + client.receive_cloud_events("faketopic", eventgrid_event_subscription_name) - @pytest.mark.live_test_only - def test_receive_cloud_event_max_events_negative(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_receive_cloud_event_max_events_negative(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): client.receive_cloud_events( - topic_name, event_subscription_name, max_events=-20 + eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20 ) - @pytest.mark.live_test_only - def test_receive_cloud_event_timeout_negative(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_receive_cloud_event_timeout_negative(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): client.receive_cloud_events( - topic_name, event_subscription_name, max_wait_time=-20 + eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20 ) - @pytest.mark.live_test_only - def test_receive_cloud_event_timeout_max_value(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_receive_cloud_event_timeout_max_value(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): client.receive_cloud_events( - topic_name, event_subscription_name, max_wait_time=121 + eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121 ) - @pytest.mark.live_test_only - def test_receive_cloud_event_timeout_min_value(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_receive_cloud_event_timeout_min_value(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): client.receive_cloud_events( - topic_name, event_subscription_name, max_wait_time=9 + eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9 ) - @pytest.mark.live_test_only - def test_acknowledge_cloud_event_not_found(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_acknowledge_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) client.acknowledge_cloud_events( - "faketopic", event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) - @pytest.mark.live_test_only - def test_release_cloud_event_not_found(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) client.release_cloud_events( - "faketopic", event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) - @pytest.mark.live_test_only - def test_reject_cloud_event_not_found(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = RejectOptions(lock_tokens=["faketoken"]) with pytest.raises(ResourceNotFoundError): client.reject_cloud_events( - "faketopic", event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) - @pytest.mark.live_test_only - def test_acknowledge_cloud_event_invalid_token(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) ack = client.acknowledge_cloud_events( - topic_name, event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(ack) == AcknowledgeResult assert ack.succeeded_lock_tokens == [] assert type(ack.failed_lock_tokens[0]) == FailedLockToken assert ack.failed_lock_tokens[0].lock_token == "faketoken" - @pytest.mark.live_test_only - def test_release_cloud_event_invalid_token(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) release = client.release_cloud_events( - topic_name, event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(release) == ReleaseResult assert release.succeeded_lock_tokens == [] assert type(release.failed_lock_tokens[0]) == FailedLockToken assert release.failed_lock_tokens[0].lock_token == "faketoken" - @pytest.mark.live_test_only - def test_reject_cloud_event_invalid_token(self): - eventgrid_endpoint = os.environ["EVENTGRID_ENDPOINT"] - topic_name = os.environ["TOPIC_NAME"] - event_subscription_name = os.environ["EVENT_SUBSCRIPTION_NAME"] - - client = self.create_eg_client(eventgrid_endpoint) + @EventGridPreparer() + @recorded_by_proxy + def test_reject_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = RejectOptions(lock_tokens=["faketoken"]) reject = client.reject_cloud_events( - topic_name, event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(reject) == RejectResult assert reject.succeeded_lock_tokens == [] diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 60a8837785f4..c939ee1d8bc8 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -54,7 +54,9 @@ def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, eventgrid_topic_endpoint): + def test_send_event_grid_event_fails_without_full_url( + self, eventgrid_topic_key, eventgrid_topic_endpoint + ): akc_credential = AzureKeyCredential(eventgrid_topic_key) parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, akc_credential) @@ -99,7 +101,9 @@ def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): + def test_send_event_grid_event_data_bytes( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -112,7 +116,9 @@ def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): + def test_send_event_grid_event_dict_data_bytes( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { "subject": "sample", @@ -143,7 +149,9 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_dict( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -155,7 +163,9 @@ def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_NULL( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" @@ -169,7 +179,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_base64_using_data( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -197,7 +209,9 @@ def test_send_cloud_event_fails_on_providing_data_and_b64(self): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_none( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" @@ -206,7 +220,9 @@ def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_str( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -217,7 +233,9 @@ def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_bytes( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -228,7 +246,9 @@ def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint) @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_as_list( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -239,7 +259,9 @@ def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoin @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_with_extensions( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -255,7 +277,9 @@ def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_dict( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { "id": "1234", @@ -286,12 +310,16 @@ def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_en @EventGridPreparer() @recorded_by_proxy def test_send_NONE_credential(self, eventgrid_topic_endpoint): - with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): + with pytest.raises( + ValueError, match="Parameter 'self._credential' must not be None." + ): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) @EventGridPreparer() @recorded_by_proxy - def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): + def test_send_custom_schema_event( + self, eventgrid_custom_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { "customSubject": "sample", @@ -305,7 +333,9 @@ def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): + def test_send_custom_schema_event_as_list( + self, eventgrid_custom_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { "customSubject": "sample", @@ -348,12 +378,13 @@ def test_send_token_credential(self, eventgrid_topic_endpoint): client.send(eg_event) @pytest.mark.live_test_only - def test_send_partner_namespace(self): - eventgrid_partner_namespace_endpoint = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT'] - eventgrid_partner_namespace_key = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY'] - channel_name = os.environ['EVENTGRID_PARTNER_CHANNEL_NAME'] - credential = AzureKeyCredential(eventgrid_partner_namespace_key) - client = EventGridPublisherClient(eventgrid_partner_namespace_endpoint, credential) + @EventGridPreparer() + @recorded_by_proxy + def test_send_partner_namespace(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, eventgrid_partner_channel_name): + credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) + client = EventGridPublisherClient( + eventgrid_partner_namespace_topic_endpoint, credential + ) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", @@ -362,6 +393,6 @@ def test_send_partner_namespace(self): def callback(request): req = request.http_request.headers - assert req.get("aeg-channel-name") == channel_name + assert req.get("aeg-channel-name") == eventgrid_partner_channel_name - client.send(cloud_event, channel_name=channel_name, raw_request_hook=callback) + client.send(cloud_event, channel_name=eventgrid_partner_channel_name, raw_request_hook=callback) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index f00c9af4f0b0..c483097183c7 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -39,7 +39,9 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_dict_async( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -52,7 +54,9 @@ async def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_as_list_async( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event1 = EventGridEvent( subject="sample", @@ -71,7 +75,9 @@ async def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, eventgrid_topic_endpoint): + async def test_send_event_grid_event_fails_without_full_url_async( + self, eventgrid_topic_key, eventgrid_topic_endpoint + ): akc_credential = AzureKeyCredential(eventgrid_topic_key) parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, akc_credential) @@ -87,7 +93,9 @@ async def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topi @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_str_async( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -100,7 +108,9 @@ async def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_bytes_async( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -114,7 +124,9 @@ async def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_dict_data_bytes_async( + self, eventgrid_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { "subject": "sample", @@ -130,7 +142,9 @@ async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_dict_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source = "http://samplesource.dev", @@ -155,7 +169,9 @@ async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_str_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -167,7 +183,9 @@ async def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_end @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_bytes_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -179,8 +197,8 @@ async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_e @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_as_list( - self, variables, eventgrid_cloud_event_topic_endpoint + async def test_send_cloud_event_data_as_list_async( + self, eventgrid_cloud_event_topic_endpoint ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( @@ -193,7 +211,9 @@ async def test_send_cloud_event_data_as_list( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_with_extensions_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -210,7 +230,9 @@ async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_dict_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { "id": "1234", @@ -224,7 +246,9 @@ async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint) @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_none_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" @@ -235,7 +259,9 @@ async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endp @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_NULL_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" @@ -250,7 +276,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_endpoint): + async def test_send_signature_credential_async( + self, eventgrid_topic_key, eventgrid_topic_endpoint + ): expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) signature = generate_sas( eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc @@ -268,7 +296,9 @@ async def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_to @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): + async def test_send_custom_schema_event_async( + self, eventgrid_custom_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { "customSubject": "sample", @@ -283,7 +313,9 @@ async def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): + async def test_send_custom_schema_event_as_list_async( + self, eventgrid_custom_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { "customSubject": "sample", @@ -306,7 +338,9 @@ async def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_top @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_and_close_async_session(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_and_close_async_session_async( + self, eventgrid_cloud_event_topic_endpoint + ): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) async with client: # this throws if client can't close cloud_event = CloudEvent( @@ -320,14 +354,16 @@ async def test_send_and_close_async_session(self, eventgrid_cloud_event_topic_en @EventGridPreparer() @recorded_by_proxy_async def test_send_NONE_credential_async(self, eventgrid_topic_endpoint): - with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): + with pytest.raises( + ValueError, match="Parameter 'self._credential' must not be None." + ): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) @pytest.mark.live_test_only @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_token_credential(self, eventgrid_topic_endpoint): + async def test_send_token_credential_async(self, eventgrid_topic_endpoint): credential = self.get_credential(EventGridPublisherClient) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( @@ -339,12 +375,13 @@ async def test_send_token_credential(self, eventgrid_topic_endpoint): await client.send(eg_event) @pytest.mark.live_test_only - async def test_send_partner_namespace(self): - eventgrid_partner_namespace_endpoint = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT'] - eventgrid_partner_namespace_key = os.environ['EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY'] - channel_name = os.environ['EVENTGRID_PARTNER_CHANNEL_NAME'] - credential = AzureKeyCredential(eventgrid_partner_namespace_key) - client = EventGridPublisherClient(eventgrid_partner_namespace_endpoint, credential) + @EventGridPreparer() + @recorded_by_proxy_async + async def test_send_partner_namespace_async(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, eventgrid_partner_channel_name): + credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) + client = EventGridPublisherClient( + eventgrid_partner_namespace_topic_endpoint, credential + ) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", @@ -353,8 +390,8 @@ async def test_send_partner_namespace(self): def callback(request): req = request.http_request.headers - assert req.get("aeg-channel-name") == channel_name + assert req.get("aeg-channel-name") == eventgrid_partner_channel_name await client.send( - cloud_event, channel_name=channel_name, raw_request_hook=callback + cloud_event, channel_name=eventgrid_partner_channel_name, raw_request_hook=callback ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index 49effd2ccf06..294ef662ab93 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -26,11 +26,9 @@ from devtools_testutils import AzureMgmtRecordedTestCase, recorded_by_proxy -from azure.core.credentials import AzureKeyCredential, AzureSasCredential +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridPublisherClient, EventGridEvent from azure.core.messaging import CloudEvent -from azure.core.serialization import NULL -from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas -from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from eventgrid_preparer import ( EventGridPreparer, @@ -66,16 +64,16 @@ def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() def test_raise_on_bad_resource(self, eventgrid_topic_key): - akc_credential = AzureKeyCredential(eventgrid_topic_key) + credential = AzureKeyCredential(eventgrid_topic_key) client = EventGridPublisherClient( - "https://bad-resource.westus-1.eventgrid.azure.net/api/events", - akc_credential, + "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", + credential, ) - eg_event = EventGridEvent( + eg_event = CloudEvent( subject="sample", data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0", + source="source", + type="Sample.Cloud.Event", ) with pytest.raises(HttpResponseError): client.send(eg_event) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index 0c26df470fcb..2779ab678bc4 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -70,10 +70,10 @@ async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @EventGridPreparer() @pytest.mark.asyncio async def test_raise_on_bad_resource(self, eventgrid_topic_key): - akc_credential = AzureKeyCredential(eventgrid_topic_key) + credential = AzureKeyCredential(eventgrid_topic_key) client = EventGridPublisherClient( - "https://bad-resource.westus-1.eventgrid.azure.net/api/events", - akc_credential, + "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", + credential, ) eg_event = EventGridEvent( subject="sample", diff --git a/sdk/eventgrid/test-resources.json b/sdk/eventgrid/test-resources.json index 88e3eab75b9d..e41dbdec3be1 100644 --- a/sdk/eventgrid/test-resources.json +++ b/sdk/eventgrid/test-resources.json @@ -26,9 +26,19 @@ "metadata": { "description": "The application client secret used to run tests." } + }, + "location": { + "type": "string", + "defaultValue": "eastus", + "metadata": { + "description": "The resource location" + } } }, "variables": { + "namespaceName": "[format('{0}-2', parameters('baseName'))]", + "topicName": "testtopic1", + "subscriptionName": "testsubscription1", "apiVersion": "2022-06-15", "eventGridTopicName": "[concat(parameters('baseName'), 'topic')]", "eventGridDomainName": "[concat(parameters('baseName'), 'domain')]", @@ -43,6 +53,55 @@ "eventGridDataSenderRoleId": "d5a91429-5739-47e2-a06b-3470a27159e7", }, "resources": [ + { + "type": "Microsoft.EventGrid/namespaces", + "apiVersion": "2023-06-01-preview", + "name": "[variables('namespaceName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard", + "capacity": 1 + }, + "properties": { + "isZoneRedundant": true, + "publicNetworkAccess": "Enabled" + } + }, + { + "type": "Microsoft.EventGrid/namespaces/topics", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', variables('namespaceName'), variables('topicName'))]", + "properties": { + "publisherType": "Custom", + "inputSchema": "CloudEventSchemaV1_0", + "eventRetentionInDays": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName'))]" + ] + }, + { + "type": "Microsoft.EventGrid/namespaces/topics/eventSubscriptions", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}/{2}', variables('namespaceName'), variables('topicName'), variables('subscriptionName'))]", + "properties": { + "deliveryConfiguration": { + "deliveryMode": "Queue", + "queue": { + "receiveLockDurationInSeconds": 60, + "maxDeliveryCount": 10, + "eventTimeToLive": "P1D" + } + }, + "eventDeliverySchema": "CloudEventSchemaV1_0", + "filtersConfiguration": { + "includedEventTypes": [] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.EventGrid/namespaces/topics', variables('namespaceName'), variables('topicName'))]" + ] + }, { "type": "Microsoft.EventGrid/topics", "apiVersion": "[variables('apiVersion')]", @@ -227,6 +286,30 @@ "EVENTGRID_PARTNER_CHANNEL_NAME": { "type": "string", "value": "[variables('partnerChannelName')]" + }, + "EVENTGRID_KEY": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-06-01-preview').key1]" + }, + "EVENTGRID_ENDPOINT": { + "type": "string", + "value": "[format('https://{0}', reference(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-06-01-preview').topicsConfiguration.hostname)]" + }, + "EVENTGRID_TOPIC_NAME": { + "type": "string", + "value": "[variables('topicName')]" + }, + "EVENTGRID_EVENT_SUBSCRIPTION_NAME": { + "type": "string", + "value": "[variables('subscriptionName')]" + }, + "RESOURCE_GROUP": { + "type": "string", + "value": "[resourceGroup().name]" + }, + "AZURE_SUBSCRIPTION_ID": { + "type": "string", + "value": "[subscription().subscriptionId]" } } } From 5ce8776a94d8c1dea4bfb66968ad44a310b678a8 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 5 Oct 2023 13:08:42 -0700 Subject: [PATCH 08/43] [EGv2] generate with newer emitter (#31962) * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * generate with newer emitter * update tsp * regen * update tests * update tspconfig * cspell * version * update serialization * update assets * update mypy --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- .vscode/cspell.json | 1 + sdk/eventgrid/azure-eventgrid/assets.json | 2 +- .../azure/eventgrid/_client.py | 14 +- .../azure/eventgrid/_configuration.py | 27 +- .../azure/eventgrid/_model_base.py | 528 +++++++++++------- .../azure/eventgrid/_operations/__init__.py | 2 +- .../eventgrid/_operations/_operations.py | 436 +++++++++++++-- .../azure-eventgrid/azure/eventgrid/_patch.py | 41 -- .../azure/eventgrid/_serialization.py | 34 +- .../azure/eventgrid/_vendor.py | 21 +- .../azure/eventgrid/aio/_client.py | 14 +- .../azure/eventgrid/aio/_configuration.py | 27 +- .../eventgrid/aio/_operations/__init__.py | 2 +- .../eventgrid/aio/_operations/_operations.py | 389 ++++++++++++- .../azure/eventgrid/aio/_patch.py | 28 - .../azure/eventgrid/aio/_vendor.py | 6 +- .../azure/eventgrid/models/_models.py | 12 +- .../sample_acknowledge_operation_async.py | 8 +- .../sample_all_operations_async.py | 8 +- .../sample_publish_operation_async.py | 8 +- .../sample_receive_operation_async.py | 8 +- .../sample_reject_operation_async.py | 8 +- .../sample_release_operation_async.py | 8 +- .../sample_acknowledge_operation.py | 8 +- .../sample_all_operations.py | 8 +- .../sample_eg_client_authentication.py | 4 +- .../sample_publish_operation.py | 8 +- .../sample_receive_operation.py | 8 +- .../sample_reject_operation.py | 8 +- .../sample_release_operation.py | 8 +- .../tests/test_serialization.py | 2 +- .../azure-eventgrid/tsp-location.yaml | 2 +- 32 files changed, 1243 insertions(+), 445 deletions(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 7e1a1a05ccea..57b7071000b2 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -299,6 +299,7 @@ "mibps", "mgmt", "mhsm", + "Nify", "mipsle", "mktime", "mlindex", diff --git a/sdk/eventgrid/azure-eventgrid/assets.json b/sdk/eventgrid/azure-eventgrid/assets.json index a00be8330ac3..46490ff40be4 100644 --- a/sdk/eventgrid/azure-eventgrid/assets.json +++ b/sdk/eventgrid/azure-eventgrid/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/eventgrid/azure-eventgrid", - "Tag": "python/eventgrid/azure-eventgrid_6f56978914" + "Tag": "python/eventgrid/azure-eventgrid_fce4958e09" } diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py index 839215bd35b5..329e214d89c1 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any +from typing import Any, TYPE_CHECKING, Union from azure.core import PipelineClient from azure.core.credentials import AzureKeyCredential @@ -17,14 +17,20 @@ from ._operations import EventGridClientOperationsMixin from ._serialization import Deserializer, Serializer +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials import TokenCredential + class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword """Azure Messaging EventGrid Client. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential + :param credential: Credential needed for the client to connect to Azure. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials.TokenCredential :keyword api_version: The API version to use for this operation. Default value is "2023-06-01-preview". Note that overriding this default value may result in unsupported behavior. @@ -34,7 +40,7 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client def __init__( self, endpoint: str, - credential: AzureKeyCredential, + credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any ) -> None: _endpoint = '{endpoint}' diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py index f294505931a0..8a5c765af4f5 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any +from typing import Any, TYPE_CHECKING, Union from azure.core.configuration import Configuration from azure.core.credentials import AzureKeyCredential @@ -14,8 +14,14 @@ from ._version import VERSION +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials import TokenCredential -class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + +class EventGridClientConfiguration( # pylint: disable=too-many-instance-attributes,name-too-long + Configuration +): """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -24,8 +30,10 @@ class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-i :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential + :param credential: Credential needed for the client to connect to Azure. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials.TokenCredential :keyword api_version: The API version to use for this operation. Default value is "2023-06-01-preview". Note that overriding this default value may result in unsupported behavior. @@ -35,7 +43,7 @@ class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-i def __init__( self, endpoint: str, - credential: AzureKeyCredential, + credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any ) -> None: super(EventGridClientConfiguration, self).__init__(**kwargs) @@ -49,9 +57,16 @@ def __init__( self.endpoint = endpoint self.credential = credential self.api_version = api_version + self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) self._configure(**kwargs) + def _infer_policy(self, **kwargs): + if isinstance(self.credential, AzureKeyCredential): + return policies.AzureKeyCredentialPolicy(self.credential, "Authorization", prefix="SharedAccessKey", **kwargs) + if hasattr(self.credential, 'get_token'): + return policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + raise TypeError(f"Unsupported credential: {self.credential}") def _configure( self, @@ -67,4 +82,4 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - self.authentication_policy = policies.AzureKeyCredentialPolicy(self.credential, "SharedAccessKey", **kwargs) + self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py index 8d3005d8f692..2e328fc6adeb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -7,6 +7,7 @@ # pylint: disable=protected-access, arguments-differ, signature-differs, broad-except # pyright: reportGeneralTypeIssues=false +import calendar import functools import sys import logging @@ -14,13 +15,14 @@ import re import copy import typing +import email from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder import isodate from azure.core.exceptions import DeserializationError from azure.core import CaseInsensitiveEnumMeta from azure.core.pipeline import PipelineResponse -from azure.core.serialization import _Null # pylint: disable=protected-access +from azure.core.serialization import _Null if sys.version_info >= (3, 9): from collections.abc import MutableMapping @@ -31,9 +33,9 @@ __all__ = ["AzureJSONEncoder", "Model", "rest_field", "rest_discriminator"] - TZ_UTC = timezone.utc + def _timedelta_as_isostr(td: timedelta) -> str: """Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S' @@ -91,38 +93,20 @@ def _timedelta_as_isostr(td: timedelta) -> str: return "P" + date_str + time_str -def _datetime_as_isostr(dt: typing.Union[datetime, date, time, timedelta]) -> str: - """Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string - - :param timedelta dt: The date object to convert - :rtype: str - :return: ISO8601 version of this datetime - """ - # First try datetime.datetime - if hasattr(dt, "year") and hasattr(dt, "hour"): - dt = typing.cast(datetime, dt) - # astimezone() fails for naive times in Python 2.7, so make make sure dt is aware (tzinfo is set) - if not dt.tzinfo: - iso_formatted = dt.replace(tzinfo=TZ_UTC).isoformat() - else: - iso_formatted = dt.astimezone(TZ_UTC).isoformat() - # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) - return iso_formatted.replace("+00:00", "Z") - # Next try datetime.date or datetime.time - try: - dt = typing.cast(typing.Union[date, time], dt) - return dt.isoformat() - # Last, try datetime.timedelta - except AttributeError: - dt = typing.cast(timedelta, dt) - return _timedelta_as_isostr(dt) - -def _serialize_bytes(o) -> str: - return base64.b64encode(o).decode() +def _serialize_bytes(o, format: typing.Optional[str] = None) -> str: + encoded = base64.b64encode(o).decode() + if format == "base64url": + return encoded.strip("=").replace("+", "-").replace("/", "_") + return encoded -def _serialize_datetime(o): +def _serialize_datetime(o, format: typing.Optional[str] = None): if hasattr(o, "year") and hasattr(o, "hour"): + if format == "rfc7231": + return email.utils.format_datetime(o, usegmt=True) + if format == "unix-timestamp": + return int(calendar.timegm(o.utctimetuple())) + # astimezone() fails for naive times in Python 2.7, so make make sure o is aware (tzinfo is set) if not o.tzinfo: iso_formatted = o.replace(tzinfo=TZ_UTC).isoformat() @@ -136,7 +120,7 @@ def _serialize_datetime(o): def _is_readonly(p): try: - return p._readonly # pylint: disable=protected-access + return p._visibility == ["read"] # pylint: disable=protected-access except AttributeError: return False @@ -144,22 +128,27 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, format: typing.Optional[str] = None, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.format = format + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] # pylint: disable=protected-access - return {k: v for k, v in o.items() if k not in readonly_props} - if isinstance(o, (bytes, bytearray)): - return base64.b64encode(o).decode() - if isinstance(o, _Null): - return None + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + return dict(o.items()) try: return super(AzureJSONEncoder, self).default(o) except TypeError: + if isinstance(o, _Null): + return None if isinstance(o, (bytes, bytearray)): - return _serialize_bytes(o) + return _serialize_bytes(o, self.format) try: # First try datetime.datetime - return _serialize_datetime(o) + return _serialize_datetime(o, self.format) except AttributeError: pass # Last, try datetime.timedelta @@ -172,6 +161,10 @@ def default(self, o): # pylint: disable=too-many-return-statements _VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") +_VALID_RFC7231 = re.compile( + r"(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s\d{2}\s" + r"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT" +) def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime: @@ -207,6 +200,36 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime: return date_obj +def _deserialize_datetime_rfc7231(attr: typing.Union[str, datetime]) -> datetime: + """Deserialize RFC7231 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + match = _VALID_RFC7231.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + return email.utils.parsedate_to_datetime(attr) + + +def _deserialize_datetime_unix_timestamp(attr: typing.Union[float, datetime]) -> datetime: + """Deserialize unix timestamp into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + return datetime.fromtimestamp(attr, TZ_UTC) + + def _deserialize_date(attr: typing.Union[str, date]) -> date: """Deserialize ISO-8601 formatted string into Date object. :param str attr: response string to be deserialized. @@ -231,13 +254,22 @@ def _deserialize_time(attr: typing.Union[str, time]) -> time: return isodate.parse_time(attr) -def deserialize_bytes(attr): +def _deserialize_bytes(attr): if isinstance(attr, (bytes, bytearray)): return attr return bytes(base64.b64decode(attr)) -def deserialize_duration(attr): +def _deserialize_bytes_base64(attr): + if isinstance(attr, (bytes, bytearray)): + return attr + padding = "=" * (3 - (len(attr) + 3) % 4) # type: ignore + attr = attr + padding # type: ignore + encoded = attr.replace("-", "+").replace("_", "/") + return bytes(base64.b64decode(encoded)) + + +def _deserialize_duration(attr): if isinstance(attr, timedelta): return attr return isodate.parse_duration(attr) @@ -247,17 +279,50 @@ def deserialize_duration(attr): datetime: _deserialize_datetime, date: _deserialize_date, time: _deserialize_time, - bytes: deserialize_bytes, - timedelta: deserialize_duration, + bytes: _deserialize_bytes, + bytearray: _deserialize_bytes, + timedelta: _deserialize_duration, typing.Any: lambda x: x, } +_DESERIALIZE_MAPPING_WITHFORMAT = { + "rfc3339": _deserialize_datetime, + "rfc7231": _deserialize_datetime_rfc7231, + "unix-timestamp": _deserialize_datetime_unix_timestamp, + "base64": _deserialize_bytes, + "base64url": _deserialize_bytes_base64, +} + + +def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = None): + if rf and rf._format: + return _DESERIALIZE_MAPPING_WITHFORMAT.get(rf._format) + return _DESERIALIZE_MAPPING.get(annotation) + + +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({ + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) + }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -358,12 +423,20 @@ def _is_model(obj: typing.Any) -> bool: return getattr(obj, "_is_model", False) -def _serialize(o): +def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-many-return-statements + if isinstance(o, list): + return [_serialize(x, format) for x in o] + if isinstance(o, dict): + return {k: _serialize(v, format) for k, v in o.items()} + if isinstance(o, set): + return {_serialize(x, format) for x in o} + if isinstance(o, tuple): + return tuple(_serialize(x, format) for x in o) if isinstance(o, (bytes, bytearray)): - return _serialize_bytes(o) + return _serialize_bytes(o, format) try: # First try datetime.datetime - return _serialize_datetime(o) + return _serialize_datetime(o, format) except AttributeError: pass # Last, try datetime.timedelta @@ -385,7 +458,7 @@ def _get_rest_field( def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any: - return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value) + return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value, rf._format if rf else None) class Model(_MyMutableMapping): @@ -409,10 +482,13 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: if non_attr_kwargs: # actual type errors only throw the first wrong keyword arg they see, so following that. raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") - dict_to_pass.update({ - self._attr_to_rest_field[k]._rest_name: _serialize(v) - for k, v in kwargs.items() if v is not None - }) + dict_to_pass.update( + { + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) + for k, v in kwargs.items() + if v is not None + } + ) super().__init__(dict_to_pass) def copy(self) -> "Model": @@ -446,163 +522,215 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators: # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() - mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) + mapped_cls = cls.__mapping__.get( + data.get(discriminator), cls + ) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access - - -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements - annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None - ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: - if not annotation or annotation in [int, float]: + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): return None + if isinstance(v, (list, tuple, set)): + return [ + Model._as_dict_value(x, exclude_readonly=exclude_readonly) + for x in v + ] + if isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) + for dk, dv in v.items() + } + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v + + +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 + annotation: typing.Any, + module: typing.Optional[str], + rf: typing.Optional["_RestField"] = None, +) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + if not annotation or annotation in [int, float]: + return None + + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): try: - if module and _is_model(_get_model(module, annotation)): - if rf: - rf._is_model = True - def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): - if _is_model(obj): - return obj - return _deserialize(model_deserializer, obj) + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) - return functools.partial(_deserialize_model, _get_model(module, annotation)) - except Exception: - pass + try: + if module and _is_model(annotation): + if rf: + rf._is_model = True - # is it a literal? - try: - if sys.version_info >= (3, 8): - from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports - else: - from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports + def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): + if _is_model(obj): + return obj + return _deserialize(model_deserializer, obj) - if annotation.__origin__ == Literal: - return None - except AttributeError: - pass + return functools.partial(_deserialize_model, annotation) + except Exception: + pass - if getattr(annotation, "__origin__", None) is typing.Union: - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module) - except DeserializationError: - pass - raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) - - # is it optional? - try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum - if any(a for a in annotation.__args__ if a == type(None)): + # is it a literal? + try: + if sys.version_info >= (3, 8): + from typing import ( + Literal, + ) # pylint: disable=no-name-in-module, ungrouped-imports + else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports - if_obj_deserializer = _get_deserialize_callable_from_annotation( - next(a for a in annotation.__args__ if a != type(None)), module, rf - ) + if annotation.__origin__ == Literal: + return None + except AttributeError: + pass - def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): - if obj is None: - return obj - return _deserialize_with_callable(if_obj_deserializer, obj) + # is it optional? + try: + if any(a for a in annotation.__args__ if a == type(None)): + if_obj_deserializer = _get_deserialize_callable_from_annotation( + next(a for a in annotation.__args__ if a != type(None)), module, rf + ) - return functools.partial(_deserialize_with_optional, if_obj_deserializer) - except AttributeError: - pass + def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): + if obj is None: + return obj + return _deserialize_with_callable(if_obj_deserializer, obj) - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + return functools.partial(_deserialize_with_optional, if_obj_deserializer) + except AttributeError: + pass - try: - if annotation._name == "Dict": - key_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) - value_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[1], module, rf) - - def _deserialize_dict( - key_deserializer: typing.Optional[typing.Callable], - value_deserializer: typing.Optional[typing.Callable], - obj: typing.Dict[typing.Any, typing.Any], - ): - if obj is None: - return obj - return { - _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) for k, v in obj.items() - } - - return functools.partial( - _deserialize_dict, - key_deserializer, - value_deserializer, - ) - except (AttributeError, IndexError): - pass - try: - if annotation._name in ["List", "Set", "Tuple", "Sequence"]: - if len(annotation.__args__) > 1: - - def _deserialize_multiple_sequence( - entry_deserializers: typing.List[typing.Optional[typing.Callable]], obj - ): - if obj is None: - return obj - return type(obj)( - _deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers) - ) - - entry_deserializers = [ - _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ - ] - return functools.partial(_deserialize_multiple_sequence, entry_deserializers) - deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) - - def _deserialize_sequence( - deserializer: typing.Optional[typing.Callable], + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) + + try: + if annotation._name == "Dict": + key_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + value_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[1], module, rf) + + def _deserialize_dict( + key_deserializer: typing.Optional[typing.Callable], + value_deserializer: typing.Optional[typing.Callable], + obj: typing.Dict[typing.Any, typing.Any], + ): + if obj is None: + return obj + return { + _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) + for k, v in obj.items() + } + + return functools.partial( + _deserialize_dict, + key_deserializer, + value_deserializer, + ) + except (AttributeError, IndexError): + pass + try: + if annotation._name in ["List", "Set", "Tuple", "Sequence"]: + if len(annotation.__args__) > 1: + + def _deserialize_multiple_sequence( + entry_deserializers: typing.List[typing.Optional[typing.Callable]], obj, ): if obj is None: return obj - return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + return type(obj)( + _deserialize(deserializer, entry, module) + for entry, deserializer in zip(obj, entry_deserializers) + ) + + entry_deserializers = [ + _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ + ] + return functools.partial(_deserialize_multiple_sequence, entry_deserializers) + deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + + def _deserialize_sequence( + deserializer: typing.Optional[typing.Callable], + obj, + ): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + + return functools.partial(_deserialize_sequence, deserializer) + except (TypeError, IndexError, AttributeError, SyntaxError): + pass - return functools.partial(_deserialize_sequence, deserializer) - except (TypeError, IndexError, AttributeError, SyntaxError): + def _deserialize_default( + annotation, + deserializer_from_mapping, + obj, + ): + if obj is None: + return obj + try: + return _deserialize_with_callable(annotation, obj) + except Exception: pass + return _deserialize_with_callable(deserializer_from_mapping, obj) - def _deserialize_default( - annotation, - deserializer_from_mapping, - obj, - ): - if obj is None: - return obj - try: - return _deserialize_with_callable(annotation, obj) - except Exception: - pass - return _deserialize_with_callable(deserializer_from_mapping, obj) - - return functools.partial(_deserialize_default, annotation, _DESERIALIZE_MAPPING.get(annotation)) + return functools.partial(_deserialize_default, annotation, get_deserializer(annotation, rf)) -def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], value: typing.Any): +def _deserialize_with_callable( + deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], + value: typing.Any, +): try: if value is None: return None @@ -615,18 +743,24 @@ def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[ty # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e -def _deserialize(deserializer: typing.Any, value: typing.Any, module: typing.Optional[str] = None) -> typing.Any: +def _deserialize( + deserializer: typing.Any, + value: typing.Any, + module: typing.Optional[str] = None, + rf: typing.Optional["_RestField"] = None, +) -> typing.Any: if isinstance(value, PipelineResponse): value = value.http_response.json() - deserializer = _get_deserialize_callable_from_annotation(deserializer, module) + deserializer = _get_deserialize_callable_from_annotation(deserializer, module, rf) return _deserialize_with_callable(deserializer, value) + class _RestField: def __init__( self, @@ -634,16 +768,18 @@ def __init__( name: typing.Optional[str] = None, type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin is_discriminator: bool = False, - readonly: bool = False, + visibility: typing.Optional[typing.List[str]] = None, default: typing.Any = _UNSET, + format: typing.Optional[str] = None, ): self._type = type self._rest_name_input = name self._module: typing.Optional[str] = None self._is_discriminator = is_discriminator - self._readonly = readonly + self._visibility = visibility self._is_model = False self._default = default + self._format = format @property def _rest_name(self) -> str: @@ -657,7 +793,9 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item - return _deserialize(self._type, _serialize(item)) + if self._is_model: + return item + return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: if value is None: @@ -667,9 +805,12 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) - obj.__setitem__(self._rest_name, _serialize(value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) + return + obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( self, annotation: typing.Any @@ -681,10 +822,11 @@ def rest_field( *, name: typing.Optional[str] = None, type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin - readonly: bool = False, + visibility: typing.Optional[typing.List[str]] = None, default: typing.Any = _UNSET, + format: typing.Optional[str] = None, ) -> typing.Any: - return _RestField(name=name, type=type, readonly=readonly, default=default) + return _RestField(name=name, type=type, visibility=visibility, default=default, format=format) def rest_discriminator( diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py index c166e5de9c64..5d63b0e4eaa0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import EventGridClientOperationsMixin +from ._patch import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 63e9753a018b..b665dd492629 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -6,20 +6,27 @@ # Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +from io import IOBase import json -from typing import Any, Callable, Dict, List, Optional, TypeVar +import sys +from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import HttpResponse -from azure.core.rest import HttpRequest +from azure.core.rest import HttpRequest, HttpResponse from azure.core.tracing.decorator import distributed_trace from azure.core.utils import case_insensitive_dict from .. import models as _models from .._model_base import AzureJSONEncoder, _deserialize from .._serialization import Serializer -from .._vendor import EventGridClientMixinABC, _format_url_section +from .._vendor import EventGridClientMixinABC + +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -27,7 +34,7 @@ _SERIALIZER.client_side_validation = False -def build_event_grid_publish_cloud_event_request( +def build_event_grid_publish_cloud_event_request( # pylint: disable=name-too-long topic_name: str, **kwargs: Any ) -> HttpRequest: @@ -36,19 +43,22 @@ def build_event_grid_publish_cloud_event_request( content_type: str = kwargs.pop('content_type') api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + # Construct URL _url = "/topics/{topicName}:publish" path_format_arguments = { "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') return HttpRequest( method="POST", @@ -59,7 +69,7 @@ def build_event_grid_publish_cloud_event_request( ) -def build_event_grid_publish_cloud_events_request( +def build_event_grid_publish_cloud_events_request( # pylint: disable=name-too-long topic_name: str, **kwargs: Any ) -> HttpRequest: @@ -68,19 +78,22 @@ def build_event_grid_publish_cloud_events_request( content_type: str = kwargs.pop('content_type') api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + accept = _headers.pop('Accept', "application/json") + # Construct URL _url = "/topics/{topicName}:publish" path_format_arguments = { "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') return HttpRequest( method="POST", @@ -91,7 +104,7 @@ def build_event_grid_publish_cloud_events_request( ) -def build_event_grid_receive_cloud_events_request( +def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, *, @@ -112,7 +125,7 @@ def build_event_grid_receive_cloud_events_request( "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') @@ -133,7 +146,7 @@ def build_event_grid_receive_cloud_events_request( ) -def build_event_grid_acknowledge_cloud_events_request( +def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any @@ -141,7 +154,7 @@ def build_event_grid_acknowledge_cloud_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: str = kwargs.pop('content_type') + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) accept = _headers.pop('Accept', "application/json") @@ -152,13 +165,14 @@ def build_event_grid_acknowledge_cloud_events_request( "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + if content_type is not None: + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') return HttpRequest( @@ -170,7 +184,7 @@ def build_event_grid_acknowledge_cloud_events_request( ) -def build_event_grid_release_cloud_events_request( +def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any @@ -178,7 +192,7 @@ def build_event_grid_release_cloud_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: str = kwargs.pop('content_type') + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) accept = _headers.pop('Accept', "application/json") @@ -189,13 +203,14 @@ def build_event_grid_release_cloud_events_request( "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + if content_type is not None: + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') return HttpRequest( @@ -207,7 +222,7 @@ def build_event_grid_release_cloud_events_request( ) -def build_event_grid_reject_cloud_events_request( +def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any @@ -215,7 +230,7 @@ def build_event_grid_reject_cloud_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: str = kwargs.pop('content_type') + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) accept = _headers.pop('Accept', "application/json") @@ -226,13 +241,14 @@ def build_event_grid_reject_cloud_events_request( "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), } - _url: str = _format_url_section(_url, **path_format_arguments) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + if content_type is not None: + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') return HttpRequest( @@ -243,15 +259,17 @@ def build_event_grid_reject_cloud_events_request( **kwargs ) -class EventGridClientOperationsMixin(EventGridClientMixinABC): +class EventGridClientOperationsMixin( + EventGridClientMixinABC +): @distributed_trace - def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,protected-access + def _publish_cloud_event( # pylint: disable=protected-access self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any - ) -> None: + ) -> _models._models.PublishResult: """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -267,8 +285,8 @@ def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,prot :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. - :return: None - :rtype: None + :return: PublishResult. The PublishResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map = { @@ -280,11 +298,11 @@ def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,prot _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) - cls: ClsType[None] = kwargs.pop( + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(event, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -309,21 +327,33 @@ def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,prot response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + if cls: - return cls(pipeline_response, None, {}) + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def _publish_cloud_events( # pylint: disable=inconsistent-return-statements + def _publish_cloud_events( # pylint: disable=protected-access self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any - ) -> None: + ) -> _models._models.PublishResult: """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -339,8 +369,8 @@ def _publish_cloud_events( # pylint: disable=inconsistent-return-statements :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. - :return: None - :rtype: None + :return: PublishResult. The PublishResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map = { @@ -352,11 +382,11 @@ def _publish_cloud_events( # pylint: disable=inconsistent-return-statements _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) - cls: ClsType[None] = kwargs.pop( + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(events, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -381,11 +411,23 @@ def _publish_cloud_events( # pylint: disable=inconsistent-return-statements response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + if cls: - return cls(pipeline_response, None, {}) + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @@ -457,6 +499,8 @@ def _receive_cloud_events( # pylint: disable=protected-access response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -475,12 +519,14 @@ def _receive_cloud_events( # pylint: disable=protected-access - @distributed_trace + @overload def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.AcknowledgeOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least @@ -494,7 +540,100 @@ def acknowledge_cloud_events( :type event_subscription_name: str :param lock_tokens: AcknowledgeOptions. Required. :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace + def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.AcknowledgeOptions, JSON, IO], + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Is one of the following types: AcknowledgeOptions, + JSON, IO Required. + :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -510,12 +649,17 @@ def acknowledge_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_acknowledge_cloud_events_request( topic_name=topic_name, @@ -541,6 +685,8 @@ def acknowledge_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -559,12 +705,14 @@ def acknowledge_cloud_events( - @distributed_trace + @overload def release_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.ReleaseOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one @@ -577,7 +725,97 @@ def release_cloud_events( :type event_subscription_name: str :param lock_tokens: ReleaseOptions. Required. :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace + def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.ReleaseOptions, JSON, IO], + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO + Required. + :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -593,12 +831,17 @@ def release_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_release_cloud_events_request( topic_name=topic_name, @@ -624,6 +867,8 @@ def release_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -642,12 +887,14 @@ def release_cloud_events( - @distributed_trace + @overload def reject_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.RejectOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. @@ -658,7 +905,91 @@ def reject_cloud_events( :type event_subscription_name: str :param lock_tokens: RejectOptions. Required. :type lock_tokens: ~azure.eventgrid.models.RejectOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace + def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.RejectOptions, JSON, IO], + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Is one of the following types: RejectOptions, JSON, IO + Required. + :type lock_tokens: ~azure.eventgrid.models.RejectOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -674,12 +1005,17 @@ def reject_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.RejectResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_reject_cloud_events_request( topic_name=topic_name, @@ -705,6 +1041,8 @@ def reject_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index 4ead1bf7ec05..9ac00715fa22 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -7,9 +7,6 @@ """ from typing import List -from azure.core.pipeline.policies import SansIOHTTPPolicy -from azure.core.credentials import AzureKeyCredential -from ._client import EventGridClient as ServiceClientGenerated from ._legacy import ( EventGridPublisherClient, SystemEventNames, @@ -17,43 +14,6 @@ generate_sas, ) - -class EventGridSharedAccessKeyPolicy(SansIOHTTPPolicy): - def __init__( - self, credential: "AzureKeyCredential", **kwargs - ) -> None: # pylint: disable=unused-argument - super(EventGridSharedAccessKeyPolicy, self).__init__() - self._credential = credential - - def on_request(self, request): - request.http_request.headers["Authorization"] = ( - "SharedAccessKey " + self._credential.key - ) - - -class EventGridClient(ServiceClientGenerated): - """Azure Messaging EventGrid Client. - - :param endpoint: The host name of the namespace, e.g. - namespaceName1.westus-1.eventgrid.azure.net. Required. - :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported - behavior. - :paramtype api_version: str - """ - - def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs) -> None: - if isinstance(credential, AzureKeyCredential): - if not kwargs.get("authentication_policy"): - kwargs["authentication_policy"] = EventGridSharedAccessKeyPolicy( - credential - ) - super().__init__(endpoint=endpoint, credential=credential, **kwargs) - - def patch_sdk(): """Do not remove from this file. `patch_sdk` is a last resort escape hatch that allows you to do customizations @@ -63,7 +23,6 @@ def patch_sdk(): __all__: List[str] = [ - "EventGridClient", "EventGridPublisherClient", "SystemEventNames", "EventGridEvent", diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index e3cc6ce6ed6f..7fd392a19926 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -664,8 +664,9 @@ def _serialize(self, target_obj, data_type=None, **kwargs): _serialized.update(_new_attr) # type: ignore _new_attr = _new_attr[k] # type: ignore _serialized = _serialized[k] - except ValueError: - continue + except ValueError as err: + if isinstance(err, SerializationError): + raise except (AttributeError, KeyError, TypeError) as err: msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj)) @@ -731,6 +732,8 @@ def url(self, name, data, data_type, **kwargs): if kwargs.get("skip_quote") is True: output = str(output) + # https://github.com/Azure/autorest.python/issues/2063 + output = output.replace("{", quote("{")).replace("}", quote("}")) else: output = quote(str(output), safe="") except SerializationError: @@ -743,6 +746,8 @@ def query(self, name, data, data_type, **kwargs): :param data: The data to be serialized. :param str data_type: The type to be serialized from. + :keyword bool skip_quote: Whether to skip quote the serialized result. + Defaults to False. :rtype: str :raises: TypeError if serialization fails. :raises: ValueError if data is None @@ -751,10 +756,8 @@ def query(self, name, data, data_type, **kwargs): # Treat the list aside, since we don't want to encode the div separator if data_type.startswith("["): internal_data_type = data_type[1:-1] - data = [self.serialize_data(d, internal_data_type, **kwargs) if d is not None else "" for d in data] - if not kwargs.get("skip_quote", False): - data = [quote(str(d), safe="") for d in data] - return str(self.serialize_iter(data, internal_data_type, **kwargs)) + do_quote = not kwargs.get('skip_quote', False) + return str(self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs)) # Not a list, regular serialization output = self.serialize_data(data, data_type, **kwargs) @@ -893,6 +896,8 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): not be None or empty. :param str div: If set, this str will be used to combine the elements in the iterable into a combined string. Default is 'None'. + :keyword bool do_quote: Whether to quote the serialized result of each iterable element. + Defaults to False. :rtype: list, str """ if isinstance(data, str): @@ -905,9 +910,18 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): for d in data: try: serialized.append(self.serialize_data(d, iter_type, **kwargs)) - except ValueError: + except ValueError as err: + if isinstance(err, SerializationError): + raise serialized.append(None) + if kwargs.get('do_quote', False): + serialized = [ + '' if s is None else quote(str(s), safe='') + for s + in serialized + ] + if div: serialized = ["" if s is None else str(s) for s in serialized] serialized = div.join(serialized) @@ -952,7 +966,9 @@ def serialize_dict(self, attr, dict_type, **kwargs): for key, value in attr.items(): try: serialized[self.serialize_unicode(key)] = self.serialize_data(value, dict_type, **kwargs) - except ValueError: + except ValueError as err: + if isinstance(err, SerializationError): + raise serialized[self.serialize_unicode(key)] = None if "xml" in serialization_ctxt: @@ -1902,7 +1918,7 @@ def deserialize_date(attr): if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore raise DeserializationError("Date must have only digits and -. Received: %s" % attr) # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. - return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + return isodate.parse_date(attr, defaultmonth=0, defaultday=0) @staticmethod def deserialize_time(attr): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py index 3aae9cfccf6b..682fa0a3f71f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py @@ -6,7 +6,7 @@ # -------------------------------------------------------------------------- from abc import ABC -from typing import List, TYPE_CHECKING, cast +from typing import TYPE_CHECKING from ._configuration import EventGridClientConfiguration @@ -16,23 +16,12 @@ from ._serialization import Deserializer, Serializer - -def _format_url_section(template, **kwargs): - components = template.split("/") - while components: - try: - return template.format(**kwargs) - except KeyError as key: - # Need the cast, as for some reasons "split" is typed as list[str | Any] - formatted_components = cast(List[str], template.split("/")) - components = [ - c for c in formatted_components if "{}".format(key.args[0]) not in c - ] - template = "/".join(components) - -class EventGridClientMixinABC(ABC): +class EventGridClientMixinABC( + ABC +): """DO NOT use this class. It is for internal typing use only.""" _client: "PipelineClient" _config: EventGridClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" + diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py index d5e929121bc0..e1d0a000fbde 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any, Awaitable +from typing import Any, Awaitable, TYPE_CHECKING, Union from azure.core import AsyncPipelineClient from azure.core.credentials import AzureKeyCredential @@ -17,14 +17,20 @@ from ._configuration import EventGridClientConfiguration from ._operations import EventGridClientOperationsMixin +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword """Azure Messaging EventGrid Client. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential + :param credential: Credential needed for the client to connect to Azure. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: The API version to use for this operation. Default value is "2023-06-01-preview". Note that overriding this default value may result in unsupported behavior. @@ -34,7 +40,7 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client def __init__( self, endpoint: str, - credential: AzureKeyCredential, + credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: _endpoint = '{endpoint}' diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py index d2308d4f626d..b06679bc2d67 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any +from typing import Any, TYPE_CHECKING, Union from azure.core.configuration import Configuration from azure.core.credentials import AzureKeyCredential @@ -14,8 +14,14 @@ from .._version import VERSION +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential -class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + +class EventGridClientConfiguration( # pylint: disable=too-many-instance-attributes,name-too-long + Configuration +): """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -24,8 +30,10 @@ class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-i :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential + :param credential: Credential needed for the client to connect to Azure. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: The API version to use for this operation. Default value is "2023-06-01-preview". Note that overriding this default value may result in unsupported behavior. @@ -35,7 +43,7 @@ class EventGridClientConfiguration(Configuration): # pylint: disable=too-many-i def __init__( self, endpoint: str, - credential: AzureKeyCredential, + credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: super(EventGridClientConfiguration, self).__init__(**kwargs) @@ -49,9 +57,16 @@ def __init__( self.endpoint = endpoint self.credential = credential self.api_version = api_version + self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) self._configure(**kwargs) + def _infer_policy(self, **kwargs): + if isinstance(self.credential, AzureKeyCredential): + return policies.AzureKeyCredentialPolicy(self.credential, "Authorization", prefix="SharedAccessKey", **kwargs) + if hasattr(self.credential, 'get_token'): + return policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + raise TypeError(f"Unsupported credential: {self.credential}") def _configure( self, @@ -67,4 +82,4 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - self.authentication_policy = policies.AzureKeyCredentialPolicy(self.credential, "SharedAccessKey", **kwargs) + self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py index c166e5de9c64..5d63b0e4eaa0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import EventGridClientOperationsMixin +from ._patch import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index 9a15d090bd8b..eb2c6cc3182f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -6,13 +6,14 @@ # Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +from io import IOBase import json -from typing import Any, Callable, Dict, List, Optional, TypeVar +import sys +from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import AsyncHttpResponse -from azure.core.rest import HttpRequest +from azure.core.rest import AsyncHttpResponse, HttpRequest from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.utils import case_insensitive_dict @@ -20,18 +21,26 @@ from ..._model_base import AzureJSONEncoder, _deserialize from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request from .._vendor import EventGridClientMixinABC + +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] -class EventGridClientOperationsMixin(EventGridClientMixinABC): +class EventGridClientOperationsMixin( + EventGridClientMixinABC +): @distributed_trace_async - async def _publish_cloud_event( # pylint: disable=inconsistent-return-statements,protected-access + async def _publish_cloud_event( # pylint: disable=protected-access self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any - ) -> None: + ) -> _models._models.PublishResult: """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -47,8 +56,8 @@ async def _publish_cloud_event( # pylint: disable=inconsistent-return-statement :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. - :return: None - :rtype: None + :return: PublishResult. The PublishResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map = { @@ -60,11 +69,11 @@ async def _publish_cloud_event( # pylint: disable=inconsistent-return-statement _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) - cls: ClsType[None] = kwargs.pop( + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(event, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -89,21 +98,33 @@ async def _publish_cloud_event( # pylint: disable=inconsistent-return-statement response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + if cls: - return cls(pipeline_response, None, {}) + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace_async - async def _publish_cloud_events( # pylint: disable=inconsistent-return-statements + async def _publish_cloud_events( # pylint: disable=protected-access self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any - ) -> None: + ) -> _models._models.PublishResult: """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -119,8 +140,8 @@ async def _publish_cloud_events( # pylint: disable=inconsistent-return-statemen :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. - :return: None - :rtype: None + :return: PublishResult. The PublishResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map = { @@ -132,11 +153,11 @@ async def _publish_cloud_events( # pylint: disable=inconsistent-return-statemen _params = kwargs.pop("params", {}) or {} content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) - cls: ClsType[None] = kwargs.pop( + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(events, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -161,11 +182,23 @@ async def _publish_cloud_events( # pylint: disable=inconsistent-return-statemen response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + if cls: - return cls(pipeline_response, None, {}) + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @@ -237,6 +270,8 @@ async def _receive_cloud_events( # pylint: disable=protected-access response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -255,12 +290,14 @@ async def _receive_cloud_events( # pylint: disable=protected-access - @distributed_trace_async + @overload async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.AcknowledgeOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least @@ -274,7 +311,100 @@ async def acknowledge_cloud_events( :type event_subscription_name: str :param lock_tokens: AcknowledgeOptions. Required. :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace_async + async def acknowledge_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.AcknowledgeOptions, JSON, IO], + **kwargs: Any + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least + one event is successfully acknowledged. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: AcknowledgeOptions. Is one of the following types: AcknowledgeOptions, + JSON, IO Required. + :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -290,12 +420,17 @@ async def acknowledge_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_acknowledge_cloud_events_request( topic_name=topic_name, @@ -321,6 +456,8 @@ async def acknowledge_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -339,12 +476,14 @@ async def acknowledge_cloud_events( - @distributed_trace_async + @overload async def release_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.ReleaseOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one @@ -357,7 +496,97 @@ async def release_cloud_events( :type event_subscription_name: str :param lock_tokens: ReleaseOptions. Required. :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace_async + async def release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.ReleaseOptions, JSON, IO], + **kwargs: Any + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one + event is successfully released. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO + Required. + :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -373,12 +602,17 @@ async def release_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_release_cloud_events_request( topic_name=topic_name, @@ -404,6 +638,8 @@ async def release_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -422,12 +658,14 @@ async def release_cloud_events( - @distributed_trace_async + @overload async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, lock_tokens: _models.RejectOptions, + *, + content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. @@ -438,7 +676,91 @@ async def reject_cloud_events( :type event_subscription_name: str :param lock_tokens: RejectOptions. Required. :type lock_tokens: ~azure.eventgrid.models.RejectOptions - :keyword content_type: content type. Default value is "application/json; charset=utf-8". + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Required. + :type lock_tokens: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace_async + async def reject_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + lock_tokens: Union[_models.RejectOptions, JSON, IO], + **kwargs: Any + ) -> _models.RejectResult: + """Reject batch of Cloud Events. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param lock_tokens: RejectOptions. Is one of the following types: RejectOptions, JSON, IO + Required. + :type lock_tokens: ~azure.eventgrid.models.RejectOptions or JSON or IO + :keyword content_type: content type. Default value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -454,12 +776,17 @@ async def reject_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/json; charset=utf-8")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) cls: ClsType[_models.RejectResult] = kwargs.pop( 'cls', None ) - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder) # type: ignore + content_type = content_type or "application/json" + _content = None + if isinstance(lock_tokens, (IOBase, bytes)): + _content = lock_tokens + else: + _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_event_grid_reject_cloud_events_request( topic_name=topic_name, @@ -485,6 +812,8 @@ async def reject_cloud_events( response = pipeline_response.http_response if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index 1b19aa235f57..506b7ccced9a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -7,35 +7,8 @@ """ from typing import List -from azure.core.credentials import AzureKeyCredential -from .._patch import EventGridSharedAccessKeyPolicy -from ._client import EventGridClient as ServiceClientGenerated from .._legacy.aio import EventGridPublisherClient - -class EventGridClient(ServiceClientGenerated): - """Azure Messaging EventGrid Client. - - :param endpoint: The host name of the namespace, e.g. - namespaceName1.westus-1.eventgrid.azure.net. Required. - :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Required. - :type credential: ~azure.core.credentials.AzureKeyCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported - behavior. - :paramtype api_version: str - """ - - def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs) -> None: - if isinstance(credential, AzureKeyCredential): - if not kwargs.get("authentication_policy"): - kwargs["authentication_policy"] = EventGridSharedAccessKeyPolicy( - credential - ) - super().__init__(endpoint=endpoint, credential=credential, **kwargs) - - def patch_sdk(): """Do not remove from this file. `patch_sdk` is a last resort escape hatch that allows you to do customizations @@ -45,6 +18,5 @@ def patch_sdk(): __all__: List[str] = [ - "EventGridClient", "EventGridPublisherClient", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py index 67626c5adc66..2f5401a3a2ee 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py @@ -16,10 +16,12 @@ from .._serialization import Deserializer, Serializer - -class EventGridClientMixinABC(ABC): +class EventGridClientMixinABC( + ABC +): """DO NOT use this class. It is for internal typing use only.""" _client: "AsyncPipelineClient" _config: EventGridClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" + diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index 3fda23b49841..5cf7dd673acd 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -146,11 +146,11 @@ class CloudEvent(_model_base.Model): unique for each distinct event. Required.""" data: Optional[Any] = rest_field() """Event data specific to the event type.""" - data_base64: Optional[bytes] = rest_field() + data_base64: Optional[bytes] = rest_field(format="base64") """Event data specific to the event type, encoded as a base64 string.""" type: str = rest_field() """Type of event related to the originating occurrence. Required.""" - time: Optional[datetime.datetime] = rest_field() + time: Optional[datetime.datetime] = rest_field(format="rfc3339") """The time (in UTC) the event was generated, in RFC3339 format.""" specversion: str = rest_field() """The version of the CloudEvents specification which the event uses. Required.""" @@ -209,6 +209,14 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- super().__init__(*args, **kwargs) +class PublishResult(_model_base.Model): + """The result of the Publish operation. + + """ + + + + class ReceiveDetails(_model_base.Model): """Receive operation details per Cloud Event. diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py index d858b811d1f9..bea9e4c5cb7e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -10,10 +10,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index 61d089485bf4..19e5863f7f2b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -11,10 +11,10 @@ from azure.core.exceptions import HttpResponseError from azure.eventgrid.aio import EventGridClient -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py index c8b321fd7f12..bb519f1cde2c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -12,10 +12,10 @@ from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py index b483a2f0abed..a25f09a40fed 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -10,10 +10,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py index d493e9055736..e46356e08fbf 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -10,10 +10,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index df57e7474b61..117dadf79287 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -10,10 +10,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py index 96cb87dc59eb..78bfdc1162fb 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py @@ -9,10 +9,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py index 9237729b12fd..db6863811b7f 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -11,10 +11,10 @@ from azure.core.exceptions import HttpResponseError from azure.eventgrid import EventGridClient -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py index f44b6d76f7c3..a95d1613c823 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py @@ -19,8 +19,8 @@ from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential -key = os.environ["EVENTGRID_KEY"] -endpoint = os.environ["EVENTGRID_ENDPOINT"] +key: str = os.environ["EVENTGRID_KEY"] +endpoint: str = os.environ["EVENTGRID_ENDPOINT"] credential = AzureKeyCredential(key) client = EventGridClient(endpoint, credential) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py index 10bfb8e0ffe8..fe5460387824 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py @@ -11,10 +11,10 @@ from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py index 222772002bd0..aefd6c39275f 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py @@ -9,10 +9,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py index d65066e52b44..a24a07a8ed74 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py @@ -9,10 +9,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py index dfea2e9489a4..60db8ed9f5e6 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -9,10 +9,10 @@ from azure.eventgrid.models import * from azure.core.exceptions import HttpResponseError -EVENTGRID_KEY = os.environ.get("EVENTGRID_KEY") -EVENTGRID_ENDPOINT = os.environ.get("EVENTGRID_ENDPOINT") -TOPIC_NAME = os.environ.get("TOPIC_NAME") -EVENT_SUBSCRIPTION_NAME = os.environ.get("EVENT_SUBSCRIPTION_NAME") +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py index e40e9c93e874..a83caf6954ae 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py @@ -9,7 +9,7 @@ import base64 from azure.core.messaging import CloudEvent -from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from azure.eventgrid import SystemEventNames, EventGridEvent from _mocks import ( cloud_storage_dict, diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml index adaa6c9354c8..94b72d10f055 100644 --- a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -1,4 +1,4 @@ cleanup: false -commit: c07d9898ed901330e5ac4996b1bc641adac2e6fd +commit: a48dbfd411ddcb91ad1e09c47d1def14e79b8905 directory: specification/eventgrid/Azure.Messaging.EventGrid repo: Azure/azure-rest-api-specs \ No newline at end of file From 211d80f713675eef5712f6b9e671504838bf7be3 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 3 Nov 2023 14:49:42 -0700 Subject: [PATCH 09/43] [EGv2] Binary mode (#32922) * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * Beta LiveTests (#30728) * add bicep file for tests * update output * update test * secret sanitization * refactor failing test * update conftest * update assets and sanitizers * update preparer loc * update conftest * conftest * update conftest * remove variables for now * update assets * update tests * try to update regex * update recordings * update conftest * update preparer * update test * update exception test * update tests * update asset * update conftest * pr comments * default needs to be eastus * import * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * fix merge * dont go to generated before binary * update patch * update patches * eventgrid client patch * changes * add * update test * update tyoe checking * pass through binary_mode for now -- * update patch aio * add async func * update * sys * update kwargs * add Todo and start adding more tests * update * differentiate between binary and not * update binary * no base64 in binary mode * binary * try JSONEncoder on everything if not str/bytes * update test * update test * update changes * whitespace * space * remove commented * str serialize extensions? * xml test * encode extensions as object * update test * update extension serialization for deserialize * move flag to operation level * extra comma * dont raise httpresponse * update patch * accept dict cloud events * spacing * remove content_type check * add live test * remove live test mark * update * use env vars * update test * only run live test * comment * typo * error incorrect * start comments * update test * add sample * update tests * update docstrings to add clarity * update err message * remove generated cloud event * update sample * update * update samples to include dict * update patch * spacing * add comments * formatting * update doc * update tests * update tests * tests * skip tests for now * typo * add dict binary mode * update docstring * update patch to allow throw error * first pass at comments * update patch eror * nit --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- .../azure/eventgrid/_operations/_patch.py | 342 ++++++++++++++++-- .../azure/eventgrid/aio/_operations/_patch.py | 202 ++++++++++- .../sample_binary_mode_async.py | 51 +++ .../sample_publish_operation_async.py | 19 +- .../sample_binary_mode.py | 43 +++ .../sample_publish_operation.py | 16 +- .../azure-eventgrid/tests/test_eg_client.py | 131 +++++++ .../tests/test_eg_client_exceptions.py | 4 +- .../azure-eventgrid/tests/test_exceptions.py | 5 +- .../tests/test_exceptions_async.py | 4 +- .../tests/unittests/test_binary_mode.py | 68 ++++ 11 files changed, 826 insertions(+), 59 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py create mode 100644 sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index dc841427df53..79d4cd307960 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -6,39 +6,33 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ import base64 -from typing import List, overload, Union, Any, Optional +import json +import sys +from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error from azure.core.messaging import CloudEvent from azure.core.tracing.decorator import distributed_trace +from azure.core.pipeline import PipelineResponse +from azure.core.rest import HttpRequest, HttpResponse +from azure.core.utils import case_insensitive_dict + from ._operations import EventGridClientOperationsMixin as OperationsMixin -from ..models._models import CloudEvent as InternalCloudEvent +from .._model_base import _deserialize from ..models._patch import ReceiveResult, ReceiveDetails +from .. import models as _models +from .._serialization import Serializer +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -def _cloud_event_to_generated(cloud_event, **kwargs): - data_kwargs = {} - - if isinstance(cloud_event.data, bytes): - data_kwargs["data_base64"] = base64.b64encode( - cloud_event.data - ) - else: - data_kwargs["data"] = cloud_event.data - - internal_event = InternalCloudEvent( - id=cloud_event.id, - source=cloud_event.source, - type=cloud_event.type, - specversion=cloud_event.specversion, - time=cloud_event.time, - dataschema=cloud_event.dataschema, - datacontenttype=cloud_event.datacontenttype, - subject=cloud_event.subject, - **data_kwargs, - **kwargs - ) - if cloud_event.extensions: - internal_event.update(cloud_event.extensions) - return internal_event +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] +_SERIALIZER = Serializer() +_SERIALIZER.client_side_validation = False class EventGridClientOperationsMixin(OperationsMixin): @@ -48,6 +42,7 @@ def publish_cloud_events( topic_name: str, body: List[CloudEvent], *, + binary_mode: bool = False, content_type: str = "application/cloudevents-batch+json; charset=utf-8", **kwargs: Any ) -> None: @@ -61,6 +56,10 @@ def publish_cloud_events( :type topic_name: str :param body: Array of Cloud Events being published. Required. :type body: list[~azure.core.messaging.CloudEvent] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. If 'datacontenttype` is not specified, + the default content type is `application/cloudevents-batch+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". :paramtype content_type: str @@ -77,6 +76,7 @@ def publish_cloud_events( topic_name: str, body: CloudEvent, *, + binary_mode: bool = False, content_type: str = "application/cloudevents+json; charset=utf-8", **kwargs: Any ) -> None: @@ -90,6 +90,44 @@ def publish_cloud_events( :type topic_name: str :param body: Single Cloud Event being published. Required. :type body: ~azure.core.messaging.CloudEvent + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def publish_cloud_events( + self, + topic_name: str, + body: Dict[str, Any], + *, + binary_mode: bool = False, + content_type: str = "application/cloudevents+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event being published. Required. + :type body: dict[str, Any] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str @@ -99,10 +137,48 @@ def publish_cloud_events( :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + + @overload + def publish_cloud_events( + self, + topic_name: str, + body: List[Dict[str, Any]], + *, + binary_mode: bool = False, + content_type: str = "application/cloudevents-batch+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Batch of Cloud Events being published. Required. + :type body: list[dict[str, Any]] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If 'datacontenttype` is not specified, the default content type is `application/cloudevents-batch+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. + :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace def publish_cloud_events( - self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs + self, + topic_name: str, + body: Union[List[CloudEvent], CloudEvent, List[Dict[str, Any]], Dict[str, Any]], + *, + binary_mode: bool = False, + **kwargs ) -> None: """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return @@ -113,7 +189,11 @@ def publish_cloud_events( :param topic_name: Topic Name. Required. :type topic_name: str :param body: Cloud Event or array of Cloud Events being published. Required. - :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] + :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] or dict[str, any] or list[dict[str, any]] + :keyword bool binary_mode: Whether to publish the events in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If not specified, the default content type is "application/cloudevents+json; charset=utf-8". + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str @@ -123,17 +203,30 @@ def publish_cloud_events( :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + + # Check that the body is a CloudEvent or list of CloudEvents even if dict + if isinstance(body, dict) or (isinstance(body, list) and isinstance(body[0], dict)): + try: + if isinstance(body, list): + body = [CloudEvent.from_dict(event) for event in body] + else: + body = CloudEvent.from_dict(body) + except AttributeError: + raise TypeError("Incorrect type for body. Expected CloudEvent," + " list of CloudEvents, dict, or list of dicts." + " If dict passed, must follow the CloudEvent format.") + if isinstance(body, CloudEvent): kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" - internal_body = _cloud_event_to_generated(body) - self._publish_cloud_event(topic_name, internal_body, **kwargs) - else: + self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + elif isinstance(body, list): kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" - internal_body_list = [] - for item in body: - internal_body_list.append(_cloud_event_to_generated(item)) - self._publish_cloud_events(topic_name, internal_body_list, **kwargs) + self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + else: + raise TypeError("Incorrect type for body. Expected CloudEvent," + " list of CloudEvents, dict, or list of dicts." + " If dict passed, must follow the CloudEvent format.") @distributed_trace def receive_cloud_events( @@ -187,6 +280,183 @@ def receive_cloud_events( receive_result_deserialized = ReceiveResult(value=detail_items) return receive_result_deserialized + def _publish(self, topic_name: str, event: Any, api_version: str, binary_mode: Optional[bool] = False, **kwargs: Any) -> None: + + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access + 'cls', None + ) + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + + # Given that we know the cloud event is binary mode, we can convert it to a HTTP request + http_request = _to_http_request( + topic_name=topic_name, + api_version=api_version, + headers=_headers, + params=_params, + content_type=content_type, + event=event, + binary_mode=binary_mode, + **kwargs + ) + + _stream = kwargs.pop("stream", False) + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + + # pipeline_response: PipelineResponse = self.send_request(http_request, **kwargs) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + http_request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: + # Create a HTTP request for a binary mode CloudEvent + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + event = kwargs.pop("event") + binary_mode = kwargs.pop("binary_mode", False) + + + if binary_mode: + # Content of the request is the data, if already in binary - no work needed + try: + if isinstance(event.data, bytes): + _content = event.data + else: + raise TypeError("CloudEvent data must be bytes when in binary mode." + "Did you forget to call `json.dumps()` and/or `encode()` on CloudEvent data?") + except AttributeError: + raise TypeError("Binary mode is not supported for batch CloudEvents. Set `binary_mode` to False when passing in a batch of CloudEvents.") + else: + # Content of the request is the serialized CloudEvent or serialized List[CloudEvent] + _content = _serialize_cloud_events(event) + + # content_type must be CloudEvent DataContentType when in binary mode + default_content_type = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + content_type: str = event.datacontenttype if (binary_mode and event.datacontenttype) else default_content_type + + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}:publish" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + if binary_mode: + # Cloud Headers + _headers['ce-source'] = _SERIALIZER.header('ce-source', event.source, 'str') + _headers['ce-type'] = _SERIALIZER.header('ce-type', event.type, 'str') + if event.specversion: + _headers['ce-specversion'] = _SERIALIZER.header('ce-specversion', event.specversion, 'str') + if event.id: + _headers['ce-id'] = _SERIALIZER.header('ce-id', event.id, 'str') + if event.time: + _headers['ce-time'] = _SERIALIZER.header('ce-time', event.time, 'str') + if event.dataschema: + _headers['ce-dataschema'] = _SERIALIZER.header('ce-dataschema', event.dataschema, 'str') + if event.subject: + _headers['ce-subject'] = _SERIALIZER.header('ce-subject', event.subject, 'str') + if event.extensions: + for extension, value in event.extensions.items(): + _headers[f'ce-{extension}'] = _SERIALIZER.header('ce-extensions', value, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + content=_content, # pass through content + **kwargs + ) + +def _serialize_cloud_events(events: Union[CloudEvent, List[CloudEvent]]) -> None: + # Serialize CloudEvent or List[CloudEvent] into a JSON string + is_list = isinstance(events, list) + data = {} + list_data = [] + for event in events if isinstance(events, list) else [events]: + # CloudEvent required fields but validate they are not set to None + if event.type: + data["type"] = _SERIALIZER.body(event.type, "str") + if event.specversion: + data["specversion"] = _SERIALIZER.body(event.specversion, "str") + if event.source: + data["source"] = _SERIALIZER.body(event.source, "str") + if event.id: + data["id"] = _SERIALIZER.body(event.id, "str") + + # Check if data is bytes and serialize to base64 + if isinstance(event.data, bytes): + data["data_base64"] = _SERIALIZER.serialize_bytearray(event.data) + elif event.data: + data["data"] = _SERIALIZER.body(event.data, "str") + + if event.subject: + data["subject"] = _SERIALIZER.body(event.subject, "str") + if event.time: + data["time"] = _SERIALIZER.body(event.time, "str") + if event.datacontenttype: + data["datacontenttype"] = _SERIALIZER.body(event.datacontenttype, "str") + if event.extensions: + for extension, value in event.extensions.items(): + data[extension] = _SERIALIZER.body(value, "str") + + # If single cloud event return the data + if not is_list: + return json.dumps(data) + else: + list_data.append(data) + # If list of cloud events return the list + return json.dumps(list_data) + __all__: List[str] = [ "EventGridClientOperationsMixin" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 4b940f11020d..6dc63a1bdfe0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -5,21 +5,36 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List, overload, Union, Any, Optional +from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar +import sys from azure.core.messaging import CloudEvent +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error from azure.core.tracing.decorator_async import distributed_trace_async +from azure.core.pipeline import PipelineResponse +from azure.core.rest import HttpRequest, AsyncHttpResponse +from azure.core.utils import case_insensitive_dict from ...models._patch import ReceiveResult, ReceiveDetails -from ..._operations._patch import _cloud_event_to_generated +from ..._operations._patch import _to_http_request from ._operations import EventGridClientOperationsMixin as OperationsMixin - +from ... import models as _models +from ..._model_base import _deserialize +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] class EventGridClientOperationsMixin(OperationsMixin): + @overload async def publish_cloud_events( self, topic_name: str, body: List[CloudEvent], *, + binary_mode: bool = False, content_type: str = "application/cloudevents-batch+json; charset=utf-8", **kwargs: Any ) -> None: @@ -33,6 +48,10 @@ async def publish_cloud_events( :type topic_name: str :param body: Array of Cloud Events being published. Required. :type body: list[~azure.core.messaging.CloudEvent] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If 'datacontenttype` is not specified the default content type is `application/cloudevents-batch+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". :paramtype content_type: str @@ -49,6 +68,7 @@ async def publish_cloud_events( topic_name: str, body: CloudEvent, *, + binary_mode: bool = False, content_type: str = "application/cloudevents+json; charset=utf-8", **kwargs: Any ) -> None: @@ -62,6 +82,78 @@ async def publish_cloud_events( :type topic_name: str :param body: Single Cloud Event being published. Required. :type body: ~azure.core.messaging.CloudEvent + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def publish_cloud_events( + self, + topic_name: str, + body: Dict[str, Any], + *, + binary_mode: bool = False, + content_type: str = "application/cloudevents+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Single Cloud Event being published. Required. + :type body: dict[str, Any] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. + :keyword content_type: content type. Default value is "application/cloudevents+json; + charset=utf-8". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def publish_cloud_events( + self, + topic_name: str, + body: List[Dict[str, Any]], + *, + binary_mode: bool = False, + content_type: str = "application/cloudevents-batch+json; charset=utf-8", + **kwargs: Any + ) -> None: + """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an + HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return + various error codes. For example, 401: which indicates authorization failure, 403: which + indicates quota exceeded or message is too large, 410: which indicates that specific topic is + not found, 400: for bad request, and 500: for internal server error. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param body: Batch of Cloud Events being published. Required. + :type body: list[dict[str, Any]] + :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If 'datacontenttype` is not specified, the default content type is `application/cloudevents-batch+json; charset=utf-8`. + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str @@ -74,7 +166,12 @@ async def publish_cloud_events( @distributed_trace_async async def publish_cloud_events( - self, topic_name: str, body: Union[List[CloudEvent], CloudEvent], **kwargs + self, + topic_name: str, + body: Union[List[CloudEvent], CloudEvent, List[Dict[str, Any]], Dict[str, Any]], + *, + binary_mode: bool = False, + **kwargs ) -> None: """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return @@ -85,7 +182,11 @@ async def publish_cloud_events( :param topic_name: Topic Name. Required. :type topic_name: str :param body: Cloud Event or Array of Cloud Events being published. Required. - :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] + :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] or dict[str, any] or list[dict[str, any]] + :keyword bool binary_mode: Whether to publish the events in binary mode. Defaults to False. + When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. + If not specified, the default content type is "application/cloudevents+json; charset=utf-8". + Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str @@ -95,16 +196,30 @@ async def publish_cloud_events( :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + + # Check that the body is a CloudEvent or list of CloudEvents even if dict + if isinstance(body, dict) or (isinstance(body, list) and isinstance(body[0], dict)): + try: + if isinstance(body, list): + body = [CloudEvent.from_dict(event) for event in body] + else: + body = CloudEvent.from_dict(body) + except AttributeError: + raise TypeError("Incorrect type for body. Expected CloudEvent," + " list of CloudEvents, dict, or list of dicts." + " If dict passed, must follow the CloudEvent format.") + + if isinstance(body, CloudEvent): kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" - internal_body = _cloud_event_to_generated(body) - await self._publish_cloud_event(topic_name, internal_body, **kwargs) - else: + await self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + elif isinstance(body, list): kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" - internal_body_list = [] - for item in body: - internal_body_list.append(_cloud_event_to_generated(item)) - await self._publish_cloud_events(topic_name, internal_body_list, **kwargs) + await self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + else: + raise TypeError("Incorrect type for body. Expected CloudEvent," + " list of CloudEvents, dict, or list of dicts." + " If dict passed, must follow the CloudEvent format.") @distributed_trace_async async def receive_cloud_events( @@ -158,6 +273,69 @@ async def receive_cloud_events( receive_result_deserialized = ReceiveResult(value=detail_items) return receive_result_deserialized + async def _publish(self, topic_name: str, event: Any, api_version, binary_mode, **kwargs: Any) -> None: + + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access + 'cls', None + ) + + content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + + # Given that we know the cloud event is binary mode, we can convert it to a HTTP request + http_request = _to_http_request( + topic_name=topic_name, + api_version=api_version, + headers=_headers, + params=_params, + content_type=content_type, + event=event, + binary_mode=binary_mode, + **kwargs + ) + + _stream = kwargs.pop("stream", False) + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + http_request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + __all__: List[str] = [ "EventGridClientOperationsMixin" diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py new file mode 100644 index 000000000000..2c440f9f9e7f --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py @@ -0,0 +1,51 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +import json +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +async def run(): + async with client: + # Publish a CloudEvent + try: + # Publish CloudEvent in binary mode with str encoded as bytes + cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + + # Publish CloudEvent in binary mode with json encoded as bytes + cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event, binary_mode=True) + + receive_result = await client.receive_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + max_events=10, + max_wait_time=10, + ) + for details in receive_result.value: + cloud_event_received = details.event + print("CloudEvent: ", cloud_event_received) + print("Data: ", cloud_event_received.data) + except HttpResponseError: + raise + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py index bb519f1cde2c..5fd2486723a6 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -14,8 +14,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) @@ -23,6 +23,21 @@ async def run(): async with client: + + # Publish a CloudEvent as dict + try: + cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + except HttpResponseError: + raise + + # Publish a list of CloudEvents as dict + try: + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=[cloud_event_dict, cloud_event_dict]) + except HttpResponseError: + raise + + # Publish a CloudEvent try: cloud_event = CloudEvent( diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py new file mode 100644 index 000000000000..de3a4c3f0c32 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py @@ -0,0 +1,43 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import json +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +# Publish a CloudEvent +try: + # Publish CloudEvent in binary mode with str encoded as bytes + cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + + # Publish CloudEvent in binary mode with json encoded as bytes + cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event, binary_mode=True) + + # Receive a CloudEvent + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) + for receive_details in receive_result.value: + cloud_event_received = receive_details.event + print("CloudEvent: ", cloud_event_received) + print("CloudEvent data: ", cloud_event_received.data) +except HttpResponseError: + raise + + diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py index fe5460387824..3c4db3a37f3b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py @@ -13,12 +13,24 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) +# Publish a CloudEvent as dict +try: + cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) +except HttpResponseError: + raise + +# Publish a list of CloudEvents as dict +try: + client.publish_cloud_events(topic_name=TOPIC_NAME, body=[cloud_event_dict, cloud_event_dict]) +except HttpResponseError: + raise # Publish a CloudEvent try: diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py index 6f848c7c28a0..ed092f4e3b39 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -21,6 +21,137 @@ def create_eg_client(self, endpoint, key): endpoint=endpoint, credential=AzureKeyCredential(key) ) return client + + + @pytest.mark.live_test_only + def test_publish_binary_mode_xml(self): + eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] + eventgrid_key = os.environ['EVENTGRID_KEY'] + eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + from xml.etree import ElementTree as ET + xml_string = """test""" + tree = xml_string.encode('utf-8') + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=tree, + datacontenttype="text/xml", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + client.publish_cloud_events( + eventgrid_topic_name, body=event, binary_mode=True + ) + + time.sleep(5) + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + my_returned_event = events.value[0].event + assert my_returned_event.data == xml_string + assert my_returned_event.datacontenttype == 'text/xml' + assert my_returned_event.type == "Contoso.Items.ItemReceived" + + + @pytest.mark.live_test_only + def test_publish_binary_mode_cloud_event(self): + eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] + eventgrid_key = os.environ['EVENTGRID_KEY'] + eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b'this is binary data', + datacontenttype='text/plain' + ) + + client.publish_cloud_events( + eventgrid_topic_name, body=event, binary_mode=True + ) + + time.sleep(5) + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + my_returned_event = events.value[0].event + assert my_returned_event.data == 'this is binary data' + assert my_returned_event.datacontenttype == 'text/plain' + assert my_returned_event.type == "Contoso.Items.ItemReceived" + + + @pytest.mark.live_test_only + def test_publish_binary_mode_incorrect_cloud_event(self): + eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] + eventgrid_key = os.environ['EVENTGRID_KEY'] + eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"key": "value"}, + datacontenttype='text/plain' + ) + + with pytest.raises(TypeError): + client.publish_cloud_events( + eventgrid_topic_name, body=event, binary_mode=True + ) + + @pytest.mark.live_test_only + def test_publish_binary_mode_list_cloud_event(self): + eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] + eventgrid_key = os.environ['EVENTGRID_KEY'] + eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"key": "value"}, + datacontenttype='text/plain' + ) + + with pytest.raises(TypeError): + client.publish_cloud_events( + eventgrid_topic_name, body=[event], binary_mode=True + ) + + @pytest.mark.live_test_only + def test_publish_binary_mode_combinations(self): + eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] + eventgrid_key = os.environ['EVENTGRID_KEY'] + eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b"hello", + datacontenttype='text/plain' + ) + + dict_event = {"type": "Contoso.Items.ItemReceived", "source": "source", "subject": "MySubject", "data": b"hello", "datacontenttype": "text/plain"} + + + client.publish_cloud_events( + eventgrid_topic_name, body=event, binary_mode=True + ) + + client.publish_cloud_events( + eventgrid_topic_name, body=dict_event, binary_mode=True + ) @pytest.mark.skip("need to update conftest") @EventGridPreparer() diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index 7f5f8ffa4a91..108b2c1a8e71 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -25,7 +25,7 @@ def create_eg_client(self, endpoint, key): @EventGridPreparer() @recorded_by_proxy - def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key): + def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", @@ -35,7 +35,7 @@ def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key ) with pytest.raises(HttpResponseError): - client.publish_cloud_events("testtopic1", [event]) + client.publish_cloud_events(eventgrid_topic_name, [event]) @EventGridPreparer() @recorded_by_proxy diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index 294ef662ab93..a6cddbd4bc1e 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -62,9 +62,8 @@ def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.skip("Fix during MQ - skip to unblock pipeline") @pytest.mark.live_test_only - @EventGridPreparer() - def test_raise_on_bad_resource(self, eventgrid_topic_key): - credential = AzureKeyCredential(eventgrid_topic_key) + def test_raise_on_bad_resource(self): + credential = AzureKeyCredential(os.environ["EVENTGRID_TOPIC_KEY"]) client = EventGridPublisherClient( "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", credential, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index 2779ab678bc4..d69eb481f763 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -69,8 +69,8 @@ async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @pytest.mark.asyncio - async def test_raise_on_bad_resource(self, eventgrid_topic_key): - credential = AzureKeyCredential(eventgrid_topic_key) + async def test_raise_on_bad_resource(self): + credential = AzureKeyCredential(os.environ["EVENTGRID_TOPIC_KEY"]) client = EventGridPublisherClient( "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", credential, diff --git a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py new file mode 100644 index 000000000000..5cbcdc2c8f39 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py @@ -0,0 +1,68 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +import json +import base64 +from azure.eventgrid._operations._patch import _to_http_request +from azure.eventgrid._model_base import AzureJSONEncoder +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent + +class MyTestClass(object): + def __init__(self, name): + self.name = name + def __str__(self): + return self.name + +class TestEGClientExceptions(): + + def test_binary_request_format(self): + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b'this is binary data', + ) + + request = _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + + assert request.data == b"this is binary data" + assert request.headers.get("ce-source") == "source" + assert request.headers.get("ce-subject") == "MySubject" + assert request.headers.get("ce-type") == "Contoso.Items.ItemReceived" + + def test_binary_request_format_with_extensions_and_datacontenttype(self): + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=b'this is my data', + datacontenttype="application/json", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + request = _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + + assert request.data == b"this is my data" + assert request.headers.get("ce-source") == "source" + assert request.headers.get("ce-subject") == "MySubject" + assert request.headers.get("ce-type") == "Contoso.Items.ItemReceived" + assert request.headers.get("ce-extension1") == "value1" + + def test_class_binary_request_format_error(self): + test_class = MyTestClass("test") + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=test_class, + datacontenttype="application/json", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + with pytest.raises(TypeError): + _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + From 3129eb9498cd4fdc0fe3461d3185e9b8149e4bf3 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 9 Nov 2023 11:24:37 -0800 Subject: [PATCH 10/43] [EventGrid] Ignite Release generate with new typespec (#32652) * Beta LiveTests (#30728) * add bicep file for tests * update output * update test * secret sanitization * refactor failing test * update conftest * update assets and sanitizers * update preparer loc * update conftest * conftest * update conftest * remove variables for now * update assets * update tests * try to update regex * update recordings * update conftest * update preparer * update test * update exception test * update tests * update asset * update conftest * pr comments * default needs to be eastus * import * [EGv2] Binary mode (#32922) * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * Beta LiveTests (#30728) * add bicep file for tests * update output * update test * secret sanitization * refactor failing test * update conftest * update assets and sanitizers * update preparer loc * update conftest * conftest * update conftest * remove variables for now * update assets * update tests * try to update regex * update recordings * update conftest * update preparer * update test * update exception test * update tests * update asset * update conftest * pr comments * default needs to be eastus * import * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * fix merge * dont go to generated before binary * update patch * update patches * eventgrid client patch * changes * add * update test * update tyoe checking * pass through binary_mode for now -- * update patch aio * add async func * update * sys * update kwargs * add Todo and start adding more tests * update * differentiate between binary and not * update binary * no base64 in binary mode * binary * try JSONEncoder on everything if not str/bytes * update test * update test * update changes * whitespace * space * remove commented * str serialize extensions? * xml test * encode extensions as object * update test * update extension serialization for deserialize * move flag to operation level * extra comma * dont raise httpresponse * update patch * accept dict cloud events * spacing * remove content_type check * add live test * remove live test mark * update * use env vars * update test * only run live test * comment * typo * error incorrect * start comments * update test * add sample * update tests * update docstrings to add clarity * update err message * remove generated cloud event * update sample * update * update samples to include dict * update patch * spacing * add comments * formatting * update doc * update tests * update tests * tests * skip tests for now * typo * add dict binary mode * update docstring * update patch to allow throw error * first pass at comments * update patch eror * nit --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * [EGv2] Build Release (#30325) * move old sdk under legacy * gen typespec code * naming changes from archboard * samples * update patch naming * update imports with new gen * update samples * update client naming on aio * update receive op * update async to close client * update receive() * update gen code * moving around samples * updating samples * update samples * update patch and samples * patch internalmodels * spacing * updating model patch * update patch models * add both models back * update docstring * update docs * updating patch for receive * old EG models * add reject samples * patch * update format * update patch * eventgrid_client exceptions * update test imports * update total sample * receive patch fix * add in more tests * update test file * remove locktoken model * remove LockToken in patch * remove event delivery delay * eg client exceptions * .8.5 generation, and deliveryCount * rename sample * update version for beta * changelog * updating for gen * regen * generate via commit * publish result * fix docstring * publish docstring * return type * publish result * return publish result -- is none * format * update Publish result model * deliverycount patch * update from main * add copyright * added to readme * remove from readme * force publish_result response * update patch tp unindent * cspell * update mypy.ini * import order * mark livetest * update operations init * rename async * mypy * ignore mypy * pylint * pylint * ignore pylint for now to avoid gen code errors * ignore samples until ARM setup * update patches * remove publish result * remove PublishResult * remove publishresult * comma Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * update publishResult * change to .value * gen code " to ' * remove comment * ran black * update changelog * update sample readme * gen code without query name * gen code * update tsp commit * remove publishresult * readme disclaimer * update changelog --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * Beta LiveTests (#30728) * add bicep file for tests * update output * update test * secret sanitization * refactor failing test * update conftest * update assets and sanitizers * update preparer loc * update conftest * conftest * update conftest * remove variables for now * update assets * update tests * try to update regex * update recordings * update conftest * update preparer * update test * update exception test * update tests * update asset * update conftest * pr comments * default needs to be eastus * import * regen * new api version * samples for new features * update test-resources.json * update operation samples * add samples * more sample * update tests * add mros * gen * fix changelog * update tests * update preparer * point at canary until release * update test deployment area * update * add * try this tests * update samples * livetest mark * update tests * eastus working? * regen - removed azure refs in gen code * update comments * add other sample * update * remove stream - no response * update version and date for release --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- .vscode/cspell.json | 1 + sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 7 + sdk/eventgrid/azure-eventgrid/assets.json | 2 +- .../azure/eventgrid/_client.py | 13 +- .../azure/eventgrid/_configuration.py | 13 +- .../azure/eventgrid/_model_base.py | 13 +- .../azure/eventgrid/_operations/__init__.py | 2 +- .../eventgrid/_operations/_operations.py | 488 ++++++++++++++---- .../azure/eventgrid/_operations/_patch.py | 10 - .../azure/eventgrid/_serialization.py | 52 +- .../azure/eventgrid/aio/_client.py | 13 +- .../azure/eventgrid/aio/_configuration.py | 13 +- .../eventgrid/aio/_operations/__init__.py | 2 +- .../eventgrid/aio/_operations/_operations.py | 420 +++++++++++---- .../azure/eventgrid/aio/_operations/_patch.py | 10 - .../azure/eventgrid/models/__init__.py | 11 + .../azure/eventgrid/models/_enums.py | 26 + .../azure/eventgrid/models/_models.py | 268 +++++++--- .../sample_acknowledge_operation_async.py | 6 +- .../sample_all_operations_async.py | 10 +- .../sample_publish_receive_renew_async.py | 49 ++ .../sample_publish_release_receive_async.py | 65 +++ .../sample_receive_operation_async.py | 4 +- .../sample_reject_operation_async.py | 8 +- .../sample_release_operation_async.py | 7 +- .../sample_renew_locks_operation_async.py | 35 ++ .../sample_aad_auth_operation.py | 14 + .../sample_acknowledge_operation.py | 8 +- .../sample_all_operations.py | 10 +- .../sample_publish_receive_renew.py | 43 ++ .../sample_publish_release_receive.py | 59 +++ .../sample_receive_operation.py | 4 +- .../sample_reject_operation.py | 6 +- .../sample_release_operation.py | 7 +- .../sample_renew_locks_operation.py | 30 ++ sdk/eventgrid/azure-eventgrid/setup.py | 2 +- .../azure-eventgrid/tests/test_eg_client.py | 68 +-- .../tests/test_eg_client_exceptions.py | 12 +- .../tests/unittests/test_binary_mode.py | 1 - .../azure-eventgrid/tsp-location.yaml | 2 +- sdk/eventgrid/test-resources.json | 20 +- sdk/eventgrid/tests.yml | 1 + 42 files changed, 1398 insertions(+), 437 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 57b7071000b2..1a4b1f702e5e 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -299,6 +299,7 @@ "mibps", "mgmt", "mhsm", + "mros", "Nify", "mipsle", "mktime", diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index ef1aeefa75ad..5a0df93620fc 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -32,6 +32,13 @@ This version and all future versions will require Python 3.8+. ### Features Added - Added new enums values to `SystemEventNames` related to Azure Storage and Azure VMware Solution. +## 4.17.0b1 (2023-11-09) + +### Features Added + +- Added new features to the EventGridClient that supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. These features include a `renew_cloud_event_locks` operation, as well as a `release_with_delay` parameter on the `release_cloud_events` operation. +- `lock_tokens` parameter in `reject_cloud_events`, `release_cloud_events`, and `acknowledge_cloud_events` renamed to `reject_options`, `release_options`, and `acknowledge_options`. +- Added new models to support these new operations on EventGridClient. ## 4.16.0 (2023-11-08) diff --git a/sdk/eventgrid/azure-eventgrid/assets.json b/sdk/eventgrid/azure-eventgrid/assets.json index 46490ff40be4..d7404dd2fdd0 100644 --- a/sdk/eventgrid/azure-eventgrid/assets.json +++ b/sdk/eventgrid/azure-eventgrid/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/eventgrid/azure-eventgrid", - "Tag": "python/eventgrid/azure-eventgrid_fce4958e09" + "Tag": "python/eventgrid/azure-eventgrid_f155c8ac2d" } diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py index 329e214d89c1..a7b6c85bbe3e 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py @@ -11,6 +11,7 @@ from azure.core import PipelineClient from azure.core.credentials import AzureKeyCredential +from azure.core.pipeline import policies from azure.core.rest import HttpRequest, HttpResponse from ._configuration import EventGridClientConfiguration @@ -32,7 +33,7 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported + "2023-10-01-preview". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ @@ -45,7 +46,11 @@ def __init__( ) -> None: _endpoint = '{endpoint}' self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) - self._client: PipelineClient = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) + _policies = kwargs.pop('policies', None) + if _policies is None: + _policies = [policies.RequestIdPolicy(**kwargs),self._config.headers_policy,self._config.user_agent_policy,self._config.proxy_policy,policies.ContentDecodePolicy(**kwargs),self._config.redirect_policy,self._config.retry_policy,self._config.authentication_policy,self._config.custom_hook_policy,self._config.logging_policy,policies.DistributedTracingPolicy(**kwargs),policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,self._config.http_logging_policy] + self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + self._serialize = Serializer() self._deserialize = Deserializer() @@ -54,7 +59,7 @@ def __init__( def send_request( self, - request: HttpRequest, + request: HttpRequest, *, stream: bool = False, **kwargs: Any ) -> HttpResponse: """Runs the network request through the client's chained policies. @@ -80,7 +85,7 @@ def send_request( } request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, **kwargs) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore def close(self) -> None: self._client.close() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py index 8a5c765af4f5..a615bd59224d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py @@ -8,7 +8,6 @@ from typing import Any, TYPE_CHECKING, Union -from azure.core.configuration import Configuration from azure.core.credentials import AzureKeyCredential from azure.core.pipeline import policies @@ -19,9 +18,7 @@ from azure.core.credentials import TokenCredential -class EventGridClientConfiguration( # pylint: disable=too-many-instance-attributes,name-too-long - Configuration -): +class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -35,7 +32,7 @@ class EventGridClientConfiguration( # pylint: disable=too-many-instance-attri :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported + "2023-10-01-preview". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ @@ -46,8 +43,7 @@ def __init__( credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any ) -> None: - super(EventGridClientConfiguration, self).__init__(**kwargs) - api_version: str = kwargs.pop('api_version', "2023-06-01-preview") + api_version: str = kwargs.pop('api_version', "2023-10-01-preview") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") @@ -59,6 +55,7 @@ def __init__( self.api_version = api_version self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) def _infer_policy(self, **kwargs): @@ -77,9 +74,9 @@ def _configure( self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) - self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py index 2e328fc6adeb..8474b72c2346 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -31,7 +31,7 @@ _LOGGER = logging.getLogger(__name__) -__all__ = ["AzureJSONEncoder", "Model", "rest_field", "rest_discriminator"] +__all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] TZ_UTC = timezone.utc @@ -125,7 +125,7 @@ def _is_readonly(p): return False -class AzureJSONEncoder(JSONEncoder): +class SdkJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" def __init__(self, *args, exclude_readonly: bool = False, format: typing.Optional[str] = None, **kwargs): @@ -140,7 +140,7 @@ def default(self, o): # pylint: disable=too-many-return-statements return {k: v for k, v in o.items() if k not in readonly_props} return dict(o.items()) try: - return super(AzureJSONEncoder, self).default(o) + return super(SdkJSONEncoder, self).default(o) except TypeError: if isinstance(o, _Null): return None @@ -157,7 +157,7 @@ def default(self, o): # pylint: disable=too-many-return-statements except AttributeError: # This will be raised when it hits value.total_seconds in the method above pass - return super(AzureJSONEncoder, self).default(o) + return super(SdkJSONEncoder, self).default(o) _VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") @@ -553,7 +553,7 @@ def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing. if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + if exclude_readonly and k in readonly_props: # pyright: ignore[reportUnboundVariable] continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @@ -754,9 +754,12 @@ def _deserialize( value: typing.Any, module: typing.Optional[str] = None, rf: typing.Optional["_RestField"] = None, + format: typing.Optional[str] = None, ) -> typing.Any: if isinstance(value, PipelineResponse): value = value.http_response.json() + if rf is None and format: + rf = _RestField(format=format) deserializer = _get_deserialize_callable_from_annotation(deserializer, module, rf) return _deserialize_with_callable(deserializer, value) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py index 5d63b0e4eaa0..c166e5de9c64 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClientOperationsMixin +from ._operations import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index b665dd492629..50a506ffb3e5 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -18,7 +18,7 @@ from azure.core.utils import case_insensitive_dict from .. import models as _models -from .._model_base import AzureJSONEncoder, _deserialize +from .._model_base import SdkJSONEncoder, _deserialize from .._serialization import Serializer from .._vendor import EventGridClientMixinABC @@ -42,7 +42,7 @@ def build_event_grid_publish_cloud_event_request( # pylint: disable=name-too-lo _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: str = kwargs.pop('content_type') - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -77,7 +77,7 @@ def build_event_grid_publish_cloud_events_request( # pylint: disable=name-too-l _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: str = kwargs.pop('content_type') - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -115,7 +115,7 @@ def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-l _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -154,8 +154,8 @@ def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-t _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -171,9 +171,9 @@ def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-t _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers - if content_type is not None: - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + if content_type is not None: + _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') return HttpRequest( method="POST", @@ -187,13 +187,15 @@ def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-t def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -207,11 +209,13 @@ def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-l # Construct parameters _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + if release_delay_in_seconds is not None: + _params['releaseDelayInSeconds'] = _SERIALIZER.query("release_delay_in_seconds", release_delay_in_seconds, 'int') # Construct headers - if content_type is not None: - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + if content_type is not None: + _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') return HttpRequest( method="POST", @@ -230,8 +234,8 @@ def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-lo _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-06-01-preview")) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) accept = _headers.pop('Accept', "application/json") # Construct URL @@ -247,9 +251,47 @@ def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-lo _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') # Construct headers + _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') if content_type is not None: - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') + _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=_url, + params=_params, + headers=_headers, + **kwargs + ) + + +def build_event_grid_renew_cloud_event_locks_request( # pylint: disable=name-too-long + topic_name: str, + event_subscription_name: str, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) + accept = _headers.pop('Accept', "application/json") + + # Construct URL + _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:renewLock" + path_format_arguments = { + "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') + if content_type is not None: + _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') return HttpRequest( method="POST", @@ -302,9 +344,9 @@ def _publish_cloud_event( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_publish_cloud_event_request( + _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -315,11 +357,11 @@ def _publish_cloud_event( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -343,7 +385,7 @@ def _publish_cloud_event( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -386,9 +428,9 @@ def _publish_cloud_events( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_publish_cloud_events_request( + _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -399,11 +441,11 @@ def _publish_cloud_events( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -427,7 +469,7 @@ def _publish_cloud_events( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -475,7 +517,7 @@ def _receive_cloud_events( # pylint: disable=protected-access ) - request = build_event_grid_receive_cloud_events_request( + _request = build_event_grid_receive_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, max_events=max_events, @@ -487,11 +529,11 @@ def _receive_cloud_events( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -515,7 +557,7 @@ def _receive_cloud_events( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -524,13 +566,13 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.AcknowledgeOptions, + acknowledge_options: _models.AcknowledgeOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -538,8 +580,8 @@ def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -555,13 +597,13 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + acknowledge_options: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -569,8 +611,8 @@ def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: JSON + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -586,13 +628,13 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + acknowledge_options: IO, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -600,8 +642,8 @@ def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: IO + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: IO :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -618,11 +660,11 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.AcknowledgeOptions, JSON, IO], + acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO], **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -630,10 +672,11 @@ def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Is one of the following types: AcknowledgeOptions, - JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :param acknowledge_options: AcknowledgeOptions. Is one of the following types: + AcknowledgeOptions, JSON, IO Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -649,19 +692,19 @@ def acknowledge_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(acknowledge_options, (IOBase, bytes)): + _content = acknowledge_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(acknowledge_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_acknowledge_cloud_events_request( + _request = build_event_grid_acknowledge_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -673,11 +716,11 @@ def acknowledge_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -701,7 +744,7 @@ def acknowledge_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -710,21 +753,25 @@ def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.ReleaseOptions, + release_options: _models.ReleaseOptions, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions + :param release_options: ReleaseOptions. Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -740,21 +787,25 @@ def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + release_options: JSON, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: JSON + :param release_options: ReleaseOptions. Required. + :type release_options: JSON + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -770,21 +821,25 @@ def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + release_options: IO, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: IO + :param release_options: ReleaseOptions. Required. + :type release_options: IO + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -801,21 +856,27 @@ def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.ReleaseOptions, JSON, IO], + release_options: Union[_models.ReleaseOptions, JSON, IO], + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -831,21 +892,22 @@ def release_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(release_options, (IOBase, bytes)): + _content = release_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_release_cloud_events_request( + _request = build_event_grid_release_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, + release_delay_in_seconds=release_delay_in_seconds, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -855,11 +917,11 @@ def release_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -883,7 +945,7 @@ def release_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -892,19 +954,21 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.RejectOptions, + reject_options: _models.RejectOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.RejectOptions + :param reject_options: RejectOptions. Required. + :type reject_options: ~azure.eventgrid.models.RejectOptions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -920,19 +984,21 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + reject_options: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: JSON + :param reject_options: RejectOptions. Required. + :type reject_options: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -948,19 +1014,21 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + reject_options: IO, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: IO + :param reject_options: RejectOptions. Required. + :type reject_options: IO :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -977,19 +1045,22 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.RejectOptions, JSON, IO], + reject_options: Union[_models.RejectOptions, JSON, IO], **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Is one of the following types: RejectOptions, JSON, IO + :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.RejectOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -1005,19 +1076,19 @@ def reject_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.RejectResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(reject_options, (IOBase, bytes)): + _content = reject_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(reject_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_reject_cloud_events_request( + _request = build_event_grid_reject_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -1029,11 +1100,11 @@ def reject_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -1057,6 +1128,197 @@ def reject_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore + + + + @overload + def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: _models.RenewLockOptions, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace + def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: Union[_models.RenewLockOptions, JSON, IO], + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, + JSON, IO Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop( + 'cls', None + ) + + content_type = content_type or "application/json" + _content = None + if isinstance(renew_lock_options, (IOBase, bytes)): + _content = renew_lock_options + else: + _content = json.dumps(renew_lock_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_event_grid_renew_cloud_event_locks_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.RenewCloudEventLocksResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 79d4cd307960..3b2a6afdde76 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -63,8 +63,6 @@ def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -97,8 +95,6 @@ def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -131,8 +127,6 @@ def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -164,8 +158,6 @@ def publish_cloud_events( Requires CloudEvent data to be passed in as bytes. :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -197,8 +189,6 @@ def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index 7fd392a19926..c33dabefd203 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -63,8 +63,8 @@ import isodate # type: ignore -from azure.core.exceptions import DeserializationError, SerializationError, raise_with_traceback -from azure.core.serialization import NULL as AzureCoreNull +from azure.core.exceptions import DeserializationError, SerializationError +from azure.core.serialization import NULL as CoreNull _BOM = codecs.BOM_UTF8.decode(encoding="utf-8") @@ -124,7 +124,7 @@ def deserialize_from_text(cls, data: Optional[Union[AnyStr, IO]], content_type: pass return ET.fromstring(data_as_str) # nosec - except ET.ParseError: + except ET.ParseError as err: # It might be because the server has an issue, and returned JSON with # content-type XML.... # So let's try a JSON load, and if it's still broken @@ -143,7 +143,7 @@ def _json_attemp(data): # The function hack is because Py2.7 messes up with exception # context otherwise. _LOGGER.critical("Wasn't XML not JSON, failing") - raise_with_traceback(DeserializationError, "XML is invalid") + raise DeserializationError("XML is invalid") from err raise DeserializationError("Cannot deserialize content-type: {}".format(content_type)) @classmethod @@ -295,7 +295,7 @@ class Model(object): _validation: Dict[str, Dict[str, Any]] = {} def __init__(self, **kwargs: Any) -> None: - self.additional_properties: Dict[str, Any] = {} + self.additional_properties: Optional[Dict[str, Any]] = {} for k in kwargs: if k not in self._attribute_map: _LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__) @@ -340,7 +340,7 @@ def _create_xml_node(cls): return _create_xml_node(xml_map.get("name", cls.__name__), xml_map.get("prefix", None), xml_map.get("ns", None)) def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: - """Return the JSON that would be sent to azure from this model. + """Return the JSON that would be sent to server from this model. This is an alias to `as_dict(full_restapi_key_transformer, keep_readonly=False)`. @@ -351,7 +351,7 @@ def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: :rtype: dict """ serializer = Serializer(self._infer_class_models()) - return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) + return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) # type: ignore def as_dict( self, @@ -392,7 +392,7 @@ def my_key_transformer(key, attr_desc, value): :rtype: dict """ serializer = Serializer(self._infer_class_models()) - return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) + return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) # type: ignore @classmethod def _infer_class_models(cls): @@ -417,7 +417,7 @@ def deserialize(cls: Type[ModelType], data: Any, content_type: Optional[str] = N :raises: DeserializationError if something went wrong """ deserializer = Deserializer(cls._infer_class_models()) - return deserializer(cls.__name__, data, content_type=content_type) + return deserializer(cls.__name__, data, content_type=content_type) # type: ignore @classmethod def from_dict( @@ -447,7 +447,7 @@ def from_dict( if key_extractors is None else key_extractors ) - return deserializer(cls.__name__, data, content_type=content_type) + return deserializer(cls.__name__, data, content_type=content_type) # type: ignore @classmethod def _flatten_subtype(cls, key, objects): @@ -670,7 +670,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): except (AttributeError, KeyError, TypeError) as err: msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj)) - raise_with_traceback(SerializationError, msg, err) + raise SerializationError(msg) from err else: return serialized @@ -712,7 +712,7 @@ def body(self, data, data_type, **kwargs): ] data = deserializer._deserialize(data_type, data) except DeserializationError as err: - raise_with_traceback(SerializationError, "Unable to build a model: " + str(err), err) + raise SerializationError("Unable to build a model: " + str(err)) from err return self._serialize(data, data_type, **kwargs) @@ -732,7 +732,6 @@ def url(self, name, data, data_type, **kwargs): if kwargs.get("skip_quote") is True: output = str(output) - # https://github.com/Azure/autorest.python/issues/2063 output = output.replace("{", quote("{")).replace("}", quote("}")) else: output = quote(str(output), safe="") @@ -757,7 +756,7 @@ def query(self, name, data, data_type, **kwargs): if data_type.startswith("["): internal_data_type = data_type[1:-1] do_quote = not kwargs.get('skip_quote', False) - return str(self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs)) + return self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs) # Not a list, regular serialization output = self.serialize_data(data, data_type, **kwargs) @@ -808,7 +807,7 @@ def serialize_data(self, data, data_type, **kwargs): raise ValueError("No value for given attribute") try: - if data is AzureCoreNull: + if data is CoreNull: return None if data_type in self.basic_types.values(): return self.serialize_basic(data, data_type, **kwargs) @@ -828,7 +827,7 @@ def serialize_data(self, data, data_type, **kwargs): except (ValueError, TypeError) as err: msg = "Unable to serialize value: {!r} as type: {!r}." - raise_with_traceback(SerializationError, msg.format(data, data_type), err) + raise SerializationError(msg.format(data, data_type)) from err else: return self._serialize(data, **kwargs) @@ -1178,10 +1177,10 @@ def serialize_iso(attr, **kwargs): return date + microseconds + "Z" except (ValueError, OverflowError) as err: msg = "Unable to serialize datetime object." - raise_with_traceback(SerializationError, msg, err) + raise SerializationError(msg) from err except AttributeError as err: msg = "ISO-8601 object must be valid Datetime object." - raise_with_traceback(TypeError, msg, err) + raise TypeError(msg) from err @staticmethod def serialize_unix(attr, **kwargs): @@ -1217,7 +1216,6 @@ def rest_key_extractor(attr, attr_desc, data): if working_data is None: # If at any point while following flatten JSON path see None, it means # that all properties under are None as well - # https://github.com/Azure/msrest-for-python/issues/197 return None key = ".".join(dict_keys[1:]) @@ -1238,7 +1236,6 @@ def rest_key_case_insensitive_extractor(attr, attr_desc, data): if working_data is None: # If at any point while following flatten JSON path see None, it means # that all properties under are None as well - # https://github.com/Azure/msrest-for-python/issues/197 return None key = ".".join(dict_keys[1:]) @@ -1489,7 +1486,7 @@ def _deserialize(self, target_obj, data): d_attrs[attr] = value except (AttributeError, TypeError, KeyError) as err: msg = "Unable to deserialize to object: " + class_name # type: ignore - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: additional_properties = self._build_additional_properties(attributes, data) return self._instantiate_model(response, d_attrs, additional_properties) @@ -1660,7 +1657,7 @@ def deserialize_data(self, data, data_type): except (ValueError, TypeError, AttributeError) as err: msg = "Unable to deserialize response data." msg += " Data: {}, {}".format(data, data_type) - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: return self._deserialize(obj_type, data) @@ -1816,7 +1813,6 @@ def deserialize_enum(data, enum_obj): data = data.value if isinstance(data, int): # Workaround. We might consider remove it in the future. - # https://github.com/Azure/azure-rest-api-specs/issues/141 try: return list(enum_obj.__members__.values())[data] except IndexError: @@ -1873,7 +1869,7 @@ def deserialize_decimal(attr): return decimal.Decimal(attr) # type: ignore except decimal.DecimalException as err: msg = "Invalid decimal {}".format(attr) - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err @staticmethod def deserialize_long(attr): @@ -1901,7 +1897,7 @@ def deserialize_duration(attr): duration = isodate.parse_duration(attr) except (ValueError, OverflowError, AttributeError) as err: msg = "Cannot deserialize duration object." - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: return duration @@ -1953,7 +1949,7 @@ def deserialize_rfc(attr): date_obj = date_obj.astimezone(tz=TZ_UTC) except ValueError as err: msg = "Cannot deserialize to rfc datetime object." - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: return date_obj @@ -1990,7 +1986,7 @@ def deserialize_iso(attr): raise OverflowError("Hit max or min date") except (ValueError, OverflowError, AttributeError) as err: msg = "Cannot deserialize datetime object." - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: return date_obj @@ -2009,6 +2005,6 @@ def deserialize_unix(attr): date_obj = datetime.datetime.fromtimestamp(attr, TZ_UTC) except ValueError as err: msg = "Cannot deserialize to unix datetime object." - raise_with_traceback(DeserializationError, msg, err) + raise DeserializationError(msg) from err else: return date_obj diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py index e1d0a000fbde..064da9dbacfb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py @@ -11,6 +11,7 @@ from azure.core import AsyncPipelineClient from azure.core.credentials import AzureKeyCredential +from azure.core.pipeline import policies from azure.core.rest import AsyncHttpResponse, HttpRequest from .._serialization import Deserializer, Serializer @@ -32,7 +33,7 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported + "2023-10-01-preview". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ @@ -45,7 +46,11 @@ def __init__( ) -> None: _endpoint = '{endpoint}' self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) - self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) + _policies = kwargs.pop('policies', None) + if _policies is None: + _policies = [policies.RequestIdPolicy(**kwargs),self._config.headers_policy,self._config.user_agent_policy,self._config.proxy_policy,policies.ContentDecodePolicy(**kwargs),self._config.redirect_policy,self._config.retry_policy,self._config.authentication_policy,self._config.custom_hook_policy,self._config.logging_policy,policies.DistributedTracingPolicy(**kwargs),policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,self._config.http_logging_policy] + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + self._serialize = Serializer() self._deserialize = Deserializer() @@ -54,7 +59,7 @@ def __init__( def send_request( self, - request: HttpRequest, + request: HttpRequest, *, stream: bool = False, **kwargs: Any ) -> Awaitable[AsyncHttpResponse]: """Runs the network request through the client's chained policies. @@ -80,7 +85,7 @@ def send_request( } request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, **kwargs) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore async def close(self) -> None: await self._client.close() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py index b06679bc2d67..847e9019f9dc 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py @@ -8,7 +8,6 @@ from typing import Any, TYPE_CHECKING, Union -from azure.core.configuration import Configuration from azure.core.credentials import AzureKeyCredential from azure.core.pipeline import policies @@ -19,9 +18,7 @@ from azure.core.credentials_async import AsyncTokenCredential -class EventGridClientConfiguration( # pylint: disable=too-many-instance-attributes,name-too-long - Configuration -): +class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -35,7 +32,7 @@ class EventGridClientConfiguration( # pylint: disable=too-many-instance-attri :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: The API version to use for this operation. Default value is - "2023-06-01-preview". Note that overriding this default value may result in unsupported + "2023-10-01-preview". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ @@ -46,8 +43,7 @@ def __init__( credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: - super(EventGridClientConfiguration, self).__init__(**kwargs) - api_version: str = kwargs.pop('api_version', "2023-06-01-preview") + api_version: str = kwargs.pop('api_version', "2023-10-01-preview") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") @@ -59,6 +55,7 @@ def __init__( self.api_version = api_version self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) def _infer_policy(self, **kwargs): @@ -77,9 +74,9 @@ def _configure( self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) - self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py index 5d63b0e4eaa0..c166e5de9c64 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClientOperationsMixin +from ._operations import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index eb2c6cc3182f..aab392f5cf99 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -18,8 +18,8 @@ from azure.core.utils import case_insensitive_dict from ... import models as _models -from ..._model_base import AzureJSONEncoder, _deserialize -from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request +from ..._model_base import SdkJSONEncoder, _deserialize +from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request, build_event_grid_renew_cloud_event_locks_request from .._vendor import EventGridClientMixinABC if sys.version_info >= (3, 9): @@ -73,9 +73,9 @@ async def _publish_cloud_event( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_publish_cloud_event_request( + _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -86,11 +86,11 @@ async def _publish_cloud_event( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -114,7 +114,7 @@ async def _publish_cloud_event( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -157,9 +157,9 @@ async def _publish_cloud_events( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_publish_cloud_events_request( + _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -170,11 +170,11 @@ async def _publish_cloud_events( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -198,7 +198,7 @@ async def _publish_cloud_events( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -246,7 +246,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access ) - request = build_event_grid_receive_cloud_events_request( + _request = build_event_grid_receive_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, max_events=max_events, @@ -258,11 +258,11 @@ async def _receive_cloud_events( # pylint: disable=protected-access path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -286,7 +286,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -295,13 +295,13 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.AcknowledgeOptions, + acknowledge_options: _models.AcknowledgeOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -309,8 +309,8 @@ async def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -326,13 +326,13 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + acknowledge_options: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -340,8 +340,8 @@ async def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: JSON + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -357,13 +357,13 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + acknowledge_options: IO, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -371,8 +371,8 @@ async def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Required. - :type lock_tokens: IO + :param acknowledge_options: AcknowledgeOptions. Required. + :type acknowledge_options: IO :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -389,11 +389,11 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.AcknowledgeOptions, JSON, IO], + acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO], **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if at least - one event is successfully acknowledged. The response body will include the set of successfully + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully acknowledged lockTokens, along with other failed lockTokens with their corresponding error information. Successfully acknowledged events will no longer be available to any consumer. @@ -401,10 +401,11 @@ async def acknowledge_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: AcknowledgeOptions. Is one of the following types: AcknowledgeOptions, - JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :param acknowledge_options: AcknowledgeOptions. Is one of the following types: + AcknowledgeOptions, JSON, IO Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -420,19 +421,19 @@ async def acknowledge_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(acknowledge_options, (IOBase, bytes)): + _content = acknowledge_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(acknowledge_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_acknowledge_cloud_events_request( + _request = build_event_grid_acknowledge_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -444,11 +445,11 @@ async def acknowledge_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -472,7 +473,7 @@ async def acknowledge_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -481,21 +482,25 @@ async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.ReleaseOptions, + release_options: _models.ReleaseOptions, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions + :param release_options: ReleaseOptions. Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -511,21 +516,25 @@ async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + release_options: JSON, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: JSON + :param release_options: ReleaseOptions. Required. + :type release_options: JSON + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -541,21 +550,25 @@ async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + release_options: IO, *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Required. - :type lock_tokens: IO + :param release_options: ReleaseOptions. Required. + :type release_options: IO + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -572,21 +585,27 @@ async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.ReleaseOptions, JSON, IO], + release_options: Union[_models.ReleaseOptions, JSON, IO], + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if at least one - event is successfully released. The response body will include the set of successfully released + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.ReleaseOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -602,21 +621,22 @@ async def release_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(release_options, (IOBase, bytes)): + _content = release_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_release_cloud_events_request( + _request = build_event_grid_release_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, + release_delay_in_seconds=release_delay_in_seconds, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -626,11 +646,11 @@ async def release_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -654,7 +674,7 @@ async def release_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore @@ -663,19 +683,21 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: _models.RejectOptions, + reject_options: _models.RejectOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: ~azure.eventgrid.models.RejectOptions + :param reject_options: RejectOptions. Required. + :type reject_options: ~azure.eventgrid.models.RejectOptions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -691,19 +713,21 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: JSON, + reject_options: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: JSON + :param reject_options: RejectOptions. Required. + :type reject_options: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -719,19 +743,21 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: IO, + reject_options: IO, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Required. - :type lock_tokens: IO + :param reject_options: RejectOptions. Required. + :type reject_options: IO :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str @@ -748,19 +774,22 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - lock_tokens: Union[_models.RejectOptions, JSON, IO], + reject_options: Union[_models.RejectOptions, JSON, IO], **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param lock_tokens: RejectOptions. Is one of the following types: RejectOptions, JSON, IO + :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, IO Required. - :type lock_tokens: ~azure.eventgrid.models.RejectOptions or JSON or IO - :keyword content_type: content type. Default value is None. + :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. :paramtype content_type: str :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You will have to context manage the returned stream. @@ -776,19 +805,19 @@ async def reject_cloud_events( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('content-type', None)) + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) cls: ClsType[_models.RejectResult] = kwargs.pop( 'cls', None ) content_type = content_type or "application/json" _content = None - if isinstance(lock_tokens, (IOBase, bytes)): - _content = lock_tokens + if isinstance(reject_options, (IOBase, bytes)): + _content = reject_options else: - _content = json.dumps(lock_tokens, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(reject_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - request = build_event_grid_reject_cloud_events_request( + _request = build_event_grid_reject_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -800,11 +829,11 @@ async def reject_cloud_events( path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - request.url = self._client.format_url(request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - request, + _request, stream=_stream, **kwargs ) @@ -828,6 +857,197 @@ async def reject_cloud_events( if cls: return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore + + + + @overload + async def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: _models.RenewLockOptions, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: IO, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Required. + :type renew_lock_options: IO + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + + @distributed_trace_async + async def renew_cloud_event_locks( + self, + topic_name: str, + event_subscription_name: str, + renew_lock_options: Union[_models.RenewLockOptions, JSON, IO], + **kwargs: Any + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param event_subscription_name: Event Subscription Name. Required. + :type event_subscription_name: str + :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, + JSON, IO Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You + will have to context manage the returned stream. + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop( + 'cls', None + ) + + content_type = content_type or "application/json" + _content = None + if isinstance(renew_lock_options, (IOBase, bytes)): + _content = renew_lock_options + else: + _content = json.dumps(renew_lock_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_event_grid_renew_cloud_event_locks_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.RenewCloudEventLocksResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 6dc63a1bdfe0..6b20e911093d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -55,8 +55,6 @@ async def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -89,8 +87,6 @@ async def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -123,8 +119,6 @@ async def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -157,8 +151,6 @@ async def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -190,8 +182,6 @@ async def publish_cloud_events( :keyword content_type: content type. Default value is "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py index bb787a2e0c74..7d7d97b1ac12 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py @@ -8,22 +8,33 @@ from ._models import AcknowledgeOptions from ._models import AcknowledgeResult +from ._models import Error from ._models import FailedLockToken +from ._models import InnerError from ._models import RejectOptions from ._models import RejectResult from ._models import ReleaseOptions from ._models import ReleaseResult +from ._models import RenewCloudEventLocksResult +from ._models import RenewLockOptions + +from ._enums import ReleaseDelay from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk __all__ = [ 'AcknowledgeOptions', 'AcknowledgeResult', + 'Error', 'FailedLockToken', + 'InnerError', 'RejectOptions', 'RejectResult', 'ReleaseOptions', 'ReleaseResult', + 'RenewCloudEventLocksResult', + 'RenewLockOptions', + 'ReleaseDelay', ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py new file mode 100644 index 000000000000..74f1f5e2eaf7 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py @@ -0,0 +1,26 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum +from azure.core import CaseInsensitiveEnumMeta + + +class ReleaseDelay(int, Enum, metaclass=CaseInsensitiveEnumMeta): + """Supported delays for release operation. + """ + + BY0_SECONDS = 0 + """Release the event after 0 seconds.""" + BY10_SECONDS = 10 + """Release the event after 10 seconds.""" + BY60_SECONDS = 60 + """Release the event after 60 seconds.""" + BY600_SECONDS = 600 + """Release the event after 600 seconds.""" + BY3600_SECONDS = 3600 + """Release the event after 3600 seconds.""" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index 5cf7dd673acd..588b90e04c7d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -19,16 +19,16 @@ class AcknowledgeOptions(_model_base.Model): - """Array of lock token strings for the corresponding received Cloud Events to be acknowledged. + """Array of lock tokens for the corresponding received Cloud Events to be acknowledged. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar lock_tokens: String array of lock tokens. Required. + :ivar lock_tokens: Array of lock tokens. Required. :vartype lock_tokens: list[str] """ lock_tokens: List[str] = rest_field(name="lockTokens") - """String array of lock tokens. Required.""" + """Array of lock tokens. Required.""" @overload def __init__( @@ -52,22 +52,22 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- class AcknowledgeResult(_model_base.Model): """The result of the Acknowledge operation. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken - includes the lock token value along with the related error information (namely, the error code - and description). Required. + :ivar failed_lock_tokens: Array of FailedLockToken for failed cloud events. Each + FailedLockToken includes the lock token along with the related error information (namely, the + error code and description). Required. :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] - :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully acknowledged - cloud events. Required. + :ivar succeeded_lock_tokens: Array of lock tokens for the successfully acknowledged cloud + events. Required. :vartype succeeded_lock_tokens: list[str] """ failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") - """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + """Array of FailedLockToken for failed cloud events. Each FailedLockToken includes the lock token along with the related error information (namely, the error code and description). Required.""" succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") - """Array of lock tokens values for the successfully acknowledged cloud events. Required.""" + """Array of lock tokens for the successfully acknowledged cloud events. Required.""" @overload def __init__( @@ -92,16 +92,16 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- class BrokerProperties(_model_base.Model): """Properties of the Event Broker operation. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar lock_token: The token used to lock the event. Required. + :ivar lock_token: The token of the lock on the event. Required. :vartype lock_token: str :ivar delivery_count: The attempt count for delivering the event. Required. :vartype delivery_count: int """ lock_token: str = rest_field(name="lockToken") - """The token used to lock the event. Required.""" + """The token of the lock on the event. Required.""" delivery_count: int = rest_field(name="deliveryCount") """The attempt count for delivering the event. Required.""" @@ -111,7 +111,7 @@ class CloudEvent(_model_base.Model): """Properties of an event published to an Azure Messaging EventGrid Namespace topic using the CloudEvent 1.0 Schema. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. :ivar id: An identifier for the event. The combination of id and source must be unique for each distinct event. Required. @@ -164,37 +164,117 @@ class CloudEvent(_model_base.Model): +class Error(_model_base.Model): + """The error object. + + All required parameters must be populated in order to send to server. + + :ivar code: One of a server-defined set of error codes. Required. + :vartype code: str + :ivar message: A human-readable representation of the error. Required. + :vartype message: str + :ivar target: The target of the error. + :vartype target: str + :ivar details: An array of details about specific errors that led to this reported error. + :vartype details: list[~azure.eventgrid.models.Error] + :ivar innererror: An object containing more specific information than the current object about + the error. + :vartype innererror: ~azure.eventgrid.models.InnerError + """ + + code: str = rest_field() + """One of a server-defined set of error codes. Required.""" + message: str = rest_field() + """A human-readable representation of the error. Required.""" + target: Optional[str] = rest_field() + """The target of the error.""" + details: Optional[List["_models.Error"]] = rest_field() + """An array of details about specific errors that led to this reported error.""" + innererror: Optional["_models.InnerError"] = rest_field() + """An object containing more specific information than the current object about the error.""" + + @overload + def __init__( + self, + *, + code: str, + message: str, + target: Optional[str] = None, + details: Optional[List["_models.Error"]] = None, + innererror: Optional["_models.InnerError"] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + class FailedLockToken(_model_base.Model): """Failed LockToken information. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar lock_token: LockToken value. Required. + :ivar lock_token: The lock token of an entry in the request. Required. :vartype lock_token: str - :ivar error_code: Error code related to the token. Example of such error codes are BadToken: - which indicates the Token is not formatted correctly, TokenLost: which indicates that token is - not found, and InternalServerError: For any internal server errors. Required. - :vartype error_code: str - :ivar error_description: Description of the token error. Required. - :vartype error_description: str + :ivar error: Error information of the failed operation result for the lock token in the + request. Required. + :vartype error: ~azure.eventgrid.models.Error """ lock_token: str = rest_field(name="lockToken") - """LockToken value. Required.""" - error_code: str = rest_field(name="errorCode") - """Error code related to the token. Example of such error codes are BadToken: which indicates the - Token is not formatted correctly, TokenLost: which indicates that token is not found, and - InternalServerError: For any internal server errors. Required.""" - error_description: str = rest_field(name="errorDescription") - """Description of the token error. Required.""" + """The lock token of an entry in the request. Required.""" + error: "_models.Error" = rest_field() + """Error information of the failed operation result for the lock token in the request. Required.""" @overload def __init__( self, *, lock_token: str, - error_code: str, - error_description: str, + error: "_models.Error", + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class InnerError(_model_base.Model): + """An object containing more specific information about the error. As per Microsoft One API + guidelines - + https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses. + + :ivar code: One of a server-defined set of error codes. + :vartype code: str + :ivar innererror: Inner error. + :vartype innererror: ~azure.eventgrid.models.InnerError + """ + + code: Optional[str] = rest_field() + """One of a server-defined set of error codes.""" + innererror: Optional["_models.InnerError"] = rest_field() + """Inner error.""" + + @overload + def __init__( + self, + *, + code: Optional[str] = None, + innererror: Optional["_models.InnerError"] = None, ): ... @@ -220,7 +300,7 @@ class PublishResult(_model_base.Model): class ReceiveDetails(_model_base.Model): """Receive operation details per Cloud Event. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. :ivar broker_properties: The Event Broker details. Required. :vartype broker_properties: ~azure.eventgrid.models.BrokerProperties @@ -238,7 +318,7 @@ class ReceiveDetails(_model_base.Model): class ReceiveResult(_model_base.Model): """Details of the Receive operation response. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. :ivar value: Array of receive responses, one per cloud event. Required. :vartype value: list[~azure.eventgrid.models.ReceiveDetails] @@ -250,16 +330,16 @@ class ReceiveResult(_model_base.Model): class RejectOptions(_model_base.Model): - """Array of lock token strings for the corresponding received Cloud Events to be rejected. + """Array of lock tokens for the corresponding received Cloud Events to be rejected. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar lock_tokens: String array of lock tokens. Required. + :ivar lock_tokens: Array of lock tokens. Required. :vartype lock_tokens: list[str] """ lock_tokens: List[str] = rest_field(name="lockTokens") - """String array of lock tokens. Required.""" + """Array of lock tokens. Required.""" @overload def __init__( @@ -283,22 +363,22 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- class RejectResult(_model_base.Model): """The result of the Reject operation. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken - includes the lock token value along with the related error information (namely, the error code - and description). Required. + :ivar failed_lock_tokens: Array of FailedLockToken for failed cloud events. Each + FailedLockToken includes the lock token along with the related error information (namely, the + error code and description). Required. :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] - :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully rejected cloud - events. Required. + :ivar succeeded_lock_tokens: Array of lock tokens for the successfully rejected cloud events. + Required. :vartype succeeded_lock_tokens: list[str] """ failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") - """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + """Array of FailedLockToken for failed cloud events. Each FailedLockToken includes the lock token along with the related error information (namely, the error code and description). Required.""" succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") - """Array of lock tokens values for the successfully rejected cloud events. Required.""" + """Array of lock tokens for the successfully rejected cloud events. Required.""" @overload def __init__( @@ -321,16 +401,16 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- class ReleaseOptions(_model_base.Model): - """Array of lock token strings for the corresponding received Cloud Events to be released. + """Array of lock tokens for the corresponding received Cloud Events to be released. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar lock_tokens: String array of lock tokens. Required. + :ivar lock_tokens: Array of lock tokens. Required. :vartype lock_tokens: list[str] """ lock_tokens: List[str] = rest_field(name="lockTokens") - """String array of lock tokens. Required.""" + """Array of lock tokens. Required.""" @overload def __init__( @@ -354,22 +434,61 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless- class ReleaseResult(_model_base.Model): """The result of the Release operation. - All required parameters must be populated in order to send to Azure. + All required parameters must be populated in order to send to server. - :ivar failed_lock_tokens: Array of LockToken values for failed cloud events. Each LockToken - includes the lock token value along with the related error information (namely, the error code - and description). Required. + :ivar failed_lock_tokens: Array of FailedLockToken for failed cloud events. Each + FailedLockToken includes the lock token along with the related error information (namely, the + error code and description). Required. :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] - :ivar succeeded_lock_tokens: Array of lock tokens values for the successfully released cloud - events. Required. + :ivar succeeded_lock_tokens: Array of lock tokens for the successfully released cloud events. + Required. + :vartype succeeded_lock_tokens: list[str] + """ + + failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") + """Array of FailedLockToken for failed cloud events. Each FailedLockToken includes the lock token + along with the related error information (namely, the error code and description). Required.""" + succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") + """Array of lock tokens for the successfully released cloud events. Required.""" + + @overload + def __init__( + self, + *, + failed_lock_tokens: List["_models.FailedLockToken"], + succeeded_lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class RenewCloudEventLocksResult(_model_base.Model): + """The result of the RenewLock operation. + + All required parameters must be populated in order to send to server. + + :ivar failed_lock_tokens: Array of FailedLockToken for failed cloud events. Each + FailedLockToken includes the lock token along with the related error information (namely, the + error code and description). Required. + :vartype failed_lock_tokens: list[~azure.eventgrid.models.FailedLockToken] + :ivar succeeded_lock_tokens: Array of lock tokens for the successfully renewed locks. Required. :vartype succeeded_lock_tokens: list[str] """ failed_lock_tokens: List["_models.FailedLockToken"] = rest_field(name="failedLockTokens") - """Array of LockToken values for failed cloud events. Each LockToken includes the lock token value + """Array of FailedLockToken for failed cloud events. Each FailedLockToken includes the lock token along with the related error information (namely, the error code and description). Required.""" succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") - """Array of lock tokens values for the successfully released cloud events. Required.""" + """Array of lock tokens for the successfully renewed locks. Required.""" @overload def __init__( @@ -389,3 +508,34 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + +class RenewLockOptions(_model_base.Model): + """Array of lock tokens for the corresponding received Cloud Events to be renewed. + + All required parameters must be populated in order to send to server. + + :ivar lock_tokens: Array of lock tokens. Required. + :vartype lock_tokens: list[str] + """ + + lock_tokens: List[str] = rest_field(name="lockTokens") + """Array of lock tokens. Required.""" + + @overload + def __init__( + self, + *, + lock_tokens: List[str], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py index bea9e4c5cb7e..bc53812fa804 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -12,8 +12,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) @@ -27,7 +27,7 @@ async def run(): ack_events = await client.acknowledge_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, + acknowledge_options=lock_tokens, ) print(ack_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index 19e5863f7f2b..d31666095998 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -13,8 +13,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client @@ -86,7 +86,7 @@ async def run(): release_result = await client.release_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=release_tokens, + release_options=release_tokens, ) except HttpResponseError: raise @@ -100,7 +100,7 @@ async def run(): ack_result = await client.acknowledge_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=ack_tokens, + acknowledge_options=ack_tokens, ) except HttpResponseError: raise @@ -114,7 +114,7 @@ async def run(): reject_result = await client.reject_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=reject_tokens, + reject_options=reject_tokens, ) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py new file mode 100644 index 000000000000..62d02f707f80 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py @@ -0,0 +1,49 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + + +async def run(): + # Create a client + client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + async with client: + try: + # Publish a CloudEvent + cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + + # Receive CloudEvents and parse out lock tokens + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + lock_tokens_to_release = [] + for item in receive_result.value: + lock_tokens_to_release.append(item.broker_properties.lock_token) + + # Renew lock tokens + lock_tokens = RenewLockOptions(lock_tokens=lock_tokens_to_release) + renew_events = await client.renew_cloud_event_locks( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + renew_lock_options=lock_tokens, + ) + print("Renewed Event:", renew_events) + except HttpResponseError: + raise + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(run()) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py new file mode 100644 index 000000000000..895640a9d8f6 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py @@ -0,0 +1,65 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + + +async def run(): + # Create a client + client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + async with client: + try: + # Publish a CloudEvent + cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + + # Receive CloudEvents and parse out lock tokens + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + lock_tokens_to_release = [] + for item in receive_result.value: + lock_tokens_to_release.append(item.broker_properties.lock_token) + + print("Received events:", receive_result.value) + + # Release a LockToken + release_token = ReleaseOptions(lock_tokens=lock_tokens_to_release) + release_events = await client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + release_delay_in_seconds=60, + release_options=release_token, + ) + print("Released Event:", release_events) + + # Receive CloudEvents again + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + print("Received events after release:", receive_result.value) + + # Acknowledge LockTokens + acknowledge_token = AcknowledgeOptions(lock_tokens=lock_tokens_to_release) + acknowledge_events = await client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + acknowledge_options=acknowledge_token, + ) + print("Acknowledged events after release:", acknowledge_events) + except HttpResponseError: + raise + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(run()) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py index a25f09a40fed..6d136c5ff5e4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -12,8 +12,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py index e46356e08fbf..c1ea4b70c3dd 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -12,22 +12,22 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) async def run(): - # Release a LockToken + # Reject a LockToken try: async with client: tokens = RejectOptions(lock_tokens=["token"]) reject_events = await client.reject_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=tokens, + reject_options=tokens, ) print(reject_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index 117dadf79287..0ef5fc8dd4ab 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -12,8 +12,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) @@ -27,7 +27,8 @@ async def run(): release_events = await client.release_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=tokens, + release_delay_in_seconds=10, + release_options=tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py new file mode 100644 index 000000000000..89938ee40978 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py @@ -0,0 +1,35 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + +async def run(): + # Renew a lockToken + try: + lock_tokens = RenewLockOptions(lock_tokens=["token"]) + release_events = await client.renew_cloud_event_locks( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + renew_lock_options=lock_tokens, + ) + print(release_events) + except HttpResponseError: + raise + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py new file mode 100644 index 000000000000..780c9cc975e2 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py @@ -0,0 +1,14 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.identity import DefaultAzureCredential + +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] + +# Create a client using DefaultAzureCredential +client = EventGridClient(EVENTGRID_ENDPOINT, DefaultAzureCredential()) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py index 78bfdc1162fb..72a5518c6228 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py @@ -11,20 +11,20 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) -# Acknowledge a batch of CloudEvents +# Acknowledge a CloudEvent try: lock_tokens = AcknowledgeOptions(lock_tokens=["token"]) ack_events = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, + acknowledge_options=lock_tokens, ) print(ack_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py index db6863811b7f..52d12730c41d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -13,8 +13,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client @@ -79,7 +79,7 @@ release_result = client.release_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=release_tokens, + release_options=release_tokens, ) except HttpResponseError: raise @@ -93,7 +93,7 @@ ack_result = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=ack_tokens, + acknowledge_options=ack_tokens, ) except HttpResponseError: raise @@ -107,7 +107,7 @@ reject_result = client.reject_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=reject_tokens, + reject_options=reject_tokens, ) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py new file mode 100644 index 000000000000..38492b231d7b --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py @@ -0,0 +1,43 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +try: + # Publish a CloudEvent + cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + + # Receive CloudEvents and parse out lock tokens + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + lock_tokens_to_release = [] + for item in receive_result.value: + lock_tokens_to_release.append(item.broker_properties.lock_token) + + # Renew a lock token + lock_tokens = RenewLockOptions(lock_tokens=lock_tokens_to_release) + renew_events = client.renew_cloud_event_locks( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + renew_lock_options=lock_tokens, + ) + print("Renewed Event:", renew_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py new file mode 100644 index 000000000000..ef97375c3f0b --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py @@ -0,0 +1,59 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError + + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + + +try: + # Publish a CloudEvent + cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + + # Receive CloudEvents and parse out lock tokens + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + lock_tokens_to_release = [] + for item in receive_result.value: + lock_tokens_to_release.append(item.broker_properties.lock_token) + + print("Received events:", receive_result.value) + + # Release a LockToken + release_token = ReleaseOptions(lock_tokens=lock_tokens_to_release) + release_events = client.release_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + release_delay_in_seconds=60, + release_options=release_token, + ) + print("Released Event:", release_events) + + # Receive CloudEvents again + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + print("Received events after release:", receive_result.value) + + # Acknowledge a LockToken + acknowledge_token = AcknowledgeOptions(lock_tokens=lock_tokens_to_release) + acknowledge_events = client.acknowledge_cloud_events( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + acknowledge_options=acknowledge_token, + ) + print("Acknowledged events after release:", acknowledge_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py index aefd6c39275f..20252bda9cac 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py @@ -11,8 +11,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py index a24a07a8ed74..3f6e87b8e050 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py @@ -11,8 +11,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) @@ -23,7 +23,7 @@ reject_events = client.reject_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, + reject_options=lock_tokens, ) print(reject_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py index 60db8ed9f5e6..8d7df562004a 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -11,8 +11,8 @@ EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENT_SUBSCRIPTION_NAME"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) @@ -23,7 +23,8 @@ release_events = client.release_cloud_events( topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, + release_delay_in_seconds=3600, + release_options=lock_tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py new file mode 100644 index 000000000000..82a4fd9f5f47 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import os +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient +from azure.eventgrid.models import * +from azure.core.exceptions import HttpResponseError + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +# Create a client +client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + +# Renew a lockToken +try: + lock_tokens = RenewLockOptions(lock_tokens=["token"]) + release_events = client.renew_cloud_event_locks( + topic_name=TOPIC_NAME, + event_subscription_name=EVENT_SUBSCRIPTION_NAME, + renew_lock_options=lock_tokens, + ) + print(release_events) +except HttpResponseError: + raise diff --git a/sdk/eventgrid/azure-eventgrid/setup.py b/sdk/eventgrid/azure-eventgrid/setup.py index 7a861fa486eb..adf215e92d0e 100644 --- a/sdk/eventgrid/azure-eventgrid/setup.py +++ b/sdk/eventgrid/azure-eventgrid/setup.py @@ -60,7 +60,7 @@ ), include_package_data=True, package_data={ - "pytyped": ["py.typed"], + "azure.eventgrid": ["py.typed"], }, install_requires=[ "isodate>=0.6.1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py index ed092f4e3b39..d08679335a42 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -23,12 +23,10 @@ def create_eg_client(self, endpoint, key): return client - @pytest.mark.live_test_only - def test_publish_binary_mode_xml(self): - eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] - eventgrid_key = os.environ['EVENTGRID_KEY'] - eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] - eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + @pytest.mark.live_test_only() + @EventGridPreparer() + @recorded_by_proxy + def test_publish_binary_mode_xml(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) from xml.etree import ElementTree as ET @@ -55,13 +53,18 @@ def test_publish_binary_mode_xml(self): assert my_returned_event.datacontenttype == 'text/xml' assert my_returned_event.type == "Contoso.Items.ItemReceived" + tokens = [] + for detail in events.value: + token = detail.broker_properties.lock_token + tokens.append(token) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) + + - @pytest.mark.live_test_only - def test_publish_binary_mode_cloud_event(self): - eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] - eventgrid_key = os.environ['EVENTGRID_KEY'] - eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] - eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + @pytest.mark.live_test_only() + @EventGridPreparer() + @recorded_by_proxy + def test_publish_binary_mode_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -84,12 +87,16 @@ def test_publish_binary_mode_cloud_event(self): assert my_returned_event.datacontenttype == 'text/plain' assert my_returned_event.type == "Contoso.Items.ItemReceived" + tokens = [] + for detail in events.value: + token = detail.broker_properties.lock_token + tokens.append(token) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) - @pytest.mark.live_test_only - def test_publish_binary_mode_incorrect_cloud_event(self): - eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] - eventgrid_key = os.environ['EVENTGRID_KEY'] - eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] + + @EventGridPreparer() + @recorded_by_proxy + def test_publish_binary_mode_incorrect_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -105,12 +112,9 @@ def test_publish_binary_mode_incorrect_cloud_event(self): eventgrid_topic_name, body=event, binary_mode=True ) - @pytest.mark.live_test_only - def test_publish_binary_mode_list_cloud_event(self): - eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] - eventgrid_key = os.environ['EVENTGRID_KEY'] - eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] - eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + @EventGridPreparer() + @recorded_by_proxy + def test_publish_binary_mode_list_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -126,12 +130,10 @@ def test_publish_binary_mode_list_cloud_event(self): eventgrid_topic_name, body=[event], binary_mode=True ) - @pytest.mark.live_test_only - def test_publish_binary_mode_combinations(self): - eventgrid_endpoint = os.environ['EVENTGRID_ENDPOINT'] - eventgrid_key = os.environ['EVENTGRID_KEY'] - eventgrid_topic_name = os.environ['EVENTGRID_TOPIC_NAME'] - eventgrid_event_subscription_name = os.environ['EVENTGRID_EVENT_SUBSCRIPTION_NAME'] + @pytest.mark.live_test_only() + @EventGridPreparer() + @recorded_by_proxy + def test_publish_binary_mode_combinations(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -153,6 +155,14 @@ def test_publish_binary_mode_combinations(self): eventgrid_topic_name, body=dict_event, binary_mode=True ) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + tokens = [] + for detail in events.value: + token = detail.broker_properties.lock_token + tokens.append(token) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) + + @pytest.mark.skip("need to update conftest") @EventGridPreparer() @recorded_by_proxy diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index 108b2c1a8e71..cfdec3f1c34d 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -107,7 +107,7 @@ def test_acknowledge_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_k with pytest.raises(ResourceNotFoundError): lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) client.acknowledge_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, acknowledge_options=lock_tokens ) @EventGridPreparer() @@ -118,7 +118,7 @@ def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, with pytest.raises(ResourceNotFoundError): lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) client.release_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, release_options=lock_tokens ) @EventGridPreparer() @@ -129,7 +129,7 @@ def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, e with pytest.raises(ResourceNotFoundError): client.reject_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens + "faketopic", eventgrid_event_subscription_name, reject_options=lock_tokens ) @EventGridPreparer() @@ -139,7 +139,7 @@ def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgr lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) ack = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, acknowledge_options=lock_tokens ) assert type(ack) == AcknowledgeResult assert ack.succeeded_lock_tokens == [] @@ -153,7 +153,7 @@ def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_k lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) release = client.release_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, release_options=lock_tokens ) assert type(release) == ReleaseResult assert release.succeeded_lock_tokens == [] @@ -167,7 +167,7 @@ def test_reject_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_ke lock_tokens = RejectOptions(lock_tokens=["faketoken"]) reject = client.reject_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens + eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=lock_tokens ) assert type(reject) == RejectResult assert reject.succeeded_lock_tokens == [] diff --git a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py index 5cbcdc2c8f39..168feb277b4f 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py @@ -7,7 +7,6 @@ import json import base64 from azure.eventgrid._operations._patch import _to_http_request -from azure.eventgrid._model_base import AzureJSONEncoder from azure.eventgrid.models import * from azure.core.messaging import CloudEvent diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml index 94b72d10f055..e5a84555e08a 100644 --- a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -1,4 +1,4 @@ cleanup: false -commit: a48dbfd411ddcb91ad1e09c47d1def14e79b8905 +commit: 116c17a841a9b37a3fce426558099b5ad5fe16de directory: specification/eventgrid/Azure.Messaging.EventGrid repo: Azure/azure-rest-api-specs \ No newline at end of file diff --git a/sdk/eventgrid/test-resources.json b/sdk/eventgrid/test-resources.json index e41dbdec3be1..a346523e7fd9 100644 --- a/sdk/eventgrid/test-resources.json +++ b/sdk/eventgrid/test-resources.json @@ -27,13 +27,7 @@ "description": "The application client secret used to run tests." } }, - "location": { - "type": "string", - "defaultValue": "eastus", - "metadata": { - "description": "The resource location" - } - } + }, "variables": { "namespaceName": "[format('{0}-2', parameters('baseName'))]", @@ -55,9 +49,9 @@ "resources": [ { "type": "Microsoft.EventGrid/namespaces", - "apiVersion": "2023-06-01-preview", + "apiVersion": "2023-12-15-preview", "name": "[variables('namespaceName')]", - "location": "[parameters('location')]", + "location": "[resourceGroup().location]", "sku": { "name": "Standard", "capacity": 1 @@ -69,7 +63,7 @@ }, { "type": "Microsoft.EventGrid/namespaces/topics", - "apiVersion": "2023-06-01-preview", + "apiVersion": "2023-12-15-preview", "name": "[format('{0}/{1}', variables('namespaceName'), variables('topicName'))]", "properties": { "publisherType": "Custom", @@ -82,7 +76,7 @@ }, { "type": "Microsoft.EventGrid/namespaces/topics/eventSubscriptions", - "apiVersion": "2023-06-01-preview", + "apiVersion": "2023-12-15-preview", "name": "[format('{0}/{1}/{2}', variables('namespaceName'), variables('topicName'), variables('subscriptionName'))]", "properties": { "deliveryConfiguration": { @@ -289,11 +283,11 @@ }, "EVENTGRID_KEY": { "type": "string", - "value": "[listKeys(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-06-01-preview').key1]" + "value": "[listKeys(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-12-15-preview').key1]" }, "EVENTGRID_ENDPOINT": { "type": "string", - "value": "[format('https://{0}', reference(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-06-01-preview').topicsConfiguration.hostname)]" + "value": "[format('https://{0}', reference(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-12-15-preview').topicsConfiguration.hostname)]" }, "EVENTGRID_TOPIC_NAME": { "type": "string", diff --git a/sdk/eventgrid/tests.yml b/sdk/eventgrid/tests.yml index 0d2e952c0c24..cf20c2c1580a 100644 --- a/sdk/eventgrid/tests.yml +++ b/sdk/eventgrid/tests.yml @@ -5,6 +5,7 @@ extends: parameters: ServiceDirectory: eventgrid BuildTargetingString: azure-eventgrid* + Location: eastus MatrixReplace: - TestSamples=.*/true EnvVars: From 280865535109a56dfa6d048cd9b5fb37f4193f8a Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Thu, 9 Nov 2023 12:56:12 -0800 Subject: [PATCH 11/43] update for release --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 3 ++- sdk/eventgrid/azure-eventgrid/README.md | 2 +- .../eventgrid_client_samples/sample_binary_mode_async.py | 2 +- .../eventgrid_client_samples/sample_binary_mode.py | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 5a0df93620fc..c48273250dd8 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -37,7 +37,8 @@ This version and all future versions will require Python 3.8+. ### Features Added - Added new features to the EventGridClient that supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. These features include a `renew_cloud_event_locks` operation, as well as a `release_with_delay` parameter on the `release_cloud_events` operation. -- `lock_tokens` parameter in `reject_cloud_events`, `release_cloud_events`, and `acknowledge_cloud_events` renamed to `reject_options`, `release_options`, and `acknowledge_options`. +- The `lock_tokens` parameter in `reject_cloud_events`, `release_cloud_events`, and `acknowledge_cloud_events` was renamed to `reject_options`, `release_options`, and `acknowledge_options`. +- The `binary_mode` keyword argument on `publish_cloud_events` was added to allow for binary mode support when publishing single Cloud Events. - Added new models to support these new operations on EventGridClient. ## 4.16.0 (2023-11-08) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 5b1959dfa632..8602ece12129 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -12,7 +12,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ## _Disclaimer_ -This is the first beta release of Azure EventGrid's `EventGridClient`, along with the GA `EventGridPublisherClient`. `EventGridClient` supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. +This is a beta release of Azure EventGrid's `EventGridClient`, which along with the GA `EventGridPublisherClient`. `EventGridClient` supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, `reject_cloud_events`, and `renew_cloud_event_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. ## Getting started diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py index 2c440f9f9e7f..6b50f1fe9444 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py @@ -28,7 +28,7 @@ async def run(): try: # Publish CloudEvent in binary mode with str encoded as bytes cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py index de3a4c3f0c32..45240b174a8c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py @@ -25,7 +25,7 @@ try: # Publish CloudEvent in binary mode with str encoded as bytes cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") From 285d5f579aa6b9593f2f779aa0d4115a14b0531a Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Thu, 9 Nov 2023 13:30:00 -0800 Subject: [PATCH 12/43] add changelog --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index c48273250dd8..6a50f56eb128 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -36,10 +36,11 @@ This version and all future versions will require Python 3.8+. ### Features Added -- Added new features to the EventGridClient that supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. These features include a `renew_cloud_event_locks` operation, as well as a `release_with_delay` parameter on the `release_cloud_events` operation. -- The `lock_tokens` parameter in `reject_cloud_events`, `release_cloud_events`, and `acknowledge_cloud_events` was renamed to `reject_options`, `release_options`, and `acknowledge_options`. -- The `binary_mode` keyword argument on `publish_cloud_events` was added to allow for binary mode support when publishing single Cloud Events. -- Added new models to support these new operations on EventGridClient. +- Beta EventGridClient features were added on top of the last GA version of EventGrid. + - Added new features to the EventGridClient that supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, and `reject_cloud_events` operations. These features include a `renew_cloud_event_locks` operation, as well as a `release_with_delay` parameter on the `release_cloud_events` operation. + - The `lock_tokens` parameter in `reject_cloud_events`, `release_cloud_events`, and `acknowledge_cloud_events` was renamed to `reject_options`, `release_options`, and `acknowledge_options`. + - The `binary_mode` keyword argument on `publish_cloud_events` was added to allow for binary mode support when publishing single Cloud Events. + - Added new models to support these new operations on EventGridClient. ## 4.16.0 (2023-11-08) @@ -63,6 +64,7 @@ This version and all future versions will require Python 3.8+. ### Features Added +- Beta EventGridClient features were removed for this and future GA versions. - Added new enum values to `SystemEventNames` related to Azure Container Services. ## 4.12.0b1 (2023-05-22) From 0fff78636fec2871dfd1b199947f319ba228f556 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 29 Mar 2024 12:35:21 -0700 Subject: [PATCH 13/43] [EG] Regenerate beta (#35014) * update generation * version * skip --- .../azure/eventgrid/_model_base.py | 129 ++- .../eventgrid/_operations/_operations.py | 797 ++++++++++++++++-- .../azure/eventgrid/_serialization.py | 36 +- .../azure/eventgrid/_validation.py | 43 + .../eventgrid/aio/_operations/_operations.py | 797 ++++++++++++++++-- .../azure/eventgrid/models/_models.py | 43 + sdk/eventgrid/azure-eventgrid/pyproject.toml | 3 +- sdk/eventgrid/azure-eventgrid/setup.py | 28 +- .../azure-eventgrid/tsp-location.yaml | 2 +- 9 files changed, 1635 insertions(+), 243 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py index 8474b72c2346..f10ebfb873b4 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -5,9 +5,9 @@ # license information. # -------------------------------------------------------------------------- # pylint: disable=protected-access, arguments-differ, signature-differs, broad-except -# pyright: reportGeneralTypeIssues=false import calendar +import decimal import functools import sys import logging @@ -15,9 +15,11 @@ import re import copy import typing -import email +import enum +import email.utils from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder +from typing_extensions import Self import isodate from azure.core.exceptions import DeserializationError from azure.core import CaseInsensitiveEnumMeta @@ -34,6 +36,7 @@ __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] TZ_UTC = timezone.utc +_T = typing.TypeVar("_T") def _timedelta_as_isostr(td: timedelta) -> str: @@ -144,6 +147,8 @@ def default(self, o): # pylint: disable=too-many-return-statements except TypeError: if isinstance(o, _Null): return None + if isinstance(o, decimal.Decimal): + return float(o) if isinstance(o, (bytes, bytearray)): return _serialize_bytes(o, self.format) try: @@ -239,7 +244,7 @@ def _deserialize_date(attr: typing.Union[str, date]) -> date: # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. if isinstance(attr, date): return attr - return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) # type: ignore def _deserialize_time(attr: typing.Union[str, time]) -> time: @@ -275,6 +280,12 @@ def _deserialize_duration(attr): return isodate.parse_duration(attr) +def _deserialize_decimal(attr): + if isinstance(attr, decimal.Decimal): + return attr + return decimal.Decimal(str(attr)) + + _DESERIALIZE_MAPPING = { datetime: _deserialize_datetime, date: _deserialize_date, @@ -283,6 +294,7 @@ def _deserialize_duration(attr): bytearray: _deserialize_bytes, timedelta: _deserialize_duration, typing.Any: lambda x: x, + decimal.Decimal: _deserialize_decimal, } _DESERIALIZE_MAPPING_WITHFORMAT = { @@ -373,8 +385,12 @@ def get(self, key: str, default: typing.Any = None) -> typing.Any: except KeyError: return default - @typing.overload # type: ignore - def pop(self, key: str) -> typing.Any: # pylint: disable=no-member + @typing.overload + def pop(self, key: str) -> typing.Any: + ... + + @typing.overload + def pop(self, key: str, default: _T) -> _T: ... @typing.overload @@ -395,8 +411,8 @@ def clear(self) -> None: def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: self._data.update(*args, **kwargs) - @typing.overload # type: ignore - def setdefault(self, key: str) -> typing.Any: + @typing.overload + def setdefault(self, key: str, default: None = None) -> None: ... @typing.overload @@ -434,6 +450,10 @@ def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-m return tuple(_serialize(x, format) for x in o) if isinstance(o, (bytes, bytearray)): return _serialize_bytes(o, format) + if isinstance(o, decimal.Decimal): + return float(o) + if isinstance(o, enum.Enum): + return o.value try: # First try datetime.datetime return _serialize_datetime(o, format) @@ -458,7 +478,13 @@ def _get_rest_field( def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any: - return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value, rf._format if rf else None) + if not rf: + return _serialize(value, None) + if rf._is_multipart_file_input: + return value + if rf._is_model: + return _deserialize(rf._type, value) + return _serialize(value, rf._format) class Model(_MyMutableMapping): @@ -494,7 +520,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: def copy(self) -> "Model": return Model(self.__dict__) - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> "Model": # pylint: disable=unused-argument + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: # pylint: disable=unused-argument # we know the last three classes in mro are going to be 'Model', 'dict', and 'object' mros = cls.__mro__[:-3][::-1] # ignore model, dict, and object parents, and reverse the mro order attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property @@ -536,7 +562,7 @@ def _deserialize(cls, data, exist_discriminators): exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get( data.get(discriminator), cls - ) # pylint: disable=no-member + ) # pyright: ignore # pylint: disable=no-member if mapped_cls == cls: return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access @@ -553,9 +579,14 @@ def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing. if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: # pyright: ignore[reportUnboundVariable] + if exclude_readonly and k in readonly_props: # pyright: ignore continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + is_multipart_file_input = False + try: + is_multipart_file_input = next(rf for rf in self._attr_to_rest_field.values() if rf._rest_name == k)._is_multipart_file_input + except StopIteration: + pass + result[k] = v if is_multipart_file_input else Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod @@ -563,10 +594,10 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [ + return type(v)( Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v - ] + ) if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) @@ -607,29 +638,22 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, annotation) + return functools.partial(_deserialize_model, annotation) # pyright: ignore except Exception: pass # is it a literal? try: - if sys.version_info >= (3, 8): - from typing import ( - Literal, - ) # pylint: disable=no-name-in-module, ungrouped-imports - else: - from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports - - if annotation.__origin__ == Literal: + if annotation.__origin__ is typing.Literal: # pyright: ignore return None except AttributeError: pass # is it optional? try: - if any(a for a in annotation.__args__ if a == type(None)): + if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore if_obj_deserializer = _get_deserialize_callable_from_annotation( - next(a for a in annotation.__args__ if a != type(None)), module, rf + next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore ) def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): @@ -642,7 +666,13 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: - deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + # initial ordering is we make `string` the last deserialization option, because it is often them most generic + deserializers = [ + _get_deserialize_callable_from_annotation(arg, module, rf) + for arg in sorted( + annotation.__args__, key=lambda x: hasattr(x, "__name__") and x.__name__ == "str" # pyright: ignore + ) + ] def _deserialize_with_union(deserializers, obj): for deserializer in deserializers: @@ -655,32 +685,31 @@ def _deserialize_with_union(deserializers, obj): return functools.partial(_deserialize_with_union, deserializers) try: - if annotation._name == "Dict": - key_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) - value_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[1], module, rf) + if annotation._name == "Dict": # pyright: ignore + value_deserializer = _get_deserialize_callable_from_annotation( + annotation.__args__[1], module, rf # pyright: ignore + ) def _deserialize_dict( - key_deserializer: typing.Optional[typing.Callable], value_deserializer: typing.Optional[typing.Callable], obj: typing.Dict[typing.Any, typing.Any], ): if obj is None: return obj return { - _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) + k: _deserialize(value_deserializer, v, module) for k, v in obj.items() } return functools.partial( _deserialize_dict, - key_deserializer, value_deserializer, ) except (AttributeError, IndexError): pass try: - if annotation._name in ["List", "Set", "Tuple", "Sequence"]: - if len(annotation.__args__) > 1: + if annotation._name in ["List", "Set", "Tuple", "Sequence"]: # pyright: ignore + if len(annotation.__args__) > 1: # pyright: ignore def _deserialize_multiple_sequence( entry_deserializers: typing.List[typing.Optional[typing.Callable]], @@ -694,10 +723,12 @@ def _deserialize_multiple_sequence( ) entry_deserializers = [ - _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ + _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ # pyright: ignore ] return functools.partial(_deserialize_multiple_sequence, entry_deserializers) - deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + deserializer = _get_deserialize_callable_from_annotation( + annotation.__args__[0], module, rf # pyright: ignore + ) def _deserialize_sequence( deserializer: typing.Optional[typing.Callable], @@ -712,19 +743,21 @@ def _deserialize_sequence( pass def _deserialize_default( - annotation, - deserializer_from_mapping, + deserializer, obj, ): if obj is None: return obj try: - return _deserialize_with_callable(annotation, obj) + return _deserialize_with_callable(deserializer, obj) except Exception: pass - return _deserialize_with_callable(deserializer_from_mapping, obj) + return obj - return functools.partial(_deserialize_default, annotation, get_deserializer(annotation, rf)) + if get_deserializer(annotation, rf): + return functools.partial(_deserialize_default, get_deserializer(annotation, rf)) + + return functools.partial(_deserialize_default, annotation) def _deserialize_with_callable( @@ -732,7 +765,7 @@ def _deserialize_with_callable( value: typing.Any, ): try: - if value is None: + if value is None or isinstance(value, _Null): return None if deserializer is None: return value @@ -760,7 +793,8 @@ def _deserialize( value = value.http_response.json() if rf is None and format: rf = _RestField(format=format) - deserializer = _get_deserialize_callable_from_annotation(deserializer, module, rf) + if not isinstance(deserializer, functools.partial): + deserializer = _get_deserialize_callable_from_annotation(deserializer, module, rf) return _deserialize_with_callable(deserializer, value) @@ -774,6 +808,7 @@ def __init__( visibility: typing.Optional[typing.List[str]] = None, default: typing.Any = _UNSET, format: typing.Optional[str] = None, + is_multipart_file_input: bool = False, ): self._type = type self._rest_name_input = name @@ -783,6 +818,11 @@ def __init__( self._is_model = False self._default = default self._format = format + self._is_multipart_file_input = is_multipart_file_input + + @property + def _class_type(self) -> typing.Any: + return getattr(self._type, "args", [None])[0] @property def _rest_name(self) -> str: @@ -828,8 +868,9 @@ def rest_field( visibility: typing.Optional[typing.List[str]] = None, default: typing.Any = _UNSET, format: typing.Optional[str] = None, + is_multipart_file_input: bool = False, ) -> typing.Any: - return _RestField(name=name, type=type, visibility=visibility, default=default, format=format) + return _RestField(name=name, type=type, visibility=visibility, default=default, format=format, is_multipart_file_input=is_multipart_file_input) def rest_discriminator( diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 50a506ffb3e5..b38ab06a9492 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=too-many-lines,too-many-statements # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -20,6 +20,7 @@ from .. import models as _models from .._model_base import SdkJSONEncoder, _deserialize from .._serialization import Serializer +from .._validation import api_version_validation from .._vendor import EventGridClientMixinABC if sys.version_info >= (3, 9): @@ -312,6 +313,7 @@ def _publish_cloud_event( # pylint: disable=protected-access event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: + # pylint: disable=line-too-long """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -322,14 +324,33 @@ def _publish_cloud_event( # pylint: disable=protected-access :type topic_name: str :param event: Single Cloud Event being published. Required. :type event: ~azure.eventgrid.models.CloudEvent - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: PublishResult. The PublishResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + event = { + "id": "str", # An identifier for the event. The combination of id and source + must be unique for each distinct event. Required. + "source": "str", # Identifies the context in which an event happened. The + combination of id and source must be unique for each distinct event. Required. + "specversion": "str", # The version of the CloudEvents specification which + the event uses. Required. + "type": "str", # Type of event related to the originating occurrence. + Required. + "data": {}, # Optional. Event data specific to the event type. + "data_base64": bytes("bytes", encoding="utf-8"), # Optional. Event data + specific to the event type, encoded as a base64 string. + "datacontenttype": "str", # Optional. Content type of data value. + "dataschema": "str", # Optional. Identifies the schema that data adheres to. + "subject": "str", # Optional. This describes the subject of the event in the + context of the event producer (identified by source). + "time": "2020-02-20 00:00:00" # Optional. The time (in UTC) the event was + generated, in RFC3339 format. + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -344,7 +365,7 @@ def _publish_cloud_event( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = event _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -396,6 +417,7 @@ def _publish_cloud_events( # pylint: disable=protected-access events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: + # pylint: disable=line-too-long """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -406,14 +428,37 @@ def _publish_cloud_events( # pylint: disable=protected-access :type topic_name: str :param events: Array of Cloud Events being published. Required. :type events: list[~azure.eventgrid.models.CloudEvent] - :keyword content_type: content type. Default value is "application/cloudevents-batch+json; - charset=utf-8". - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: PublishResult. The PublishResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + events = [ + { + "id": "str", # An identifier for the event. The combination of id + and source must be unique for each distinct event. Required. + "source": "str", # Identifies the context in which an event + happened. The combination of id and source must be unique for each distinct + event. Required. + "specversion": "str", # The version of the CloudEvents specification + which the event uses. Required. + "type": "str", # Type of event related to the originating + occurrence. Required. + "data": {}, # Optional. Event data specific to the event type. + "data_base64": bytes("bytes", encoding="utf-8"), # Optional. Event + data specific to the event type, encoded as a base64 string. + "datacontenttype": "str", # Optional. Content type of data value. + "dataschema": "str", # Optional. Identifies the schema that data + adheres to. + "subject": "str", # Optional. This describes the subject of the + event in the context of the event producer (identified by source). + "time": "2020-02-20 00:00:00" # Optional. The time (in UTC) the + event was generated, in RFC3339 format. + } + ] """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -428,7 +473,7 @@ def _publish_cloud_events( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = events _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -483,6 +528,7 @@ def _receive_cloud_events( # pylint: disable=protected-access max_wait_time: Optional[int] = None, **kwargs: Any ) -> _models._models.ReceiveResult: + # pylint: disable=line-too-long """Receive Batch of Cloud Events from the Event Subscription. :param topic_name: Topic Name. Required. @@ -498,11 +544,52 @@ def _receive_cloud_events( # pylint: disable=protected-access value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "value": [ + { + "brokerProperties": { + "deliveryCount": 0, # The attempt count for + delivering the event. Required. + "lockToken": "str" # The token of the lock on the + event. Required. + }, + "event": { + "id": "str", # An identifier for the event. The + combination of id and source must be unique for each distinct event. + Required. + "source": "str", # Identifies the context in which + an event happened. The combination of id and source must be unique + for each distinct event. Required. + "specversion": "str", # The version of the + CloudEvents specification which the event uses. Required. + "type": "str", # Type of event related to the + originating occurrence. Required. + "data": {}, # Optional. Event data specific to the + event type. + "data_base64": bytes("bytes", encoding="utf-8"), # + Optional. Event data specific to the event type, encoded as a base64 + string. + "datacontenttype": "str", # Optional. Content type + of data value. + "dataschema": "str", # Optional. Identifies the + schema that data adheres to. + "subject": "str", # Optional. This describes the + subject of the event in the context of the event producer (identified + by source). + "time": "2020-02-20 00:00:00" # Optional. The time + (in UTC) the event was generated, in RFC3339 format. + } + } + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -585,11 +672,48 @@ def acknowledge_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + acknowledge_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @overload @@ -616,11 +740,41 @@ def acknowledge_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @overload @@ -628,7 +782,7 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: IO, + acknowledge_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -643,15 +797,45 @@ def acknowledge_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: IO + :type acknowledge_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @@ -660,7 +844,7 @@ def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO], + acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -673,16 +857,50 @@ def acknowledge_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param acknowledge_options: AcknowledgeOptions. Is one of the following types: - AcknowledgeOptions, JSON, IO Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + AcknowledgeOptions, JSON, IO[bytes] Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO[bytes] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + acknowledge_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -749,6 +967,9 @@ def acknowledge_cloud_events( @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) def release_cloud_events( self, topic_name: str, @@ -775,14 +996,54 @@ def release_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + release_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) def release_cloud_events( self, topic_name: str, @@ -809,19 +1070,52 @@ def release_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) def release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: IO, + release_options: IO[bytes], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", @@ -836,27 +1130,60 @@ def release_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param release_options: ReleaseOptions. Required. - :type release_options: IO + :type release_options: IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @distributed_trace + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) def release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: Union[_models.ReleaseOptions, JSON, IO], + release_options: Union[_models.ReleaseOptions, JSON, IO[bytes]], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any @@ -869,20 +1196,54 @@ def release_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO - Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, + IO[bytes] Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + release_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -972,11 +1333,48 @@ def reject_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + reject_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @overload @@ -1002,11 +1400,41 @@ def reject_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @overload @@ -1014,7 +1442,7 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: IO, + reject_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -1028,15 +1456,45 @@ def reject_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param reject_options: RejectOptions. Required. - :type reject_options: IO + :type reject_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @@ -1045,7 +1503,7 @@ def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models.RejectOptions, JSON, IO], + reject_options: Union[_models.RejectOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -1056,17 +1514,51 @@ def reject_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, IO - Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, + IO[bytes] Required. + :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO[bytes] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + reject_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -1133,6 +1625,9 @@ def reject_cloud_events( @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) def renew_cloud_event_locks( self, topic_name: str, @@ -1156,15 +1651,55 @@ def renew_cloud_event_locks( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + renew_lock_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) def renew_cloud_event_locks( self, topic_name: str, @@ -1188,20 +1723,53 @@ def renew_cloud_event_locks( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) def renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: IO, + renew_lock_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -1216,25 +1784,58 @@ def renew_cloud_event_locks( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: IO + :type renew_lock_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @distributed_trace + @api_version_validation( + method_added_on="2023-10-01-preview", + ) def renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models.RenewLockOptions, JSON, IO], + renew_lock_options: Union[_models.RenewLockOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RenewCloudEventLocksResult: """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -1247,17 +1848,51 @@ def renew_cloud_event_locks( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, - JSON, IO Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + JSON, IO[bytes] Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO[bytes] :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + renew_lock_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index c33dabefd203..75e26c415d2c 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -170,13 +170,6 @@ def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], return None -try: - basestring # type: ignore - unicode_str = unicode # type: ignore -except NameError: - basestring = str - unicode_str = str - _LOGGER = logging.getLogger(__name__) try: @@ -547,7 +540,7 @@ class Serializer(object): "multiple": lambda x, y: x % y != 0, } - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): + def __init__(self, classes: Optional[Mapping[str, type]]=None): self.serialize_type = { "iso-8601": Serializer.serialize_iso, "rfc-1123": Serializer.serialize_rfc, @@ -563,7 +556,7 @@ def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): "[]": self.serialize_iter, "{}": self.serialize_dict, } - self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.dependencies: Dict[str, type] = dict(classes) if classes else {} self.key_transformer = full_restapi_key_transformer self.client_side_validation = True @@ -651,7 +644,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): else: # That's a basic type # Integrate namespace if necessary local_node = _create_xml_node(xml_name, xml_prefix, xml_ns) - local_node.text = unicode_str(new_attr) + local_node.text = str(new_attr) serialized.append(local_node) # type: ignore else: # JSON for k in reversed(keys): # type: ignore @@ -747,7 +740,7 @@ def query(self, name, data, data_type, **kwargs): :param str data_type: The type to be serialized from. :keyword bool skip_quote: Whether to skip quote the serialized result. Defaults to False. - :rtype: str + :rtype: str, list :raises: TypeError if serialization fails. :raises: ValueError if data is None """ @@ -1000,7 +993,7 @@ def serialize_object(self, attr, **kwargs): return self.serialize_basic(attr, self.basic_types[obj_type], **kwargs) if obj_type is _long_type: return self.serialize_long(attr) - if obj_type is unicode_str: + if obj_type is str: return self.serialize_unicode(attr) if obj_type is datetime.datetime: return self.serialize_iso(attr) @@ -1376,7 +1369,7 @@ class Deserializer(object): valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): + def __init__(self, classes: Optional[Mapping[str, type]]=None): self.deserialize_type = { "iso-8601": Deserializer.deserialize_iso, "rfc-1123": Deserializer.deserialize_rfc, @@ -1396,7 +1389,7 @@ def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]]=None): "duration": (isodate.Duration, datetime.timedelta), "iso-8601": (datetime.datetime), } - self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.dependencies: Dict[str, type] = dict(classes) if classes else {} self.key_extractors = [rest_key_extractor, xml_key_extractor] # Additional properties only works if the "rest_key_extractor" is used to # extract the keys. Making it to work whatever the key extractor is too much @@ -1449,7 +1442,7 @@ def _deserialize(self, target_obj, data): response, class_name = self._classify_target(target_obj, data) - if isinstance(response, basestring): + if isinstance(response, str): return self.deserialize_data(data, response) elif isinstance(response, type) and issubclass(response, Enum): return self.deserialize_enum(data, response) @@ -1520,14 +1513,14 @@ def _classify_target(self, target, data): if target is None: return None, None - if isinstance(target, basestring): + if isinstance(target, str): try: target = self.dependencies[target] except KeyError: return target, target try: - target = target._classify(data, self.dependencies) + target = target._classify(data, self.dependencies) # type: ignore except AttributeError: pass # Target is not a Model, no classify return target, target.__class__.__name__ # type: ignore @@ -1583,7 +1576,7 @@ def _unpack_content(raw_data, content_type=None): if hasattr(raw_data, "_content_consumed"): return RawDeserializer.deserialize_from_http_generics(raw_data.text, raw_data.headers) - if isinstance(raw_data, (basestring, bytes)) or hasattr(raw_data, "read"): + if isinstance(raw_data, (str, bytes)) or hasattr(raw_data, "read"): return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore return raw_data @@ -1705,7 +1698,7 @@ def deserialize_object(self, attr, **kwargs): if isinstance(attr, ET.Element): # Do no recurse on XML, just return the tree as-is return attr - if isinstance(attr, basestring): + if isinstance(attr, str): return self.deserialize_basic(attr, "str") obj_type = type(attr) if obj_type in self.basic_types: @@ -1762,7 +1755,7 @@ def deserialize_basic(self, attr, data_type): if data_type == "bool": if attr in [True, False, 1, 0]: return bool(attr) - elif isinstance(attr, basestring): + elif isinstance(attr, str): if attr.lower() in ["true", "1"]: return True elif attr.lower() in ["false", "0"]: @@ -1866,7 +1859,7 @@ def deserialize_decimal(attr): if isinstance(attr, ET.Element): attr = attr.text try: - return decimal.Decimal(attr) # type: ignore + return decimal.Decimal(str(attr)) # type: ignore except decimal.DecimalException as err: msg = "Invalid decimal {}".format(attr) raise DeserializationError(msg) from err @@ -2002,6 +1995,7 @@ def deserialize_unix(attr): if isinstance(attr, ET.Element): attr = int(attr.text) # type: ignore try: + attr = int(attr) date_obj = datetime.datetime.fromtimestamp(attr, TZ_UTC) except ValueError as err: msg = "Cannot deserialize to unix datetime object." diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py new file mode 100644 index 000000000000..102dea177140 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py @@ -0,0 +1,43 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import functools + +def api_version_validation(**kwargs): + params_added_on = kwargs.pop("params_added_on", {}) + method_added_on = kwargs.pop("method_added_on", "") + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + # this assumes the client has an _api_version attribute + client = args[0] + client_api_version = client._config.api_version # pylint: disable=protected-access + except AttributeError: + return func(*args, **kwargs) + + if method_added_on > client_api_version: + raise ValueError( + f"'{func.__name__}' is not available in API version " + f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." + ) + + unsupported = { + parameter: api_version + for api_version, parameters in params_added_on.items() + for parameter in parameters + if parameter in kwargs and api_version > client_api_version + } + if unsupported: + raise ValueError("".join([ + f"'{param}' is not available in API version {client_api_version}. " + f"Use service API version {version} or newer.\n" + for param, version in unsupported.items() + ])) + return func(*args, **kwargs) + return wrapper + return decorator diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index aab392f5cf99..5583df5b4b9e 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=too-many-lines,too-many-statements # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -20,6 +20,7 @@ from ... import models as _models from ..._model_base import SdkJSONEncoder, _deserialize from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request, build_event_grid_renew_cloud_event_locks_request +from ..._validation import api_version_validation from .._vendor import EventGridClientMixinABC if sys.version_info >= (3, 9): @@ -41,6 +42,7 @@ async def _publish_cloud_event( # pylint: disable=protected-access event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: + # pylint: disable=line-too-long """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -51,14 +53,33 @@ async def _publish_cloud_event( # pylint: disable=protected-access :type topic_name: str :param event: Single Cloud Event being published. Required. :type event: ~azure.eventgrid.models.CloudEvent - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: PublishResult. The PublishResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + event = { + "id": "str", # An identifier for the event. The combination of id and source + must be unique for each distinct event. Required. + "source": "str", # Identifies the context in which an event happened. The + combination of id and source must be unique for each distinct event. Required. + "specversion": "str", # The version of the CloudEvents specification which + the event uses. Required. + "type": "str", # Type of event related to the originating occurrence. + Required. + "data": {}, # Optional. Event data specific to the event type. + "data_base64": bytes("bytes", encoding="utf-8"), # Optional. Event data + specific to the event type, encoded as a base64 string. + "datacontenttype": "str", # Optional. Content type of data value. + "dataschema": "str", # Optional. Identifies the schema that data adheres to. + "subject": "str", # Optional. This describes the subject of the event in the + context of the event producer (identified by source). + "time": "2020-02-20 00:00:00" # Optional. The time (in UTC) the event was + generated, in RFC3339 format. + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -73,7 +94,7 @@ async def _publish_cloud_event( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = event _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -125,6 +146,7 @@ async def _publish_cloud_events( # pylint: disable=protected-access events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: + # pylint: disable=line-too-long """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which @@ -135,14 +157,37 @@ async def _publish_cloud_events( # pylint: disable=protected-access :type topic_name: str :param events: Array of Cloud Events being published. Required. :type events: list[~azure.eventgrid.models.CloudEvent] - :keyword content_type: content type. Default value is "application/cloudevents-batch+json; - charset=utf-8". - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: PublishResult. The PublishResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + events = [ + { + "id": "str", # An identifier for the event. The combination of id + and source must be unique for each distinct event. Required. + "source": "str", # Identifies the context in which an event + happened. The combination of id and source must be unique for each distinct + event. Required. + "specversion": "str", # The version of the CloudEvents specification + which the event uses. Required. + "type": "str", # Type of event related to the originating + occurrence. Required. + "data": {}, # Optional. Event data specific to the event type. + "data_base64": bytes("bytes", encoding="utf-8"), # Optional. Event + data specific to the event type, encoded as a base64 string. + "datacontenttype": "str", # Optional. Content type of data value. + "dataschema": "str", # Optional. Identifies the schema that data + adheres to. + "subject": "str", # Optional. This describes the subject of the + event in the context of the event producer (identified by source). + "time": "2020-02-20 00:00:00" # Optional. The time (in UTC) the + event was generated, in RFC3339 format. + } + ] """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -157,7 +202,7 @@ async def _publish_cloud_events( # pylint: disable=protected-access 'cls', None ) - _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = events _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -212,6 +257,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access max_wait_time: Optional[int] = None, **kwargs: Any ) -> _models._models.ReceiveResult: + # pylint: disable=line-too-long """Receive Batch of Cloud Events from the Event Subscription. :param topic_name: Topic Name. Required. @@ -227,11 +273,52 @@ async def _receive_cloud_events( # pylint: disable=protected-access value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "value": [ + { + "brokerProperties": { + "deliveryCount": 0, # The attempt count for + delivering the event. Required. + "lockToken": "str" # The token of the lock on the + event. Required. + }, + "event": { + "id": "str", # An identifier for the event. The + combination of id and source must be unique for each distinct event. + Required. + "source": "str", # Identifies the context in which + an event happened. The combination of id and source must be unique + for each distinct event. Required. + "specversion": "str", # The version of the + CloudEvents specification which the event uses. Required. + "type": "str", # Type of event related to the + originating occurrence. Required. + "data": {}, # Optional. Event data specific to the + event type. + "data_base64": bytes("bytes", encoding="utf-8"), # + Optional. Event data specific to the event type, encoded as a base64 + string. + "datacontenttype": "str", # Optional. Content type + of data value. + "dataschema": "str", # Optional. Identifies the + schema that data adheres to. + "subject": "str", # Optional. This describes the + subject of the event in the context of the event producer (identified + by source). + "time": "2020-02-20 00:00:00" # Optional. The time + (in UTC) the event was generated, in RFC3339 format. + } + } + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -314,11 +401,48 @@ async def acknowledge_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + acknowledge_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @overload @@ -345,11 +469,41 @@ async def acknowledge_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @overload @@ -357,7 +511,7 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: IO, + acknowledge_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -372,15 +526,45 @@ async def acknowledge_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: IO + :type acknowledge_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ @@ -389,7 +573,7 @@ async def acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO], + acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -402,16 +586,50 @@ async def acknowledge_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param acknowledge_options: AcknowledgeOptions. Is one of the following types: - AcknowledgeOptions, JSON, IO Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + AcknowledgeOptions, JSON, IO[bytes] Required. + :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO[bytes] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + acknowledge_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully acknowledged cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -478,6 +696,9 @@ async def acknowledge_cloud_events( @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) async def release_cloud_events( self, topic_name: str, @@ -504,14 +725,54 @@ async def release_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + release_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) async def release_cloud_events( self, topic_name: str, @@ -538,19 +799,52 @@ async def release_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: IO, + release_options: IO[bytes], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", @@ -565,27 +859,60 @@ async def release_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param release_options: ReleaseOptions. Required. - :type release_options: IO + :type release_options: IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ @distributed_trace_async + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) async def release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: Union[_models.ReleaseOptions, JSON, IO], + release_options: Union[_models.ReleaseOptions, JSON, IO[bytes]], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any @@ -598,20 +925,54 @@ async def release_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, IO - Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, + IO[bytes] Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + release_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully released cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -701,11 +1062,48 @@ async def reject_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + reject_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @overload @@ -731,11 +1129,41 @@ async def reject_cloud_events( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @overload @@ -743,7 +1171,7 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: IO, + reject_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -757,15 +1185,45 @@ async def reject_cloud_events( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param reject_options: RejectOptions. Required. - :type reject_options: IO + :type reject_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ @@ -774,7 +1232,7 @@ async def reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models.RejectOptions, JSON, IO], + reject_options: Union[_models.RejectOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -785,17 +1243,51 @@ async def reject_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, IO - Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, + IO[bytes] Required. + :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO[bytes] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + reject_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully rejected cloud + events. Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError @@ -862,6 +1354,9 @@ async def reject_cloud_events( @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) async def renew_cloud_event_locks( self, topic_name: str, @@ -885,15 +1380,55 @@ async def renew_cloud_event_locks( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + renew_lock_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) async def renew_cloud_event_locks( self, topic_name: str, @@ -917,20 +1452,53 @@ async def renew_cloud_event_locks( :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @overload + @api_version_validation( + method_added_on="2023-10-01-preview", + ) async def renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: IO, + renew_lock_options: IO[bytes], *, content_type: str = "application/json", **kwargs: Any @@ -945,25 +1513,58 @@ async def renew_cloud_event_locks( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: IO + :type renew_lock_options: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ @distributed_trace_async + @api_version_validation( + method_added_on="2023-10-01-preview", + ) async def renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models.RenewLockOptions, JSON, IO], + renew_lock_options: Union[_models.RenewLockOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RenewCloudEventLocksResult: """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -976,17 +1577,51 @@ async def renew_cloud_event_locks( :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, - JSON, IO Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO - :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default - value is None. - :paramtype content_type: str - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. + JSON, IO[bytes] Required. + :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO[bytes] :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult :raises ~azure.core.exceptions.HttpResponseError: + + Example: + .. code-block:: python + + # JSON input template you can fill out and use as your body input. + renew_lock_options = { + "lockTokens": [ + "str" # Array of lock tokens. Required. + ] + } + + # response body for status code(s): 200 + response == { + "failedLockTokens": [ + { + "error": { + "code": "str", # One of a server-defined set of + error codes. Required. + "message": "str", # A human-readable representation + of the error. Required. + "details": [ + ... + ], + "innererror": { + "code": "str", # Optional. One of a + server-defined set of error codes. + "innererror": ... + }, + "target": "str" # Optional. The target of the error. + }, + "lockToken": "str" # The lock token of an entry in the + request. Required. + } + ], + "succeededLockTokens": [ + "str" # Array of lock tokens for the successfully renewed locks. + Required. + ] + } """ error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index 588b90e04c7d..a9bcc960fafc 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -30,6 +30,7 @@ class AcknowledgeOptions(_model_base.Model): lock_tokens: List[str] = rest_field(name="lockTokens") """Array of lock tokens. Required.""" + @overload def __init__( self, @@ -47,6 +48,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class AcknowledgeResult(_model_base.Model): @@ -69,6 +72,7 @@ class AcknowledgeResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully acknowledged cloud events. Required.""" + @overload def __init__( self, @@ -87,6 +91,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class BrokerProperties(_model_base.Model): @@ -106,6 +112,8 @@ class BrokerProperties(_model_base.Model): """The attempt count for delivering the event. Required.""" + + class CloudEvent(_model_base.Model): """Properties of an event published to an Azure Messaging EventGrid Namespace topic using the @@ -163,6 +171,8 @@ class CloudEvent(_model_base.Model): source).""" + + class Error(_model_base.Model): """The error object. @@ -193,6 +203,7 @@ class Error(_model_base.Model): innererror: Optional["_models.InnerError"] = rest_field() """An object containing more specific information than the current object about the error.""" + @overload def __init__( self, @@ -214,6 +225,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class FailedLockToken(_model_base.Model): @@ -233,6 +246,7 @@ class FailedLockToken(_model_base.Model): error: "_models.Error" = rest_field() """Error information of the failed operation result for the lock token in the request. Required.""" + @overload def __init__( self, @@ -251,6 +265,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class InnerError(_model_base.Model): @@ -269,6 +285,7 @@ class InnerError(_model_base.Model): innererror: Optional["_models.InnerError"] = rest_field() """Inner error.""" + @overload def __init__( self, @@ -287,6 +304,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class PublishResult(_model_base.Model): @@ -296,6 +315,8 @@ class PublishResult(_model_base.Model): + + class ReceiveDetails(_model_base.Model): """Receive operation details per Cloud Event. @@ -314,6 +335,8 @@ class ReceiveDetails(_model_base.Model): """Cloud Event details. Required.""" + + class ReceiveResult(_model_base.Model): """Details of the Receive operation response. @@ -328,6 +351,8 @@ class ReceiveResult(_model_base.Model): """Array of receive responses, one per cloud event. Required.""" + + class RejectOptions(_model_base.Model): """Array of lock tokens for the corresponding received Cloud Events to be rejected. @@ -341,6 +366,7 @@ class RejectOptions(_model_base.Model): lock_tokens: List[str] = rest_field(name="lockTokens") """Array of lock tokens. Required.""" + @overload def __init__( self, @@ -358,6 +384,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class RejectResult(_model_base.Model): @@ -380,6 +408,7 @@ class RejectResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully rejected cloud events. Required.""" + @overload def __init__( self, @@ -398,6 +427,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class ReleaseOptions(_model_base.Model): @@ -412,6 +443,7 @@ class ReleaseOptions(_model_base.Model): lock_tokens: List[str] = rest_field(name="lockTokens") """Array of lock tokens. Required.""" + @overload def __init__( self, @@ -429,6 +461,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class ReleaseResult(_model_base.Model): @@ -451,6 +485,7 @@ class ReleaseResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully released cloud events. Required.""" + @overload def __init__( self, @@ -469,6 +504,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class RenewCloudEventLocksResult(_model_base.Model): @@ -490,6 +527,7 @@ class RenewCloudEventLocksResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully renewed locks. Required.""" + @overload def __init__( self, @@ -508,6 +546,8 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + class RenewLockOptions(_model_base.Model): @@ -522,6 +562,7 @@ class RenewLockOptions(_model_base.Model): lock_tokens: List[str] = rest_field(name="lockTokens") """Array of lock tokens. Required.""" + @overload def __init__( self, @@ -539,3 +580,5 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) + + diff --git a/sdk/eventgrid/azure-eventgrid/pyproject.toml b/sdk/eventgrid/azure-eventgrid/pyproject.toml index fdde94224048..5f3098c4c74b 100644 --- a/sdk/eventgrid/azure-eventgrid/pyproject.toml +++ b/sdk/eventgrid/azure-eventgrid/pyproject.toml @@ -2,4 +2,5 @@ pyright = false type_check_samples = false verifytypes = false -strict_sphinx = true +strict_sphinx = false +pylint = false \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/setup.py b/sdk/eventgrid/azure-eventgrid/setup.py index adf215e92d0e..ad121db2982c 100644 --- a/sdk/eventgrid/azure-eventgrid/setup.py +++ b/sdk/eventgrid/azure-eventgrid/setup.py @@ -38,18 +38,17 @@ url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk", keywords="azure, azure sdk", classifiers=[ - "Development Status :: 5 - Production/Stable", - 'Programming Language :: Python', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'License :: OSI Approved :: MIT License', + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "License :: OSI Approved :: MIT License", ], - python_requires=">=3.8", zip_safe=False, packages=find_packages( exclude=[ @@ -63,8 +62,9 @@ "azure.eventgrid": ["py.typed"], }, install_requires=[ - "isodate>=0.6.1", - 'azure-core>=1.24.0', + "isodate<1.0.0,>=0.6.1", + "azure-core<2.0.0,>=1.30.0", + "typing-extensions>=4.6.0", ], - python_requires=">=3.7", + python_requires=">=3.8", ) diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml index e5a84555e08a..3f8ef6b354e8 100644 --- a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -1,4 +1,4 @@ cleanup: false -commit: 116c17a841a9b37a3fce426558099b5ad5fe16de +commit: f56fd0ca360a8545e4a9e108b84abf01ba195d2d directory: specification/eventgrid/Azure.Messaging.EventGrid repo: Azure/azure-rest-api-specs \ No newline at end of file From 9123ac0d3218f41765b4ebfe06322074ae21a459 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 8 Apr 2024 13:35:05 -0700 Subject: [PATCH 14/43] [EG] Beta One Client (#34973) * [EG] dont hardcode api_version on request (#34965) * dont hardcode api_version on request * pylint fixes * revert * api version * Update sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py * Update sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py * add sync side patches * aio patches * update readme samples * all samples use EGClient * update readme samples * fix imports * import issue * missing pathc * allow sas cred * typo * updates * sas * client * self serialize cloudevent * add bakc in * updates * update ptach * update * update exception logic * async w client * aio [atch * typo * import * update links * tests * raise error * content type * use more fake url * remove content type * mypy * update apiversion * content type * unitttests * update auth * updates * add level * update readme * update * binary mode * args, kwargs * remove auth * add sample comments * testing * move around readme * content type * update tests * docstring * cncf event * add more tests * update doc * update inits to prevent typing errors * ran blakc * fix pylint patch * changes * add all kwargs * indent * reviews * nit * name changes * options * options/result rename * Revert "options" This reverts commit fe0623a51126ae474a8465ecc60ac5e6aadae5c3. * Revert "options/result rename" This reverts commit 6d374222f1fd763e197d280f43cb1a511a16a0c5. * fix tests * remove or None * remove EGPubClient * remove options naming * Revert "remove EGPubClient" This reverts commit bf943640407239ae568c81d7ee0558305c3e30f7. * typeerror * update readme * readme nit * readme updates * add send operation samples * add datacontenttpye * typo * make Options bag models kwargs * remove models * import * exception * update changelog * shorten operation names * nit --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 13 +- sdk/eventgrid/azure-eventgrid/README.md | 324 +++--- .../azure-eventgrid/azure/__init__.py | 2 +- .../azure/eventgrid/__init__.py | 2 +- .../azure/eventgrid/_operations/__init__.py | 2 +- .../eventgrid/_operations/_operations.py | 920 +++--------------- .../azure/eventgrid/_operations/_patch.py | 849 ++++++++++------ .../azure-eventgrid/azure/eventgrid/_patch.py | 85 +- .../azure/eventgrid/aio/__init__.py | 2 +- .../eventgrid/aio/_operations/__init__.py | 2 +- .../eventgrid/aio/_operations/_operations.py | 920 +++--------------- .../azure/eventgrid/aio/_operations/_patch.py | 547 +++++++---- .../azure/eventgrid/aio/_patch.py | 78 +- .../azure/eventgrid/models/__init__.py | 12 - .../azure/eventgrid/models/_models.py | 123 +-- .../azure/eventgrid/models/_patch.py | 23 +- .../azure-eventgrid/samples/README.md | 76 +- .../sample_acknowledge_operation_async.py | 21 +- .../sample_all_operations_async.py | 46 +- .../sample_binary_mode_async.py | 21 +- .../sample_publish_operation_async.py | 23 +- .../sample_publish_receive_renew_async.py | 24 +- .../sample_publish_release_receive_async.py | 35 +- .../sample_receive_operation_async.py | 17 +- .../sample_reject_operation_async.py | 21 +- .../sample_release_operation_async.py | 21 +- .../sample_renew_locks_operation_async.py | 21 +- .../sample_authentication_async.py | 12 +- ...le_publish_cloud_event_using_dict_async.py | 4 +- .../sample_publish_cncf_cloud_events_async.py | 29 +- ..._publish_custom_schema_to_a_topic_async.py | 4 +- ...ample_publish_eg_event_using_dict_async.py | 4 +- ...ple_publish_eg_events_to_a_domain_async.py | 42 +- ...mple_publish_eg_events_to_a_topic_async.py | 26 +- ...s_to_a_topic_using_sas_credential_async.py | 4 +- ...nts_using_cloud_events_1.0_schema_async.py | 26 +- .../sample_publish_to_channel_async.py | 4 +- ...ish_cloud_events_to_custom_topic_sample.py | 4 +- ...ish_cloud_events_to_domain_topic_sample.py | 4 +- ...sh_custom_schema_events_to_topic_sample.py | 4 +- ...vent_grid_events_to_custom_topic_sample.py | 4 +- ...ish_with_shared_access_signature_sample.py | 4 +- .../sample_aad_auth_operation.py | 14 - .../sample_acknowledge_operation.py | 21 +- .../sample_all_operations.py | 42 +- .../sample_binary_mode.py | 19 +- .../sample_eg_client_authentication.py | 27 - .../sample_publish_operation.py | 21 +- .../sample_publish_receive_renew.py | 28 +- .../sample_publish_release_receive.py | 35 +- .../sample_receive_operation.py | 17 +- .../sample_reject_operation.py | 21 +- .../sample_release_operation.py | 21 +- .../sample_renew_locks_operation.py | 21 +- .../sync_samples/sample_authentication.py | 22 +- .../sample_publish_cloud_event_using_dict.py | 4 +- .../sample_publish_cncf_cloud_events.py | 4 +- ...sample_publish_custom_schema_to_a_topic.py | 4 +- .../sample_publish_eg_event_using_dict.py | 4 +- .../sample_publish_eg_events_to_a_domain.py | 4 +- .../sample_publish_eg_events_to_a_topic.py | 4 +- ..._events_to_a_topic_using_sas_credential.py | 4 +- ...sh_events_using_cloud_events_1.0_schema.py | 4 +- .../sync_samples/sample_publish_to_channel.py | 4 +- .../azure-eventgrid/tests/conftest.py | 16 + .../azure-eventgrid/tests/test_dual_client.py | 287 ++++++ .../azure-eventgrid/tests/test_eg_client.py | 68 +- .../tests/test_eg_client_exceptions.py | 50 +- .../tests/unittests/test_binary_mode.py | 7 +- 69 files changed, 2516 insertions(+), 2662 deletions(-) delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 6a50f56eb128..8ce61a9625ef 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,14 +1,17 @@ # Release History -## 4.19.1 (Unreleased) +## 4.19.0b1 (2024-04-11) ### Features Added +- This is a Beta of the EventGridClient + - EventGridClient `send` can be used for both Event Grid Namespace Resources and Event Grid Basic Resources. + - Added a kwarg `level` in the EventGridClient constructor. The default value is `Standard` which creates a client for an Event Grid Namespace Resource. + ### Breaking Changes -### Bugs Fixed - -### Other Changes +- Removed the `AcknowledgeOptions`,`ReleaseOptions`, `RejectOptions`, and `RenewLockOptions` models. `lock_tokens` can now be specified as a `kwarg` on the operation. +- Renamed `publish_cloud_events` to `send` ## 4.19.0 (2024-04-10) @@ -16,7 +19,7 @@ - Added new enum values to `SystemEventNames` related to Azure Communication Services. -### Bugs Fixed +### Breaking Changes - Fixed a bug where the Api Version was being hardcoded to `2018-01-01` on any request sent to the service. diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 8602ece12129..9952c57507f8 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -2,7 +2,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allows for uniform event consumption using a publish-subscribe model. -[Source code][python-eg-src] +| [Source code][python-eg-src] | [Package (PyPI)][python-eg-pypi] | [Package (Conda)](https://anaconda.org/microsoft/azure-eventgrid/) | [API reference documentation][python-eg-ref-docs] @@ -12,14 +12,34 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ## _Disclaimer_ -This is a beta release of Azure EventGrid's `EventGridClient`, which along with the GA `EventGridPublisherClient`. `EventGridClient` supports `publish_cloud_events`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, `reject_cloud_events`, and `renew_cloud_event_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. +This is a beta release of Azure EventGrid's `EventGridClient`. `EventGridClient` supports `send`, `receive`, `acknowledge` , `release`, `reject`, and `renew_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. ## Getting started ### Prerequisites -* Python 3.7 or later is required to use this package. -* You must have an [Azure subscription][azure_subscription] and an Event Grid Topic resource to use this package. Follow this [step-by-step tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart-portal) to register the Event Grid resource provider and create Event Grid topics using the [Azure portal](https://portal.azure.com/). There is a [similar tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart) using [Azure CLI](https://docs.microsoft.com/cli/azure). - +* Python 3.8 or later is required to use this package. +* You must have an [Azure subscription][azure_subscription] and at least one of the following: + * an Event Grid Namespace resource. To create an Event Grid Namespace resource follow [this tutorial](https://learn.microsoft.com/azure/event-grid/create-view-manage-namespaces). + * an Event Grid Basic resource. To create an Event Grid Basic resource via the Azure portal follow this [step-by-step tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart-portal). To create an Event Grid Basic resource via the [Azure CLI](https://docs.microsoft.com/cli/azure) follow this [tutorial](https://docs.microsoft.com/azure/event-grid/custom-event-quickstart) + +### Event Grid Resources + +Below is a brief synopsis of the differences between Azure Event Grid Namespaces and Azure Event Grid Basic. +More information on the two resource types can be found [here](https://learn.microsoft.com/azure/event-grid/choose-right-tier). + +| Feature | Namespaces (Standard) | Basic | +| :---------------- | :------: | :----: | +| Throughput | High | Low | +| MQTT | Yes | No | +| Publish and Subscribe to custom events | Yes | Yes | +| Push Delivery to Event Hubs | Yes | Yes | +| Maximum message retention | 7 days | 1 day | +| Push Delivery to Azure Services | No | Yes | +| Subscribe to Azure System Events | No | Yes | +| Subscribe to Partner Events | No | Yes | +| Domain Scope Subscriptions | No | Yes | + +**Note:** Azure Event Grid Namespaces only supports the Cloud Event v1.0 Schema. ### Install the package Install the Azure Event Grid client library for Python with [pip][pip]: @@ -28,17 +48,29 @@ Install the Azure Event Grid client library for Python with [pip][pip]: pip install azure-eventgrid ``` -* An existing Event Grid topic or domain is required. You can create the resource using [Azure Portal][azure_portal_create_EG_resource] or [Azure CLI][azure_cli_link] +* An existing Event Grid Basic topic or domain, or Event Grid Namespace topic is required. You can create the resource using [Azure Portal][azure_portal_create_EG_resource] or [Azure CLI][azure_cli_link] If you use Azure CLI, replace `` and `` with your own unique names. -#### Create an Event Grid Topic +#### Create an Event Grid Namespace + +``` +az eventgrid namespace create --location --resource-group --name +``` + +#### Create an Event Grid Namespace Topic + +``` +az eventgrid namespace create topic --location --resource-group --name +``` + +#### Create an Event Grid Basic Topic ``` az eventgrid topic --create --location --resource-group --name ``` -#### Create an Event Grid Domain +#### Create an Event Grid Basic Domain ``` az eventgrid domain --create --location --resource-group --name @@ -47,6 +79,11 @@ az eventgrid domain --create --location --resource-group -#### Looking up the endpoint +### Looking up the endpoint + +#### Event Grid Namespace +You can find the Namespace endpoint within the Event Grid Namespace resource on the Azure portal. This will look like: +`"..eventgrid.azure.net"` + +#### Event Grid Basic You can find the topic endpoint within the Event Grid Topic resource on the Azure portal. This will look like: `"https://..eventgrid.azure.net/api/events"` -#### Create the client with AzureKeyCredential +### Create the client with AzureKeyCredential To use an Access key as the `credential` parameter, pass the key as a string into an instance of [AzureKeyCredential][azure-key-credential]. @@ -86,49 +129,68 @@ pass the key as a string into an instance of [AzureKeyCredential][azure-key-cred ```python import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential -topic_key = os.environ["EVENTGRID_TOPIC_KEY"] -endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] -credential_key = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential_key) +credential_key = AzureKeyCredential(key) +client = EventGridClient(endpoint, credential_key) ``` -> **Note:** A client may also be authenticated via SAS signature, using the `AzureSasCredential`. A sample demonstrating this, is available [here][python-eg-sample-send-using-sas] ([async_version][python-eg-sample-send-using-sas-async]). +> **Note:** A Basic client may also be authenticated via SAS signature, using the `AzureSasCredential`. A sample demonstrating this, is available [here][python-eg-sample-send-using-sas] ([async_version][python-eg-sample-send-using-sas-async]). > **Note:** The `generate_sas` method can be used to generate a shared access signature. A sample demonstrating this can be seen [here][python-eg-generate-sas]. ## Key concepts -### Topic +### *Event Grid Namespace* + +A **[namespace](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#namespaces)** is a management container for other resources. It allows for grouping of related resources in order to manage them under one subscription. + +#### Namespace Topic + +A **[namespace topic](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#namespace-topics)** is a topic that is created within an Event Grid namespace. The client publishes events to an HTTP namespace endpoint specifying a namespace topic where published events are logically contained. A namespace topic only supports the CloudEvent v1.0 schema. + +#### Event Subscription + +An **[event subscription](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#event-subscriptions)** is a configuration resource associated with a single topic. + +#### Binary Content Mode + +A namespace topic can receive CloudEvents published in **[binary mode](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#binary-content-mode)**. + +### *Event Grid Basic* + +#### Topic A **[topic](https://docs.microsoft.com/azure/event-grid/concepts#topics)** is a channel within the EventGrid service to send events. The event schema that a topic accepts is decided at topic creation time. If events of a schema type are sent to a topic that requires a different schema type, errors will be raised. -### Domain +#### Domain An event **[domain](https://docs.microsoft.com/azure/event-grid/event-domains)** is a management tool for large numbers of Event Grid topics related to the same application. They allow you to publish events to thousands of topics. Domains also give you authorization and authentication control over each topic. For more information, visit [Event domain overview](https://docs.microsoft.com/azure/event-grid/event-domains). -When you create an event domain, a publishing endpoint for this domain is made available to you. This process is similar to creating an Event Grid Topic. The only difference is that, when publishing to a domain, you must specify the topic within the domain that you'd like the event to be delivered to. - -### Event schemas +#### Event schemas An **[event](https://docs.microsoft.com/azure/event-grid/concepts#events)** is the smallest amount of information that fully describes something that happened in the system. When a custom topic or domain is created, you must specify the schema that will be used when publishing events. Event Grid supports multiple schemas for encoding events. -#### Event Grid schema -While you may configure your topic to use a [custom schema](https://docs.microsoft.com/azure/event-grid/input-mappings), it is more common to use the already-defined Event Grid schema. See the specifications and requirements [here](https://docs.microsoft.com/azure/event-grid/event-schema). +##### System Topics +A **[system topic](https://docs.microsoft.com/azure/event-grid/system-topics)** in Event Grid represents one or more events published by Azure services such as Azure Storage or Azure Event Hubs. For example, a system topic may represent all blob events or only blob creation and blob deletion events published for a specific storage account. -#### CloudEvents v1.0 schema -Another option is to use the CloudEvents v1.0 schema. [CloudEvents](https://cloudevents.io/) is a Cloud Native Computing Foundation project which produces a specification for describing event data in a common way. The service summary of CloudEvents can be found [here](https://docs.microsoft.com/azure/event-grid/cloud-event-schema). +The names of the various event types for the system events published to Azure Event Grid are available in `azure.eventgrid.SystemEventNames`. +For complete list of recognizable system topics, visit [System Topics](https://docs.microsoft.com/azure/event-grid/system-topics). + + For more information about the key concepts on Event Grid, see [Concepts in Azure Event Grid][publisher-service-doc]. + +## EventGridClient -### EventGridPublisherClient -`EventGridPublisherClient` provides operations to send event data to a topic hostname specified during client initialization. +`EventGridClient` provides operations to send to, receive from, acknowledge, reject, release event data for a resource specified during client initialization. -Regardless of the schema that your topic or domain is configured to use, `EventGridPublisherClient` will be used to publish events to it. Use the `send` method publishing events. +If you are using Event Grid Basic, regardless of the schema that your topic or domain is configured to use, `EventGridClient` will be used to publish events to it. Use the `send` method to publish events. -The following formats of events are allowed to be sent: +The following formats of events are allowed to be sent to an EventGrid Basic resource: - A list or a single instance of strongly typed EventGridEvents. - A dict representation of a serialized EventGridEvent object. - A list or a single instance of strongly typed CloudEvents. @@ -136,18 +198,13 @@ The following formats of events are allowed to be sent: - A dict representation of any Custom Schema. -Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. - +The following formats of events are allowed to be sent to an EventGrid Namespace resource: - **Note:** It is important to know if your topic supports CloudEvents or EventGridEvents before publishing. If you send to a topic that does not support the schema of the event you are sending, send() will throw an exception. +* A list of single instance of strongly typed CloudEvents. +* A dict representation of a serialized CloudEvent object. -### System Topics -A **[system topic](https://docs.microsoft.com/azure/event-grid/system-topics)** in Event Grid represents one or more events published by Azure services such as Azure Storage or Azure Event Hubs. For example, a system topic may represent all blob events or only blob creation and blob deletion events published for a specific storage account. - -The names of the various event types for the system events published to Azure Event Grid are available in `azure.eventgrid.SystemEventNames`. -For complete list of recognizable system topics, visit [System Topics](https://docs.microsoft.com/azure/event-grid/system-topics). +Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. - For more information about the key concepts on Event Grid, see [Concepts in Azure Event Grid][publisher-service-doc]. ## Event Grid on Kubernetes with Azure Arc @@ -174,34 +231,10 @@ The following sections provide several code snippets covering some of the most c * [Send a Cloud Event](#send-a-cloud-event) * [Send Multiple Events](#send-multiple-events) * [Send events as Dictionaries](#send-events-as-dictionaries) +* [Receive events](#receive-events-from-namespace) * [Consume a payload from storage queue](#consume-from-storage-queue) * [Consume from ServiceBus](#consume-from-servicebus) -### Send an Event Grid Event - -This example publishes an Event Grid event. - -```python -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, EventGridEvent - -key = os.environ["EG_ACCESS_KEY"] -endpoint = os.environ["EG_TOPIC_HOSTNAME"] - -event = EventGridEvent( - data={"team": "azure-sdk"}, - subject="Door1", - event_type="Azure.Sdk.Demo", - data_version="2.0" -) - -credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) - -client.send(event) -``` - ### Send a Cloud Event This example publishes a Cloud event. @@ -210,10 +243,12 @@ This example publishes a Cloud event. import os from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient, ClientLevel + +key = os.environ["EVENTGRID_NAMESPACE_KEY"] +endpoint = os.environ["EVENTGRID_NAMESPACE_ENDPOINT"] +topic_name = os.environ["EVENTGRID_TOPIC_NAME"] -key = os.environ["CLOUD_ACCESS_KEY"] -endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] event = CloudEvent( type="Azure.Sdk.Sample", @@ -222,9 +257,9 @@ event = CloudEvent( ) credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level=ClientLevel.STANDARD) -client.send(event) +client.send(topic_name, event) ``` ### Send Multiple events @@ -237,10 +272,11 @@ It is possible to send events as a batch when sending multiple events to a topic import os from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient, ClientLevel -key = os.environ["CLOUD_ACCESS_KEY"] -endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] +key = os.environ["EVENTGRID_NAMESPACE_KEY"] +endpoint = os.environ["EVENTGRID_NAMESPACE_ENDPOINT"] +topic_name = os.environ["EVENTGRID_TOPIC_NAME"] event0 = CloudEvent( type="Azure.Sdk.Sample", @@ -256,86 +292,88 @@ event1 = CloudEvent( events = [event0, event1] credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level=ClientLevel.STANDARD) -client.send(events) +client.send(topic_name, events) ``` -### Send events as dictionaries - -A dict representation of respective serialized models can also be used to publish CloudEvent(s) or EventGridEvent(s) apart from the strongly typed objects. +### Receive and Process Events from Namespace -Use a dict-like representation to send to a topic with custom schema as shown below. +Use EventGridClient's receive function to receive CloudEvents from a Namespace event subscription. Then try to acknowledge, reject, release or renew the locks. ```python import os import uuid import datetime as dt -from msrest.serialization import UTC from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient, ClientLevel -key = os.environ["CUSTOM_SCHEMA_ACCESS_KEY"] -endpoint = os.environ["CUSTOM_SCHEMA_TOPIC_HOSTNAME"] - -event = custom_schema_event = { - "customSubject": "sample", - "customEventType": "sample.event", - "customDataVersion": "2.0", - "customId": uuid.uuid4(), - "customEventTime": dt.datetime.now(UTC()).isoformat(), - "customData": "sample data" - } +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] +topic_name = os.environ["EVENTGRID_TOPIC_NAME"] +sub_name = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) - -client.send(event) -``` - -### Consume from storage queue - -This example consumes a message received from storage queue and deserializes it to a CloudEvent object. - -```python -from azure.core.messaging import CloudEvent -from azure.storage.queue import QueueServiceClient, BinaryBase64DecodePolicy -import os -import json +client = EventGridClient(endpoint, credential, level=ClientLevel.STANDARD) + +events = client.receive(topic_name, sub_name, max_events=4) + +for e in events: + renew_tokens = e.broker_properties.lock_token + renew_result = client.renew_locks( + topic_name=TOPIC_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=renew_tokens, + ) + +release_tokens = events[0].broker_properties.lock_token +release_result = client.release( + topic_name=TOPIC_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=release_tokens, +) -# all types of CloudEvents below produce same DeserializedEvent -connection_str = os.environ['STORAGE_QUEUE_CONN_STR'] -queue_name = os.environ['STORAGE_QUEUE_NAME'] +ack_tokens = events[1].broker_properties.lock_token +ack_result = client.acknowledge( + topic_name=TOPIC_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=ack_tokens, +) -with QueueServiceClient.from_connection_string(connection_str) as qsc: - payload = qsc.get_queue_client( - queue=queue_name, - message_decode_policy=BinaryBase64DecodePolicy() - ).peek_messages() +reject_tokens = events[2].broker_properties.lock_token +reject_result = client.reject( + topic_name=TOPIC_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=reject_tokens, +) - ## deserialize payload into a list of typed Events - events = [CloudEvent.from_dict(json.loads(msg.content)) for msg in payload] ``` -### Consume from servicebus +### Legacy EventGrid operations +#### Send an Event Grid Event + -This example consumes a payload message received from ServiceBus and deserializes it to an EventGridEvent object. +This example publishes an Event Grid event. ```python -from azure.eventgrid import EventGridEvent -from azure.servicebus import ServiceBusClient import os -import json +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridClient, EventGridEvent, ClientLevel + +key = os.environ["EG_ACCESS_KEY"] +endpoint = os.environ["EG_TOPIC_HOSTNAME"] -# all types of EventGridEvents below produce same DeserializedEvent -connection_str = os.environ['SERVICE_BUS_CONN_STR'] -queue_name = os.environ['SERVICE_BUS_QUEUE_NAME'] +event = EventGridEvent( + data={"team": "azure-sdk"}, + subject="Door1", + event_type="Azure.Sdk.Demo", + data_version="2.0" +) -with ServiceBusClient.from_connection_string(connection_str) as sb_client: - payload = sb_client.get_queue_receiver(queue_name).receive_messages() +credential = AzureKeyCredential(key) +client = EventGridClient(endpoint, credential, level=ClientLevel.BASIC) - ## deserialize payload into a list of typed Events - events = [EventGridEvent.from_dict(json.loads(next(msg.body).decode('utf-8'))) for msg in payload] +client.send(event) ``` ## Distributed Tracing with EventGrid @@ -372,11 +410,11 @@ trace.get_tracer_provider().add_span_processor( ) ``` -Once the `tracer` and `exporter` are set, please follow the example below to start collecting traces while using the `send` method from the `EventGridPublisherClient` to send a CloudEvent object. +Once the `tracer` and `exporter` are set, please follow the example below to start collecting traces while using the `send` method from the `EventGridClient` to send a CloudEvent object. ```python import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient, ClientLevel from azure.core.messaging import CloudEvent from azure.core.credentials import AzureKeyCredential @@ -388,7 +426,7 @@ cloud_event = CloudEvent( data = {'test': 'hello'}, ) with tracer.start_as_current_span(name="MyApplication"): - client = EventGridPublisherClient(hostname, key) + client = EventGridClient(hostname, key, level=ClientLevel.BASIC) client.send(cloud_event) ``` @@ -419,6 +457,14 @@ The following section provides several code snippets illustrating common pattern These code samples show common champion scenario operations with the Azure Event Grid client library. +#### Namespaces EventGrid Scenarios + +* Authenticate the client: [sample_eg_client_authentication.py][python-eg-client-auth-samples] +* Sample of all operations: [sample_all_operations.py][python-eg-client-all-ops-sample] +* Publish cloud event in binary mode: [sample_binary_mode_operation.py][python-eg-client-binary-mode-sample] + +#### Basic EventGrid Scenarios + * Generate Shared Access Signature: [sample_generate_sas.py][python-eg-generate-sas] * Authenticate the client: [sample_authentication.py][python-eg-auth] ([async_version][python-eg-auth-async]) @@ -455,7 +501,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [azure_cli_link]: https://pypi.org/project/azure-cli/ -[python-eg-src]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/ +[python-eg-src]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid [python-eg-pypi]: https://pypi.org/project/azure-eventgrid [python-eg-product-docs]: https://docs.microsoft.com/azure/event-grid/overview [python-eg-ref-docs]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-eventgrid/latest/index.html @@ -494,7 +540,17 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/consume_samples [python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py + +[python-eg-client-aad-auth-samples]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py + +[python-eg-client-auth-samples]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py + +[python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py + +[python-eg-client-binary-mode-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py + + [cla]: https://cla.microsoft.com [code_of_conduct]: https://opensource.microsoft.com/codeofconduct/ [coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/ -[coc_contact]: mailto:opencode@microsoft.com +[coc_contact]: mailto:opencode@microsoft.com \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/azure/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/__init__.py index 5960c353a898..0d1f7edf5dc6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/__init__.py @@ -1 +1 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore \ No newline at end of file +__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py index 32166aad43a3..f6da3df3d6bc 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._client import EventGridClient +from ._patch import EventGridClient from ._version import VERSION __version__ = VERSION diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py index c166e5de9c64..5d63b0e4eaa0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import EventGridClientOperationsMixin +from ._patch import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index b38ab06a9492..a2706730432d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -649,75 +649,18 @@ def _receive_cloud_events( # pylint: disable=protected-access @overload - def acknowledge_cloud_events( + def _acknowledge_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - acknowledge_options: _models.AcknowledgeOptions, + acknowledge_options: _models._models.AcknowledgeOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - acknowledge_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @overload - def acknowledge_cloud_events( + def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -726,59 +669,9 @@ def acknowledge_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @overload - def acknowledge_cloud_events( + def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -787,64 +680,14 @@ def acknowledge_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @distributed_trace - def acknowledge_cloud_events( + def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO[bytes]], + acknowledge_options: Union[_models._models.AcknowledgeOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -966,19 +809,64 @@ def acknowledge_cloud_events( + @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) # pylint: disable=protected-access + def _release_cloud_events( # pylint: disable=protected-access + self, + topic_name: str, + event_subscription_name: str, + release_options: _models._models.ReleaseOptions, + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + ... + @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) + def _release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + release_options: JSON, + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + ... @overload @api_version_validation( params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, ) - def release_cloud_events( + def _release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: _models.ReleaseOptions, + release_options: IO[bytes], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any + ) -> _models.ReleaseResult: + ... + + @distributed_trace + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) + def _release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + release_options: Union[_models._models.ReleaseOptions, JSON, IO[bytes]], + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + **kwargs: Any ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request is successfully accepted. The response body will include the set of successfully released @@ -988,14 +876,12 @@ def release_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, + IO[bytes] Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -1039,346 +925,84 @@ def release_cloud_events( ] } """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + cls: ClsType[_models.ReleaseResult] = kwargs.pop( + 'cls', None + ) + + content_type = content_type or "application/json" + _content = None + if isinstance(release_options, (IOBase, bytes)): + _content = release_options + else: + _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_event_grid_release_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + release_delay_in_seconds=release_delay_in_seconds, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.ReleaseResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - def release_cloud_events( + def _reject_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - release_options: JSON, + reject_options: _models._models.RejectOptions, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: JSON - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - - @overload - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - def release_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - release_options: IO[bytes], - *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: IO[bytes] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - - - @distributed_trace - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - def release_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - release_options: Union[_models.ReleaseOptions, JSON, IO[bytes]], - *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, - **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, - IO[bytes] Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - release_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError - } - error_map.update(kwargs.pop('error_map', {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.ReleaseResult] = kwargs.pop( - 'cls', None - ) - - content_type = content_type or "application/json" - _content = None - if isinstance(release_options, (IOBase, bytes)): - _content = release_options - else: - _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_event_grid_release_cloud_events_request( - topic_name=topic_name, - event_subscription_name=event_subscription_name, - release_delay_in_seconds=release_delay_in_seconds, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() - else: - deserialized = _deserialize( - _models.ReleaseResult, - response.json() - ) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - - - @overload - def reject_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - reject_options: _models.RejectOptions, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - reject_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ) -> _models.RejectResult: + ... @overload - def reject_cloud_events( + def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -1387,58 +1011,9 @@ def reject_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ... @overload - def reject_cloud_events( + def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -1447,63 +1022,14 @@ def reject_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ... @distributed_trace - def reject_cloud_events( + def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models.RejectOptions, JSON, IO[bytes]], + reject_options: Union[_models._models.RejectOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -1627,80 +1153,22 @@ def reject_cloud_events( @overload @api_version_validation( method_added_on="2023-10-01-preview", - ) - def renew_cloud_event_locks( + ) # pylint: disable=protected-access + def _renew_cloud_event_locks( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - renew_lock_options: _models.RenewLockOptions, + renew_lock_options: _models._models.RenewLockOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - renew_lock_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @overload @api_version_validation( method_added_on="2023-10-01-preview", ) - def renew_cloud_event_locks( + def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, @@ -1709,63 +1177,12 @@ def renew_cloud_event_locks( content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @overload @api_version_validation( method_added_on="2023-10-01-preview", ) - def renew_cloud_event_locks( + def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, @@ -1774,68 +1191,17 @@ def renew_cloud_event_locks( content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @distributed_trace @api_version_validation( method_added_on="2023-10-01-preview", ) - def renew_cloud_event_locks( + def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models.RenewLockOptions, JSON, IO[bytes]], + renew_lock_options: Union[_models._models.RenewLockOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RenewCloudEventLocksResult: """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 3b2a6afdde76..cde0db4f1926 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -5,12 +5,30 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -import base64 import json import sys -from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload - -from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from functools import wraps +from typing import ( + Any, + Callable, + Dict, + IO, + List, + Optional, + TypeVar, + Union, + overload, + TYPE_CHECKING, +) + +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + map_error, +) from azure.core.messaging import CloudEvent from azure.core.tracing.decorator import distributed_trace from azure.core.pipeline import PipelineResponse @@ -18,222 +36,402 @@ from azure.core.utils import case_insensitive_dict from ._operations import EventGridClientOperationsMixin as OperationsMixin -from .._model_base import _deserialize -from ..models._patch import ReceiveResult, ReceiveDetails +from .._model_base import _deserialize +from ..models._patch import ( + ReceiveResult, + ReceiveDetails, +) from .. import models as _models +from ..models._models import AcknowledgeOptions, ReleaseOptions, RejectOptions, RenewLockOptions +from .._validation import api_version_validation + +from .._legacy import EventGridEvent +from .._legacy._helpers import _from_cncf_events, _is_eventgrid_event from .._serialization import Serializer + if sys.version_info >= (3, 9): from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object -T = TypeVar('T') -ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar("T") +ClsType = Optional[ + Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any] +] _SERIALIZER = Serializer() _SERIALIZER.client_side_validation = False +if TYPE_CHECKING: + from cloudevents.http.event import CloudEvent as CNCFCloudEvent + +EVENT_TYPES_BASIC = Union[ + CloudEvent, + List[CloudEvent], + Dict[str, Any], + List[Dict[str, Any]], + EventGridEvent, + List[EventGridEvent], + "CNCFCloudEvent", + List["CNCFCloudEvent"], +] +EVENT_TYPES_STD = Union[ + CloudEvent, + List[CloudEvent], + Dict[str, Any], + List[Dict[str, Any]], +] + + +def use_standard_only(func): + """Use the standard client only. + + This decorator raises an AttributeError if the client is not a standard client. + + :param func: The function to decorate. + :type func: Callable + :return: The decorated function. + :rtype: Callable + """ + + @wraps(func) + def wrapper(self, *args, **kwargs): + if self._level == "Basic": # pylint: disable=protected-access + raise AttributeError( + "The basic client is not supported for this operation." + ) + return func(self, *args, **kwargs) + + return wrapper + + +def validate_args(**kwargs: Any): + kwargs_mapping = kwargs.pop("kwargs_mapping", None) + + def decorator(func): + @wraps(func) + def wrapper(self, *args: Any, **kwargs: Any) -> T: + selected_client_level = self._level # pylint: disable=protected-access + + if kwargs_mapping: + unsupported_kwargs = { + arg: level + for level, arguments in kwargs_mapping.items() + for arg in arguments + if arg + in kwargs.keys() # pylint: disable=consider-iterating-dictionary + and selected_client_level != level + } + + error_strings = [] + if unsupported_kwargs: + error_strings += [ + f"'{param}' is not available for the {selected_client_level} client. " + f"Use the {level} client.\n" + for param, level in unsupported_kwargs.items() + ] + if len(error_strings) > 0: + raise ValueError("".join(error_strings)) + + return func(self, *args, **kwargs) + + return wrapper + + return decorator + class EventGridClientOperationsMixin(OperationsMixin): + @overload - def publish_cloud_events( + def send( self, - topic_name: str, - body: List[CloudEvent], + events: EVENT_TYPES_BASIC, *, - binary_mode: bool = False, - content_type: str = "application/cloudevents-batch+json; charset=utf-8", - **kwargs: Any + channel_name: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, ) -> None: - """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Send events to the Event Grid Basic Service. + + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] + or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] + :keyword channel_name: The name of the channel to send the event to. + :paramtype channel_name: str or None + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". + :paramtype content_type: str or None - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Array of Cloud Events being published. Required. - :type body: list[~azure.core.messaging.CloudEvent] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. If 'datacontenttype` is not specified, - the default content type is `application/cloudevents-batch+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents-batch+json; - charset=utf-8". - :paramtype content_type: str :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: """ + ... @overload - def publish_cloud_events( + def send( self, topic_name: str, - body: CloudEvent, + events: EVENT_TYPES_STD, *, binary_mode: bool = False, - content_type: str = "application/cloudevents+json; charset=utf-8", - **kwargs: Any + content_type: Optional[str] = None, + **kwargs: Any, ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Send events to the Event Grid Namespace Service. - :param topic_name: Topic Name. Required. + :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param body: Single Cloud Event being published. Required. - :type body: ~azure.core.messaging.CloudEvent - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default + value is False. + :paramtype binary_mode: bool + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". + :paramtype content_type: str or None + :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: """ + ... - @overload - def publish_cloud_events( - self, - topic_name: str, - body: Dict[str, Any], - *, - binary_mode: bool = False, - content_type: str = "application/cloudevents+json; charset=utf-8", - **kwargs: Any - ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + @validate_args( + kwargs_mapping={ + "Basic": ["channel_name"], + "Standard": ["binary_mode"], + } + ) + @distributed_trace + def send(self, *args, **kwargs) -> None: + """Send events to the Event Grid Service. - :param topic_name: Topic Name. Required. + :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param body: Single Cloud Event being published. Required. - :type body: dict[str, Any] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] + :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default + value is False. + :paramtype binary_mode: bool + :keyword channel_name: The name of the channel to send the event to. + :paramtype channel_name: str or None + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". :paramtype content_type: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def publish_cloud_events( - self, - topic_name: str, - body: List[Dict[str, Any]], - *, - binary_mode: bool = False, - content_type: str = "application/cloudevents-batch+json; charset=utf-8", - **kwargs: Any - ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Batch of Cloud Events being published. Required. - :type body: list[dict[str, Any]] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If 'datacontenttype` is not specified, the default content type is `application/cloudevents-batch+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents-batch+json; charset=utf-8". - :paramtype content_type: str :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: + + A single instance or a list of dictionaries, CloudEvents are accepted. In the case of an Azure Event Grid + Basic Resource, EventGridEvent(s) and CNCFCloudEvents are also accepted. + + .. admonition:: Example: + + .. literalinclude:: ../samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py + :start-after: [START publish_cloud_event] + :end-before: [END publish_cloud_event] + :language: python + :dedent: 0 + :caption: Publishing a Cloud Event to a Namespace Topic. + + .. literalinclude:: ../samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py + :start-after: [START publish_cloud_event_to_topic] + :end-before: [END publish_cloud_event_to_topic] + :language: python + :dedent: 0 + :caption: Publishing a CloudEvent to a Basic Topic. """ - - @distributed_trace - def publish_cloud_events( + # Check kwargs + channel_name = kwargs.pop("channel_name", None) + binary_mode = kwargs.pop("binary_mode", False) + topic_name = kwargs.pop("topic_name", None) + events = kwargs.pop("events", None) + + # both there + if len(args) > 1: + if events is not None: + raise ValueError("events is already passed as a keyword argument.") + if topic_name is not None: + raise ValueError("topic_name is already passed as a keyword argument.") + events = args[1] + topic_name = args[0] + + elif len(args) == 1: + if events is not None: + if topic_name is not None: + raise ValueError( + "topic_name is already passed as a keyword argument." + ) + topic_name = args[0] + else: + events = args[0] + + if self._level == "Standard" and topic_name is None: + raise ValueError("Topic name is required for standard level client.") + + # check binary mode + if binary_mode: + self._send_binary(topic_name, events, **kwargs) + else: + # If not binary_mode send whatever event is passed + + # If a cloud event dict, convert to CloudEvent for serializing + try: + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + if isinstance(events, list) and isinstance(events[0], dict): + events = [CloudEvent.from_dict(e) for e in events] + except Exception: # pylint: disable=broad-except + pass + + if self._level == "Standard": + kwargs["content_type"] = kwargs.get( + "content_type", "application/cloudevents-batch+json; charset=utf-8" + ) + if not isinstance(events, list): + events = [events] + + if isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): + raise TypeError("EventGridEvent is not supported for standard level client.") + try: + # Try to send via namespace + self._send(topic_name, _serialize_events(events), **kwargs) + except Exception as exception: # pylint: disable=broad-except + self._http_response_error_handler(exception, "Standard") + raise exception + else: + try: + self._send(events, channel_name=channel_name, **kwargs) + except Exception as exception: + self._http_response_error_handler(exception, "Basic") + raise exception + + def _send_binary(self, topic_name, events, **kwargs): + # If data is passed as a dictionary, make sure it is a CloudEvent + try: + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + except AttributeError: + raise TypeError( # pylint: disable=raise-missing-from + "Binary mode is only supported for type CloudEvent." + ) + + # If data is a cloud event, convert to an HTTP Request in binary mode + # Content type becomes the data content type + if isinstance(events, CloudEvent): + self._publish(topic_name, events, self._config.api_version, **kwargs) + else: + raise TypeError("Binary mode is only supported for type CloudEvent.") + + def _http_response_error_handler(self, exception, level): + if isinstance(exception, HttpResponseError): + if exception.status_code == 400: + raise HttpResponseError( + "Invalid event data. Please check the data and try again." + ) from exception + if exception.status_code == 404: + raise ResourceNotFoundError( + "Resource not found. " + f"Please check that the level set on the client, {level}, corresponds to the correct " + "endpoint and/or topic name." + ) from exception + raise exception + + def _publish( self, topic_name: str, - body: Union[List[CloudEvent], CloudEvent, List[Dict[str, Any]], Dict[str, Any]], - *, - binary_mode: bool = False, - **kwargs + event: Any, + api_version: str, + **kwargs: Any, ) -> None: - """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Cloud Event or array of Cloud Events being published. Required. - :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] or dict[str, any] or list[dict[str, any]] - :keyword bool binary_mode: Whether to publish the events in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If not specified, the default content type is "application/cloudevents+json; charset=utf-8". - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - - # Check that the body is a CloudEvent or list of CloudEvents even if dict - if isinstance(body, dict) or (isinstance(body, list) and isinstance(body[0], dict)): - try: - if isinstance(body, list): - body = [CloudEvent.from_dict(event) for event in body] - else: - body = CloudEvent.from_dict(body) - except AttributeError: - raise TypeError("Incorrect type for body. Expected CloudEvent," - " list of CloudEvents, dict, or list of dicts." - " If dict passed, must follow the CloudEvent format.") - - - if isinstance(body, CloudEvent): - kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" - self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) - elif isinstance(body, list): - kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" - self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models._models.PublishResult] = kwargs.pop( + "cls", None + ) # pylint: disable=protected-access + + content_type = kwargs.pop( # pylint: disable=unused-variable + "content_type", None + ) + # Given that we know the cloud event is binary mode, we can convert it to a HTTP request + http_request = _to_http_request( + topic_name=topic_name, + api_version=api_version, + headers=_headers, + params=_params, + event=event, + **kwargs, + ) + + _stream = kwargs.pop("stream", False) + + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + http_request.url = self._client.format_url( + http_request.url, **path_format_arguments + ) + + # pipeline_response: PipelineResponse = self.send_request(http_request, **kwargs) + pipeline_response: PipelineResponse = ( + self._client._pipeline.run( # pylint: disable=protected-access + http_request, stream=_stream, **kwargs + ) + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + response.read() # Load the body in memory and close the socket + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() else: - raise TypeError("Incorrect type for body. Expected CloudEvent," - " list of CloudEvents, dict, or list of dicts." - " If dict passed, must follow the CloudEvent format.") + deserialized = _deserialize( + _models._models.PublishResult, # pylint: disable=protected-access + response.json(), + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + @use_standard_only @distributed_trace - def receive_cloud_events( + def receive( self, topic_name: str, - event_subscription_name: str, + subscription_name: str, *, max_events: Optional[int] = None, max_wait_time: Optional[int] = None, - **kwargs: Any + **kwargs: Any, ) -> ReceiveResult: """Receive Batch of Cloud Events from the Event Subscription. :param topic_name: Topic Name. Required. :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value is 100 events. If not specified, the default value is 1. Default value is None. :paramtype max_events: int @@ -243,8 +441,6 @@ def receive_cloud_events( value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: @@ -253,10 +449,10 @@ def receive_cloud_events( detail_items = [] received_result = self._receive_cloud_events( topic_name, - event_subscription_name, + subscription_name, max_events=max_events, max_wait_time=max_wait_time, - **kwargs + **kwargs, ) for detail_item in received_result.value: deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) @@ -270,159 +466,262 @@ def receive_cloud_events( receive_result_deserialized = ReceiveResult(value=detail_items) return receive_result_deserialized - def _publish(self, topic_name: str, event: Any, api_version: str, binary_mode: Optional[bool] = False, **kwargs: Any) -> None: - - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError - } - error_map.update(kwargs.pop('error_map', {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + @use_standard_only + @distributed_trace + def acknowledge( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = AcknowledgeOptions(lock_tokens=lock_tokens) + return super()._acknowledge_cloud_events( + topic_name=topic_name, + event_subscription_name=subscription_name, + acknowledge_options=options, + **kwargs, ) - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + @use_standard_only + @distributed_trace + @api_version_validation( + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, + ) + def release( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + **kwargs: Any, + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. - # Given that we know the cloud event is binary mode, we can convert it to a HTTP request - http_request = _to_http_request( + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = ReleaseOptions(lock_tokens=lock_tokens) + return super()._release_cloud_events( topic_name=topic_name, - api_version=api_version, - headers=_headers, - params=_params, - content_type=content_type, - event=event, - binary_mode=binary_mode, - **kwargs + event_subscription_name=subscription_name, + release_options=options, + release_delay_in_seconds=release_delay_in_seconds, + **kwargs, ) - _stream = kwargs.pop("stream", False) - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + @use_standard_only + @distributed_trace + def reject( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.RejectResult: + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. - # pipeline_response: PipelineResponse = self.send_request(http_request, **kwargs) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - http_request, - stream=_stream, - **kwargs + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = RejectOptions(lock_tokens=lock_tokens) + return super()._reject_cloud_events( + topic_name=topic_name, + event_subscription_name=subscription_name, + reject_options=options, + **kwargs, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() - else: - deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json() - ) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + @use_standard_only + @distributed_trace + @api_version_validation( + method_added_on="2023-10-01-preview", + ) + def renew_locks( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. - return deserialized # type: ignore + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = RenewLockOptions(lock_tokens=lock_tokens) + return super()._renew_cloud_event_locks( + topic_name=topic_name, + event_subscription_name=subscription_name, + renew_lock_options=options, + **kwargs, + ) -def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: +def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: # Create a HTTP request for a binary mode CloudEvent _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) event = kwargs.pop("event") - binary_mode = kwargs.pop("binary_mode", False) - - if binary_mode: - # Content of the request is the data, if already in binary - no work needed - try: - if isinstance(event.data, bytes): - _content = event.data - else: - raise TypeError("CloudEvent data must be bytes when in binary mode." - "Did you forget to call `json.dumps()` and/or `encode()` on CloudEvent data?") - except AttributeError: - raise TypeError("Binary mode is not supported for batch CloudEvents. Set `binary_mode` to False when passing in a batch of CloudEvents.") - else: - # Content of the request is the serialized CloudEvent or serialized List[CloudEvent] - _content = _serialize_cloud_events(event) - + # Content of the request is the data, if already in binary - no work needed + try: + if isinstance(event.data, bytes): + _content = event.data + else: + raise TypeError( + "CloudEvent data must be bytes when in binary mode." + "Did you forget to call `json.dumps()` and/or `encode()` on CloudEvent data?" + ) + except AttributeError as exc: + raise TypeError( + "Binary mode is not supported for batch CloudEvents." + " Set `binary_mode` to False when passing in a batch of CloudEvents." + ) from exc + # content_type must be CloudEvent DataContentType when in binary mode - default_content_type = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) - content_type: str = event.datacontenttype if (binary_mode and event.datacontenttype) else default_content_type + if not event.datacontenttype: + raise TypeError("CloudEvent datacontenttype must be set when in binary mode.") + content_type: str = event.datacontenttype - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + api_version: str = kwargs.pop( + "api_version", _params.pop("api-version", "2023-10-01-preview") + ) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}:publish" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') - - if binary_mode: - # Cloud Headers - _headers['ce-source'] = _SERIALIZER.header('ce-source', event.source, 'str') - _headers['ce-type'] = _SERIALIZER.header('ce-type', event.type, 'str') - if event.specversion: - _headers['ce-specversion'] = _SERIALIZER.header('ce-specversion', event.specversion, 'str') - if event.id: - _headers['ce-id'] = _SERIALIZER.header('ce-id', event.id, 'str') - if event.time: - _headers['ce-time'] = _SERIALIZER.header('ce-time', event.time, 'str') - if event.dataschema: - _headers['ce-dataschema'] = _SERIALIZER.header('ce-dataschema', event.dataschema, 'str') - if event.subject: - _headers['ce-subject'] = _SERIALIZER.header('ce-subject', event.subject, 'str') - if event.extensions: - for extension, value in event.extensions.items(): - _headers[f'ce-{extension}'] = _SERIALIZER.header('ce-extensions', value, 'str') + _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + # Cloud Headers + _headers["ce-source"] = _SERIALIZER.header("ce-source", event.source, "str") + _headers["ce-type"] = _SERIALIZER.header("ce-type", event.type, "str") + if event.specversion: + _headers["ce-specversion"] = _SERIALIZER.header( + "ce-specversion", event.specversion, "str" + ) + if event.id: + _headers["ce-id"] = _SERIALIZER.header("ce-id", event.id, "str") + if event.time: + _headers["ce-time"] = _SERIALIZER.header("ce-time", event.time, "str") + if event.dataschema: + _headers["ce-dataschema"] = _SERIALIZER.header( + "ce-dataschema", event.dataschema, "str" + ) + if event.subject: + _headers["ce-subject"] = _SERIALIZER.header("ce-subject", event.subject, "str") + if event.extensions: + for extension, value in event.extensions.items(): + _headers[f"ce-{extension}"] = _SERIALIZER.header( + "ce-extensions", value, "str" + ) return HttpRequest( method="POST", url=_url, params=_params, headers=_headers, - content=_content, # pass through content - **kwargs + content=_content, # pass through content + **kwargs, ) -def _serialize_cloud_events(events: Union[CloudEvent, List[CloudEvent]]) -> None: - # Serialize CloudEvent or List[CloudEvent] into a JSON string - is_list = isinstance(events, list) - data = {} - list_data = [] - for event in events if isinstance(events, list) else [events]: + +def _serialize_events(events): + if isinstance(events[0], CloudEvent): + internal_body_list = [] + for item in events: + internal_body_list.append(_serialize_cloud_event(item)) + return json.dumps(internal_body_list) + try: + serialize = Serializer() + body = serialize.body(events, "[object]") + if body is None: + data = None + else: + data = json.dumps(body) + + return data + except AttributeError: + return events + + +def _serialize_cloud_event(event): + try: + data = {} # CloudEvent required fields but validate they are not set to None if event.type: - data["type"] = _SERIALIZER.body(event.type, "str") + data["type"] = _SERIALIZER.body(event.type, "str") if event.specversion: data["specversion"] = _SERIALIZER.body(event.specversion, "str") if event.source: data["source"] = _SERIALIZER.body(event.source, "str") if event.id: data["id"] = _SERIALIZER.body(event.id, "str") - + # Check if data is bytes and serialize to base64 if isinstance(event.data, bytes): data["data_base64"] = _SERIALIZER.serialize_bytearray(event.data) @@ -439,13 +738,9 @@ def _serialize_cloud_events(events: Union[CloudEvent, List[CloudEvent]]) -> None for extension, value in event.extensions.items(): data[extension] = _SERIALIZER.body(value, "str") - # If single cloud event return the data - if not is_list: - return json.dumps(data) - else: - list_data.append(data) - # If list of cloud events return the list - return json.dumps(list_data) + return data + except AttributeError: + return [_from_cncf_events(e) for e in event] __all__: List[str] = [ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index 9ac00715fa22..bc579af964bc 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -6,13 +6,94 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List +from typing import List, Union, Optional, Any +from enum import Enum + +from azure.core import CaseInsensitiveEnumMeta +from azure.core.credentials import ( + AzureKeyCredential, + TokenCredential, + AzureSasCredential, +) + from ._legacy import ( EventGridPublisherClient, SystemEventNames, EventGridEvent, generate_sas, ) +from ._client import ( + EventGridClient as InternalEventGridClient, +) +from ._serialization import Serializer, Deserializer + + +class ClientLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + STANDARD = ("Standard",) + BASIC = "Basic" + + +DEFAULT_STANDARD_API_VERSION = "2023-10-01-preview" +DEFAULT_BASIC_API_VERSION = "2018-01-01" + + +class EventGridClient(InternalEventGridClient): + """ + Azure Messaging EventGrid Client. + + :param endpoint: The endpoint to the Event Grid resource. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value for namespaces is + "2023-10-01-preview". Default value for basic is "2018-01-01". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str or None + :keyword level: The level of client to use. Known values are + `Standard` and `Basic`. Default value is `Standard`. + `Standard` is used for working with a namespace topic. + `Basic` is used for working with a basic topic. + :paramtype level: str + """ + + def __init__( + self, + endpoint: str, + credential: Union[AzureKeyCredential, AzureSasCredential, "TokenCredential"], + *, + api_version: Optional[str] = None, + level: Union[str, ClientLevel] = "Standard", + **kwargs: Any + ) -> None: + _endpoint = "{endpoint}" + self._level = level + + if level == ClientLevel.BASIC: + self._client = EventGridPublisherClient( + endpoint, + credential, + api_version=api_version or DEFAULT_BASIC_API_VERSION, + ) # type:ignore[assignment] + self._send = self._client.send # type:ignore[attr-defined] + elif level == ClientLevel.STANDARD: + if isinstance(credential, AzureSasCredential): + raise TypeError( + "SAS token authentication is not supported for the standard client." + ) + super().__init__( + endpoint=endpoint, + credential=credential, + api_version=api_version or DEFAULT_STANDARD_API_VERSION, + **kwargs + ) + + self._send = self._publish_cloud_events + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + def patch_sdk(): """Do not remove from this file. @@ -27,4 +108,6 @@ def patch_sdk(): "SystemEventNames", "EventGridEvent", "generate_sas", + "EventGridClient", + "ClientLevel", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py index 6c53eb888303..149d797cbe4e 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._client import EventGridClient +from ._patch import EventGridClient try: from ._patch import __all__ as _patch_all diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py index c166e5de9c64..5d63b0e4eaa0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import EventGridClientOperationsMixin +from ._patch import EventGridClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index 5583df5b4b9e..8640bcff8730 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -378,75 +378,18 @@ async def _receive_cloud_events( # pylint: disable=protected-access @overload - async def acknowledge_cloud_events( + async def _acknowledge_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - acknowledge_options: _models.AcknowledgeOptions, + acknowledge_options: _models._models.AcknowledgeOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - acknowledge_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @overload - async def acknowledge_cloud_events( + async def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -455,59 +398,9 @@ async def acknowledge_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @overload - async def acknowledge_cloud_events( + async def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -516,64 +409,14 @@ async def acknowledge_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Required. - :type acknowledge_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.AcknowledgeResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully acknowledged cloud - events. Required. - ] - } - """ - + ... @distributed_trace_async - async def acknowledge_cloud_events( + async def _acknowledge_cloud_events( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models.AcknowledgeOptions, JSON, IO[bytes]], + acknowledge_options: Union[_models._models.AcknowledgeOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.AcknowledgeResult: """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the @@ -695,19 +538,64 @@ async def acknowledge_cloud_events( + @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) # pylint: disable=protected-access + async def _release_cloud_events( # pylint: disable=protected-access + self, + topic_name: str, + event_subscription_name: str, + release_options: _models._models.ReleaseOptions, + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + ... + @overload + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) + async def _release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + release_options: JSON, + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ReleaseResult: + ... @overload @api_version_validation( params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, ) - async def release_cloud_events( + async def _release_cloud_events( self, topic_name: str, event_subscription_name: str, - release_options: _models.ReleaseOptions, + release_options: IO[bytes], *, release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any + ) -> _models.ReleaseResult: + ... + + @distributed_trace_async + @api_version_validation( + params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + ) + async def _release_cloud_events( + self, + topic_name: str, + event_subscription_name: str, + release_options: Union[_models._models.ReleaseOptions, JSON, IO[bytes]], + *, + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + **kwargs: Any ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request is successfully accepted. The response body will include the set of successfully released @@ -717,14 +605,12 @@ async def release_cloud_events( :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions + :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, + IO[bytes] Required. + :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -768,346 +654,84 @@ async def release_cloud_events( ] } """ + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + } + error_map.update(kwargs.pop('error_map', {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) + cls: ClsType[_models.ReleaseResult] = kwargs.pop( + 'cls', None + ) + + content_type = content_type or "application/json" + _content = None + if isinstance(release_options, (IOBase, bytes)): + _content = release_options + else: + _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_event_grid_release_cloud_events_request( + topic_name=topic_name, + event_subscription_name=event_subscription_name, + release_delay_in_seconds=release_delay_in_seconds, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _request, + stream=_stream, + **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + await response.read() # Load the body in memory and close the socket + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize( + _models.ReleaseResult, + response.json() + ) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - async def release_cloud_events( + async def _reject_cloud_events( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - release_options: JSON, + reject_options: _models._models.RejectOptions, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: JSON - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - - @overload - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - async def release_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - release_options: IO[bytes], - *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Required. - :type release_options: IO[bytes] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - - - @distributed_trace_async - @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, - ) - async def release_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - release_options: Union[_models.ReleaseOptions, JSON, IO[bytes]], - *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, - **kwargs: Any - ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, - IO[bytes] Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay - :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReleaseResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - release_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully released cloud - events. Required. - ] - } - """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError - } - error_map.update(kwargs.pop('error_map', {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.ReleaseResult] = kwargs.pop( - 'cls', None - ) - - content_type = content_type or "application/json" - _content = None - if isinstance(release_options, (IOBase, bytes)): - _content = release_options - else: - _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_event_grid_release_cloud_events_request( - topic_name=topic_name, - event_subscription_name=event_subscription_name, - release_delay_in_seconds=release_delay_in_seconds, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() - else: - deserialized = _deserialize( - _models.ReleaseResult, - response.json() - ) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - - - @overload - async def reject_cloud_events( - self, - topic_name: str, - event_subscription_name: str, - reject_options: _models.RejectOptions, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - reject_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ) -> _models.RejectResult: + ... @overload - async def reject_cloud_events( + async def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -1116,58 +740,9 @@ async def reject_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ... @overload - async def reject_cloud_events( + async def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, @@ -1176,63 +751,14 @@ async def reject_cloud_events( content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param reject_options: RejectOptions. Required. - :type reject_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RejectResult. The RejectResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RejectResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully rejected cloud - events. Required. - ] - } - """ - + ... @distributed_trace_async - async def reject_cloud_events( + async def _reject_cloud_events( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models.RejectOptions, JSON, IO[bytes]], + reject_options: Union[_models._models.RejectOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RejectResult: """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -1356,80 +882,22 @@ async def reject_cloud_events( @overload @api_version_validation( method_added_on="2023-10-01-preview", - ) - async def renew_cloud_event_locks( + ) # pylint: disable=protected-access + async def _renew_cloud_event_locks( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, - renew_lock_options: _models.RenewLockOptions, + renew_lock_options: _models._models.RenewLockOptions, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your body input. - renew_lock_options = { - "lockTokens": [ - "str" # Array of lock tokens. Required. - ] - } - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @overload @api_version_validation( method_added_on="2023-10-01-preview", ) - async def renew_cloud_event_locks( + async def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, @@ -1438,63 +906,12 @@ async def renew_cloud_event_locks( content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @overload @api_version_validation( method_added_on="2023-10-01-preview", ) - async def renew_cloud_event_locks( + async def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, @@ -1503,68 +920,17 @@ async def renew_cloud_event_locks( content_type: str = "application/json", **kwargs: Any ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. - - :param topic_name: Topic Name. Required. - :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Required. - :type renew_lock_options: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # response body for status code(s): 200 - response == { - "failedLockTokens": [ - { - "error": { - "code": "str", # One of a server-defined set of - error codes. Required. - "message": "str", # A human-readable representation - of the error. Required. - "details": [ - ... - ], - "innererror": { - "code": "str", # Optional. One of a - server-defined set of error codes. - "innererror": ... - }, - "target": "str" # Optional. The target of the error. - }, - "lockToken": "str" # The lock token of an entry in the - request. Required. - } - ], - "succeededLockTokens": [ - "str" # Array of lock tokens for the successfully renewed locks. - Required. - ] - } - """ - + ... @distributed_trace_async @api_version_validation( method_added_on="2023-10-01-preview", ) - async def renew_cloud_event_locks( + async def _renew_cloud_event_locks( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models.RenewLockOptions, JSON, IO[bytes]], + renew_lock_options: Union[_models._models.RenewLockOptions, JSON, IO[bytes]], **kwargs: Any ) -> _models.RenewCloudEventLocksResult: """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 6b20e911093d..70d55e829fb9 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -5,228 +5,264 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar +from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar, IO import sys from azure.core.messaging import CloudEvent -from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + map_error, +) from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, AsyncHttpResponse from azure.core.utils import case_insensitive_dict from ...models._patch import ReceiveResult, ReceiveDetails -from ..._operations._patch import _to_http_request +from ..._operations._patch import _to_http_request, use_standard_only from ._operations import EventGridClientOperationsMixin as OperationsMixin from ... import models as _models +from ...models._models import AcknowledgeOptions, ReleaseOptions, RejectOptions, RenewLockOptions from ..._model_base import _deserialize +from ..._validation import api_version_validation + +from ..._operations._patch import ( + _serialize_events, + EVENT_TYPES_BASIC, + EVENT_TYPES_STD, + validate_args, +) + +from ..._legacy import EventGridEvent +from ..._legacy._helpers import _is_eventgrid_event + if sys.version_info >= (3, 9): from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object -T = TypeVar('T') -ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar("T") +ClsType = Optional[ + Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any] +] + class EventGridClientOperationsMixin(OperationsMixin): @overload - async def publish_cloud_events( + async def send( self, - topic_name: str, - body: List[CloudEvent], + events: EVENT_TYPES_BASIC, *, - binary_mode: bool = False, - content_type: str = "application/cloudevents-batch+json; charset=utf-8", - **kwargs: Any + channel_name: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, ) -> None: - """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Send events to the Event Grid Basic Service. + + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] + or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] + :keyword channel_name: The name of the channel to send the event to. + :paramtype channel_name: str or None + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". + :paramtype content_type: str or None - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Array of Cloud Events being published. Required. - :type body: list[~azure.core.messaging.CloudEvent] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If 'datacontenttype` is not specified the default content type is `application/cloudevents-batch+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents-batch+json; - charset=utf-8". - :paramtype content_type: str :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: """ + ... @overload - async def publish_cloud_events( + async def send( self, topic_name: str, - body: CloudEvent, + events: EVENT_TYPES_STD, *, binary_mode: bool = False, - content_type: str = "application/cloudevents+json; charset=utf-8", - **kwargs: Any + content_type: Optional[str] = None, + **kwargs: Any, ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Send events to the Event Grid Namespace Service. - :param topic_name: Topic Name. Required. + :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param body: Single Cloud Event being published. Required. - :type body: ~azure.core.messaging.CloudEvent - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default + value is False. + :paramtype binary_mode: bool + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". + :paramtype content_type: str or None + :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: """ + ... - @overload - async def publish_cloud_events( - self, - topic_name: str, - body: Dict[str, Any], - *, - binary_mode: bool = False, - content_type: str = "application/cloudevents+json; charset=utf-8", - **kwargs: Any - ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + @validate_args( + kwargs_mapping={ + "Basic": ["channel_name"], + "Standard": ["binary_mode"], + } + ) + @distributed_trace_async + async def send(self, *args, **kwargs) -> None: + """Send events to the Event Grid Namespace Service. - :param topic_name: Topic Name. Required. + :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param body: Single Cloud Event being published. Required. - :type body: dict[str, Any] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If `datacontenttype` is not specified, the default content type is `application/cloudevents+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". + :param event: The event to send. + :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default + value is False. + :paramtype binary_mode: bool + :keyword channel_name: The name of the channel to send the event to. + :paramtype channel_name: str or None + :keyword content_type: The content type of the event. If not specified, the default value is + "application/cloudevents+json; charset=utf-8". :paramtype content_type: str + :return: None :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - @overload - async def publish_cloud_events( - self, - topic_name: str, - body: List[Dict[str, Any]], - *, - binary_mode: bool = False, - content_type: str = "application/cloudevents-batch+json; charset=utf-8", - **kwargs: Any - ) -> None: - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + A single instance or a list of dictionaries, CloudEvents are accepted. In the case of an Azure Event Grid + Basic Resource, EventGridEvent(s) and CNCFCloudEvents are also accepted. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Batch of Cloud Events being published. Required. - :type body: list[dict[str, Any]] - :keyword bool binary_mode: Whether to publish a CloudEvent in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If 'datacontenttype` is not specified, the default content type is `application/cloudevents-batch+json; charset=utf-8`. - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ + .. admonition:: Example: - @distributed_trace_async - async def publish_cloud_events( - self, - topic_name: str, - body: Union[List[CloudEvent], CloudEvent, List[Dict[str, Any]], Dict[str, Any]], - *, - binary_mode: bool = False, - **kwargs - ) -> None: - """Publish Batch Cloud Event or Events to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + .. literalinclude:: ../samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py + :start-after: [START publish_cloud_event_async] + :end-before: [END publish_cloud_event_async] + :language: python + :dedent: 0 + :caption: Publishing a Cloud Event to a Namespace Topic. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param body: Cloud Event or Array of Cloud Events being published. Required. - :type body: ~azure.core.messaging.CloudEvent or list[~azure.core.messaging.CloudEvent] or dict[str, any] or list[dict[str, any]] - :keyword bool binary_mode: Whether to publish the events in binary mode. Defaults to False. - When True and `datacontenttype` is specified in CloudEvent, content type is set to `datacontenttype`. - If not specified, the default content type is "application/cloudevents+json; charset=utf-8". - Requires CloudEvent data to be passed in as bytes. - :keyword content_type: content type. Default value is "application/cloudevents+json; - charset=utf-8". - :paramtype content_type: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: + .. literalinclude:: ../samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py + :start-after: [START publish_cloud_event_to_topic_async] + :end-before: [END publish_cloud_event_to_topic_async] + :language: python + :dedent: 0 + :caption: Publishing a CloudEvent to a Basic Topic. """ - - # Check that the body is a CloudEvent or list of CloudEvents even if dict - if isinstance(body, dict) or (isinstance(body, list) and isinstance(body[0], dict)): - try: - if isinstance(body, list): - body = [CloudEvent.from_dict(event) for event in body] - else: - body = CloudEvent.from_dict(body) - except AttributeError: - raise TypeError("Incorrect type for body. Expected CloudEvent," - " list of CloudEvents, dict, or list of dicts." - " If dict passed, must follow the CloudEvent format.") - - - if isinstance(body, CloudEvent): - kwargs["content_type"] = "application/cloudevents+json; charset=utf-8" - await self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) - elif isinstance(body, list): - kwargs["content_type"] = "application/cloudevents-batch+json; charset=utf-8" - await self._publish(topic_name, body, self._config.api_version, binary_mode, **kwargs) + # Check kwargs + channel_name = kwargs.pop("channel_name", None) + binary_mode = kwargs.pop("binary_mode", False) + topic_name = kwargs.pop("topic_name", None) + events = kwargs.pop("events", None) + + # both there + if len(args) > 1: + if events is not None: + raise ValueError("events is already passed as a keyword argument.") + if topic_name is not None: + raise ValueError("topic_name is already passed as a keyword argument.") + events = args[1] + topic_name = args[0] + + elif len(args) == 1: + if events is not None: + if topic_name is not None: + raise ValueError( + "topic_name is already passed as a keyword argument." + ) + topic_name = args[0] + else: + events = args[0] + + if self._level == "Standard" and topic_name is None: + raise ValueError("Topic name is required for standard level client.") + + # check binary mode + if binary_mode: + await self._send_binary(topic_name, events, **kwargs) else: - raise TypeError("Incorrect type for body. Expected CloudEvent," - " list of CloudEvents, dict, or list of dicts." - " If dict passed, must follow the CloudEvent format.") + # If no binary_mode is set, send whatever event is passed + # If a cloud event dict, convert to CloudEvent for serializing + try: + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + if isinstance(events, list) and isinstance(events[0], dict): + events = [CloudEvent.from_dict(e) for e in events] + except Exception: # pylint: disable=broad-except + pass + + if self._level == "Standard": + kwargs["content_type"] = kwargs.get( + "content_type", "application/cloudevents-batch+json; charset=utf-8" + ) + if not isinstance(events, list): + events = [events] + + if isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): + raise TypeError("EventGridEvent is not supported for standard level client.") + try: + # Try to send via namespace + await self._send(topic_name, _serialize_events(events), **kwargs) + except Exception as exception: # pylint: disable=broad-except + self._http_response_error_handler(exception, "Standard") + raise exception + # # If that fails, try to send via basic + # self._last_exception = exception + else: + try: + await self._send(events, channel_name=channel_name, **kwargs) + except Exception as exception: + self._http_response_error_handler(exception, "Basic") + raise exception + + async def _send_binary(self, topic_name: str, events: Any, **kwargs: Any) -> None: + # If data is passed as a dictionary, make sure it is a CloudEvent + try: + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + except AttributeError: + raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from + + # If data is a cloud event, convert to an HTTP Request in binary mode + if isinstance(events, CloudEvent): + await self._publish( + topic_name, events, self._config.api_version, **kwargs + ) + else: + raise TypeError("Binary mode is only supported for type CloudEvent.") + + def _http_response_error_handler(self, exception, level): + if isinstance(exception, HttpResponseError): + if exception.status_code == 400: + raise HttpResponseError( + "Invalid event data. Please check the data and try again." + ) from exception + if exception.status_code == 404: + raise ResourceNotFoundError( + "Resource not found. " + f"Please check that the level set on the client, {level}, corresponds to the correct " + "endpoint and/or topic name." + ) from exception + raise exception + + @use_standard_only @distributed_trace_async - async def receive_cloud_events( + async def receive( self, topic_name: str, - event_subscription_name: str, + subscription_name: str, *, max_events: Optional[int] = None, max_wait_time: Optional[int] = None, - **kwargs: Any + **kwargs: Any, ) -> ReceiveResult: """Receive Batch of Cloud Events from the Event Subscription. :param topic_name: Topic Name. Required. :type topic_name: str - :param event_subscription_name: Event Subscription Name. Required. - :type event_subscription_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value is 100 events. If not specified, the default value is 1. Default value is None. :paramtype max_events: int @@ -236,8 +272,6 @@ async def receive_cloud_events( value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :keyword bool stream: Whether to stream the response of this operation. Defaults to False. You - will have to context manage the returned stream. :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: @@ -246,10 +280,10 @@ async def receive_cloud_events( detail_items = [] receive_result = await self._receive_cloud_events( topic_name, - event_subscription_name, + subscription_name, max_events=max_events, max_wait_time=max_wait_time, - **kwargs + **kwargs, ) for detail_item in receive_result.value: deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) @@ -263,54 +297,193 @@ async def receive_cloud_events( receive_result_deserialized = ReceiveResult(value=detail_items) return receive_result_deserialized - async def _publish(self, topic_name: str, event: Any, api_version, binary_mode, **kwargs: Any) -> None: + @use_standard_only + @distributed_trace_async + async def acknowledge( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.AcknowledgeResult: + """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + acknowledged lockTokens, along with other failed lockTokens with their corresponding error + information. Successfully acknowledged events will no longer be available to any consumer. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.AcknowledgeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = AcknowledgeOptions(lock_tokens=lock_tokens) + return await super()._acknowledge_cloud_events( + topic_name, subscription_name, options, **kwargs + ) + + @use_standard_only + @distributed_trace_async + @api_version_validation( + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, + ) + async def release( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + **kwargs: Any, + ) -> _models.ReleaseResult: + """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully released + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + Known values are: 0, 10, 60, 600, and 3600. Default value is None. + :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.ReleaseResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = ReleaseOptions(lock_tokens=lock_tokens) + return await super()._release_cloud_events( + topic_name, + subscription_name, + options, + release_delay_in_seconds=release_delay_in_seconds, + **kwargs, + ) + + @use_standard_only + @distributed_trace_async + async def reject( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.RejectResult: + """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request + is successfully accepted. The response body will include the set of successfully rejected + lockTokens, along with other failed lockTokens with their corresponding error information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: RejectResult. The RejectResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RejectResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = RejectOptions(lock_tokens=lock_tokens) + return await super()._reject_cloud_events( + topic_name, subscription_name, options, **kwargs + ) + + @use_standard_only + @distributed_trace_async + @api_version_validation( + method_added_on="2023-10-01-preview", + ) + async def renew_locks( + self, + topic_name: str, + subscription_name: str, + *, + lock_tokens: List[str], + **kwargs: Any, + ) -> _models.RenewCloudEventLocksResult: + """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the + request is successfully accepted. The response body will include the set of successfully + renewed lockTokens, along with other failed lockTokens with their corresponding error + information. + + :param topic_name: Topic Name. Required. + :type topic_name: str + :param subscription_name: Event Subscription Name. Required. + :type subscription_name: str + :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. + :paramtype lock_tokens: List[str] + :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + MutableMapping + :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + options = RenewLockOptions(lock_tokens=lock_tokens) + return await super()._renew_cloud_event_locks( + topic_name, subscription_name, options, **kwargs + ) + + async def _publish( + self, topic_name: str, event: Any, api_version, **kwargs: Any + ) -> None: error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None - ) - - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) + cls: ClsType[_models._models.PublishResult] = kwargs.pop( + "cls", None + ) # pylint: disable=protected-access + content_type = kwargs.pop("content_type", None) # pylint: disable=unused-variable # Given that we know the cloud event is binary mode, we can convert it to a HTTP request - http_request = _to_http_request( + http_request = _to_http_request( topic_name=topic_name, api_version=api_version, headers=_headers, params=_params, - content_type=content_type, event=event, - binary_mode=binary_mode, - **kwargs + **kwargs, ) _stream = kwargs.pop("stream", False) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), } - http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + http_request.url = self._client.format_url( + http_request.url, **path_format_arguments + ) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - http_request, - stream=_stream, - **kwargs + http_request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) + await response.read() # Load the body in memory and close the socket + map_error( + status_code=response.status_code, response=response, error_map=error_map + ) raise HttpResponseError(response=response) if _stream: @@ -318,13 +491,13 @@ async def _publish(self, topic_name: str, event: Any, api_version, binary_mode, else: deserialized = _deserialize( _models._models.PublishResult, # pylint: disable=protected-access - response.json() + response.json(), ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore - return deserialized # type: ignore + return deserialized # type: ignore __all__: List[str] = [ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index 506b7ccced9a..5e8c19f9276d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -6,8 +6,83 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List +from typing import List, Union, Any, TYPE_CHECKING, Optional +from azure.core.credentials import AzureKeyCredential, AzureSasCredential + + from .._legacy.aio import EventGridPublisherClient +from ._client import EventGridClient as InternalEventGridClient +from .._serialization import Deserializer, Serializer +from .._patch import ( + ClientLevel, + DEFAULT_BASIC_API_VERSION, + DEFAULT_STANDARD_API_VERSION, +) + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + + +class EventGridClient(InternalEventGridClient): + """Azure Messaging EventGrid Client. + + :param endpoint: The endpoint to the Event Grid resource. + :type endpoint: str + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value for namespaces is + "2023-10-01-preview". Default value for basic is "2018-01-01". Note that overriding this default value may result in unsupported + behavior. + :paramtype api_version: str or None + :keyword level: The level of client to use. + Known values include: "Basic", "Standard". Default value is "Standard". + `Standard` is used for working with a namespace topic. + `Basic` is used for working with a basic topic. + :paramtype level: str + """ + + def __init__( + self, + endpoint: str, + credential: Union[ + AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential" + ], + *, + api_version: Optional[str] = None, + level: Union[str, ClientLevel] = "Standard", + **kwargs: Any + ) -> None: + _endpoint = "{endpoint}" + self._level = level + + if level == ClientLevel.BASIC: + self._client = EventGridPublisherClient( # type: ignore[assignment] + endpoint, + credential, + api_version=api_version or DEFAULT_BASIC_API_VERSION, + **kwargs + ) + self._send = self._client.send # type: ignore[attr-defined] + elif level == ClientLevel.STANDARD: + if isinstance(credential, AzureSasCredential): + raise TypeError( + "SAS token authentication is not supported for the standard client." + ) + + super().__init__( + endpoint=endpoint, + credential=credential, + api_version=api_version or DEFAULT_STANDARD_API_VERSION, + **kwargs + ) + self._send = self._publish_cloud_events + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + def patch_sdk(): """Do not remove from this file. @@ -18,5 +93,6 @@ def patch_sdk(): __all__: List[str] = [ + "EventGridClient", "EventGridPublisherClient", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py index 7d7d97b1ac12..2bf8ba7809c7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py @@ -6,34 +6,22 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._models import AcknowledgeOptions from ._models import AcknowledgeResult -from ._models import Error from ._models import FailedLockToken -from ._models import InnerError -from ._models import RejectOptions from ._models import RejectResult -from ._models import ReleaseOptions from ._models import ReleaseResult from ._models import RenewCloudEventLocksResult -from ._models import RenewLockOptions from ._enums import ReleaseDelay from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk __all__ = [ - 'AcknowledgeOptions', 'AcknowledgeResult', - 'Error', 'FailedLockToken', - 'InnerError', - 'RejectOptions', 'RejectResult', - 'ReleaseOptions', 'ReleaseResult', 'RenewCloudEventLocksResult', - 'RenewLockOptions', 'ReleaseDelay', ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index a9bcc960fafc..c7fb2c8270fa 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -31,24 +31,6 @@ class AcknowledgeOptions(_model_base.Model): """Array of lock tokens. Required.""" - @overload - def __init__( - self, - *, - lock_tokens: List[str], - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - @@ -198,34 +180,12 @@ class Error(_model_base.Model): """A human-readable representation of the error. Required.""" target: Optional[str] = rest_field() """The target of the error.""" - details: Optional[List["_models.Error"]] = rest_field() + details: Optional[List["_models._models.Error"]] = rest_field() """An array of details about specific errors that led to this reported error.""" - innererror: Optional["_models.InnerError"] = rest_field() + innererror: Optional["_models._models.InnerError"] = rest_field() """An object containing more specific information than the current object about the error.""" - @overload - def __init__( - self, - *, - code: str, - message: str, - target: Optional[str] = None, - details: Optional[List["_models.Error"]] = None, - innererror: Optional["_models.InnerError"] = None, - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - @@ -243,7 +203,7 @@ class FailedLockToken(_model_base.Model): lock_token: str = rest_field(name="lockToken") """The lock token of an entry in the request. Required.""" - error: "_models.Error" = rest_field() + error: "_models._models.Error" = rest_field() """Error information of the failed operation result for the lock token in the request. Required.""" @@ -252,7 +212,7 @@ def __init__( self, *, lock_token: str, - error: "_models.Error", + error: "_models._models.Error", ): ... @@ -282,29 +242,10 @@ class InnerError(_model_base.Model): code: Optional[str] = rest_field() """One of a server-defined set of error codes.""" - innererror: Optional["_models.InnerError"] = rest_field() + innererror: Optional["_models._models.InnerError"] = rest_field() """Inner error.""" - @overload - def __init__( - self, - *, - code: Optional[str] = None, - innererror: Optional["_models.InnerError"] = None, - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - @@ -367,24 +308,6 @@ class RejectOptions(_model_base.Model): """Array of lock tokens. Required.""" - @overload - def __init__( - self, - *, - lock_tokens: List[str], - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - @@ -444,24 +367,6 @@ class ReleaseOptions(_model_base.Model): """Array of lock tokens. Required.""" - @overload - def __init__( - self, - *, - lock_tokens: List[str], - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - @@ -563,22 +468,4 @@ class RenewLockOptions(_model_base.Model): """Array of lock tokens. Required.""" - @overload - def __init__( - self, - *, - lock_tokens: List[str], - ): - ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py index ff93f72c6f87..ee8fa6387b70 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py @@ -8,13 +8,13 @@ """ from typing import List, overload, Mapping, Any from azure.core.messaging import CloudEvent -from .. import _model_base from ._models import ( ReceiveDetails as InternalReceiveDetails, ReceiveResult as InternalReceiveResult, BrokerProperties as InternalBrokerProperties, ) + class ReceiveDetails(InternalReceiveDetails): """Receive operation details per Cloud Event. @@ -32,8 +32,7 @@ def __init__( *, broker_properties: "BrokerProperties", event: "CloudEvent", - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -42,9 +41,9 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( + def __init__( # pylint: disable=useless-super-delegation self, *args: Any, **kwargs: Any - ) -> None: # pylint: disable=useless-super-delegation + ) -> None: super().__init__(*args, **kwargs) @@ -62,8 +61,7 @@ def __init__( self, *, value: List["ReceiveDetails"], - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -72,9 +70,9 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( + def __init__( # pylint: disable=useless-super-delegation self, *args: Any, **kwargs: Any - ) -> None: # pylint: disable=useless-super-delegation + ) -> None: super().__init__(*args, **kwargs) @@ -95,8 +93,7 @@ def __init__( *, lock_token: str, delivery_count: int, - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -105,9 +102,9 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( + def __init__( # pylint: disable=useless-super-delegation self, *args: Any, **kwargs: Any - ) -> None: # pylint: disable=useless-super-delegation + ) -> None: super().__init__(*args, **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/samples/README.md b/sdk/eventgrid/azure-eventgrid/samples/README.md index fff007e9966e..4a456ff13937 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/README.md +++ b/sdk/eventgrid/azure-eventgrid/samples/README.md @@ -10,7 +10,30 @@ urlFragment: eventgrid-samples # Azure Event Grid Client Library Python Samples -## Sync samples +## Namespace Sync samples +These code samples show common champion scenario operations with the Azure Event Grid client library. + +* Authenticate the client: [sample_authentication.py][python-eg-auth] +* Publish events to a namespace topic:[sample_publish_operation.py][python-eg-client-publish-sample] +* Publish events in binary mode to a namespace topic: [sample_binary_mode.py][python-eg-client-binary-mode-sample] +* Receive events from a namespace topic: [sample_receive_operation.py][python-eg-client-receive-sample] +* Acknowledge events from a namespace topic: [sample_acknowledge_operation.py][python-eg-client-ack-sample] +* Release events from a namespace topic: [sample_release_operation.py][python-eg-client-release-sample] +* Reject events from a namespace topic: [sample_reject_operation.py][python-eg-client-reject-sample] +* Renew locks: [sample_renew_locks_operation.py][python-eg-client-renew-locks-sample] + +## Namespace Async samples + +* Publish events to a namespace topic:[sample_publish_operation_async.py][python-eg-client-publish-sample-async] +* Publish events in binary mode to a namespace topic: [sample_binary_mode_async.py][python-eg-client-binary-mode-sample-async] +* Receive events from a namespace topic: [sample_receive_operation_async.py][python-eg-client-receive-sample-async] +* Acknowledge events from a namespace topic: [sample_acknowledge_operation_async.py][python-eg-client-ack-sample-async] +* Release events from a namespace topic: [sample_release_operation_async.py][python-eg-client-release-sample-async] +* Reject events from a namespace topic: [sample_reject_operation_async.py][python-eg-client-reject-sample-async] +* Renew locks: [sample_renew_locks_operation_async.py][python-eg-client-renew-locks-sample-async] + + +## Basic Sync samples These code samples show common champion scenario operations with the Azure Event Grid client library. * Generate Shared Access Signature: [sample_generate_sas.py][python-eg-generate-sas] @@ -29,9 +52,7 @@ To publish events, dict representation of the models could also be used as follo * Consume a Custom Payload of raw cloudevent data: [sample_consume_custom_payload.py][python-eg-sample-consume-custom-payload] -EventGridClient operation samples: [EventGridClient samples][python-eg-client-sync-samples] - -## Async samples +## Basic Async samples These code samples show common champion scenario operations with the Azure Event Grid client library using the async client. * Authenticate the client: [sample_authentication_async.py][python-eg-auth-async] @@ -46,8 +67,6 @@ To publish events, dict representation of the models could also be used as follo * Publish EventGridEvent as dict like representation: [sample_publish_eg_event_using_dict_async.py][python-eg-sample-send-eg-as-dict-async] * Publish CloudEvent as dict like representation: [sample_publish_cloud_event_using_dict_async.py][python-eg-sample-send-cloudevent-as-dict-async] -EventGridClient operation samples: [EventGridClient samples][python-eg-client-async-samples] - ## More Samples * More samples related to the send scenario can be seen [here][python-eg-publish-samples]. @@ -80,4 +99,47 @@ EventGridClient operation samples: [EventGridClient samples][python-eg-client-as [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts [python-eg-client-sync-samples]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples -[python-eg-client-async-samples]:https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples \ No newline at end of file +[python-eg-client-async-samples]:https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples + +[python-eg-client-ack-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py + +[python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py + +[python-eg-client-binary-mode-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py + +[python-eg-client-publish-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py + +[python-eg-client-receive-renew-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py + +[python-eg-client-release-receive-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py + +[python-eg-client-receive-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py + +[python-eg-client-release-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py + + +[python-eg-client-reject-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py + +[python-eg-client-renew-locks-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py + + +[python-eg-client-ack-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py + +[python-eg-client-all-ops-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py + +[python-eg-client-binary-mode-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py + +[python-eg-client-publish-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py + +[python-eg-client-receive-renew-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py + +[python-eg-client-release-receive-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py + +[python-eg-client-receive-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py + +[python-eg-client-release-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py + + +[python-eg-client-reject-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py + +[python-eg-client-renew-locks-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py index bc53812fa804..acbde2f1e706 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_acknowledge_operation_async.py +DESCRIPTION: + These samples demonstrate acknowledging CloudEvent lock tokens. +USAGE: + python sample_acknowledge_operation_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -23,11 +36,11 @@ async def run(): # Acknowledge a batch of CloudEvents try: async with client: - lock_tokens = AcknowledgeOptions(lock_tokens=["token"]) - ack_events = await client.acknowledge_cloud_events( + lock_tokens = ["token"] + ack_events = await client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, ) print(ack_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index d31666095998..ac862916ab27 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_all_operations_async.py +DESCRIPTION: + These samples demonstrate sending, receiving, acknowledging, and releasing CloudEvents. +USAGE: + python sample_all_operations_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -36,8 +49,8 @@ async def run(): async with client: # Publish a CloudEvent try: - await client.publish_cloud_events( - topic_name=TOPIC_NAME, body=cloud_event_reject + await client.send( + topic_name=TOPIC_NAME, events=cloud_event_reject ) except HttpResponseError: raise @@ -45,17 +58,17 @@ async def run(): # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event_release, cloud_event_ack] - await client.publish_cloud_events( - topic_name=TOPIC_NAME, body=list_of_cloud_events + await client.send( + topic_name=TOPIC_NAME, events=list_of_cloud_events ) except HttpResponseError: raise # Receive Published Cloud Events try: - receive_results = await client.receive_cloud_events( + receive_results = await client.receive( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10, ) @@ -82,11 +95,10 @@ async def run(): if len(release_events) > 0: try: - release_tokens = ReleaseOptions(lock_tokens=release_events) - release_result = await client.release_cloud_events( + release_result = await client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - release_options=release_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=release_events, ) except HttpResponseError: raise @@ -96,11 +108,10 @@ async def run(): if len(acknowledge_events) > 0: try: - ack_tokens = AcknowledgeOptions(lock_tokens=acknowledge_events) - ack_result = await client.acknowledge_cloud_events( + ack_result = await client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=ack_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=acknowledge_events, ) except HttpResponseError: raise @@ -110,11 +121,10 @@ async def run(): if len(reject_events) > 0: try: - reject_tokens = RejectOptions(lock_tokens=reject_events) - reject_result = await client.reject_cloud_events( + reject_result = await client.reject( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - reject_options=reject_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=reject_events, ) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py index 6b50f1fe9444..3e9d918cd15c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_binary_mode_async.py +DESCRIPTION: + These samples demonstrate sending CloudEvents in binary mode. +USAGE: + python sample_binary_mode_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio import json @@ -28,15 +41,15 @@ async def run(): try: # Publish CloudEvent in binary mode with str encoded as bytes cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict, binary_mode=True) + await client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event, binary_mode=True) + await client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) - receive_result = await client.receive_cloud_events( + receive_result = await client.receive( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10, ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py index 5fd2486723a6..aae84b550ecc 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_operation_async.py +DESCRIPTION: + These samples demonstrate sending CloudEvents. +USAGE: + python sample_publish_operation_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -27,13 +40,13 @@ async def run(): # Publish a CloudEvent as dict try: cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + await client.send(topic_name=TOPIC_NAME, events=cloud_event_dict) except HttpResponseError: raise # Publish a list of CloudEvents as dict try: - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=[cloud_event_dict, cloud_event_dict]) + await client.send(topic_name=TOPIC_NAME, events=[cloud_event_dict, cloud_event_dict]) except HttpResponseError: raise @@ -43,15 +56,15 @@ async def run(): cloud_event = CloudEvent( data="HI", source="https://example.com", type="example" ) - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + await client.send(topic_name=TOPIC_NAME, events=cloud_event) except HttpResponseError: raise # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event, cloud_event] - await client.publish_cloud_events( - topic_name=TOPIC_NAME, body=list_of_cloud_events + await client.send( + topic_name=TOPIC_NAME, events=list_of_cloud_events ) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py index 62d02f707f80..020b830b6e5e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_receive_renew_async.py +DESCRIPTION: + These samples demonstrate sending, receiving, and renewing CloudEvents. +USAGE: + python sample_publish_receive_renew_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -26,20 +39,19 @@ async def run(): try: # Publish a CloudEvent cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) # Renew lock tokens - lock_tokens = RenewLockOptions(lock_tokens=lock_tokens_to_release) - renew_events = await client.renew_cloud_event_locks( + renew_events = await client.renew_locks( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - renew_lock_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens_to_release, ) print("Renewed Event:", renew_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py index 895640a9d8f6..d1b5d0c6bbe3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_release_receive_async.py +DESCRIPTION: + These samples demonstrate sending, receiving, and releasing CloudEvents. +USAGE: + python sample_publish_release_receive_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -26,10 +39,10 @@ async def run(): try: # Publish a CloudEvent cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - await client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -37,25 +50,23 @@ async def run(): print("Received events:", receive_result.value) # Release a LockToken - release_token = ReleaseOptions(lock_tokens=lock_tokens_to_release) - release_events = await client.release_cloud_events( + release_events = await client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=60, - release_options=release_token, + lock_tokens=lock_tokens_to_release, ) print("Released Event:", release_events) # Receive CloudEvents again - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) print("Received events after release:", receive_result.value) - # Acknowledge LockTokens - acknowledge_token = AcknowledgeOptions(lock_tokens=lock_tokens_to_release) - acknowledge_events = await client.acknowledge_cloud_events( + # Acknowledge a LockToken that was released + acknowledge_events = await client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=acknowledge_token, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens_to_release, ) print("Acknowledged events after release:", acknowledge_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py index 6d136c5ff5e4..c166adc49d84 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_receive_operation_async.py +DESCRIPTION: + These samples demonstrate receiving CloudEvents. +USAGE: + python sample_receive_operations_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -23,9 +36,9 @@ async def run(): # Receive CloudEvents try: async with client: - receive_result = await client.receive_cloud_events( + receive_result = await client.receive( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10, ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py index c1ea4b70c3dd..c8ccc0c30a6c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_reject_operation_async.py +DESCRIPTION: + These samples demonstrate rejecting CloudEvents. +USAGE: + python sample_reject_operation_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -23,11 +36,11 @@ async def run(): # Reject a LockToken try: async with client: - tokens = RejectOptions(lock_tokens=["token"]) - reject_events = await client.reject_cloud_events( + tokens = ["token"] + reject_events = await client.reject( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - reject_options=tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=tokens, ) print(reject_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index 0ef5fc8dd4ab..cdb308dd6aac 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_release_operation_async.py +DESCRIPTION: + These samples demonstrate releasing CloudEvents. +USAGE: + python sample_release_operation_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -23,12 +36,12 @@ async def run(): # Release a LockToken try: async with client: - tokens = ReleaseOptions(lock_tokens=["token"]) - release_events = await client.release_cloud_events( + tokens = ["token"] + release_events = await client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=10, - release_options=tokens, + lock_tokens=tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py index 89938ee40978..09e672fc9661 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_renew_locks_operation_async.py +DESCRIPTION: + These samples demonstrate renewing CloudEvents locks. +USAGE: + python sample_renew_locks_operation_async.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -21,11 +34,11 @@ async def run(): # Renew a lockToken try: - lock_tokens = RenewLockOptions(lock_tokens=["token"]) - release_events = await client.renew_cloud_event_locks( + lock_tokens = ["token"] + release_events = await client.renew_locks( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - renew_lock_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py index a26411bb95ed..54075cdbf128 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py @@ -17,31 +17,31 @@ """ # [START client_auth_with_key_cred_async] import os -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_key = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential_key) +client = EventGridClient(endpoint, credential_key, level="Basic") # [END client_auth_with_key_cred_async] # [START client_auth_with_sas_cred_async] import os -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureSasCredential signature = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_sas = AzureSasCredential(signature) -client = EventGridPublisherClient(endpoint, credential_sas) +client = EventGridClient(endpoint, credential_sas, level="Basic") # [END client_auth_with_sas_cred_async] # [START client_auth_with_token_cred_async] from azure.identity.aio import DefaultAzureCredential -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.eventgrid import EventGridEvent event = EventGridEvent( @@ -53,5 +53,5 @@ default_az_credential = DefaultAzureCredential() endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -client = EventGridPublisherClient(endpoint, default_az_credential) +client = EventGridClient(endpoint, default_az_credential, level="Basic") # [END client_auth_with_token_cred_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py index d6737c21420d..5e2be47c8c7c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.core.messaging import CloudEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] @@ -27,7 +27,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") # [START publish_cloud_event_dict_async] async with client: diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py index f755c9724c46..a72484e27301 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py @@ -16,7 +16,7 @@ """ import os import asyncio -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential from cloudevents.http import CloudEvent @@ -26,19 +26,20 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) - await client.send( - [ - CloudEvent( - attributes={ - "type": "cloudevent", - "source": "/cncf/cloud/event/1.0", - "subject": "testing-cncf-event", - }, - data=b"This is a cncf cloud event.", - ) - ] - ) + client = EventGridClient(endpoint, credential, level="Basic") + async with client: + await client.send( + [ + CloudEvent( + attributes={ + "type": "cloudevent", + "source": "/cncf/cloud/event/1.0", + "subject": "testing-cncf-event", + }, + data=b"This is a cncf cloud event.", + ) + ] + ) if __name__ == "__main__": diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py index 2d7ccbb8cbcf..40f268f84112 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py @@ -23,7 +23,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -33,7 +33,7 @@ async def publish_event(): # authenticate client # [START publish_custom_schema_async] credential = AzureKeyCredential(key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") custom_schema_event = { "customSubject": "sample", diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py index 8909b5717b2b..605c0b3f5236 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py @@ -20,7 +20,7 @@ import asyncio from datetime import datetime from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -29,7 +29,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") # [START publish_eg_event_dict_async] event0 = { diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py index 48272cb30166..ace029405cda 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential domain_key = os.environ["EVENTGRID_DOMAIN_KEY"] @@ -27,26 +27,26 @@ async def publish(): credential = AzureKeyCredential(domain_key) - client = EventGridPublisherClient(domain_hostname, credential) - - await client.send( - [ - EventGridEvent( - topic="MyCustomDomainTopic1", - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - data_version="2.0", - ), - EventGridEvent( - topic="MyCustomDomainTopic2", - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #2"}, - subject="Door1", - data_version="2.0", - ), - ] - ) + client = EventGridClient(domain_hostname, credential, level="Basic") + async with client: + await client.send( + [ + EventGridEvent( + topic="MyCustomDomainTopic1", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ), + EventGridEvent( + topic="MyCustomDomainTopic2", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #2"}, + subject="Door1", + data_version="2.0", + ), + ] + ) if __name__ == "__main__": diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py index 4ab76f2a81fa..8628477492ce 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -27,18 +27,18 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) - - await client.send( - [ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - data_version="2.0", - ) - ] - ) + client = EventGridClient(endpoint, credential, level="Basic") + async with client: + await client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] + ) # [END publish_eg_event_to_topic_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py index c70bfd11aef4..d56ce6c5f265 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py @@ -17,7 +17,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureSasCredential sas = os.environ["EVENTGRID_SAS"] @@ -26,7 +26,7 @@ async def publish(): credential = AzureSasCredential(sas) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") async with client: await client.send( diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py index 1d3ea0337e33..93f953a7ba9b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.core.messaging import CloudEvent -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] @@ -27,18 +27,18 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) - - await client.send( - [ - CloudEvent( - type="Contoso.Items.ItemReceived", - source="/contoso/items", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - ) - ] - ) + client = EventGridClient(endpoint, credential, level="Basic") + async with client: + await client.send( + [ + CloudEvent( + type="Contoso.Items.ItemReceived", + source="/contoso/items", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + ) + ] + ) # [END publish_cloud_event_to_topic_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py index f12070c35a1e..8cf418b53207 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py @@ -18,7 +18,7 @@ # [START publish_cloud_event_to_topic] import os import asyncio -from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid.aio import EventGridClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -30,7 +30,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") async with client: await client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py index bb6b7420cef1..9a04a87df6d9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py @@ -21,14 +21,14 @@ from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] # authenticate client credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") services = [ "EventGrid", diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py index b12784c078b7..d30969af523b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py @@ -22,7 +22,7 @@ from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient domain_key = os.environ["EVENTGRID_CLOUD_EVENT_DOMAIN_KEY"] domain_endpoint = os.environ["EVENTGRID_CLOUD_EVENT_DOMAIN_ENDPOINT"] @@ -30,7 +30,7 @@ # authenticate client credential = AzureKeyCredential(domain_key) -client = EventGridPublisherClient(domain_endpoint, credential) +client = EventGridClient(domain_endpoint, credential, level="Basic") def publish_event(): diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py index 4f51f1b6990c..8a25456e45cb 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py @@ -22,7 +22,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -31,7 +31,7 @@ def publish_event(): # authenticate client credential = AzureKeyCredential(key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") custom_schema_event = { "customSubject": "sample", diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py index 075dc12fdfdf..1f00e36dcf18 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py @@ -20,14 +20,14 @@ import time from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, EventGridEvent +from azure.eventgrid import EventGridClient, EventGridEvent key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] # authenticate client credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") services = [ "EventGrid", "ServiceBus", diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py index dea31e7b7ae0..4afdeebc182b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py @@ -22,7 +22,7 @@ from datetime import datetime, timedelta from azure.core.credentials import AzureSasCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridPublisherClient, generate_sas +from azure.eventgrid import EventGridClient, generate_sas key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] @@ -32,7 +32,7 @@ # authenticate client credential = AzureSasCredential(signature) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") services = [ "EventGrid", diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py deleted file mode 100644 index 780c9cc975e2..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py +++ /dev/null @@ -1,14 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -import os -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.identity import DefaultAzureCredential - -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] - -# Create a client using DefaultAzureCredential -client = EventGridClient(EVENTGRID_ENDPOINT, DefaultAzureCredential()) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py index 72a5518c6228..c7c2df51bed1 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_acknowledge_operation.py +DESCRIPTION: + These samples demonstrate acknowledging CloudEvents. +USAGE: + python sample_acknowledge_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -20,11 +33,11 @@ # Acknowledge a CloudEvent try: - lock_tokens = AcknowledgeOptions(lock_tokens=["token"]) - ack_events = client.acknowledge_cloud_events( + lock_tokens = ["token"] + ack_events = client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, ) print(ack_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py index 52d12730c41d..2299988e0b4c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_all_operations.py +DESCRIPTION: + These samples demonstrate sending, receiving, releasing, and acknowledging CloudEvents. +USAGE: + python sample_all_operations.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import asyncio from azure.core.credentials import AzureKeyCredential @@ -33,22 +46,22 @@ # Publish a CloudEvent try: - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_reject) + client.send(topic_name=TOPIC_NAME, events=cloud_event_reject) except HttpResponseError: raise # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event_release, cloud_event_ack] - client.publish_cloud_events(topic_name=TOPIC_NAME, body=list_of_cloud_events) + client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) except HttpResponseError: raise # Receive Published Cloud Events try: - receive_results = client.receive_cloud_events( + receive_results = client.receive( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10, ) @@ -75,11 +88,10 @@ if len(release_events) > 0: try: - release_tokens = ReleaseOptions(lock_tokens=release_events) - release_result = client.release_cloud_events( + release_result = client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - release_options=release_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=release_events, ) except HttpResponseError: raise @@ -89,11 +101,10 @@ if len(acknowledge_events) > 0: try: - ack_tokens = AcknowledgeOptions(lock_tokens=acknowledge_events) - ack_result = client.acknowledge_cloud_events( + ack_result = client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=ack_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=acknowledge_events, ) except HttpResponseError: raise @@ -103,11 +114,10 @@ if len(reject_events) > 0: try: - reject_tokens = RejectOptions(lock_tokens=reject_events) - reject_result = client.reject_cloud_events( + reject_result = client.reject( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - reject_options=reject_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=reject_events, ) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py index 45240b174a8c..884c9adfbd15 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_binary_mode.py +DESCRIPTION: + These samples demonstrate sending CloudEvents in binary mode. +USAGE: + python sample_binary_mode.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os import json from azure.core.credentials import AzureKeyCredential @@ -25,14 +38,14 @@ try: # Publish CloudEvent in binary mode with str encoded as bytes cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict, binary_mode=True) + client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event, binary_mode=True) + client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) # Receive a CloudEvent - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) + receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) for receive_details in receive_result.value: cloud_event_received = receive_details.event print("CloudEvent: ", cloud_event_received) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py deleted file mode 100644 index a95d1613c823..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py +++ /dev/null @@ -1,27 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_eg_client_authentication.py -DESCRIPTION: - These samples demonstrate authenticating an EventGridClient. -USAGE: - python sample_eg_client_authentication.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace hostname. Typically it exists in the format - "https://..eventgrid.azure.net". -""" -# [START client_auth_with_key_cred] -import os -from azure.eventgrid import EventGridClient -from azure.core.credentials import AzureKeyCredential - -key: str = os.environ["EVENTGRID_KEY"] -endpoint: str = os.environ["EVENTGRID_ENDPOINT"] - -credential = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential) -# [END client_auth_with_key_cred] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py index 3c4db3a37f3b..d6ce90dee42b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_operation.py +DESCRIPTION: + These samples demonstrate sending CloudEvents. +USAGE: + python sample_publish_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -22,26 +35,26 @@ # Publish a CloudEvent as dict try: cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event_dict) + client.send(topic_name=TOPIC_NAME, events=cloud_event_dict) except HttpResponseError: raise # Publish a list of CloudEvents as dict try: - client.publish_cloud_events(topic_name=TOPIC_NAME, body=[cloud_event_dict, cloud_event_dict]) + client.send(topic_name=TOPIC_NAME, events=[cloud_event_dict, cloud_event_dict]) except HttpResponseError: raise # Publish a CloudEvent try: cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + client.send(topic_name=TOPIC_NAME, events=cloud_event) except HttpResponseError: raise # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event, cloud_event] - client.publish_cloud_events(topic_name=TOPIC_NAME, body=list_of_cloud_events) + client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py index 38492b231d7b..1db143b432f9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_receive_renew.py +DESCRIPTION: + These samples demonstrate sending, receiving and renewing CloudEvents. +USAGE: + python sample_publish_receive_renew.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -23,20 +36,19 @@ try: # Publish a CloudEvent cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) - lock_tokens_to_release = [] + receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + lock_tokens_to_renew = [] for item in receive_result.value: - lock_tokens_to_release.append(item.broker_properties.lock_token) + lock_tokens_to_renew.append(item.broker_properties.lock_token) # Renew a lock token - lock_tokens = RenewLockOptions(lock_tokens=lock_tokens_to_release) - renew_events = client.renew_cloud_event_locks( + renew_events = client.renew_locks( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - renew_lock_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens_to_renew, ) print("Renewed Event:", renew_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py index ef97375c3f0b..ed357aa1ad52 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_publish_release_receive.py +DESCRIPTION: + These samples demonstrate sending, receiving and releasing CloudEvents. +USAGE: + python sample_publish_release_receive.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -23,10 +36,10 @@ try: # Publish a CloudEvent cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.publish_cloud_events(topic_name=TOPIC_NAME, body=cloud_event) + client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -34,25 +47,23 @@ print("Received events:", receive_result.value) # Release a LockToken - release_token = ReleaseOptions(lock_tokens=lock_tokens_to_release) - release_events = client.release_cloud_events( + release_events = client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=60, - release_options=release_token, + lock_tokens=lock_tokens_to_release, ) print("Released Event:", release_events) # Receive CloudEvents again - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, event_subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) print("Received events after release:", receive_result.value) - # Acknowledge a LockToken - acknowledge_token = AcknowledgeOptions(lock_tokens=lock_tokens_to_release) - acknowledge_events = client.acknowledge_cloud_events( + # Acknowledge a LockToken that was released + acknowledge_events = client.acknowledge( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - acknowledge_options=acknowledge_token, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens_to_release, ) print("Acknowledged events after release:", acknowledge_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py index 20252bda9cac..4e7c69bcec7b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_receive_operation.py +DESCRIPTION: + These samples demonstrate receiving CloudEvents. +USAGE: + python sample_receive_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -20,9 +33,9 @@ # Receive CloudEvents try: - receive_result = client.receive_cloud_events( + receive_result = client.receive( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10, ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py index 3f6e87b8e050..7743fe3de606 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_reject_operation.py +DESCRIPTION: + These samples demonstrate rejecting CloudEvents. +USAGE: + python sample_reject_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -19,11 +32,11 @@ # Release a LockToken try: - lock_tokens = RejectOptions(lock_tokens=["token"]) - reject_events = client.reject_cloud_events( + lock_tokens = ["token"] + reject_events = client.reject( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - reject_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, ) print(reject_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py index 8d7df562004a..cb0858e01666 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_release_operation.py +DESCRIPTION: + These samples demonstrate releasing CloudEvents. +USAGE: + python sample_release_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -19,12 +32,12 @@ # Release a LockToken try: - lock_tokens = ReleaseOptions(lock_tokens=["token"]) - release_events = client.release_cloud_events( + lock_tokens = ["token"] + release_events = client.release( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, + subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=3600, - release_options=lock_tokens, + lock_tokens=lock_tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py index 82a4fd9f5f47..52796dc9b1a2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py @@ -3,6 +3,19 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- +""" +FILE: sample_renew_locks_operation.py +DESCRIPTION: + These samples demonstrate renew locks CloudEvents. +USAGE: + python sample_renew_locks_operation.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" import os from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridClient @@ -19,11 +32,11 @@ # Renew a lockToken try: - lock_tokens = RenewLockOptions(lock_tokens=["token"]) - release_events = client.renew_cloud_event_locks( + lock_tokens = ["token"] + release_events = client.renew_locks( topic_name=TOPIC_NAME, - event_subscription_name=EVENT_SUBSCRIPTION_NAME, - renew_lock_options=lock_tokens, + subscription_name=EVENT_SUBSCRIPTION_NAME, + lock_tokens=lock_tokens, ) print(release_events) except HttpResponseError: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py index eb54049d0925..a70aa2965b75 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py @@ -6,7 +6,7 @@ """ FILE: sample_authentication.py DESCRIPTION: - These samples demonstrate authenticating an EventGridPublisherClient. + These samples demonstrate authenticating an EventGridClient. USAGE: python sample_authentication.py Set the environment variables with your own values before running the sample: @@ -17,33 +17,33 @@ """ # [START client_auth_with_key_cred] import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential -topic_key = os.environ["EVENTGRID_TOPIC_KEY"] -endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] -credential_key = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential_key) +credential_key = AzureKeyCredential(key) +client = EventGridClient(endpoint, credential_key) # [END client_auth_with_key_cred] # [START client_auth_with_sas_cred] import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureSasCredential signature = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_sas = AzureSasCredential(signature) -client = EventGridPublisherClient(endpoint, credential_sas) +client = EventGridClient(endpoint, credential_sas, level="Basic") # [END client_auth_with_sas_cred] # [START client_auth_with_token_cred] from azure.identity import DefaultAzureCredential -from azure.eventgrid import EventGridPublisherClient, EventGridEvent +from azure.eventgrid import EventGridClient, EventGridEvent default_az_credential = DefaultAzureCredential() -endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -client = EventGridPublisherClient(endpoint, default_az_credential) +endpoint = os.environ["EVENTGRID_ENDPOINT"] +client = EventGridClient(endpoint, default_az_credential) # [END client_auth_with_token_cred] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py index 0630d409ebd6..260bf1b16ff2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py @@ -16,14 +16,14 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") # [START publish_cloud_event_dict] client.send( diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py index 83432366aa74..5fdecaf7ecf2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py @@ -15,7 +15,7 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential from cloudevents.http import CloudEvent @@ -23,7 +23,7 @@ endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py index 4650aae15d61..978a9002bc45 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py @@ -22,7 +22,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -31,7 +31,7 @@ def publish_event(): # authenticate client credential = AzureKeyCredential(key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") # [START publish_custom_schema] custom_schema_event = { diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py index b7154a0e07b8..4fc92b61b925 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py @@ -19,7 +19,7 @@ import os from datetime import datetime from msrest.serialization import UTC -from azure.eventgrid import EventGridPublisherClient, EventGridEvent +from azure.eventgrid import EventGridClient, EventGridEvent from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -29,7 +29,7 @@ def publish(): # [START publish_eg_event_dict] credential = AzureKeyCredential(topic_key) - client = EventGridPublisherClient(endpoint, credential) + client = EventGridClient(endpoint, credential, level="Basic") event0 = { "eventType": "Contoso.Items.ItemReceived", diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py index 960f91aeae70..67c7bc725dbd 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py @@ -15,14 +15,14 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridPublisherClient, EventGridEvent +from azure.eventgrid import EventGridClient, EventGridEvent from azure.core.credentials import AzureKeyCredential domain_key = os.environ["EVENTGRID_DOMAIN_KEY"] domain_hostname = os.environ["EVENTGRID_DOMAIN_ENDPOINT"] credential = AzureKeyCredential(domain_key) -client = EventGridPublisherClient(domain_hostname, credential) +client = EventGridClient(domain_hostname, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py index a0e3ab58b6dc..742a2080bb19 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py @@ -16,14 +16,14 @@ """ # [START publish_eg_event_to_topic] import os -from azure.eventgrid import EventGridPublisherClient, EventGridEvent +from azure.eventgrid import EventGridClient, EventGridEvent from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py index 6051d883fbd4..48a66df61e8a 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py @@ -16,14 +16,14 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas +from azure.eventgrid import EventGridClient, EventGridEvent, generate_sas from azure.core.credentials import AzureKeyCredential, AzureSasCredential sas = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential = AzureSasCredential(sas) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py index a0297f9950a3..abc4bec0cb3f 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py @@ -16,7 +16,7 @@ """ # [START publish_cloud_event_to_topic] import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -24,7 +24,7 @@ endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py index 433ce0fefe72..1bed2ad38113 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py @@ -17,7 +17,7 @@ """ # [START publish_cloud_event_to_topic] import os -from azure.eventgrid import EventGridPublisherClient +from azure.eventgrid import EventGridClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -27,7 +27,7 @@ channel_name = os.environ["EVENTGRID_PARTNER_CHANNEL_NAME"] credential = AzureKeyCredential(topic_key) -client = EventGridPublisherClient(endpoint, credential) +client = EventGridClient(endpoint, credential, level="Basic") client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index c69c75af758e..0676dd77c87d 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -58,6 +58,22 @@ def add_sanitizers(test_proxy): eventgrid_client_secret = os.getenv("EVENTGRID_CLIENT_SECRET", "sanitized") tenant_id = os.getenv("AZURE_TENANT_ID", "sanitized") eventgrid_topic_endpoint = os.getenv("EVENTGRID_TOPIC_ENDPOINT", "sanitized") + + eventgrid_endpoint = os.getenv("EVENTGRID_ENDPOINT", "sanitized") + eventgrid_key = os.getenv("EVENTGRID_KEY", "sanitized") + eventgrid_topic_name = os.getenv("EVENTGRID_TOPIC_NAME", "sanitized") + eventgrid_event_subscription_name = os.getenv("EVENTGRID_EVENT_SUBSCRIPTION_NAME", "sanitized") + + eventgrid_cloud_event_topic_key = os.getenv("EVENTGRID_CLOUD_EVENT_TOPIC_KEY", "sanitized") + eventgrid_cloud_event_topic_endpoint = os.getenv("EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT", "sanitized") + + eventgrid_topic_key = os.getenv("EVENTGRID_TOPIC_KEY", "sanitized") + eventgrid_topic_endpoint = os.getenv("EVENTGRID_TOPIC_ENDPOINT", "sanitized") + + eventgrid_partner_channel_name=os.getenv("EVENTGRID_PARTNER_CHANNEL_NAME", "sanitized") + eventgrid_partner_namespace_topic_endpoint=os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT", "sanitized") + eventgrid_partner_namespace_topic_key=os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY", "sanitized") + # Need to santize namespace for eventgrid_topic: try: eventgrid_hostname = urlparse(eventgrid_topic_endpoint).hostname diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py new file mode 100644 index 000000000000..f3e28d500e09 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py @@ -0,0 +1,287 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from datetime import datetime +from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy +from azure.eventgrid import EventGridClient, EventGridEvent, ClientLevel +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from cloudevents.http import CloudEvent as CNCFCloudEvent + +from eventgrid_preparer import EventGridPreparer + +class ArgPasser: + def __call__(self, fn): + def _preparer(test_class, level, **kwargs): + fn(test_class, level, **kwargs) + return _preparer + +class TestEGDualClient(AzureRecordedTestCase): + def create_eg_client(self, endpoint, key, level): + client = EventGridClient( + endpoint=endpoint, credential=AzureKeyCredential(key), level=level + ) + return client + + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_publish(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + from xml.etree import ElementTree as ET + xml_string = """test""" + tree = xml_string.encode('utf-8') + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=tree, + datacontenttype="text/xml", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + if level=="Basic": + with pytest.raises(ValueError): + client.send( + topic_name=eventgrid_topic_name, events=event, binary_mode=True + ) + else: + client.send( + topic_name=eventgrid_topic_name, events=event, binary_mode=True + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_receive(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + from xml.etree import ElementTree as ET + xml_string = """test""" + tree = xml_string.encode('utf-8') + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data=tree, + datacontenttype="text/xml", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + if level=="Basic": + with pytest.raises(AttributeError): + client.receive( + topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name + ) + else: + client.receive( + topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_publish_event(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_topic_key, eventgrid_topic_endpoint): + if level=="Basic": + client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) + else: + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + event = EventGridEvent( + id="7f7d", + subject="MySubject", + data={ + "test": "data" + }, + event_type="Contoso.Items.ItemReceived", + data_version="1.0" + ) + + if level=="Basic": + client.send( + events=event + ) + else: + with pytest.raises(TypeError): + client.send( + topic_name=eventgrid_topic_name, events=event + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_cloud_event(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): + if level=="Basic": + client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + else: + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"test": "data"}, + datacontenttype="application/json", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + client.send( + topic_name=eventgrid_topic_name, events=event + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_channel_name(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_partner_namespace_topic_key, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name): + + client = self.create_eg_client(eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, level=level) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"test": "data"}, + datacontenttype="application/json", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + if level=="Standard": + with pytest.raises(ValueError): + client.send( + topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name + ) + else: + client.send( + topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_publish_endpoint(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"test": "data"}, + datacontenttype="application/json", + extensions={"extension1": "value1", "extension2": "value2"} + ) + + if level=="Basic": + with pytest.raises(ResourceNotFoundError): + client.send( + topic_name=eventgrid_topic_name, events=event + ) + else: + client.send( + topic_name=eventgrid_topic_name, events=event + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_publish_cncf_events(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): + if level=="Basic": + client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + else: + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + attributes = { + "type": "com.example.sampletype1", + "source": "https://example.com/event-producer", + } + data = {"message": "Hello World!"} + cloud_event = CNCFCloudEvent(attributes, data) + + if level==ClientLevel.STANDARD: + with pytest.raises(HttpResponseError): + client.send( + topic_name=eventgrid_topic_name, events=cloud_event + ) + else: + client.send( + topic_name=eventgrid_topic_name, events=cloud_event + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_cloud_event_dict(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): + if level=="Basic": + client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + else: + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + event = {"type": "Contoso.Items.ItemReceived", + "source": "source", + "subject": "MySubject", + "data": {"test": "data"}, + "datacontenttype": "application/json", + "extensions": {"extension1": "value1", "extension2": "value2"}} + + client.send( + topic_name=eventgrid_topic_name, events=event + ) + + @pytest.mark.live_test_only() + @pytest.mark.parametrize("level", ["Standard", "Basic"]) + @EventGridPreparer() + @ArgPasser() + @recorded_by_proxy + def test_create_client_publish_event_dict(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, + eventgrid_topic_key, eventgrid_topic_endpoint): + if level=="Basic": + client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) + else: + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) + + event = { + "eventType": "Contoso.Items.ItemReceived", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "dataVersion": "2.0", + "id": "randomuuid11", + "eventTime": datetime.now(), + } + + if level==ClientLevel.STANDARD: + with pytest.raises(TypeError): + client.send( + topic_name=eventgrid_topic_name, events=event + ) + else: + client.send( + topic_name=eventgrid_topic_name, events=event + ) \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py index d08679335a42..70a49863bb74 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -41,23 +41,19 @@ def test_publish_binary_mode_xml(self, eventgrid_endpoint, eventgrid_key, eventg extensions={"extension1": "value1", "extension2": "value2"} ) - client.publish_cloud_events( - eventgrid_topic_name, body=event, binary_mode=True + client.send( + topic_name=eventgrid_topic_name, events=event, binary_mode=True ) time.sleep(5) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) - my_returned_event = events.value[0].event - assert my_returned_event.data == xml_string - assert my_returned_event.datacontenttype == 'text/xml' - assert my_returned_event.type == "Contoso.Items.ItemReceived" + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) + rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) @@ -75,23 +71,17 @@ def test_publish_binary_mode_cloud_event(self, eventgrid_endpoint, eventgrid_key datacontenttype='text/plain' ) - client.publish_cloud_events( - eventgrid_topic_name, body=event, binary_mode=True + client.send( + topic_name= eventgrid_topic_name, events=event, binary_mode=True ) - time.sleep(5) - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) - my_returned_event = events.value[0].event - assert my_returned_event.data == 'this is binary data' - assert my_returned_event.datacontenttype == 'text/plain' - assert my_returned_event.type == "Contoso.Items.ItemReceived" + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) + rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) @EventGridPreparer() @@ -108,8 +98,8 @@ def test_publish_binary_mode_incorrect_cloud_event(self, eventgrid_endpoint, eve ) with pytest.raises(TypeError): - client.publish_cloud_events( - eventgrid_topic_name, body=event, binary_mode=True + client.send( + topic_name=eventgrid_topic_name, events=event, binary_mode=True ) @EventGridPreparer() @@ -126,8 +116,8 @@ def test_publish_binary_mode_list_cloud_event(self, eventgrid_endpoint, eventgri ) with pytest.raises(TypeError): - client.publish_cloud_events( - eventgrid_topic_name, body=[event], binary_mode=True + client.send( + topic_name=eventgrid_topic_name, events=[event], binary_mode=True ) @pytest.mark.live_test_only() @@ -147,23 +137,23 @@ def test_publish_binary_mode_combinations(self, eventgrid_endpoint, eventgrid_ke dict_event = {"type": "Contoso.Items.ItemReceived", "source": "source", "subject": "MySubject", "data": b"hello", "datacontenttype": "text/plain"} - client.publish_cloud_events( - eventgrid_topic_name, body=event, binary_mode=True + client.send( + topic_name=eventgrid_topic_name, events=event, binary_mode=True ) - client.publish_cloud_events( - eventgrid_topic_name, body=dict_event, binary_mode=True + client.send( + topic_name=eventgrid_topic_name, events=dict_event, binary_mode=True ) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=RejectOptions(lock_tokens=tokens)) + rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) - @pytest.mark.skip("need to update conftest") + @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy def test_publish_receive_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): @@ -176,20 +166,20 @@ def test_publish_receive_cloud_event(self, eventgrid_endpoint, eventgrid_key, ev data=b'this is binary data', ) - client.publish_cloud_events( - eventgrid_topic_name, body=[event] + client.send( + topic_name=eventgrid_topic_name, events=[event] ) time.sleep(5) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.acknowledge_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=AcknowledgeOptions(lock_tokens=[lock_token])) + ack = client.acknowledge(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 - @pytest.mark.skip("need to update conftest") + @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy def test_publish_release_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): @@ -202,18 +192,18 @@ def test_publish_release_cloud_event(self, eventgrid_endpoint, eventgrid_key, ev data=b'this is binary data', ) - client.publish_cloud_events( - eventgrid_topic_name, body=[event] + client.send( + topic_name=eventgrid_topic_name, events=[event] ) time.sleep(5) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.release_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=ReleaseOptions(lock_tokens=[lock_token])) + ack = client.release(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) assert events.value[0].broker_properties.delivery_count > 1 \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index cfdec3f1c34d..b33ba86c2c3c 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -35,7 +35,7 @@ def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key ) with pytest.raises(HttpResponseError): - client.publish_cloud_events(eventgrid_topic_name, [event]) + client.send(topic_name=eventgrid_topic_name, events=[event]) @EventGridPreparer() @recorded_by_proxy @@ -49,7 +49,7 @@ def test_publish_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key): ) with pytest.raises(ResourceNotFoundError): - client.publish_cloud_events("faketopic", [event]) + client.send(topic_name="faketopic", events=[event]) @EventGridPreparer() @recorded_by_proxy @@ -57,7 +57,7 @@ def test_receive_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): - client.receive_cloud_events("faketopic", eventgrid_event_subscription_name) + client.receive("faketopic", eventgrid_event_subscription_name) @EventGridPreparer() @recorded_by_proxy @@ -65,7 +65,7 @@ def test_receive_cloud_event_max_events_negative(self, eventgrid_endpoint, event client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( + client.receive( eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20 ) @@ -75,7 +75,7 @@ def test_receive_cloud_event_timeout_negative(self, eventgrid_endpoint, eventgri client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( + client.receive( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20 ) @@ -85,7 +85,7 @@ def test_receive_cloud_event_timeout_max_value(self, eventgrid_endpoint, eventgr client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( + client.receive( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121 ) @@ -95,7 +95,7 @@ def test_receive_cloud_event_timeout_min_value(self, eventgrid_endpoint, eventgr client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( + client.receive( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9 ) @@ -105,9 +105,9 @@ def test_acknowledge_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_k client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): - lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) - client.acknowledge_cloud_events( - "faketopic", eventgrid_event_subscription_name, acknowledge_options=lock_tokens + lock_tokens = ["faketoken"] + client.acknowledge( + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @EventGridPreparer() @@ -116,20 +116,20 @@ def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): - lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) - client.release_cloud_events( - "faketopic", eventgrid_event_subscription_name, release_options=lock_tokens + lock_tokens = ["faketoken"] + client.release( + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @EventGridPreparer() @recorded_by_proxy def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = RejectOptions(lock_tokens=["faketoken"]) + lock_tokens = ["faketoken"] with pytest.raises(ResourceNotFoundError): - client.reject_cloud_events( - "faketopic", eventgrid_event_subscription_name, reject_options=lock_tokens + client.reject( + "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @EventGridPreparer() @@ -137,9 +137,9 @@ def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, e def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = AcknowledgeOptions(lock_tokens=["faketoken"]) - ack = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, acknowledge_options=lock_tokens + lock_tokens = ["faketoken"] + ack = client.acknowledge( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(ack) == AcknowledgeResult assert ack.succeeded_lock_tokens == [] @@ -151,9 +151,9 @@ def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgr def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = ReleaseOptions(lock_tokens=["faketoken"]) - release = client.release_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, release_options=lock_tokens + lock_tokens = ["faketoken"] + release = client.release( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(release) == ReleaseResult assert release.succeeded_lock_tokens == [] @@ -164,10 +164,10 @@ def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_k @recorded_by_proxy def test_reject_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = RejectOptions(lock_tokens=["faketoken"]) + lock_tokens = ["faketoken"] - reject = client.reject_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, reject_options=lock_tokens + reject = client.reject( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(reject) == RejectResult assert reject.succeeded_lock_tokens == [] diff --git a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py index 168feb277b4f..2824d8a2251b 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py @@ -24,9 +24,10 @@ def test_binary_request_format(self): source="source", subject="MySubject", data=b'this is binary data', + datacontenttype="application/json" ) - request = _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) assert request.data == b"this is binary data" assert request.headers.get("ce-source") == "source" @@ -43,7 +44,7 @@ def test_binary_request_format_with_extensions_and_datacontenttype(self): extensions={"extension1": "value1", "extension2": "value2"} ) - request = _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) assert request.data == b"this is my data" assert request.headers.get("ce-source") == "source" @@ -63,5 +64,5 @@ def test_class_binary_request_format_error(self): ) with pytest.raises(TypeError): - _to_http_request("https://eg-topic.westus2-1.eventgrid.azure.net/api/events", event=event, binary_mode=True) + _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) From c1e2e673a41afe8127d9246bde8e56199169b6cb Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 9 Apr 2024 13:01:24 -0700 Subject: [PATCH 15/43] [EG] Docstring/update changelog (#35108) * nits * Revert "shorten operation names" This reverts commit cd37161b28e56bfa805c8a00615a7e5cac073ab0. * remove broken link * edit --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 7 +++--- sdk/eventgrid/azure-eventgrid/README.md | 18 ++++++--------- .../azure/eventgrid/_operations/_patch.py | 11 +++++----- .../azure-eventgrid/azure/eventgrid/_patch.py | 5 ++++- .../azure/eventgrid/aio/_operations/_patch.py | 12 +++++----- .../azure/eventgrid/aio/_patch.py | 5 ++++- .../sample_acknowledge_operation_async.py | 2 +- .../sample_all_operations_async.py | 8 +++---- .../sample_binary_mode_async.py | 2 +- .../sample_publish_receive_renew_async.py | 4 ++-- .../sample_publish_release_receive_async.py | 8 +++---- .../sample_receive_operation_async.py | 2 +- .../sample_reject_operation_async.py | 2 +- .../sample_release_operation_async.py | 2 +- .../sample_renew_locks_operation_async.py | 2 +- .../sample_acknowledge_operation.py | 2 +- .../sample_all_operations.py | 8 +++---- .../sample_binary_mode.py | 2 +- .../sample_publish_receive_renew.py | 4 ++-- .../sample_publish_release_receive.py | 8 +++---- .../sample_receive_operation.py | 2 +- .../sample_reject_operation.py | 2 +- .../sample_release_operation.py | 2 +- .../sample_renew_locks_operation.py | 2 +- .../azure-eventgrid/tests/test_dual_client.py | 4 ++-- .../azure-eventgrid/tests/test_eg_client.py | 22 +++++++++---------- .../tests/test_eg_client_exceptions.py | 22 +++++++++---------- 27 files changed, 84 insertions(+), 86 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 8ce61a9625ef..1bd83a8df331 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -8,10 +8,9 @@ - EventGridClient `send` can be used for both Event Grid Namespace Resources and Event Grid Basic Resources. - Added a kwarg `level` in the EventGridClient constructor. The default value is `Standard` which creates a client for an Event Grid Namespace Resource. -### Breaking Changes - -- Removed the `AcknowledgeOptions`,`ReleaseOptions`, `RejectOptions`, and `RenewLockOptions` models. `lock_tokens` can now be specified as a `kwarg` on the operation. -- Renamed `publish_cloud_events` to `send` + ### Breaking Changes + - Removed the `AcknowledgeOptions`,`ReleaseOptions`, `RejectOptions`, and `RenewLockOptions` models. `lock_tokens` can now be specified as a `kwarg` on the operation. + - Renamed `publish_cloud_events` to `send`. ## 4.19.0 (2024-04-10) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 9952c57507f8..65d9b239a3c2 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -12,7 +12,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ## _Disclaimer_ -This is a beta release of Azure EventGrid's `EventGridClient`. `EventGridClient` supports `send`, `receive`, `acknowledge` , `release`, `reject`, and `renew_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. +This is a beta release of Azure EventGrid's `EventGridClient`. `EventGridClient` supports `send`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, `reject_cloud_events`, and `renew_cloud_event_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. ## Getting started @@ -316,32 +316,32 @@ sub_name = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] credential = AzureKeyCredential(key) client = EventGridClient(endpoint, credential, level=ClientLevel.STANDARD) -events = client.receive(topic_name, sub_name, max_events=4) +events = client.receive_cloud_events(topic_name, sub_name, max_events=4) for e in events: renew_tokens = e.broker_properties.lock_token - renew_result = client.renew_locks( + renew_result = client.renew_cloud_events_lock( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=renew_tokens, ) release_tokens = events[0].broker_properties.lock_token -release_result = client.release( +release_result = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=release_tokens, ) ack_tokens = events[1].broker_properties.lock_token -ack_result = client.acknowledge( +ack_result = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=ack_tokens, ) reject_tokens = events[2].broker_properties.lock_token -reject_result = client.reject( +reject_result = client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=reject_tokens, @@ -459,7 +459,7 @@ These code samples show common champion scenario operations with the Azure Event #### Namespaces EventGrid Scenarios -* Authenticate the client: [sample_eg_client_authentication.py][python-eg-client-auth-samples] +* Authenticate the client: [sample_authentication.py][python-eg-auth] * Sample of all operations: [sample_all_operations.py][python-eg-client-all-ops-sample] * Publish cloud event in binary mode: [sample_binary_mode_operation.py][python-eg-client-binary-mode-sample] @@ -541,10 +541,6 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py -[python-eg-client-aad-auth-samples]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_aad_auth_operation.py - -[python-eg-client-auth-samples]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_eg_client_authentication.py - [python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py [python-eg-client-binary-mode-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index cde0db4f1926..3e3158b7d4e7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -385,7 +385,6 @@ def _publish( http_request.url, **path_format_arguments ) - # pipeline_response: PipelineResponse = self.send_request(http_request, **kwargs) pipeline_response: PipelineResponse = ( self._client._pipeline.run( # pylint: disable=protected-access http_request, stream=_stream, **kwargs @@ -417,7 +416,7 @@ def _publish( @use_standard_only @distributed_trace - def receive( + def receive_cloud_events( self, topic_name: str, subscription_name: str, @@ -468,7 +467,7 @@ def receive( @use_standard_only @distributed_trace - def acknowledge( + def acknowledge_cloud_events( self, topic_name: str, subscription_name: str, @@ -504,7 +503,7 @@ def acknowledge( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - def release( + def release_cloud_events( self, topic_name: str, subscription_name: str, @@ -541,7 +540,7 @@ def release( @use_standard_only @distributed_trace - def reject( + def reject_cloud_events( self, topic_name: str, subscription_name: str, @@ -576,7 +575,7 @@ def reject( @api_version_validation( method_added_on="2023-10-01-preview", ) - def renew_locks( + def renew_cloud_event_locks( self, topic_name: str, subscription_name: str, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index bc579af964bc..cadec781c7cb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -89,7 +89,10 @@ def __init__( ) self._send = self._publish_cloud_events - + else: + raise ValueError( + "Unknown client level. Known values are `Standard` and `Basic`." + ) self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 70d55e829fb9..234d1a48d605 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -207,8 +207,6 @@ async def send(self, *args, **kwargs) -> None: except Exception as exception: # pylint: disable=broad-except self._http_response_error_handler(exception, "Standard") raise exception - # # If that fails, try to send via basic - # self._last_exception = exception else: try: await self._send(events, channel_name=channel_name, **kwargs) @@ -248,7 +246,7 @@ def _http_response_error_handler(self, exception, level): @use_standard_only @distributed_trace_async - async def receive( + async def receive_cloud_events( self, topic_name: str, subscription_name: str, @@ -299,7 +297,7 @@ async def receive( @use_standard_only @distributed_trace_async - async def acknowledge( + async def acknowledge_cloud_events( self, topic_name: str, subscription_name: str, @@ -332,7 +330,7 @@ async def acknowledge( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - async def release( + async def release_cloud_events( self, topic_name: str, subscription_name: str, @@ -369,7 +367,7 @@ async def release( @use_standard_only @distributed_trace_async - async def reject( + async def reject_cloud_events( self, topic_name: str, subscription_name: str, @@ -401,7 +399,7 @@ async def reject( @api_version_validation( method_added_on="2023-10-01-preview", ) - async def renew_locks( + async def renew_cloud_event_locks( self, topic_name: str, subscription_name: str, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index 5e8c19f9276d..b0a6a7dd9253 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -78,7 +78,10 @@ def __init__( **kwargs ) self._send = self._publish_cloud_events - + else: + raise ValueError( + "Unknown client level. Known values are `Standard` and `Basic`." + ) self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py index acbde2f1e706..fc4556b55a65 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py @@ -37,7 +37,7 @@ async def run(): try: async with client: lock_tokens = ["token"] - ack_events = await client.acknowledge( + ack_events = await client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index ac862916ab27..0bed8a6ddc74 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -66,7 +66,7 @@ async def run(): # Receive Published Cloud Events try: - receive_results = await client.receive( + receive_results = await client.receive_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, @@ -95,7 +95,7 @@ async def run(): if len(release_events) > 0: try: - release_result = await client.release( + release_result = await client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=release_events, @@ -108,7 +108,7 @@ async def run(): if len(acknowledge_events) > 0: try: - ack_result = await client.acknowledge( + ack_result = await client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=acknowledge_events, @@ -121,7 +121,7 @@ async def run(): if len(reject_events) > 0: try: - reject_result = await client.reject( + reject_result = await client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=reject_events, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py index 3e9d918cd15c..23ddeb5abd90 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py @@ -47,7 +47,7 @@ async def run(): cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") await client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) - receive_result = await client.receive( + receive_result = await client.receive_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py index 020b830b6e5e..04cd15696d9e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py @@ -42,13 +42,13 @@ async def run(): await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) # Renew lock tokens - renew_events = await client.renew_locks( + renew_events = await client.renew_cloud_event_locks( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens_to_release, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py index d1b5d0c6bbe3..804500c1d727 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py @@ -42,7 +42,7 @@ async def run(): await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -50,7 +50,7 @@ async def run(): print("Received events:", receive_result.value) # Release a LockToken - release_events = await client.release( + release_events = await client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=60, @@ -59,11 +59,11 @@ async def run(): print("Released Event:", release_events) # Receive CloudEvents again - receive_result = await client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) print("Received events after release:", receive_result.value) # Acknowledge a LockToken that was released - acknowledge_events = await client.acknowledge( + acknowledge_events = await client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens_to_release, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py index c166adc49d84..03ce721b4199 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py @@ -36,7 +36,7 @@ async def run(): # Receive CloudEvents try: async with client: - receive_result = await client.receive( + receive_result = await client.receive_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py index c8ccc0c30a6c..194c78bfaae3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py @@ -37,7 +37,7 @@ async def run(): try: async with client: tokens = ["token"] - reject_events = await client.reject( + reject_events = await client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=tokens, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index cdb308dd6aac..62c540af93f2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -37,7 +37,7 @@ async def run(): try: async with client: tokens = ["token"] - release_events = await client.release( + release_events = await client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=10, diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py index 09e672fc9661..349f18991ee0 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py @@ -35,7 +35,7 @@ async def run(): # Renew a lockToken try: lock_tokens = ["token"] - release_events = await client.renew_locks( + release_events = await client.renew_cloud_event_locks( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py index c7c2df51bed1..68d57ae30bda 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py @@ -34,7 +34,7 @@ # Acknowledge a CloudEvent try: lock_tokens = ["token"] - ack_events = client.acknowledge( + ack_events = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py index 2299988e0b4c..68b9ea7962d6 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -59,7 +59,7 @@ # Receive Published Cloud Events try: - receive_results = client.receive( + receive_results = client.receive_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, @@ -88,7 +88,7 @@ if len(release_events) > 0: try: - release_result = client.release( + release_result = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=release_events, @@ -101,7 +101,7 @@ if len(acknowledge_events) > 0: try: - ack_result = client.acknowledge( + ack_result = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=acknowledge_events, @@ -114,7 +114,7 @@ if len(reject_events) > 0: try: - reject_result = client.reject( + reject_result = client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=reject_events, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py index 884c9adfbd15..8a6a0188a184 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py @@ -45,7 +45,7 @@ client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) # Receive a CloudEvent - receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) for receive_details in receive_result.value: cloud_event_received = receive_details.event print("CloudEvent: ", cloud_event_received) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py index 1db143b432f9..438f88c7b570 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py @@ -39,13 +39,13 @@ client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) lock_tokens_to_renew = [] for item in receive_result.value: lock_tokens_to_renew.append(item.broker_properties.lock_token) # Renew a lock token - renew_events = client.renew_locks( + renew_events = client.renew_cloud_event_locks( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens_to_renew, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py index ed357aa1ad52..39b8c72b45c2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py @@ -39,7 +39,7 @@ client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -47,7 +47,7 @@ print("Received events:", receive_result.value) # Release a LockToken - release_events = client.release( + release_events = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=60, @@ -56,11 +56,11 @@ print("Released Event:", release_events) # Receive CloudEvents again - receive_result = client.receive(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) print("Received events after release:", receive_result.value) # Acknowledge a LockToken that was released - acknowledge_events = client.acknowledge( + acknowledge_events = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens_to_release, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py index 4e7c69bcec7b..0e091aa883b8 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py @@ -33,7 +33,7 @@ # Receive CloudEvents try: - receive_result = client.receive( + receive_result = client.receive_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py index 7743fe3de606..35700a827266 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py @@ -33,7 +33,7 @@ # Release a LockToken try: lock_tokens = ["token"] - reject_events = client.reject( + reject_events = client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py index cb0858e01666..e88cf3dc08f9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -33,7 +33,7 @@ # Release a LockToken try: lock_tokens = ["token"] - release_events = client.release( + release_events = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, release_delay_in_seconds=3600, diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py index 52796dc9b1a2..3fb2e502f03d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py @@ -33,7 +33,7 @@ # Renew a lockToken try: lock_tokens = ["token"] - release_events = client.renew_locks( + release_events = client.renew_cloud_event_locks( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py index f3e28d500e09..c3d785f432b5 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py @@ -81,11 +81,11 @@ def test_create_client_receive(self, level, eventgrid_endpoint, eventgrid_key, e if level=="Basic": with pytest.raises(AttributeError): - client.receive( + client.receive_cloud_events( topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name ) else: - client.receive( + client.receive_cloud_events( topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py index 70a49863bb74..19a90030a072 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -47,13 +47,13 @@ def test_publish_binary_mode_xml(self, eventgrid_endpoint, eventgrid_key, eventg time.sleep(5) - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) @@ -75,13 +75,13 @@ def test_publish_binary_mode_cloud_event(self, eventgrid_endpoint, eventgrid_key topic_name= eventgrid_topic_name, events=event, binary_mode=True ) - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) @EventGridPreparer() @@ -145,12 +145,12 @@ def test_publish_binary_mode_combinations(self, eventgrid_endpoint, eventgrid_ke topic_name=eventgrid_topic_name, events=dict_event, binary_mode=True ) - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) tokens = [] for detail in events.value: token = detail.broker_properties.lock_token tokens.append(token) - rejected_result = client.reject(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) + rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) @pytest.mark.live_test_only() @@ -172,10 +172,10 @@ def test_publish_receive_cloud_event(self, eventgrid_endpoint, eventgrid_key, ev time.sleep(5) - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.acknowledge(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) + ack = client.acknowledge_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 @@ -198,12 +198,12 @@ def test_publish_release_cloud_event(self, eventgrid_endpoint, eventgrid_key, ev time.sleep(5) - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.release(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) + ack = client.release_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 - events = client.receive(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) assert events.value[0].broker_properties.delivery_count > 1 \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index b33ba86c2c3c..2751e0615d23 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -57,7 +57,7 @@ def test_receive_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): - client.receive("faketopic", eventgrid_event_subscription_name) + client.receive_cloud_events("faketopic", eventgrid_event_subscription_name) @EventGridPreparer() @recorded_by_proxy @@ -65,7 +65,7 @@ def test_receive_cloud_event_max_events_negative(self, eventgrid_endpoint, event client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive( + client.receive_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20 ) @@ -75,7 +75,7 @@ def test_receive_cloud_event_timeout_negative(self, eventgrid_endpoint, eventgri client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive( + client.receive_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20 ) @@ -85,7 +85,7 @@ def test_receive_cloud_event_timeout_max_value(self, eventgrid_endpoint, eventgr client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive( + client.receive_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121 ) @@ -95,7 +95,7 @@ def test_receive_cloud_event_timeout_min_value(self, eventgrid_endpoint, eventgr client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive( + client.receive_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9 ) @@ -106,7 +106,7 @@ def test_acknowledge_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_k with pytest.raises(ResourceNotFoundError): lock_tokens = ["faketoken"] - client.acknowledge( + client.acknowledge_cloud_events( "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @@ -117,7 +117,7 @@ def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, with pytest.raises(ResourceNotFoundError): lock_tokens = ["faketoken"] - client.release( + client.release_cloud_events( "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @@ -128,7 +128,7 @@ def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, e lock_tokens = ["faketoken"] with pytest.raises(ResourceNotFoundError): - client.reject( + client.reject_cloud_events( "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens ) @@ -138,7 +138,7 @@ def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgr client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] - ack = client.acknowledge( + ack = client.acknowledge_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(ack) == AcknowledgeResult @@ -152,7 +152,7 @@ def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_k client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] - release = client.release( + release = client.release_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(release) == ReleaseResult @@ -166,7 +166,7 @@ def test_reject_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_ke client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] - reject = client.reject( + reject = client.reject_cloud_events( eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens ) assert type(reject) == RejectResult From f1cb640a1dfb8201c840b682a84b9f42b34e6f75 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 10 Apr 2024 12:51:40 -0700 Subject: [PATCH 16/43] update readme (#35147) --- sdk/eventgrid/azure-eventgrid/README.md | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 65d9b239a3c2..88690bd43a61 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -227,13 +227,9 @@ client.send(event) The following sections provide several code snippets covering some of the most common Event Grid tasks, including: -* [Send an Event Grid Event](#send-an-event-grid-event) * [Send a Cloud Event](#send-a-cloud-event) * [Send Multiple Events](#send-multiple-events) -* [Send events as Dictionaries](#send-events-as-dictionaries) -* [Receive events](#receive-events-from-namespace) -* [Consume a payload from storage queue](#consume-from-storage-queue) -* [Consume from ServiceBus](#consume-from-servicebus) +* [Receive and Process Events from Namespace](#receive-and-process-events-from-namespace) ### Send a Cloud Event @@ -318,7 +314,17 @@ client = EventGridClient(endpoint, credential, level=ClientLevel.STANDARD) events = client.receive_cloud_events(topic_name, sub_name, max_events=4) -for e in events: +for detail in events.value: + data = detail.event.data + broker_properties = detail.broker_properties + if data == "release": + release_events.append(broker_properties.lock_token) + elif data == "acknowledge": + acknowledge_events.append(broker_properties.lock_token) + else: + reject_events.append(broker_properties.lock_token) + + # Renew all Locks renew_tokens = e.broker_properties.lock_token renew_result = client.renew_cloud_events_lock( topic_name=TOPIC_NAME, @@ -326,25 +332,23 @@ for e in events: lock_tokens=renew_tokens, ) -release_tokens = events[0].broker_properties.lock_token + release_result = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=release_tokens, + lock_tokens=release_events, ) -ack_tokens = events[1].broker_properties.lock_token ack_result = client.acknowledge_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=ack_tokens, + lock_tokens=acknowledge_events, ) -reject_tokens = events[2].broker_properties.lock_token reject_result = client.reject_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=reject_tokens, + lock_tokens=reject_events, ) ``` From 49d46d47d509a91614e9bc61203a1f340cfb4814 Mon Sep 17 00:00:00 2001 From: l0lawrence Date: Wed, 10 Apr 2024 15:46:47 -0700 Subject: [PATCH 17/43] beta version --- sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index 4c7f8043b9d7..d008fcf48907 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "4.19.1" +VERSION = "4.19.0b1" From f48ab908297bacb9db5bb55a55f04e46550c421a Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 11 Apr 2024 08:55:11 -0700 Subject: [PATCH 18/43] [EG] Readme updates (#35152) * simplify readme * update all links to feature branch * spacing * try --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 7 +- sdk/eventgrid/azure-eventgrid/README.md | 92 ++++++-------------- sdk/eventgrid/azure-eventgrid/pyproject.toml | 1 - 3 files changed, 31 insertions(+), 69 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 1bd83a8df331..aa6a475e6f12 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -8,9 +8,10 @@ - EventGridClient `send` can be used for both Event Grid Namespace Resources and Event Grid Basic Resources. - Added a kwarg `level` in the EventGridClient constructor. The default value is `Standard` which creates a client for an Event Grid Namespace Resource. - ### Breaking Changes - - Removed the `AcknowledgeOptions`,`ReleaseOptions`, `RejectOptions`, and `RenewLockOptions` models. `lock_tokens` can now be specified as a `kwarg` on the operation. - - Renamed `publish_cloud_events` to `send`. +### Breaking Changes + +- Removed the `AcknowledgeOptions`,`ReleaseOptions`, `RejectOptions`, and `RenewLockOptions` models. `lock_tokens` can now be specified as a `kwarg` on the operation. +- Renamed `publish_cloud_events` to `send`. ## 4.19.0 (2024-04-10) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 88690bd43a61..1d2fdc57ca42 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -24,21 +24,9 @@ This is a beta release of Azure EventGrid's `EventGridClient`. `EventGridClient` ### Event Grid Resources -Below is a brief synopsis of the differences between Azure Event Grid Namespaces and Azure Event Grid Basic. +Azure Event Grid Namespaces supports both pull and push delivery. Azure Event Grid Basic supports only push delivery. More information on the two resource types can be found [here](https://learn.microsoft.com/azure/event-grid/choose-right-tier). -| Feature | Namespaces (Standard) | Basic | -| :---------------- | :------: | :----: | -| Throughput | High | Low | -| MQTT | Yes | No | -| Publish and Subscribe to custom events | Yes | Yes | -| Push Delivery to Event Hubs | Yes | Yes | -| Maximum message retention | 7 days | 1 day | -| Push Delivery to Azure Services | No | Yes | -| Subscribe to Azure System Events | No | Yes | -| Subscribe to Partner Events | No | Yes | -| Domain Scope Subscriptions | No | Yes | - **Note:** Azure Event Grid Namespaces only supports the Cloud Event v1.0 Schema. ### Install the package @@ -64,18 +52,6 @@ az eventgrid namespace create --location --resource-group --resource-group --name ``` -#### Create an Event Grid Basic Topic - -``` -az eventgrid topic --create --location --resource-group --name -``` - -#### Create an Event Grid Basic Domain - -``` -az eventgrid domain --create --location --resource-group --name -``` - ### Authenticate the client In order to interact with the Event Grid service, you will need to create an instance of a client. An **endpoint** and **credential** are necessary to instantiate the client object. @@ -176,7 +152,7 @@ An **[event](https://docs.microsoft.com/azure/event-grid/concepts#events)** is t Event Grid supports multiple schemas for encoding events. -##### System Topics +#### System Topics A **[system topic](https://docs.microsoft.com/azure/event-grid/system-topics)** in Event Grid represents one or more events published by Azure services such as Azure Storage or Azure Event Hubs. For example, a system topic may represent all blob events or only blob creation and blob deletion events published for a specific storage account. The names of the various event types for the system events published to Azure Event Grid are available in `azure.eventgrid.SystemEventNames`. @@ -205,24 +181,10 @@ The following formats of events are allowed to be sent to an EventGrid Namespace Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples) for detailed examples. - ## Event Grid on Kubernetes with Azure Arc Event Grid on Kubernetes with Azure Arc is an offering that allows you to run Event Grid on your own Kubernetes cluster. This capability is enabled by the use of Azure Arc enabled Kubernetes. Through Azure Arc enabled Kubernetes, a supported Kubernetes cluster connects to Azure. Once connected, you are able to install Event Grid on it. Learn more about it [here](https://docs.microsoft.com/azure/event-grid/kubernetes/overview). -### Support for CNCF Cloud Events - -Starting with v4.7.0, this package also supports publishing a CNCF cloud event from https://pypi.org/project/cloudevents/. You would be able to pass a CloudEvent object from this library to the `send` API. - -```python - -from cloudevents.http import CloudEvent - -event = CloudEvent(...) - -client.send(event) -``` - ## Examples The following sections provide several code snippets covering some of the most common Event Grid tasks, including: @@ -510,39 +472,39 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [python-eg-product-docs]: https://docs.microsoft.com/azure/event-grid/overview [python-eg-ref-docs]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-eventgrid/latest/index.html [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts -[python-eg-samples]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples -[python-eg-changelog]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +[python-eg-samples]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples +[python-eg-changelog]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/CHANGELOG.md [pip]: https://pypi.org/project/pip/ [azure_portal_create_EG_resource]: https://ms.portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.EventGrid%2Ftopics [azure-key-credential]: https://aka.ms/azsdk/python/core/azurekeycredential [azure_core_exceptions]: https://aka.ms/azsdk/python/core/docs#module-azure.core.exceptions [python_logging]: https://docs.python.org/3/library/logging.html -[azure_core_ref_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core#configurations +[azure_core_ref_docs]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/core/azure-core#configurations [azure_subscription]: https://azure.microsoft.com/free/ -[python-eg-auth]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py -[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py -[python-eg-sample-send-using-sas]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py -[python-eg-sample-eg-event]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py -[python-eg-sample-eg-event-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py -[python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py -[python-eg-publish-custom-schema]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py -[python-eg-sample-send-eg-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py -[python-eg-sample-send-cloudevent-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py - -[python-eg-auth-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py -[python-eg-sample-send-using-sas-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py -[python-eg-sample-eg-event-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py -[python-eg-sample-eg-event-to-domain-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py -[python-eg-sample-send-cloudevent-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py -[python-eg-publish-custom-schema-async]:https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py -[python-eg-sample-send-eg-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py -[python-eg-sample-send-cloudevent-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py - -[python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/publish_samples -[python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/consume_samples -[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py +[python-eg-auth]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py +[python-eg-sample-send-using-sas]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +[python-eg-sample-eg-event]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +[python-eg-sample-eg-event-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +[python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +[python-eg-publish-custom-schema]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +[python-eg-sample-send-eg-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +[python-eg-sample-send-cloudevent-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py + +[python-eg-auth-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +[python-eg-sample-send-using-sas-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +[python-eg-sample-eg-event-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +[python-eg-sample-eg-event-to-domain-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +[python-eg-sample-send-cloudevent-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +[python-eg-publish-custom-schema-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +[python-eg-sample-send-eg-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +[python-eg-sample-send-cloudevent-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py + +[python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/publish_samples +[python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/consume_samples +[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py [python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py diff --git a/sdk/eventgrid/azure-eventgrid/pyproject.toml b/sdk/eventgrid/azure-eventgrid/pyproject.toml index 5f3098c4c74b..1753fb8036e7 100644 --- a/sdk/eventgrid/azure-eventgrid/pyproject.toml +++ b/sdk/eventgrid/azure-eventgrid/pyproject.toml @@ -1,6 +1,5 @@ [tool.azure-sdk-build] pyright = false -type_check_samples = false verifytypes = false strict_sphinx = false pylint = false \ No newline at end of file From 47fc92e4255d39b07cd24a2e3a46e7710388cdca Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 11 Apr 2024 10:53:41 -0700 Subject: [PATCH 19/43] type error to value error (#35164) --- .../azure-eventgrid/azure/eventgrid/_operations/_patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 3e3158b7d4e7..158d0010dcde 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -633,7 +633,7 @@ def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: # content_type must be CloudEvent DataContentType when in binary mode if not event.datacontenttype: - raise TypeError("CloudEvent datacontenttype must be set when in binary mode.") + raise ValueError("CloudEvent datacontenttype must be set when in binary mode.") content_type: str = event.datacontenttype api_version: str = kwargs.pop( From 2950192498cadaab9700c65568186563a7adaf20 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 11 Apr 2024 16:20:44 -0700 Subject: [PATCH 20/43] [EG] rename release_delay (#35172) * rename * valueError * update version * version --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 2 +- .../azure/eventgrid/_operations/_patch.py | 12 ++++++------ .../azure-eventgrid/azure/eventgrid/_version.py | 2 +- .../azure/eventgrid/aio/_operations/_patch.py | 10 +++++----- .../sample_publish_release_receive_async.py | 2 +- .../sample_release_operation_async.py | 2 +- .../sample_publish_release_receive.py | 2 +- .../sample_release_operation.py | 2 +- .../azure-eventgrid/tests/test_dual_client.py | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index aa6a475e6f12..3a99607a128e 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -## 4.19.0b1 (2024-04-11) +## 4.20.0b1 (2024-04-11) ### Features Added diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 158d0010dcde..f1e16a2909ef 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -98,7 +98,7 @@ def use_standard_only(func): @wraps(func) def wrapper(self, *args, **kwargs): if self._level == "Basic": # pylint: disable=protected-access - raise AttributeError( + raise ValueError( "The basic client is not supported for this operation." ) return func(self, *args, **kwargs) @@ -501,7 +501,7 @@ def acknowledge_cloud_events( @use_standard_only @distributed_trace @api_version_validation( - params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, + params_added_on={"2023-10-01-preview": ["release_delay"]}, ) def release_cloud_events( self, @@ -509,7 +509,7 @@ def release_cloud_events( subscription_name: str, *, lock_tokens: List[str], - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any, ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -522,9 +522,9 @@ def release_cloud_events( :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + :keyword release_delay: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :paramtype release_delay: int or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -534,7 +534,7 @@ def release_cloud_events( topic_name=topic_name, event_subscription_name=subscription_name, release_options=options, - release_delay_in_seconds=release_delay_in_seconds, + release_delay_in_seconds=release_delay, **kwargs, ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index d008fcf48907..4997406f0693 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "4.19.0b1" +VERSION = "4.20.0b1" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 234d1a48d605..20c46b61de31 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -328,7 +328,7 @@ async def acknowledge_cloud_events( @use_standard_only @distributed_trace_async @api_version_validation( - params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, + params_added_on={"2023-10-01-preview": ["release_delay"]}, ) async def release_cloud_events( self, @@ -336,7 +336,7 @@ async def release_cloud_events( subscription_name: str, *, lock_tokens: List[str], - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any, ) -> _models.ReleaseResult: """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request @@ -349,9 +349,9 @@ async def release_cloud_events( :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] - :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. + :keyword release_delay: Release cloud events with the specified delay in seconds. Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + :paramtype release_delay: int or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -361,7 +361,7 @@ async def release_cloud_events( topic_name, subscription_name, options, - release_delay_in_seconds=release_delay_in_seconds, + release_delay_in_seconds=release_delay, **kwargs, ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py index 804500c1d727..f0946c2bcd57 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py @@ -53,7 +53,7 @@ async def run(): release_events = await client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay_in_seconds=60, + release_delay=60, lock_tokens=lock_tokens_to_release, ) print("Released Event:", release_events) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py index 62c540af93f2..d0d4ce112959 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py @@ -40,7 +40,7 @@ async def run(): release_events = await client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay_in_seconds=10, + release_delay=10, lock_tokens=tokens, ) print(release_events) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py index 39b8c72b45c2..0951efb50a7c 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py @@ -50,7 +50,7 @@ release_events = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay_in_seconds=60, + release_delay=60, lock_tokens=lock_tokens_to_release, ) print("Released Event:", release_events) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py index e88cf3dc08f9..efb00fb374e9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py @@ -36,7 +36,7 @@ release_events = client.release_cloud_events( topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay_in_seconds=3600, + release_delay=3600, lock_tokens=lock_tokens, ) print(release_events) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py index c3d785f432b5..f05ab6841345 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py @@ -80,7 +80,7 @@ def test_create_client_receive(self, level, eventgrid_endpoint, eventgrid_key, e ) if level=="Basic": - with pytest.raises(AttributeError): + with pytest.raises(ValueError): client.receive_cloud_events( topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name ) From 7ddd0e580a0ae9efbb6a7dc8551938e3cdf50e9d Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 24 Apr 2024 12:30:19 -0700 Subject: [PATCH 21/43] [EG] regenerate to fix gen code bug (#35327) * regenerate to fix gen code bug * update serialization code * update * pylint * update faulty tests * use _patch * use _patch * add test type * fix test + add version --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 8 + .../azure-eventgrid/azure/__init__.py | 2 +- .../azure/eventgrid/__init__.py | 3 +- .../azure/eventgrid/_client.py | 40 +- .../azure/eventgrid/_configuration.py | 46 +- .../eventgrid/_legacy/_event_mappings.py | 514 +++++++++-------- .../eventgrid/_legacy/_generated/_client.py | 12 +- .../_legacy/_generated/_configuration.py | 28 +- .../_generated/_operations/_operations.py | 106 +--- .../_legacy/_generated/_operations/_patch.py | 4 +- .../eventgrid/_legacy/_generated/_patch.py | 4 +- .../_legacy/_generated/_serialization.py | 186 ++----- .../_legacy/_generated/aio/_client.py | 16 +- .../_legacy/_generated/aio/_configuration.py | 32 +- .../_generated/aio/_operations/_operations.py | 66 +-- .../_generated/aio/_operations/_patch.py | 4 +- .../_legacy/_generated/aio/_patch.py | 4 +- .../_legacy/_generated/models/_models.py | 4 +- .../_legacy/_generated/models/_patch.py | 4 +- .../azure/eventgrid/_legacy/_helpers.py | 34 +- .../eventgrid/_legacy/_messaging_shared.py | 5 +- .../azure/eventgrid/_legacy/_policies.py | 3 +- .../eventgrid/_legacy/_publisher_client.py | 35 +- .../_legacy/aio/_publisher_client_async.py | 30 +- .../azure/eventgrid/_model_base.py | 172 +++--- .../azure/eventgrid/_operations/__init__.py | 3 +- .../eventgrid/_operations/_operations.py | 515 ++++++++---------- .../azure/eventgrid/_operations/_patch.py | 265 +++------ .../azure-eventgrid/azure/eventgrid/_patch.py | 12 +- .../azure/eventgrid/_serialization.py | 18 +- .../azure/eventgrid/_validation.py | 17 +- .../azure/eventgrid/_vendor.py | 7 +- .../azure/eventgrid/_version.py | 2 +- .../azure/eventgrid/aio/__init__.py | 3 +- .../azure/eventgrid/aio/_client.py | 36 +- .../azure/eventgrid/aio/_configuration.py | 44 +- .../eventgrid/aio/_operations/__init__.py | 3 +- .../eventgrid/aio/_operations/_operations.py | 311 +++++------ .../azure/eventgrid/aio/_operations/_patch.py | 152 ++---- .../azure/eventgrid/aio/_patch.py | 21 +- .../azure/eventgrid/aio/_vendor.py | 7 +- .../azure/eventgrid/models/__init__.py | 13 +- .../azure/eventgrid/models/_enums.py | 3 +- .../azure/eventgrid/models/_models.py | 78 +-- .../azure/eventgrid/models/_patch.py | 12 +- .../sample_all_operations_async.py | 20 +- .../sample_binary_mode_async.py | 15 +- .../sample_publish_operation_async.py | 9 +- .../sample_publish_receive_renew_async.py | 7 +- .../sample_publish_release_receive_async.py | 11 +- .../sample_renew_locks_operation_async.py | 2 + ...consume_cloud_events_from_storage_queue.py | 6 +- ...ish_cloud_events_to_custom_topic_sample.py | 4 +- ...ish_cloud_events_to_domain_topic_sample.py | 4 +- ...vent_grid_events_to_custom_topic_sample.py | 4 +- ...ish_with_shared_access_signature_sample.py | 4 +- .../sample_all_operations.py | 12 +- .../sample_binary_mode.py | 20 +- .../sample_publish_receive_renew.py | 4 +- .../sample_publish_release_receive.py | 8 +- sdk/eventgrid/azure-eventgrid/setup.py | 4 +- .../azure-eventgrid/swagger/_constants.py | 22 +- .../swagger/postprocess_eventnames.py | 8 +- .../azure-eventgrid/tests/conftest.py | 17 +- .../tests/eventgrid_preparer.py | 14 +- .../tests/perfstress_tests/send.py | 12 +- .../tests/test_cloud_event_tracing.py | 4 +- .../azure-eventgrid/tests/test_cncf_events.py | 28 +- .../tests/test_cncf_events_async.py | 28 +- .../azure-eventgrid/tests/test_dual_client.py | 278 ++++++---- .../azure-eventgrid/tests/test_eg_client.py | 176 +++--- .../tests/test_eg_client_exceptions.py | 66 +-- .../tests/test_eg_event_get_bytes.py | 12 +- .../tests/test_eg_publisher_client.py | 91 +--- .../tests/test_eg_publisher_client_async.py | 116 ++-- .../azure-eventgrid/tests/test_exceptions.py | 8 +- .../tests/test_exceptions_async.py | 8 +- .../tests/test_serialization.py | 29 +- .../tests/unittests/test_binary_mode.py | 20 +- 79 files changed, 1654 insertions(+), 2301 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 3a99607a128e..7619f52c83d7 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,5 +1,13 @@ # Release History +## 4.20.1b1 (2024-04-24) + +This is a Beta of the EventGridClient + +### Bug Fixes + +- Fixed serialization issues with CloudEvent and CNCF Cloud Event + ## 4.20.0b1 (2024-04-11) ### Features Added diff --git a/sdk/eventgrid/azure-eventgrid/azure/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/__init__.py index 0d1f7edf5dc6..d55ccad1f573 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/__init__.py @@ -1 +1 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py index f6da3df3d6bc..dbb47f36735d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py @@ -17,8 +17,9 @@ except ImportError: _patch_all = [] from ._patch import patch_sdk as _patch_sdk + __all__ = [ - 'EventGridClient', + "EventGridClient", ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py index a7b6c85bbe3e..2d43c8ce7ea4 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py @@ -22,13 +22,14 @@ # pylint: disable=unused-import,ungrouped-imports from azure.core.credentials import TokenCredential + class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword """Azure Messaging EventGrid Client. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Is either a + :param credential: Credential used to authenticate requests to the service. Is either a AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential @@ -38,30 +39,33 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client :paramtype api_version: str """ - def __init__( - self, - endpoint: str, - credential: Union[AzureKeyCredential, "TokenCredential"], - **kwargs: Any - ) -> None: - _endpoint = '{endpoint}' + def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: + _endpoint = "{endpoint}" self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) - _policies = kwargs.pop('policies', None) + _policies = kwargs.pop("policies", None) if _policies is None: - _policies = [policies.RequestIdPolicy(**kwargs),self._config.headers_policy,self._config.user_agent_policy,self._config.proxy_policy,policies.ContentDecodePolicy(**kwargs),self._config.redirect_policy,self._config.retry_policy,self._config.authentication_policy,self._config.custom_hook_policy,self._config.logging_policy,policies.DistributedTracingPolicy(**kwargs),policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,self._config.http_logging_policy] + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - - def send_request( - self, - request: HttpRequest, *, stream: bool = False, - **kwargs: Any - ) -> HttpResponse: + def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: """Runs the network request through the client's chained policies. >>> from azure.core.rest import HttpRequest @@ -81,7 +85,7 @@ def send_request( request_copy = deepcopy(request) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py index a615bd59224d..9f9f76551394 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py @@ -18,7 +18,7 @@ from azure.core.credentials import TokenCredential -class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long +class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -27,7 +27,7 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attri :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Is either a + :param credential: Credential used to authenticate requests to the service. Is either a AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential @@ -37,13 +37,8 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attri :paramtype api_version: str """ - def __init__( - self, - endpoint: str, - credential: Union[AzureKeyCredential, "TokenCredential"], - **kwargs: Any - ) -> None: - api_version: str = kwargs.pop('api_version', "2023-10-01-preview") + def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: + api_version: str = kwargs.pop("api_version", "2023-10-01-preview") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") @@ -53,30 +48,29 @@ def __init__( self.endpoint = endpoint self.credential = credential self.api_version = api_version - self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) - kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self.credential_scopes = kwargs.pop("credential_scopes", ["https://eventgrid.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "eventgrid/{}".format(VERSION)) self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) def _infer_policy(self, **kwargs): if isinstance(self.credential, AzureKeyCredential): - return policies.AzureKeyCredentialPolicy(self.credential, "Authorization", prefix="SharedAccessKey", **kwargs) - if hasattr(self.credential, 'get_token'): + return policies.AzureKeyCredentialPolicy( + self.credential, "Authorization", prefix="SharedAccessKey", **kwargs + ) + if hasattr(self.credential, "get_token"): return policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) raise TypeError(f"Unsupported credential: {self.credential}") - def _configure( - self, - **kwargs: Any - ) -> None: - self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) - self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) - self.authentication_policy = kwargs.get('authentication_policy') + def _configure(self, **kwargs: Any) -> None: + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs) + self.authentication_policy = kwargs.get("authentication_policy") if self.credential and not self.authentication_policy: self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py index bb1644791288..59fbfed265e6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_event_mappings.py @@ -7,6 +7,7 @@ from enum import Enum from azure.core import CaseInsensitiveEnumMeta + # pylint: disable=line-too-long # pylint: disable=enum-must-be-uppercase class SystemEventNames(str, Enum, metaclass=CaseInsensitiveEnumMeta): @@ -15,487 +16,518 @@ class SystemEventNames(str, Enum, metaclass=CaseInsensitiveEnumMeta): Azure Event Grid. To check the list of recognizable system topics, visit https://docs.microsoft.com/azure/event-grid/system-topics. """ + # These names at the top are 'corrected' aliases of duplicate values that appear below, which are # deprecated but maintained for backwards compatibility. - AcsChatMemberAddedToThreadWithUserEventName = 'Microsoft.Communication.ChatMemberAddedToThreadWithUser' + AcsChatMemberAddedToThreadWithUserEventName = "Microsoft.Communication.ChatMemberAddedToThreadWithUser" - ResourceWriteFailureEventName = 'Microsoft.Resources.ResourceWriteFailure' + ResourceWriteFailureEventName = "Microsoft.Resources.ResourceWriteFailure" - IoTHubDeviceDeletedEventName = 'Microsoft.Devices.DeviceDeleted' + IoTHubDeviceDeletedEventName = "Microsoft.Devices.DeviceDeleted" - IoTHubDeviceDisconnectedEventName = 'Microsoft.Devices.DeviceDisconnected' + IoTHubDeviceDisconnectedEventName = "Microsoft.Devices.DeviceDisconnected" - ResourceDeleteFailureEventName = 'Microsoft.Resources.ResourceDeleteFailure' + ResourceDeleteFailureEventName = "Microsoft.Resources.ResourceDeleteFailure" - ResourceDeleteCancelEventName = 'Microsoft.Resources.ResourceDeleteCancel' + ResourceDeleteCancelEventName = "Microsoft.Resources.ResourceDeleteCancel" - AcsChatThreadParticipantAddedEventName = 'Microsoft.Communication.ChatThreadParticipantAdded' + AcsChatThreadParticipantAddedEventName = "Microsoft.Communication.ChatThreadParticipantAdded" - ResourceDeleteSuccessEventName = 'Microsoft.Resources.ResourceDeleteSuccess' + ResourceDeleteSuccessEventName = "Microsoft.Resources.ResourceDeleteSuccess" - EventGridSubscriptionValidationEventName = 'Microsoft.EventGrid.SubscriptionValidationEvent' + EventGridSubscriptionValidationEventName = "Microsoft.EventGrid.SubscriptionValidationEvent" - ResourceWriteSuccessEventName = 'Microsoft.Resources.ResourceWriteSuccess' + ResourceWriteSuccessEventName = "Microsoft.Resources.ResourceWriteSuccess" - ResourceActionSuccessEventName = 'Microsoft.Resources.ResourceActionSuccess' + ResourceActionSuccessEventName = "Microsoft.Resources.ResourceActionSuccess" - ResourceWriteCancelEventName = 'Microsoft.Resources.ResourceWriteCancel' + ResourceWriteCancelEventName = "Microsoft.Resources.ResourceWriteCancel" - ResourceActionFailureEventName = 'Microsoft.Resources.ResourceActionFailure' + ResourceActionFailureEventName = "Microsoft.Resources.ResourceActionFailure" - AcsChatMemberRemovedFromThreadWithUserEventName = 'Microsoft.Communication.ChatMemberRemovedFromThreadWithUser' + AcsChatMemberRemovedFromThreadWithUserEventName = "Microsoft.Communication.ChatMemberRemovedFromThreadWithUser" - IoTHubDeviceConnectedEventName = 'Microsoft.Devices.DeviceConnected' + IoTHubDeviceConnectedEventName = "Microsoft.Devices.DeviceConnected" - EventGridSubscriptionDeletedEventName = 'Microsoft.EventGrid.SubscriptionDeletedEvent' + EventGridSubscriptionDeletedEventName = "Microsoft.EventGrid.SubscriptionDeletedEvent" - AcsChatThreadParticipantRemovedEventName = 'Microsoft.Communication.ChatThreadParticipantRemoved' + AcsChatThreadParticipantRemovedEventName = "Microsoft.Communication.ChatThreadParticipantRemoved" - ResourceActionCancelEventName = 'Microsoft.Resources.ResourceActionCancel' + ResourceActionCancelEventName = "Microsoft.Resources.ResourceActionCancel" - IoTHubDeviceCreatedEventName = 'Microsoft.Devices.DeviceCreated' + IoTHubDeviceCreatedEventName = "Microsoft.Devices.DeviceCreated" # Aliases end here - AcsAdvancedMessageDeliveryStatusUpdatedEventName = 'Microsoft.Communication.AdvancedMessageDeliveryStatusUpdated' + AcsAdvancedMessageDeliveryStatusUpdatedEventName = "Microsoft.Communication.AdvancedMessageDeliveryStatusUpdated" - AcsAdvancedMessageReceivedEventName = 'Microsoft.Communication.AdvancedMessageReceived' + AcsAdvancedMessageReceivedEventName = "Microsoft.Communication.AdvancedMessageReceived" - AcsChatMessageDeletedEventName = 'Microsoft.Communication.ChatMessageDeleted' + AcsChatMessageDeletedEventName = "Microsoft.Communication.ChatMessageDeleted" - AcsChatMessageDeletedInThreadEventName = 'Microsoft.Communication.ChatMessageDeletedInThread' + AcsChatMessageDeletedInThreadEventName = "Microsoft.Communication.ChatMessageDeletedInThread" - AcsChatMessageEditedEventName = 'Microsoft.Communication.ChatMessageEdited' + AcsChatMessageEditedEventName = "Microsoft.Communication.ChatMessageEdited" - AcsChatMessageEditedInThreadEventName = 'Microsoft.Communication.ChatMessageEditedInThread' + AcsChatMessageEditedInThreadEventName = "Microsoft.Communication.ChatMessageEditedInThread" - AcsChatMessageReceivedEventName = 'Microsoft.Communication.ChatMessageReceived' + AcsChatMessageReceivedEventName = "Microsoft.Communication.ChatMessageReceived" - AcsChatMessageReceivedInThreadEventName = 'Microsoft.Communication.ChatMessageReceivedInThread' + AcsChatMessageReceivedInThreadEventName = "Microsoft.Communication.ChatMessageReceivedInThread" - AcsChatParticipantAddedToThreadEventName = 'Microsoft.Communication.ChatThreadParticipantAdded' + AcsChatParticipantAddedToThreadEventName = "Microsoft.Communication.ChatThreadParticipantAdded" - AcsChatParticipantAddedToThreadWithUserEventName = 'Microsoft.Communication.ChatParticipantAddedToThreadWithUser' + AcsChatParticipantAddedToThreadWithUserEventName = "Microsoft.Communication.ChatParticipantAddedToThreadWithUser" - AcsChatParticipantRemovedFromThreadEventName = 'Microsoft.Communication.ChatThreadParticipantRemoved' + AcsChatParticipantRemovedFromThreadEventName = "Microsoft.Communication.ChatThreadParticipantRemoved" - AcsChatParticipantRemovedFromThreadWithUserEventName = 'Microsoft.Communication.ChatParticipantRemovedFromThreadWithUser' + AcsChatParticipantRemovedFromThreadWithUserEventName = ( + "Microsoft.Communication.ChatParticipantRemovedFromThreadWithUser" + ) - AcsChatThreadCreatedEventName = 'Microsoft.Communication.ChatThreadCreated' + AcsChatThreadCreatedEventName = "Microsoft.Communication.ChatThreadCreated" - AcsChatThreadCreatedWithUserEventName = 'Microsoft.Communication.ChatThreadCreatedWithUser' + AcsChatThreadCreatedWithUserEventName = "Microsoft.Communication.ChatThreadCreatedWithUser" - AcsChatThreadDeletedEventName = 'Microsoft.Communication.ChatThreadDeleted' + AcsChatThreadDeletedEventName = "Microsoft.Communication.ChatThreadDeleted" - AcsChatThreadPropertiesUpdatedEventName = 'Microsoft.Communication.ChatThreadPropertiesUpdated' + AcsChatThreadPropertiesUpdatedEventName = "Microsoft.Communication.ChatThreadPropertiesUpdated" - AcsChatThreadPropertiesUpdatedPerUserEventName = 'Microsoft.Communication.ChatThreadPropertiesUpdatedPerUser' + AcsChatThreadPropertiesUpdatedPerUserEventName = "Microsoft.Communication.ChatThreadPropertiesUpdatedPerUser" - AcsChatThreadWithUserDeletedEventName = 'Microsoft.Communication.ChatThreadWithUserDeleted' + AcsChatThreadWithUserDeletedEventName = "Microsoft.Communication.ChatThreadWithUserDeleted" - AcsEmailDeliveryReportReceivedEventName = 'Microsoft.Communication.EmailDeliveryReportReceived' + AcsEmailDeliveryReportReceivedEventName = "Microsoft.Communication.EmailDeliveryReportReceived" - AcsEmailEngagementTrackingReportReceivedEventName = 'Microsoft.Communication.EmailEngagementTrackingReportReceived' + AcsEmailEngagementTrackingReportReceivedEventName = "Microsoft.Communication.EmailEngagementTrackingReportReceived" - AcsIncomingCallEventName = 'Microsoft.Communication.IncomingCall' + AcsIncomingCallEventName = "Microsoft.Communication.IncomingCall" - AcsRecordingFileStatusUpdatedEventName = 'Microsoft.Communication.RecordingFileStatusUpdated' + AcsRecordingFileStatusUpdatedEventName = "Microsoft.Communication.RecordingFileStatusUpdated" - AcsRouterJobCancelledEventName = 'Microsoft.Communication.RouterJobCancelled' + AcsRouterJobCancelledEventName = "Microsoft.Communication.RouterJobCancelled" - AcsRouterJobClassificationFailedEventName = 'Microsoft.Communication.RouterJobClassificationFailed' + AcsRouterJobClassificationFailedEventName = "Microsoft.Communication.RouterJobClassificationFailed" - AcsRouterJobClassifiedEventName = 'Microsoft.Communication.RouterJobClassified' + AcsRouterJobClassifiedEventName = "Microsoft.Communication.RouterJobClassified" - AcsRouterJobClosedEventName = 'Microsoft.Communication.RouterJobClosed' + AcsRouterJobClosedEventName = "Microsoft.Communication.RouterJobClosed" - AcsRouterJobCompletedEventName = 'Microsoft.Communication.RouterJobCompleted' + AcsRouterJobCompletedEventName = "Microsoft.Communication.RouterJobCompleted" - AcsRouterJobDeletedEventName = 'Microsoft.Communication.RouterJobDeleted' + AcsRouterJobDeletedEventName = "Microsoft.Communication.RouterJobDeleted" - AcsRouterJobExceptionTriggeredEventName = 'Microsoft.Communication.RouterJobExceptionTriggered' + AcsRouterJobExceptionTriggeredEventName = "Microsoft.Communication.RouterJobExceptionTriggered" - AcsRouterJobQueuedEventName = 'Microsoft.Communication.RouterJobQueued' + AcsRouterJobQueuedEventName = "Microsoft.Communication.RouterJobQueued" - AcsRouterJobReceivedEventName = 'Microsoft.Communication.RouterJobReceived' + AcsRouterJobReceivedEventName = "Microsoft.Communication.RouterJobReceived" - AcsRouterJobSchedulingFailedEventName = 'Microsoft.Communication.RouterJobSchedulingFailed' + AcsRouterJobSchedulingFailedEventName = "Microsoft.Communication.RouterJobSchedulingFailed" - AcsRouterJobUnassignedEventName = 'Microsoft.Communication.RouterJobUnassigned' + AcsRouterJobUnassignedEventName = "Microsoft.Communication.RouterJobUnassigned" - AcsRouterJobWaitingForActivationEventName = 'Microsoft.Communication.RouterJobWaitingForActivation' + AcsRouterJobWaitingForActivationEventName = "Microsoft.Communication.RouterJobWaitingForActivation" - AcsRouterJobWorkerSelectorsExpiredEventName = 'Microsoft.Communication.RouterJobWorkerSelectorsExpired' + AcsRouterJobWorkerSelectorsExpiredEventName = "Microsoft.Communication.RouterJobWorkerSelectorsExpired" - AcsRouterWorkerDeletedEventName = 'Microsoft.Communication.RouterWorkerDeleted' + AcsRouterWorkerDeletedEventName = "Microsoft.Communication.RouterWorkerDeleted" - AcsRouterWorkerDeregisteredEventName = 'Microsoft.Communication.RouterWorkerDeregistered' + AcsRouterWorkerDeregisteredEventName = "Microsoft.Communication.RouterWorkerDeregistered" - AcsRouterWorkerOfferAcceptedEventName = 'Microsoft.Communication.RouterWorkerOfferAccepted' + AcsRouterWorkerOfferAcceptedEventName = "Microsoft.Communication.RouterWorkerOfferAccepted" - AcsRouterWorkerOfferDeclinedEventName = 'Microsoft.Communication.RouterWorkerOfferDeclined' + AcsRouterWorkerOfferDeclinedEventName = "Microsoft.Communication.RouterWorkerOfferDeclined" - AcsRouterWorkerOfferExpiredEventName = 'Microsoft.Communication.RouterWorkerOfferExpired' + AcsRouterWorkerOfferExpiredEventName = "Microsoft.Communication.RouterWorkerOfferExpired" - AcsRouterWorkerOfferIssuedEventName = 'Microsoft.Communication.RouterWorkerOfferIssued' + AcsRouterWorkerOfferIssuedEventName = "Microsoft.Communication.RouterWorkerOfferIssued" - AcsRouterWorkerOfferRevokedEventName = 'Microsoft.Communication.RouterWorkerOfferRevoked' + AcsRouterWorkerOfferRevokedEventName = "Microsoft.Communication.RouterWorkerOfferRevoked" - AcsRouterWorkerRegisteredEventName = 'Microsoft.Communication.RouterWorkerRegistered' + AcsRouterWorkerRegisteredEventName = "Microsoft.Communication.RouterWorkerRegistered" - AcsRouterWorkerUpdatedEventName = 'Microsoft.Communication.RouterWorkerUpdated' + AcsRouterWorkerUpdatedEventName = "Microsoft.Communication.RouterWorkerUpdated" - AcsSmsDeliveryReportReceivedEventName = 'Microsoft.Communication.SMSDeliveryReportReceived' + AcsSmsDeliveryReportReceivedEventName = "Microsoft.Communication.SMSDeliveryReportReceived" - AcsSmsReceivedEventName = 'Microsoft.Communication.SMSReceived' + AcsSmsReceivedEventName = "Microsoft.Communication.SMSReceived" - AcsUserDisconnectedEventName = 'Microsoft.Communication.UserDisconnected' + AcsUserDisconnectedEventName = "Microsoft.Communication.UserDisconnected" - ApiCenterApiDefinitionAddedEventName = 'Microsoft.ApiCenter.ApiDefinitionAdded' + ApiCenterApiDefinitionAddedEventName = "Microsoft.ApiCenter.ApiDefinitionAdded" - ApiCenterApiDefinitionUpdatedEventName = 'Microsoft.ApiCenter.ApiDefinitionUpdated' + ApiCenterApiDefinitionUpdatedEventName = "Microsoft.ApiCenter.ApiDefinitionUpdated" - ApiManagementApiCreatedEventName = 'Microsoft.ApiManagement.APICreated' + ApiManagementApiCreatedEventName = "Microsoft.ApiManagement.APICreated" - ApiManagementApiDeletedEventName = 'Microsoft.ApiManagement.APIDeleted' + ApiManagementApiDeletedEventName = "Microsoft.ApiManagement.APIDeleted" - ApiManagementApiReleaseCreatedEventName = 'Microsoft.ApiManagement.APIReleaseCreated' + ApiManagementApiReleaseCreatedEventName = "Microsoft.ApiManagement.APIReleaseCreated" - ApiManagementApiReleaseDeletedEventName = 'Microsoft.ApiManagement.APIReleaseDeleted' + ApiManagementApiReleaseDeletedEventName = "Microsoft.ApiManagement.APIReleaseDeleted" - ApiManagementApiReleaseUpdatedEventName = 'Microsoft.ApiManagement.APIReleaseUpdated' + ApiManagementApiReleaseUpdatedEventName = "Microsoft.ApiManagement.APIReleaseUpdated" - ApiManagementApiUpdatedEventName = 'Microsoft.ApiManagement.APIUpdated' + ApiManagementApiUpdatedEventName = "Microsoft.ApiManagement.APIUpdated" - ApiManagementGatewayApiAddedEventName = 'Microsoft.ApiManagement.GatewayAPIAdded' + ApiManagementGatewayApiAddedEventName = "Microsoft.ApiManagement.GatewayAPIAdded" - ApiManagementGatewayApiRemovedEventName = 'Microsoft.ApiManagement.GatewayAPIRemoved' + ApiManagementGatewayApiRemovedEventName = "Microsoft.ApiManagement.GatewayAPIRemoved" - ApiManagementGatewayCertificateAuthorityCreatedEventName = 'Microsoft.ApiManagement.GatewayCertificateAuthorityCreated' + ApiManagementGatewayCertificateAuthorityCreatedEventName = ( + "Microsoft.ApiManagement.GatewayCertificateAuthorityCreated" + ) - ApiManagementGatewayCertificateAuthorityDeletedEventName = 'Microsoft.ApiManagement.GatewayCertificateAuthorityDeleted' + ApiManagementGatewayCertificateAuthorityDeletedEventName = ( + "Microsoft.ApiManagement.GatewayCertificateAuthorityDeleted" + ) - ApiManagementGatewayCertificateAuthorityUpdatedEventName = 'Microsoft.ApiManagement.GatewayCertificateAuthorityUpdated' + ApiManagementGatewayCertificateAuthorityUpdatedEventName = ( + "Microsoft.ApiManagement.GatewayCertificateAuthorityUpdated" + ) - ApiManagementGatewayCreatedEventName = 'Microsoft.ApiManagement.GatewayCreated' + ApiManagementGatewayCreatedEventName = "Microsoft.ApiManagement.GatewayCreated" - ApiManagementGatewayDeletedEventName = 'Microsoft.ApiManagement.GatewayDeleted' + ApiManagementGatewayDeletedEventName = "Microsoft.ApiManagement.GatewayDeleted" - ApiManagementGatewayHostnameConfigurationCreatedEventName = 'Microsoft.ApiManagement.GatewayHostnameConfigurationCreated' + ApiManagementGatewayHostnameConfigurationCreatedEventName = ( + "Microsoft.ApiManagement.GatewayHostnameConfigurationCreated" + ) - ApiManagementGatewayHostnameConfigurationDeletedEventName = 'Microsoft.ApiManagement.GatewayHostnameConfigurationDeleted' + ApiManagementGatewayHostnameConfigurationDeletedEventName = ( + "Microsoft.ApiManagement.GatewayHostnameConfigurationDeleted" + ) - ApiManagementGatewayHostnameConfigurationUpdatedEventName = 'Microsoft.ApiManagement.GatewayHostnameConfigurationUpdated' + ApiManagementGatewayHostnameConfigurationUpdatedEventName = ( + "Microsoft.ApiManagement.GatewayHostnameConfigurationUpdated" + ) - ApiManagementGatewayUpdatedEventName = 'Microsoft.ApiManagement.GatewayUpdated' + ApiManagementGatewayUpdatedEventName = "Microsoft.ApiManagement.GatewayUpdated" - ApiManagementProductCreatedEventName = 'Microsoft.ApiManagement.ProductCreated' + ApiManagementProductCreatedEventName = "Microsoft.ApiManagement.ProductCreated" - ApiManagementProductDeletedEventName = 'Microsoft.ApiManagement.ProductDeleted' + ApiManagementProductDeletedEventName = "Microsoft.ApiManagement.ProductDeleted" - ApiManagementProductUpdatedEventName = 'Microsoft.ApiManagement.ProductUpdated' + ApiManagementProductUpdatedEventName = "Microsoft.ApiManagement.ProductUpdated" - ApiManagementSubscriptionCreatedEventName = 'Microsoft.ApiManagement.SubscriptionCreated' + ApiManagementSubscriptionCreatedEventName = "Microsoft.ApiManagement.SubscriptionCreated" - ApiManagementSubscriptionDeletedEventName = 'Microsoft.ApiManagement.SubscriptionDeleted' + ApiManagementSubscriptionDeletedEventName = "Microsoft.ApiManagement.SubscriptionDeleted" - ApiManagementSubscriptionUpdatedEventName = 'Microsoft.ApiManagement.SubscriptionUpdated' + ApiManagementSubscriptionUpdatedEventName = "Microsoft.ApiManagement.SubscriptionUpdated" - ApiManagementUserCreatedEventName = 'Microsoft.ApiManagement.UserCreated' + ApiManagementUserCreatedEventName = "Microsoft.ApiManagement.UserCreated" - ApiManagementUserDeletedEventName = 'Microsoft.ApiManagement.UserDeleted' + ApiManagementUserDeletedEventName = "Microsoft.ApiManagement.UserDeleted" - ApiManagementUserUpdatedEventName = 'Microsoft.ApiManagement.UserUpdated' + ApiManagementUserUpdatedEventName = "Microsoft.ApiManagement.UserUpdated" - AppConfigurationKeyValueDeletedEventName = 'Microsoft.AppConfiguration.KeyValueDeleted' + AppConfigurationKeyValueDeletedEventName = "Microsoft.AppConfiguration.KeyValueDeleted" - AppConfigurationKeyValueModifiedEventName = 'Microsoft.AppConfiguration.KeyValueModified' + AppConfigurationKeyValueModifiedEventName = "Microsoft.AppConfiguration.KeyValueModified" - AppConfigurationSnapshotCreatedEventName = 'Microsoft.AppConfiguration.SnapshotCreated' + AppConfigurationSnapshotCreatedEventName = "Microsoft.AppConfiguration.SnapshotCreated" - AppConfigurationSnapshotModifiedEventName = 'Microsoft.AppConfiguration.SnapshotModified' + AppConfigurationSnapshotModifiedEventName = "Microsoft.AppConfiguration.SnapshotModified" - AvsClusterCreatedEventName = 'Microsoft.AVS.ClusterCreated' + AvsClusterCreatedEventName = "Microsoft.AVS.ClusterCreated" - AvsClusterDeletedEventName = 'Microsoft.AVS.ClusterDeleted' + AvsClusterDeletedEventName = "Microsoft.AVS.ClusterDeleted" - AvsClusterFailedEventName = 'Microsoft.AVS.ClusterFailed' + AvsClusterFailedEventName = "Microsoft.AVS.ClusterFailed" - AvsClusterUpdatedEventName = 'Microsoft.AVS.ClusterUpdated' + AvsClusterUpdatedEventName = "Microsoft.AVS.ClusterUpdated" - AvsClusterUpdatingEventName = 'Microsoft.AVS.ClusterUpdating' + AvsClusterUpdatingEventName = "Microsoft.AVS.ClusterUpdating" - AvsPrivateCloudFailedEventName = 'Microsoft.AVS.PrivateCloudFailed' + AvsPrivateCloudFailedEventName = "Microsoft.AVS.PrivateCloudFailed" - AvsPrivateCloudUpdatedEventName = 'Microsoft.AVS.PrivateCloudUpdated' + AvsPrivateCloudUpdatedEventName = "Microsoft.AVS.PrivateCloudUpdated" - AvsPrivateCloudUpdatingEventName = 'Microsoft.AVS.PrivateCloudUpdating' + AvsPrivateCloudUpdatingEventName = "Microsoft.AVS.PrivateCloudUpdating" - AvsScriptExecutionCancelledEventName = 'Microsoft.AVS.ScriptExecutionCancelled' + AvsScriptExecutionCancelledEventName = "Microsoft.AVS.ScriptExecutionCancelled" - AvsScriptExecutionFailedEventName = 'Microsoft.AVS.ScriptExecutionFailed' + AvsScriptExecutionFailedEventName = "Microsoft.AVS.ScriptExecutionFailed" - AvsScriptExecutionFinishedEventName = 'Microsoft.AVS.ScriptExecutionFinished' + AvsScriptExecutionFinishedEventName = "Microsoft.AVS.ScriptExecutionFinished" - AvsScriptExecutionStartedEventName = 'Microsoft.AVS.ScriptExecutionStarted' + AvsScriptExecutionStartedEventName = "Microsoft.AVS.ScriptExecutionStarted" - ContainerRegistryChartDeletedEventName = 'Microsoft.ContainerRegistry.ChartDeleted' + ContainerRegistryChartDeletedEventName = "Microsoft.ContainerRegistry.ChartDeleted" - ContainerRegistryChartPushedEventName = 'Microsoft.ContainerRegistry.ChartPushed' + ContainerRegistryChartPushedEventName = "Microsoft.ContainerRegistry.ChartPushed" - ContainerRegistryImageDeletedEventName = 'Microsoft.ContainerRegistry.ImageDeleted' + ContainerRegistryImageDeletedEventName = "Microsoft.ContainerRegistry.ImageDeleted" - ContainerRegistryImagePushedEventName = 'Microsoft.ContainerRegistry.ImagePushed' + ContainerRegistryImagePushedEventName = "Microsoft.ContainerRegistry.ImagePushed" - ContainerServiceClusterSupportEndedEventName = 'Microsoft.ContainerService.ClusterSupportEnded' + ContainerServiceClusterSupportEndedEventName = "Microsoft.ContainerService.ClusterSupportEnded" - ContainerServiceClusterSupportEndingEventName = 'Microsoft.ContainerService.ClusterSupportEnding' + ContainerServiceClusterSupportEndingEventName = "Microsoft.ContainerService.ClusterSupportEnding" - ContainerServiceNewKubernetesVersionAvailableEventName = 'Microsoft.ContainerService.NewKubernetesVersionAvailable' + ContainerServiceNewKubernetesVersionAvailableEventName = "Microsoft.ContainerService.NewKubernetesVersionAvailable" - ContainerServiceNodePoolRollingFailedEventName = 'Microsoft.ContainerService.NodePoolRollingFailed' + ContainerServiceNodePoolRollingFailedEventName = "Microsoft.ContainerService.NodePoolRollingFailed" - ContainerServiceNodePoolRollingStartedEventName = 'Microsoft.ContainerService.NodePoolRollingStarted' + ContainerServiceNodePoolRollingStartedEventName = "Microsoft.ContainerService.NodePoolRollingStarted" - ContainerServiceNodePoolRollingSucceededEventName = 'Microsoft.ContainerService.NodePoolRollingSucceeded' + ContainerServiceNodePoolRollingSucceededEventName = "Microsoft.ContainerService.NodePoolRollingSucceeded" - DataBoxCopyCompletedEventName = 'Microsoft.DataBox.CopyCompleted' + DataBoxCopyCompletedEventName = "Microsoft.DataBox.CopyCompleted" - DataBoxCopyStartedEventName = 'Microsoft.DataBox.CopyStarted' + DataBoxCopyStartedEventName = "Microsoft.DataBox.CopyStarted" - DataBoxOrderCompletedEventName = 'Microsoft.DataBox.OrderCompleted' + DataBoxOrderCompletedEventName = "Microsoft.DataBox.OrderCompleted" - EventGridMQTTClientCreatedOrUpdatedEventName = 'Microsoft.EventGrid.MQTTClientCreatedOrUpdated' + EventGridMQTTClientCreatedOrUpdatedEventName = "Microsoft.EventGrid.MQTTClientCreatedOrUpdated" - EventGridMQTTClientDeletedEventName = 'Microsoft.EventGrid.MQTTClientDeleted' + EventGridMQTTClientDeletedEventName = "Microsoft.EventGrid.MQTTClientDeleted" - EventGridMQTTClientSessionConnectedEventName = 'Microsoft.EventGrid.MQTTClientSessionConnected' + EventGridMQTTClientSessionConnectedEventName = "Microsoft.EventGrid.MQTTClientSessionConnected" - EventGridMQTTClientSessionDisconnectedEventName = 'Microsoft.EventGrid.MQTTClientSessionDisconnected' + EventGridMQTTClientSessionDisconnectedEventName = "Microsoft.EventGrid.MQTTClientSessionDisconnected" - EventHubCaptureFileCreatedEventName = 'Microsoft.EventHub.CaptureFileCreated' + EventHubCaptureFileCreatedEventName = "Microsoft.EventHub.CaptureFileCreated" - HealthcareDicomImageCreatedEventName = 'Microsoft.HealthcareApis.DicomImageCreated' + HealthcareDicomImageCreatedEventName = "Microsoft.HealthcareApis.DicomImageCreated" - HealthcareDicomImageDeletedEventName = 'Microsoft.HealthcareApis.DicomImageDeleted' + HealthcareDicomImageDeletedEventName = "Microsoft.HealthcareApis.DicomImageDeleted" - HealthcareDicomImageUpdatedEventName = 'Microsoft.HealthcareApis.DicomImageUpdated' + HealthcareDicomImageUpdatedEventName = "Microsoft.HealthcareApis.DicomImageUpdated" - HealthcareFhirResourceCreatedEventName = 'Microsoft.HealthcareApis.FhirResourceCreated' + HealthcareFhirResourceCreatedEventName = "Microsoft.HealthcareApis.FhirResourceCreated" - HealthcareFhirResourceDeletedEventName = 'Microsoft.HealthcareApis.FhirResourceDeleted' + HealthcareFhirResourceDeletedEventName = "Microsoft.HealthcareApis.FhirResourceDeleted" - HealthcareFhirResourceUpdatedEventName = 'Microsoft.HealthcareApis.FhirResourceUpdated' + HealthcareFhirResourceUpdatedEventName = "Microsoft.HealthcareApis.FhirResourceUpdated" - IotHubDeviceConnectedEventName = 'Microsoft.Devices.DeviceConnected' + IotHubDeviceConnectedEventName = "Microsoft.Devices.DeviceConnected" - IotHubDeviceCreatedEventName = 'Microsoft.Devices.DeviceCreated' + IotHubDeviceCreatedEventName = "Microsoft.Devices.DeviceCreated" - IotHubDeviceDeletedEventName = 'Microsoft.Devices.DeviceDeleted' + IotHubDeviceDeletedEventName = "Microsoft.Devices.DeviceDeleted" - IotHubDeviceDisconnectedEventName = 'Microsoft.Devices.DeviceDisconnected' + IotHubDeviceDisconnectedEventName = "Microsoft.Devices.DeviceDisconnected" - IotHubDeviceTelemetryEventName = 'Microsoft.Devices.DeviceTelemetry' + IotHubDeviceTelemetryEventName = "Microsoft.Devices.DeviceTelemetry" - KeyVaultCertificateExpiredEventName = 'Microsoft.KeyVault.CertificateExpired' + KeyVaultCertificateExpiredEventName = "Microsoft.KeyVault.CertificateExpired" - KeyVaultCertificateNearExpiryEventName = 'Microsoft.KeyVault.CertificateNearExpiry' + KeyVaultCertificateNearExpiryEventName = "Microsoft.KeyVault.CertificateNearExpiry" - KeyVaultCertificateNewVersionCreatedEventName = 'Microsoft.KeyVault.CertificateNewVersionCreated' + KeyVaultCertificateNewVersionCreatedEventName = "Microsoft.KeyVault.CertificateNewVersionCreated" - KeyVaultKeyExpiredEventName = 'Microsoft.KeyVault.KeyExpired' + KeyVaultKeyExpiredEventName = "Microsoft.KeyVault.KeyExpired" - KeyVaultKeyNearExpiryEventName = 'Microsoft.KeyVault.KeyNearExpiry' + KeyVaultKeyNearExpiryEventName = "Microsoft.KeyVault.KeyNearExpiry" - KeyVaultKeyNewVersionCreatedEventName = 'Microsoft.KeyVault.KeyNewVersionCreated' + KeyVaultKeyNewVersionCreatedEventName = "Microsoft.KeyVault.KeyNewVersionCreated" - KeyVaultSecretExpiredEventName = 'Microsoft.KeyVault.SecretExpired' + KeyVaultSecretExpiredEventName = "Microsoft.KeyVault.SecretExpired" - KeyVaultSecretNearExpiryEventName = 'Microsoft.KeyVault.SecretNearExpiry' + KeyVaultSecretNearExpiryEventName = "Microsoft.KeyVault.SecretNearExpiry" - KeyVaultSecretNewVersionCreatedEventName = 'Microsoft.KeyVault.SecretNewVersionCreated' + KeyVaultSecretNewVersionCreatedEventName = "Microsoft.KeyVault.SecretNewVersionCreated" - KeyVaultVaultAccessPolicyChangedEventName = 'Microsoft.KeyVault.VaultAccessPolicyChanged' + KeyVaultVaultAccessPolicyChangedEventName = "Microsoft.KeyVault.VaultAccessPolicyChanged" - MachineLearningServicesDatasetDriftDetectedEventName = 'Microsoft.MachineLearningServices.DatasetDriftDetected' + MachineLearningServicesDatasetDriftDetectedEventName = "Microsoft.MachineLearningServices.DatasetDriftDetected" - MachineLearningServicesModelDeployedEventName = 'Microsoft.MachineLearningServices.ModelDeployed' + MachineLearningServicesModelDeployedEventName = "Microsoft.MachineLearningServices.ModelDeployed" - MachineLearningServicesModelRegisteredEventName = 'Microsoft.MachineLearningServices.ModelRegistered' + MachineLearningServicesModelRegisteredEventName = "Microsoft.MachineLearningServices.ModelRegistered" - MachineLearningServicesRunCompletedEventName = 'Microsoft.MachineLearningServices.RunCompleted' + MachineLearningServicesRunCompletedEventName = "Microsoft.MachineLearningServices.RunCompleted" - MachineLearningServicesRunStatusChangedEventName = 'Microsoft.MachineLearningServices.RunStatusChanged' + MachineLearningServicesRunStatusChangedEventName = "Microsoft.MachineLearningServices.RunStatusChanged" - MapsGeofenceEnteredEventName = 'Microsoft.Maps.GeofenceEntered' + MapsGeofenceEnteredEventName = "Microsoft.Maps.GeofenceEntered" - MapsGeofenceExitedEventName = 'Microsoft.Maps.GeofenceExited' + MapsGeofenceExitedEventName = "Microsoft.Maps.GeofenceExited" - MapsGeofenceResultEventName = 'Microsoft.Maps.GeofenceResult' + MapsGeofenceResultEventName = "Microsoft.Maps.GeofenceResult" - MediaJobCanceledEventName = 'Microsoft.Media.JobCanceled' + MediaJobCanceledEventName = "Microsoft.Media.JobCanceled" - MediaJobCancelingEventName = 'Microsoft.Media.JobCanceling' + MediaJobCancelingEventName = "Microsoft.Media.JobCanceling" - MediaJobErroredEventName = 'Microsoft.Media.JobErrored' + MediaJobErroredEventName = "Microsoft.Media.JobErrored" - MediaJobFinishedEventName = 'Microsoft.Media.JobFinished' + MediaJobFinishedEventName = "Microsoft.Media.JobFinished" - MediaJobOutputCanceledEventName = 'Microsoft.Media.JobOutputCanceled' + MediaJobOutputCanceledEventName = "Microsoft.Media.JobOutputCanceled" - MediaJobOutputCancelingEventName = 'Microsoft.Media.JobOutputCanceling' + MediaJobOutputCancelingEventName = "Microsoft.Media.JobOutputCanceling" - MediaJobOutputErroredEventName = 'Microsoft.Media.JobOutputErrored' + MediaJobOutputErroredEventName = "Microsoft.Media.JobOutputErrored" - MediaJobOutputFinishedEventName = 'Microsoft.Media.JobOutputFinished' + MediaJobOutputFinishedEventName = "Microsoft.Media.JobOutputFinished" - MediaJobOutputProcessingEventName = 'Microsoft.Media.JobOutputProcessing' + MediaJobOutputProcessingEventName = "Microsoft.Media.JobOutputProcessing" - MediaJobOutputProgressEventName = 'Microsoft.Media.JobOutputProgress' + MediaJobOutputProgressEventName = "Microsoft.Media.JobOutputProgress" - MediaJobOutputScheduledEventName = 'Microsoft.Media.JobOutputScheduled' + MediaJobOutputScheduledEventName = "Microsoft.Media.JobOutputScheduled" - MediaJobOutputStateChangeEventName = 'Microsoft.Media.JobOutputStateChange' + MediaJobOutputStateChangeEventName = "Microsoft.Media.JobOutputStateChange" - MediaJobProcessingEventName = 'Microsoft.Media.JobProcessing' + MediaJobProcessingEventName = "Microsoft.Media.JobProcessing" - MediaJobScheduledEventName = 'Microsoft.Media.JobScheduled' + MediaJobScheduledEventName = "Microsoft.Media.JobScheduled" - MediaJobStateChangeEventName = 'Microsoft.Media.JobStateChange' + MediaJobStateChangeEventName = "Microsoft.Media.JobStateChange" - MediaLiveEventChannelArchiveHeartbeatEventName = 'Microsoft.Media.LiveEventChannelArchiveHeartbeat' + MediaLiveEventChannelArchiveHeartbeatEventName = "Microsoft.Media.LiveEventChannelArchiveHeartbeat" - MediaLiveEventConnectionRejectedEventName = 'Microsoft.Media.LiveEventConnectionRejected' + MediaLiveEventConnectionRejectedEventName = "Microsoft.Media.LiveEventConnectionRejected" - MediaLiveEventEncoderConnectedEventName = 'Microsoft.Media.LiveEventEncoderConnected' + MediaLiveEventEncoderConnectedEventName = "Microsoft.Media.LiveEventEncoderConnected" - MediaLiveEventEncoderDisconnectedEventName = 'Microsoft.Media.LiveEventEncoderDisconnected' + MediaLiveEventEncoderDisconnectedEventName = "Microsoft.Media.LiveEventEncoderDisconnected" - MediaLiveEventIncomingDataChunkDroppedEventName = 'Microsoft.Media.LiveEventIncomingDataChunkDropped' + MediaLiveEventIncomingDataChunkDroppedEventName = "Microsoft.Media.LiveEventIncomingDataChunkDropped" - MediaLiveEventIncomingStreamReceivedEventName = 'Microsoft.Media.LiveEventIncomingStreamReceived' + MediaLiveEventIncomingStreamReceivedEventName = "Microsoft.Media.LiveEventIncomingStreamReceived" - MediaLiveEventIncomingStreamsOutOfSyncEventName = 'Microsoft.Media.LiveEventIncomingStreamsOutOfSync' + MediaLiveEventIncomingStreamsOutOfSyncEventName = "Microsoft.Media.LiveEventIncomingStreamsOutOfSync" - MediaLiveEventIncomingVideoStreamsOutOfSyncEventName = 'Microsoft.Media.LiveEventIncomingVideoStreamsOutOfSync' + MediaLiveEventIncomingVideoStreamsOutOfSyncEventName = "Microsoft.Media.LiveEventIncomingVideoStreamsOutOfSync" - MediaLiveEventIngestHeartbeatEventName = 'Microsoft.Media.LiveEventIngestHeartbeat' + MediaLiveEventIngestHeartbeatEventName = "Microsoft.Media.LiveEventIngestHeartbeat" - MediaLiveEventTrackDiscontinuityDetectedEventName = 'Microsoft.Media.LiveEventTrackDiscontinuityDetected' + MediaLiveEventTrackDiscontinuityDetectedEventName = "Microsoft.Media.LiveEventTrackDiscontinuityDetected" - PolicyInsightsPolicyStateChangedEventName = 'Microsoft.PolicyInsights.PolicyStateChanged' + PolicyInsightsPolicyStateChangedEventName = "Microsoft.PolicyInsights.PolicyStateChanged" - PolicyInsightsPolicyStateCreatedEventName = 'Microsoft.PolicyInsights.PolicyStateCreated' + PolicyInsightsPolicyStateCreatedEventName = "Microsoft.PolicyInsights.PolicyStateCreated" - PolicyInsightsPolicyStateDeletedEventName = 'Microsoft.PolicyInsights.PolicyStateDeleted' + PolicyInsightsPolicyStateDeletedEventName = "Microsoft.PolicyInsights.PolicyStateDeleted" - RedisExportRDBCompletedEventName = 'Microsoft.Cache.ExportRDBCompleted' + RedisExportRDBCompletedEventName = "Microsoft.Cache.ExportRDBCompleted" - RedisImportRDBCompletedEventName = 'Microsoft.Cache.ImportRDBCompleted' + RedisImportRDBCompletedEventName = "Microsoft.Cache.ImportRDBCompleted" - RedisPatchingCompletedEventName = 'Microsoft.Cache.PatchingCompleted' + RedisPatchingCompletedEventName = "Microsoft.Cache.PatchingCompleted" - RedisScalingCompletedEventName = 'Microsoft.Cache.ScalingCompleted' + RedisScalingCompletedEventName = "Microsoft.Cache.ScalingCompleted" - ResourceActionCancelName = 'Microsoft.Resources.ResourceActionCancel' + ResourceActionCancelName = "Microsoft.Resources.ResourceActionCancel" - ResourceActionFailureName = 'Microsoft.Resources.ResourceActionFailure' + ResourceActionFailureName = "Microsoft.Resources.ResourceActionFailure" - ResourceActionSuccessName = 'Microsoft.Resources.ResourceActionSuccess' + ResourceActionSuccessName = "Microsoft.Resources.ResourceActionSuccess" - ResourceDeleteCancelName = 'Microsoft.Resources.ResourceDeleteCancel' + ResourceDeleteCancelName = "Microsoft.Resources.ResourceDeleteCancel" - ResourceDeleteFailureName = 'Microsoft.Resources.ResourceDeleteFailure' + ResourceDeleteFailureName = "Microsoft.Resources.ResourceDeleteFailure" - ResourceDeleteSuccessName = 'Microsoft.Resources.ResourceDeleteSuccess' + ResourceDeleteSuccessName = "Microsoft.Resources.ResourceDeleteSuccess" - ResourceNotificationsHealthResourcesAnnotatedEventName = 'Microsoft.ResourceNotifications.HealthResources.ResourceAnnotated' + ResourceNotificationsHealthResourcesAnnotatedEventName = ( + "Microsoft.ResourceNotifications.HealthResources.ResourceAnnotated" + ) - ResourceNotificationsHealthResourcesAvailabilityStatusChangedEventName = 'Microsoft.ResourceNotifications.HealthResources.AvailabilityStatusChanged' + ResourceNotificationsHealthResourcesAvailabilityStatusChangedEventName = ( + "Microsoft.ResourceNotifications.HealthResources.AvailabilityStatusChanged" + ) - ResourceNotificationsResourceManagementCreatedOrUpdatedEventName = 'Microsoft.ResourceNotifications.Resources.CreatedOrUpdated' + ResourceNotificationsResourceManagementCreatedOrUpdatedEventName = ( + "Microsoft.ResourceNotifications.Resources.CreatedOrUpdated" + ) - ResourceNotificationsResourceManagementDeletedEventName = 'Microsoft.ResourceNotifications.Resources.Deleted' + ResourceNotificationsResourceManagementDeletedEventName = "Microsoft.ResourceNotifications.Resources.Deleted" - ResourceWriteCancelName = 'Microsoft.Resources.ResourceWriteCancel' + ResourceWriteCancelName = "Microsoft.Resources.ResourceWriteCancel" - ResourceWriteFailureName = 'Microsoft.Resources.ResourceWriteFailure' + ResourceWriteFailureName = "Microsoft.Resources.ResourceWriteFailure" - ResourceWriteSuccessName = 'Microsoft.Resources.ResourceWriteSuccess' + ResourceWriteSuccessName = "Microsoft.Resources.ResourceWriteSuccess" - ServiceBusActiveMessagesAvailablePeriodicNotificationsEventName = 'Microsoft.ServiceBus.ActiveMessagesAvailablePeriodicNotifications' + ServiceBusActiveMessagesAvailablePeriodicNotificationsEventName = ( + "Microsoft.ServiceBus.ActiveMessagesAvailablePeriodicNotifications" + ) - ServiceBusActiveMessagesAvailableWithNoListenersEventName = 'Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners' + ServiceBusActiveMessagesAvailableWithNoListenersEventName = ( + "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners" + ) - ServiceBusDeadletterMessagesAvailablePeriodicNotificationsEventName = 'Microsoft.ServiceBus.DeadletterMessagesAvailablePeriodicNotifications' + ServiceBusDeadletterMessagesAvailablePeriodicNotificationsEventName = ( + "Microsoft.ServiceBus.DeadletterMessagesAvailablePeriodicNotifications" + ) - ServiceBusDeadletterMessagesAvailableWithNoListenersEventName = 'Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners' + ServiceBusDeadletterMessagesAvailableWithNoListenersEventName = ( + "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners" + ) - SignalRServiceClientConnectionConnectedEventName = 'Microsoft.SignalRService.ClientConnectionConnected' + SignalRServiceClientConnectionConnectedEventName = "Microsoft.SignalRService.ClientConnectionConnected" - SignalRServiceClientConnectionDisconnectedEventName = 'Microsoft.SignalRService.ClientConnectionDisconnected' + SignalRServiceClientConnectionDisconnectedEventName = "Microsoft.SignalRService.ClientConnectionDisconnected" - StorageAsyncOperationInitiatedEventName = 'Microsoft.Storage.AsyncOperationInitiated' + StorageAsyncOperationInitiatedEventName = "Microsoft.Storage.AsyncOperationInitiated" - StorageBlobCreatedEventName = 'Microsoft.Storage.BlobCreated' + StorageBlobCreatedEventName = "Microsoft.Storage.BlobCreated" - StorageBlobDeletedEventName = 'Microsoft.Storage.BlobDeleted' + StorageBlobDeletedEventName = "Microsoft.Storage.BlobDeleted" - StorageBlobInventoryPolicyCompletedEventName = 'Microsoft.Storage.BlobInventoryPolicyCompleted' + StorageBlobInventoryPolicyCompletedEventName = "Microsoft.Storage.BlobInventoryPolicyCompleted" - StorageBlobRenamedEventName = 'Microsoft.Storage.BlobRenamed' + StorageBlobRenamedEventName = "Microsoft.Storage.BlobRenamed" - StorageBlobTierChangedEventName = 'Microsoft.Storage.BlobTierChanged' + StorageBlobTierChangedEventName = "Microsoft.Storage.BlobTierChanged" - StorageDirectoryCreatedEventName = 'Microsoft.Storage.DirectoryCreated' + StorageDirectoryCreatedEventName = "Microsoft.Storage.DirectoryCreated" - StorageDirectoryDeletedEventName = 'Microsoft.Storage.DirectoryDeleted' + StorageDirectoryDeletedEventName = "Microsoft.Storage.DirectoryDeleted" - StorageDirectoryRenamedEventName = 'Microsoft.Storage.DirectoryRenamed' + StorageDirectoryRenamedEventName = "Microsoft.Storage.DirectoryRenamed" - StorageLifecyclePolicyCompletedEventName = 'Microsoft.Storage.LifecyclePolicyCompleted' + StorageLifecyclePolicyCompletedEventName = "Microsoft.Storage.LifecyclePolicyCompleted" - StorageTaskAssignmentCompletedEventName = 'Microsoft.Storage.StorageTaskAssignmentCompleted' + StorageTaskAssignmentCompletedEventName = "Microsoft.Storage.StorageTaskAssignmentCompleted" - StorageTaskAssignmentQueuedEventName = 'Microsoft.Storage.StorageTaskAssignmentQueued' + StorageTaskAssignmentQueuedEventName = "Microsoft.Storage.StorageTaskAssignmentQueued" - StorageTaskCompletedEventName = 'Microsoft.Storage.StorageTaskCompleted' + StorageTaskCompletedEventName = "Microsoft.Storage.StorageTaskCompleted" - StorageTaskQueuedEventName = 'Microsoft.Storage.StorageTaskQueued' + StorageTaskQueuedEventName = "Microsoft.Storage.StorageTaskQueued" - SubscriptionDeletedEventName = 'Microsoft.EventGrid.SubscriptionDeletedEvent' + SubscriptionDeletedEventName = "Microsoft.EventGrid.SubscriptionDeletedEvent" - SubscriptionValidationEventName = 'Microsoft.EventGrid.SubscriptionValidationEvent' + SubscriptionValidationEventName = "Microsoft.EventGrid.SubscriptionValidationEvent" - WebAppServicePlanUpdatedEventName = 'Microsoft.Web.AppServicePlanUpdated' + WebAppServicePlanUpdatedEventName = "Microsoft.Web.AppServicePlanUpdated" - WebAppUpdatedEventName = 'Microsoft.Web.AppUpdated' + WebAppUpdatedEventName = "Microsoft.Web.AppUpdated" - WebBackupOperationCompletedEventName = 'Microsoft.Web.BackupOperationCompleted' + WebBackupOperationCompletedEventName = "Microsoft.Web.BackupOperationCompleted" - WebBackupOperationFailedEventName = 'Microsoft.Web.BackupOperationFailed' + WebBackupOperationFailedEventName = "Microsoft.Web.BackupOperationFailed" - WebBackupOperationStartedEventName = 'Microsoft.Web.BackupOperationStarted' + WebBackupOperationStartedEventName = "Microsoft.Web.BackupOperationStarted" - WebRestoreOperationCompletedEventName = 'Microsoft.Web.RestoreOperationCompleted' + WebRestoreOperationCompletedEventName = "Microsoft.Web.RestoreOperationCompleted" - WebRestoreOperationFailedEventName = 'Microsoft.Web.RestoreOperationFailed' + WebRestoreOperationFailedEventName = "Microsoft.Web.RestoreOperationFailed" - WebRestoreOperationStartedEventName = 'Microsoft.Web.RestoreOperationStarted' + WebRestoreOperationStartedEventName = "Microsoft.Web.RestoreOperationStarted" - WebSlotSwapCompletedEventName = 'Microsoft.Web.SlotSwapCompleted' + WebSlotSwapCompletedEventName = "Microsoft.Web.SlotSwapCompleted" - WebSlotSwapFailedEventName = 'Microsoft.Web.SlotSwapFailed' + WebSlotSwapFailedEventName = "Microsoft.Web.SlotSwapFailed" - WebSlotSwapStartedEventName = 'Microsoft.Web.SlotSwapStarted' + WebSlotSwapStartedEventName = "Microsoft.Web.SlotSwapStarted" - WebSlotSwapWithPreviewCancelledEventName = 'Microsoft.Web.SlotSwapWithPreviewCancelled' + WebSlotSwapWithPreviewCancelledEventName = "Microsoft.Web.SlotSwapWithPreviewCancelled" - WebSlotSwapWithPreviewStartedEventName = 'Microsoft.Web.SlotSwapWithPreviewStarted' + WebSlotSwapWithPreviewStartedEventName = "Microsoft.Web.SlotSwapWithPreviewStarted" - ContainerRegistryArtifactEventName = 'Microsoft.AppConfiguration.KeyValueModified' + ContainerRegistryArtifactEventName = "Microsoft.AppConfiguration.KeyValueModified" - KeyVaultAccessPolicyChangedEventName = 'Microsoft.KeyVault.VaultAccessPolicyChanged' + KeyVaultAccessPolicyChangedEventName = "Microsoft.KeyVault.VaultAccessPolicyChanged" - ContainerRegistryEventName = 'Microsoft.ContainerRegistry.ChartPushed' + ContainerRegistryEventName = "Microsoft.ContainerRegistry.ChartPushed" - ServiceBusDeadletterMessagesAvailableWithNoListenerEventName = 'Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners' + ServiceBusDeadletterMessagesAvailableWithNoListenerEventName = ( + "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners" + ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py index d1897c866468..f3ad2db7363a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_client.py @@ -28,18 +28,12 @@ class EventGridPublisherClient( :paramtype api_version: str """ - def __init__( - self, **kwargs: Any - ) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential _endpoint = "https://{topicHostname}" self._config = EventGridPublisherClientConfiguration(**kwargs) - self._client: PipelineClient = PipelineClient( - base_url=_endpoint, config=self._config, **kwargs - ) + self._client: PipelineClient = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) - client_models = { - k: v for k, v in _models.__dict__.items() if isinstance(v, type) - } + client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)} self._serialize = Serializer(client_models) self._deserialize = Deserializer(client_models) self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py index 5077ede3b176..d105970e51f9 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_configuration.py @@ -20,9 +20,7 @@ VERSION = "unknown" -class EventGridPublisherClientConfiguration( - Configuration -): # pylint: disable=too-many-instance-attributes +class EventGridPublisherClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance @@ -42,24 +40,12 @@ def __init__(self, **kwargs: Any) -> None: self._configure(**kwargs) def _configure(self, **kwargs: Any) -> None: - self.user_agent_policy = kwargs.get( - "user_agent_policy" - ) or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy( - **kwargs - ) + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get( - "logging_policy" - ) or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get( - "http_logging_policy" - ) or policies.HttpLoggingPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get( - "custom_hook_policy" - ) or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy( - **kwargs - ) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get("authentication_policy") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py index f1db47f93f7a..0ba43ddc6003 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_operations.py @@ -37,9 +37,7 @@ from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[ - Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any] -] +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] _SERIALIZER = Serializer() _SERIALIZER.client_side_validation = False @@ -49,12 +47,8 @@ def build_event_grid_publisher_publish_events_request(**kwargs: Any) -> HttpRequ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) - api_version: Literal["2018-01-01"] = kwargs.pop( - "api_version", _params.pop("api-version", "2018-01-01") - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) # Construct URL _url = "/api/events" @@ -63,13 +57,9 @@ def build_event_grid_publisher_publish_events_request(**kwargs: Any) -> HttpRequ # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header( - "content_type", content_type, "str" - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") - return HttpRequest( - method="POST", url=_url, params=_params, headers=_headers, **kwargs - ) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_publisher_publish_cloud_event_events_request( @@ -78,12 +68,8 @@ def build_event_grid_publisher_publish_cloud_event_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) - api_version: Literal["2018-01-01"] = kwargs.pop( - "api_version", _params.pop("api-version", "2018-01-01") - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) # Construct URL _url = "/api/events" @@ -92,13 +78,9 @@ def build_event_grid_publisher_publish_cloud_event_events_request( # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header( - "content_type", content_type, "str" - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") - return HttpRequest( - method="POST", url=_url, params=_params, headers=_headers, json=json, **kwargs - ) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, json=json, **kwargs) def build_event_grid_publisher_publish_custom_event_events_request( @@ -107,12 +89,8 @@ def build_event_grid_publisher_publish_custom_event_events_request( _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) - api_version: Literal["2018-01-01"] = kwargs.pop( - "api_version", _params.pop("api-version", "2018-01-01") - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["2018-01-01"] = kwargs.pop("api_version", _params.pop("api-version", "2018-01-01")) # Construct URL _url = "/api/events" @@ -121,13 +99,9 @@ def build_event_grid_publisher_publish_custom_event_events_request( # Construct headers if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header( - "content_type", content_type, "str" - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") - return HttpRequest( - method="POST", url=_url, params=_params, headers=_headers, **kwargs - ) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @@ -212,9 +186,7 @@ def publish_events( # pylint: disable=inconsistent-return-statements _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -234,25 +206,19 @@ def publish_events( # pylint: disable=inconsistent-return-statements params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = ( - self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs - ) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: @@ -286,9 +252,7 @@ def publish_cloud_event_events( # pylint: disable=inconsistent-return-statement content_type: str = kwargs.pop( "content_type", - _headers.pop( - "Content-Type", "application/cloudevents-batch+json; charset=utf-8" - ), + _headers.pop("Content-Type", "application/cloudevents-batch+json; charset=utf-8"), ) cls: ClsType[None] = kwargs.pop("cls", None) @@ -302,25 +266,19 @@ def publish_cloud_event_events( # pylint: disable=inconsistent-return-statement params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = ( - self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs - ) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: @@ -404,9 +362,7 @@ def publish_custom_event_events( # pylint: disable=inconsistent-return-statemen _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -426,25 +382,19 @@ def publish_custom_event_events( # pylint: disable=inconsistent-return-statemen params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) _stream = False - pipeline_response: PipelineResponse = ( - self._client._pipeline.run( # pylint: disable=protected-access - request, stream=_stream, **kwargs - ) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py index d400d2d124e2..f7dd32510333 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_operations/_patch.py @@ -8,9 +8,7 @@ """ from typing import List -__all__: List[ - str -] = [] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py index d400d2d124e2..f7dd32510333 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_patch.py @@ -8,9 +8,7 @@ """ from typing import List -__all__: List[ - str -] = [] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py index 615a169a649a..1e7a11b1d256 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/_serialization.py @@ -84,9 +84,7 @@ class RawDeserializer: CONTEXT_NAME = "deserialized_data" @classmethod - def deserialize_from_text( - cls, data: Optional[Union[AnyStr, IO]], content_type: Optional[str] = None - ) -> Any: + def deserialize_from_text(cls, data: Optional[Union[AnyStr, IO]], content_type: Optional[str] = None) -> Any: """Decode data according to content-type. Accept a stream of data as well, but will be load at once in memory for now. @@ -148,14 +146,10 @@ def _json_attemp(data): # context otherwise. _LOGGER.critical("Wasn't XML not JSON, failing") raise_with_traceback(DeserializationError, "XML is invalid") - raise DeserializationError( - "Cannot deserialize content-type: {}".format(content_type) - ) + raise DeserializationError("Cannot deserialize content-type: {}".format(content_type)) @classmethod - def deserialize_from_http_generics( - cls, body_bytes: Optional[Union[AnyStr, IO]], headers: Mapping - ) -> Any: + def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], headers: Mapping) -> Any: """Deserialize from HTTP response. Use bytes and headers to NOT use any requests/aiohttp or whatever @@ -376,9 +370,7 @@ def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: def as_dict( self, keep_readonly: bool = True, - key_transformer: Callable[ - [str, Dict[str, Any], Any], Any - ] = attribute_transformer, + key_transformer: Callable[[str, Dict[str, Any], Any], Any] = attribute_transformer, **kwargs: Any ) -> JSON: """Return a dict that can be serialized using json.dump. @@ -412,18 +404,14 @@ def my_key_transformer(key, attr_desc, value): :rtype: dict """ serializer = Serializer(self._infer_class_models()) - return serializer._serialize( - self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs - ) + return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) @classmethod def _infer_class_models(cls): try: str_models = cls.__module__.rsplit(".", 1)[0] models = sys.modules[str_models] - client_models = { - k: v for k, v in models.__dict__.items() if isinstance(v, type) - } + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} if cls.__name__ not in client_models: raise ValueError("Not Autorest generated code") except Exception: @@ -432,9 +420,7 @@ def _infer_class_models(cls): return client_models @classmethod - def deserialize( - cls: Type[ModelType], data: Any, content_type: Optional[str] = None - ) -> ModelType: + def deserialize(cls: Type[ModelType], data: Any, content_type: Optional[str] = None) -> ModelType: """Parse a str using the RestAPI syntax and return a model. :param str data: A str using RestAPI structure. JSON by default. @@ -495,13 +481,9 @@ def _classify(cls, response, objects): if not isinstance(response, ET.Element): rest_api_response_key = cls._get_rest_key_parts(subtype_key)[-1] - subtype_value = response.pop( - rest_api_response_key, None - ) or response.pop(subtype_key, None) + subtype_value = response.pop(rest_api_response_key, None) or response.pop(subtype_key, None) else: - subtype_value = xml_key_extractor( - subtype_key, cls._attribute_map[subtype_key], response - ) + subtype_value = xml_key_extractor(subtype_key, cls._attribute_map[subtype_key], response) if subtype_value: # Try to match base class. Can be class name only # (bug to fix in Autorest to support x-ms-discriminator-name) @@ -629,9 +611,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): try: is_xml_model_serialization = kwargs["is_xml"] except KeyError: - is_xml_model_serialization = kwargs.setdefault( - "is_xml", target_obj.is_xml_model() - ) + is_xml_model_serialization = kwargs.setdefault("is_xml", target_obj.is_xml_model()) serialized = {} if is_xml_model_serialization: @@ -640,9 +620,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): attributes = target_obj._attribute_map for attr, attr_desc in attributes.items(): attr_name = attr - if not keep_readonly and target_obj._validation.get(attr_name, {}).get( - "readonly", False - ): + if not keep_readonly and target_obj._validation.get(attr_name, {}).get("readonly", False): continue if attr_name == "additional_properties" and attr_desc["key"] == "": @@ -654,15 +632,11 @@ def _serialize(self, target_obj, data_type=None, **kwargs): if is_xml_model_serialization: pass # Don't provide "transformer" for XML for now. Keep "orig_attr" else: # JSON - keys, orig_attr = key_transformer( - attr, attr_desc.copy(), orig_attr - ) + keys, orig_attr = key_transformer(attr, attr_desc.copy(), orig_attr) keys = keys if isinstance(keys, list) else [keys] kwargs["serialization_ctxt"] = attr_desc - new_attr = self.serialize_data( - orig_attr, attr_desc["type"], **kwargs - ) + new_attr = self.serialize_data(orig_attr, attr_desc["type"], **kwargs) if is_xml_model_serialization: xml_desc = attr_desc.get("xml", {}) @@ -709,9 +683,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): continue except (AttributeError, KeyError, TypeError) as err: - msg = "Attribute {} in object {} cannot be serialized.\n{}".format( - attr_name, class_name, str(target_obj) - ) + msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj)) raise_with_traceback(SerializationError, msg, err) else: return serialized @@ -733,9 +705,7 @@ def body(self, data, data_type, **kwargs): is_xml_model_serialization = kwargs["is_xml"] except KeyError: if internal_data_type and issubclass(internal_data_type, Model): - is_xml_model_serialization = kwargs.setdefault( - "is_xml", internal_data_type.is_xml_model() - ) + is_xml_model_serialization = kwargs.setdefault("is_xml", internal_data_type.is_xml_model()) else: is_xml_model_serialization = False if internal_data_type and not isinstance(internal_data_type, Enum): @@ -756,9 +726,7 @@ def body(self, data, data_type, **kwargs): ] data = deserializer._deserialize(data_type, data) except DeserializationError as err: - raise_with_traceback( - SerializationError, "Unable to build a model: " + str(err), err - ) + raise_with_traceback(SerializationError, "Unable to build a model: " + str(err), err) return self._serialize(data, data_type, **kwargs) @@ -798,12 +766,7 @@ def query(self, name, data, data_type, **kwargs): # Treat the list aside, since we don't want to encode the div separator if data_type.startswith("["): internal_data_type = data_type[1:-1] - data = [ - self.serialize_data(d, internal_data_type, **kwargs) - if d is not None - else "" - for d in data - ] + data = [self.serialize_data(d, internal_data_type, **kwargs) if d is not None else "" for d in data] if not kwargs.get("skip_quote", False): data = [quote(str(d), safe="") for d in data] return str(self.serialize_iter(data, internal_data_type, **kwargs)) @@ -975,9 +938,7 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): is_wrapped = xml_desc.get("wrapped", False) node_name = xml_desc.get("itemsName", xml_name) if is_wrapped: - final_result = _create_xml_node( - xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None) - ) + final_result = _create_xml_node(xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None)) else: final_result = [] # All list elements to "local_node" @@ -1009,9 +970,7 @@ def serialize_dict(self, attr, dict_type, **kwargs): serialized = {} for key, value in attr.items(): try: - serialized[self.serialize_unicode(key)] = self.serialize_data( - value, dict_type, **kwargs - ) + serialized[self.serialize_unicode(key)] = self.serialize_data(value, dict_type, **kwargs) except ValueError: serialized[self.serialize_unicode(key)] = None @@ -1020,9 +979,7 @@ def serialize_dict(self, attr, dict_type, **kwargs): xml_desc = serialization_ctxt["xml"] xml_name = xml_desc["name"] - final_result = _create_xml_node( - xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None) - ) + final_result = _create_xml_node(xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None)) for key, value in serialized.items(): ET.SubElement(final_result, key).text = value return final_result @@ -1068,9 +1025,7 @@ def serialize_object(self, attr, **kwargs): serialized = {} for key, value in attr.items(): try: - serialized[self.serialize_unicode(key)] = self.serialize_object( - value, **kwargs - ) + serialized[self.serialize_unicode(key)] = self.serialize_object(value, **kwargs) except ValueError: serialized[self.serialize_unicode(key)] = None return serialized @@ -1287,9 +1242,7 @@ def rest_key_case_insensitive_extractor(attr, attr_desc, data): key = _decode_attribute_map_key(dict_keys[0]) break working_key = _decode_attribute_map_key(dict_keys[0]) - working_data = attribute_key_case_insensitive_extractor( - working_key, None, working_data - ) + working_data = attribute_key_case_insensitive_extractor(working_key, None, working_data) if working_data is None: # If at any point while following flatten JSON path see None, it means # that all properties under are None as well @@ -1382,10 +1335,7 @@ def xml_key_extractor(attr, attr_desc, data): # - Wrapped node # - Internal type is an enum (considered basic types) # - Internal type has no XML/Name node - if is_wrapped or ( - internal_type - and (issubclass(internal_type, Enum) or "name" not in internal_type_xml_map) - ): + if is_wrapped or (internal_type and (issubclass(internal_type, Enum) or "name" not in internal_type_xml_map)): children = data.findall(xml_name) # If internal type has a local name and it's not a list, I use that name elif not is_iter_type and internal_type and "name" in internal_type_xml_map: @@ -1393,9 +1343,7 @@ def xml_key_extractor(attr, attr_desc, data): children = data.findall(xml_name) # That's an array else: - if ( - internal_type - ): # Complex type, ignore itemsName and use the complex type name + if internal_type: # Complex type, ignore itemsName and use the complex type name items_name = _extract_name_from_internal_type(internal_type) else: items_name = xml_desc.get("itemsName", xml_name) @@ -1424,9 +1372,7 @@ def xml_key_extractor(attr, attr_desc, data): # Here it's not a itertype, we should have found one element only or empty if len(children) > 1: - raise DeserializationError( - "Find several XML '{}' where it was not expected".format(xml_name) - ) + raise DeserializationError("Find several XML '{}' where it was not expected".format(xml_name)) return children[0] @@ -1439,9 +1385,7 @@ class Deserializer(object): basic_types = {str: "str", int: "int", bool: "bool", float: "float"} - valid_date = re.compile( - r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?" - ) + valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): self.deserialize_type = { @@ -1497,11 +1441,7 @@ def _deserialize(self, target_obj, data): """ # This is already a model, go recursive just in case if hasattr(data, "_attribute_map"): - constants = [ - name - for name, config in getattr(data, "_validation", {}).items() - if config.get("constant") - ] + constants = [name for name, config in getattr(data, "_validation", {}).items() if config.get("constant")] try: for attr, mapconfig in data._attribute_map.items(): if attr in constants: @@ -1511,9 +1451,7 @@ def _deserialize(self, target_obj, data): continue local_type = mapconfig["type"] internal_data_type = local_type.strip("[]{}") - if internal_data_type not in self.dependencies or isinstance( - internal_data_type, Enum - ): + if internal_data_type not in self.dependencies or isinstance(internal_data_type, Enum): continue setattr(data, attr, self._deserialize(local_type, value)) return data @@ -1567,10 +1505,7 @@ def _deserialize(self, target_obj, data): def _build_additional_properties(self, attribute_map, data): if not self.additional_properties_detection: return None - if ( - "additional_properties" in attribute_map - and attribute_map.get("additional_properties", {}).get("key") != "" - ): + if "additional_properties" in attribute_map and attribute_map.get("additional_properties", {}).get("key") != "": # Check empty string. If it's not empty, someone has a real "additionalProperties" return None if isinstance(data, ET.Element): @@ -1650,21 +1585,15 @@ def _unpack_content(raw_data, content_type=None): if context: if RawDeserializer.CONTEXT_NAME in context: return context[RawDeserializer.CONTEXT_NAME] - raise ValueError( - "This pipeline didn't have the RawDeserializer policy; can't deserialize" - ) + raise ValueError("This pipeline didn't have the RawDeserializer policy; can't deserialize") # Assume this is enough to recognize universal_http.ClientResponse without importing it if hasattr(raw_data, "body"): - return RawDeserializer.deserialize_from_http_generics( - raw_data.text(), raw_data.headers - ) + return RawDeserializer.deserialize_from_http_generics(raw_data.text(), raw_data.headers) # Assume this enough to recognize requests.Response without importing it. if hasattr(raw_data, "_content_consumed"): - return RawDeserializer.deserialize_from_http_generics( - raw_data.text, raw_data.headers - ) + return RawDeserializer.deserialize_from_http_generics(raw_data.text, raw_data.headers) if isinstance(raw_data, (basestring, bytes)) or hasattr(raw_data, "read"): return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore @@ -1679,17 +1608,9 @@ def _instantiate_model(self, response, attrs, additional_properties=None): if callable(response): subtype = getattr(response, "_subtype_map", {}) try: - readonly = [ - k for k, v in response._validation.items() if v.get("readonly") - ] - const = [ - k for k, v in response._validation.items() if v.get("constant") - ] - kwargs = { - k: v - for k, v in attrs.items() - if k not in subtype and k not in readonly + const - } + readonly = [k for k, v in response._validation.items() if v.get("readonly")] + const = [k for k, v in response._validation.items() if v.get("constant")] + kwargs = {k: v for k, v in attrs.items() if k not in subtype and k not in readonly + const} response_obj = response(**kwargs) for attr in readonly: setattr(response_obj, attr, attrs.get(attr)) @@ -1726,17 +1647,11 @@ def deserialize_data(self, data, data_type): if data_type in self.basic_types.values(): return self.deserialize_basic(data, data_type) if data_type in self.deserialize_type: - if isinstance( - data, self.deserialize_expected_types.get(data_type, tuple()) - ): + if isinstance(data, self.deserialize_expected_types.get(data_type, tuple())): return data is_a_text_parsing_type = lambda x: x not in ["object", "[]", r"{}"] - if ( - isinstance(data, ET.Element) - and is_a_text_parsing_type(data_type) - and not data.text - ): + if isinstance(data, ET.Element) and is_a_text_parsing_type(data_type) and not data.text: return None data_val = self.deserialize_type[data_type](data) return data_val @@ -1767,16 +1682,10 @@ def deserialize_iter(self, attr, iter_type): """ if attr is None: return None - if isinstance( - attr, ET.Element - ): # If I receive an element here, get the children + if isinstance(attr, ET.Element): # If I receive an element here, get the children attr = list(attr) if not isinstance(attr, (list, set)): - raise DeserializationError( - "Cannot deserialize as [{}] an object of type {}".format( - iter_type, type(attr) - ) - ) + raise DeserializationError("Cannot deserialize as [{}] an object of type {}".format(iter_type, type(attr))) return [self.deserialize_data(a, iter_type) for a in attr] def deserialize_dict(self, attr, dict_type): @@ -1788,9 +1697,7 @@ def deserialize_dict(self, attr, dict_type): :rtype: dict """ if isinstance(attr, list): - return { - x["key"]: self.deserialize_data(x["value"], dict_type) for x in attr - } + return {x["key"]: self.deserialize_data(x["value"], dict_type) for x in attr} if isinstance(attr, ET.Element): # Transform value into {"Key": "value"} @@ -2022,9 +1929,7 @@ def deserialize_date(attr): if isinstance(attr, ET.Element): attr = attr.text if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore - raise DeserializationError( - "Date must have only digits and -. Received: %s" % attr - ) + raise DeserializationError("Date must have only digits and -. Received: %s" % attr) # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. return isodate.parse_date(attr, defaultmonth=None, defaultday=None) @@ -2039,9 +1944,7 @@ def deserialize_time(attr): if isinstance(attr, ET.Element): attr = attr.text if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore - raise DeserializationError( - "Date must have only digits and -. Received: %s" % attr - ) + raise DeserializationError("Date must have only digits and -. Received: %s" % attr) return isodate.parse_time(attr) @staticmethod @@ -2057,10 +1960,7 @@ def deserialize_rfc(attr): try: parsed_date = email.utils.parsedate_tz(attr) # type: ignore date_obj = datetime.datetime( - *parsed_date[:6], - tzinfo=_FixedOffset( - datetime.timedelta(minutes=(parsed_date[9] or 0) / 60) - ) + *parsed_date[:6], tzinfo=_FixedOffset(datetime.timedelta(minutes=(parsed_date[9] or 0) / 60)) ) if not date_obj.tzinfo: date_obj = date_obj.astimezone(tz=TZ_UTC) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py index b094add0dc06..f81ce4181ad6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_client.py @@ -28,25 +28,17 @@ class EventGridPublisherClient( :paramtype api_version: str """ - def __init__( - self, **kwargs: Any - ) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential _endpoint = "https://{topicHostname}" self._config = EventGridPublisherClientConfiguration(**kwargs) - self._client: AsyncPipelineClient = AsyncPipelineClient( - base_url=_endpoint, config=self._config, **kwargs - ) + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) - client_models = { - k: v for k, v in _models.__dict__.items() if isinstance(v, type) - } + client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)} self._serialize = Serializer(client_models) self._deserialize = Deserializer(client_models) self._serialize.client_side_validation = False - def send_request( - self, request: HttpRequest, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: + def send_request(self, request: HttpRequest, **kwargs: Any) -> Awaitable[AsyncHttpResponse]: """Runs the network request through the client's chained policies. >>> from azure.core.rest import HttpRequest diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py index 06deaef1eb5c..52c2f3551ad7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_configuration.py @@ -20,9 +20,7 @@ VERSION = "unknown" -class EventGridPublisherClientConfiguration( - Configuration -): # pylint: disable=too-many-instance-attributes +class EventGridPublisherClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance @@ -42,26 +40,12 @@ def __init__(self, **kwargs: Any) -> None: self._configure(**kwargs) def _configure(self, **kwargs: Any) -> None: - self.user_agent_policy = kwargs.get( - "user_agent_policy" - ) or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy( - **kwargs - ) + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get( - "logging_policy" - ) or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get( - "http_logging_policy" - ) or policies.HttpLoggingPolicy(**kwargs) - self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy( - **kwargs - ) - self.custom_hook_policy = kwargs.get( - "custom_hook_policy" - ) or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get( - "redirect_policy" - ) or policies.AsyncRedirectPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get("authentication_policy") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py index fe65e0c6cf06..ba6dc3ff67e5 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_operations.py @@ -37,9 +37,7 @@ from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[ - Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any] -] +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @@ -69,12 +67,7 @@ async def publish_events( # pylint: disable=inconsistent-return-statements @overload async def publish_events( # pylint: disable=inconsistent-return-statements - self, - topic_hostname: str, - events: IO, - *, - content_type: str = "application/json", - **kwargs: Any + self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -93,10 +86,7 @@ async def publish_events( # pylint: disable=inconsistent-return-statements @distributed_trace_async async def publish_events( # pylint: disable=inconsistent-return-statements - self, - topic_hostname: str, - events: Union[List[_models.EventGridEvent], IO], - **kwargs: Any + self, topic_hostname: str, events: Union[List[_models.EventGridEvent], IO], **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -124,9 +114,7 @@ async def publish_events( # pylint: disable=inconsistent-return-statements _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -146,9 +134,7 @@ async def publish_events( # pylint: disable=inconsistent-return-statements params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -160,9 +146,7 @@ async def publish_events( # pylint: disable=inconsistent-return-statements response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: @@ -196,9 +180,7 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta content_type: str = kwargs.pop( "content_type", - _headers.pop( - "Content-Type", "application/cloudevents-batch+json; charset=utf-8" - ), + _headers.pop("Content-Type", "application/cloudevents-batch+json; charset=utf-8"), ) cls: ClsType[None] = kwargs.pop("cls", None) @@ -212,9 +194,7 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -226,9 +206,7 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: @@ -236,12 +214,7 @@ async def publish_cloud_event_events( # pylint: disable=inconsistent-return-sta @overload async def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, - topic_hostname: str, - events: List[JSON], - *, - content_type: str = "application/json", - **kwargs: Any + self, topic_hostname: str, events: List[JSON], *, content_type: str = "application/json", **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -260,12 +233,7 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st @overload async def publish_custom_event_events( # pylint: disable=inconsistent-return-statements - self, - topic_hostname: str, - events: IO, - *, - content_type: str = "application/json", - **kwargs: Any + self, topic_hostname: str, events: IO, *, content_type: str = "application/json", **kwargs: Any ) -> None: """Publishes a batch of events to an Azure Event Grid topic. @@ -312,9 +280,7 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop( - "content_type", _headers.pop("Content-Type", None) - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[None] = kwargs.pop("cls", None) content_type = content_type or "application/json" @@ -334,9 +300,7 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st params=_params, ) path_format_arguments = { - "topicHostname": self._serialize.url( - "topic_hostname", topic_hostname, "str", skip_quote=True - ), + "topicHostname": self._serialize.url("topic_hostname", topic_hostname, "str", skip_quote=True), } request.url = self._client.format_url(request.url, **path_format_arguments) @@ -348,9 +312,7 @@ async def publish_custom_event_events( # pylint: disable=inconsistent-return-st response = pipeline_response.http_response if response.status_code not in [200]: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if cls: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py index d400d2d124e2..f7dd32510333 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_operations/_patch.py @@ -8,9 +8,7 @@ """ from typing import List -__all__: List[ - str -] = [] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py index d400d2d124e2..f7dd32510333 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/aio/_patch.py @@ -8,9 +8,7 @@ """ from typing import List -__all__: List[ - str -] = [] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py index 5b7573872822..1308cb0f76e1 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_models.py @@ -291,9 +291,7 @@ class SubscriptionValidationResponse(_serialization.Model): "validation_response": {"key": "validationResponse", "type": "str"}, } - def __init__( - self, *, validation_response: Optional[str] = None, **kwargs: Any - ) -> None: + def __init__(self, *, validation_response: Optional[str] = None, **kwargs: Any) -> None: """ :keyword validation_response: The validation response sent by the subscriber to Azure Event Grid to complete the validation of an event subscription. diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py index d400d2d124e2..f7dd32510333 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_generated/models/_patch.py @@ -8,9 +8,7 @@ """ from typing import List -__all__: List[ - str -] = [] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py index 0e7f08461e26..d28317777391 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py @@ -27,6 +27,7 @@ if TYPE_CHECKING: from datetime import datetime + def generate_sas( endpoint: str, shared_access_key: str, @@ -55,16 +56,12 @@ def generate_sas( :caption: Generate a shared access signature. """ - full_endpoint = "{}?apiVersion={}".format( - endpoint, api_version - ) + full_endpoint = "{}?apiVersion={}".format(endpoint, api_version) encoded_resource = quote(full_endpoint, safe=constants.SAFE_ENCODE) encoded_expiration_utc = quote(str(expiration_date_utc), safe=constants.SAFE_ENCODE) unsigned_sas = "r={}&e={}".format(encoded_resource, encoded_expiration_utc) - signature = quote( - _generate_hmac(shared_access_key, unsigned_sas), safe=constants.SAFE_ENCODE - ) + signature = quote(_generate_hmac(shared_access_key, unsigned_sas), safe=constants.SAFE_ENCODE) signed_sas = "{}&s={}".format(unsigned_sas, signature) return signed_sas @@ -77,21 +74,15 @@ def _generate_hmac(key, message): return base64.b64encode(hmac_new) -def _get_authentication_policy( - credential, bearer_token_policy=BearerTokenCredentialPolicy -): +def _get_authentication_policy(credential, bearer_token_policy=BearerTokenCredentialPolicy): if credential is None: raise ValueError("Parameter 'self._credential' must not be None.") if hasattr(credential, "get_token"): return bearer_token_policy(credential, constants.DEFAULT_EVENTGRID_SCOPE) if isinstance(credential, AzureKeyCredential): - return AzureKeyCredentialPolicy( - credential=credential, name=constants.EVENTGRID_KEY_HEADER - ) + return AzureKeyCredentialPolicy(credential=credential, name=constants.EVENTGRID_KEY_HEADER) if isinstance(credential, AzureSasCredential): - return EventGridSasCredentialPolicy( - credential=credential, name=constants.EVENTGRID_TOKEN_HEADER - ) + return EventGridSasCredentialPolicy(credential=credential, name=constants.EVENTGRID_TOKEN_HEADER) raise ValueError( "The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential" ) @@ -147,10 +138,11 @@ def _cloud_event_to_generated(cloud_event, **kwargs): datacontenttype=cloud_event.datacontenttype, subject=cloud_event.subject, additional_properties=cloud_event.extensions, - **kwargs + **kwargs, ) -def _from_cncf_events(event): # pylint: disable=inconsistent-return-statements + +def _from_cncf_events(event): # pylint: disable=inconsistent-return-statements """This takes in a CNCF cloudevent and returns a dictionary. If cloud events library is not installed, the event is returned back. @@ -175,13 +167,13 @@ def _from_cncf_events(event): # pylint: disable=inconsistent-return-statements def _build_request(endpoint, content_type, events, *, channel_name=None, api_version=constants.DEFAULT_API_VERSION): serialize = Serializer() header_parameters: Dict[str, Any] = {} - header_parameters['Content-Type'] = serialize.header("content_type", content_type, 'str') + header_parameters["Content-Type"] = serialize.header("content_type", content_type, "str") if channel_name: header_parameters["aeg-channel-name"] = channel_name query_parameters: Dict[str, Any] = {} - query_parameters['api-version'] = serialize.query("api_version", api_version, 'str') + query_parameters["api-version"] = serialize.query("api_version", api_version, "str") body = serialize.body(events, "[object]") if body is None: @@ -190,8 +182,6 @@ def _build_request(endpoint, content_type, events, *, channel_name=None, api_ver data = json.dumps(body) header_parameters["Content-Length"] = str(len(data)) - request = HttpRequest( - method="POST", url=endpoint, headers=header_parameters, data=data - ) + request = HttpRequest(method="POST", url=endpoint, headers=header_parameters, data=data) request.format_parameters(query_parameters) return request diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py index c37971d694ff..107ebc6d670d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_messaging_shared.py @@ -13,7 +13,8 @@ import json -def _get_json_content(obj): # pylint: disable=inconsistent-return-statements + +def _get_json_content(obj): # pylint: disable=inconsistent-return-statements """Event mixin to have methods that are common to different Event types like CloudEvent, EventGridEvent etc. @@ -38,7 +39,7 @@ def _get_json_content(obj): # pylint: disable=inconsistent-return-statements return json.loads(next(obj.body)) except ValueError as err: raise ValueError(msg) from err - except: # pylint: disable=bare-except + except: # pylint: disable=bare-except try: return json.loads(obj) except ValueError as err: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py index 6feda49c6f36..d4f2dcfd5638 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_policies.py @@ -36,8 +36,7 @@ def on_request(self, request): return if ( - request.http_request.headers["content-type"] - == CloudEventDistributedTracingPolicy._CONTENT_TYPE + request.http_request.headers["content-type"] == CloudEventDistributedTracingPolicy._CONTENT_TYPE and traceparent is not None ): body = json.loads(request.http_request.body) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py index 409644f893dc..75d3c8227055 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py @@ -71,9 +71,7 @@ ListEventType = Union[List[CloudEvent], List[EventGridEvent], List[Dict]] -class EventGridPublisherClient( - object -): # pylint: disable=client-accepts-api-version-keyword +class EventGridPublisherClient(object): # pylint: disable=client-accepts-api-version-keyword """EventGridPublisherClient publishes events to an EventGrid topic or domain. It can be used to publish either an EventGridEvent, a CloudEvent or a Custom Schema. @@ -105,13 +103,13 @@ class EventGridPublisherClient( """ def __init__( - self, - endpoint: str, - credential: Union["AzureKeyCredential", "AzureSasCredential", "TokenCredential"], - *, - api_version: Optional[str] = None, - **kwargs: Any - ) -> None: + self, + endpoint: str, + credential: Union["AzureKeyCredential", "AzureSasCredential", "TokenCredential"], + *, + api_version: Optional[str] = None, + **kwargs: Any + ) -> None: self._endpoint = endpoint self._client = EventGridPublisherClientImpl( policies=EventGridPublisherClient._policies(credential, **kwargs), **kwargs @@ -141,9 +139,7 @@ def _policies(credential, **kwargs): return policies @distributed_trace - def send( - self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any - ) -> None: + def send(self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any) -> None: """Sends events to a topic or a domain specified during the client initialization. A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. @@ -216,9 +212,7 @@ def send( content_type = kwargs.pop("content_type", "application/json; charset=utf-8") if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: - events = [ - _cloud_event_to_generated(e, **kwargs) for e in events - ] # pylint: disable=protected-access + events = [_cloud_event_to_generated(e, **kwargs) for e in events] # pylint: disable=protected-access except AttributeError: ## this is either a dictionary or a CNCF cloud event events = [_from_cncf_events(e) for e in events] @@ -228,8 +222,9 @@ def send( _eventgrid_data_typecheck(event) response = self._client.send_request( # pylint: disable=protected-access _build_request( - self._endpoint,content_type, events, channel_name=channel_name, api_version=self._api_version), - **kwargs + self._endpoint, content_type, events, channel_name=channel_name, api_version=self._api_version + ), + **kwargs ) error_map = { 401: ClientAuthenticationError, @@ -237,9 +232,7 @@ def send( 409: ResourceExistsError, } if response.status_code != 200: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) def close(self): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py index 692451987fd7..ed70d6cdd6ad 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py @@ -99,9 +99,7 @@ class EventGridPublisherClient: # pylint: disable=client-accepts-api-version-ke def __init__( self, endpoint: str, - credential: Union[ - "AsyncTokenCredential", AzureKeyCredential, AzureSasCredential - ], + credential: Union["AsyncTokenCredential", AzureKeyCredential, AzureSasCredential], *, api_version: Optional[str] = None, **kwargs: Any @@ -114,14 +112,9 @@ def __init__( @staticmethod def _policies( - credential: Union[ - AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential" - ], - **kwargs: Any + credential: Union[AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential"], **kwargs: Any ) -> List[Any]: - auth_policy = _get_authentication_policy( - credential, AsyncBearerTokenCredentialPolicy - ) + auth_policy = _get_authentication_policy(credential, AsyncBearerTokenCredentialPolicy) sdk_moniker = "eventgridpublisherclient/{}".format(VERSION) policies = [ RequestIdPolicy(**kwargs), @@ -141,9 +134,7 @@ def _policies( return policies @distributed_trace_async - async def send( - self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any - ) -> None: + async def send(self, events: SendType, *, channel_name: Optional[str] = None, **kwargs: Any) -> None: """Sends events to a topic or a domain specified during the client initialization. A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. @@ -216,9 +207,7 @@ async def send( content_type = kwargs.pop("content_type", "application/json; charset=utf-8") if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: - events = [ - _cloud_event_to_generated(e, **kwargs) for e in events - ] # pylint: disable=protected-access + events = [_cloud_event_to_generated(e, **kwargs) for e in events] # pylint: disable=protected-access except AttributeError: ## this is either a dictionary or a CNCF cloud event events = [_from_cncf_events(e) for e in events] @@ -227,8 +216,9 @@ async def send( for event in events: _eventgrid_data_typecheck(event) response = await self._client.send_request( # pylint: disable=protected-access - _build_request(self._endpoint, content_type, events, - channel_name=channel_name, api_version=self._api_version), + _build_request( + self._endpoint, content_type, events, channel_name=channel_name, api_version=self._api_version + ), **kwargs ) error_map = { @@ -237,9 +227,7 @@ async def send( 409: ResourceExistsError, } if response.status_code != 200: - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) + map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) async def __aenter__(self) -> "EventGridPublisherClient": diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py index f10ebfb873b4..4b0f59f73e4c 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -13,7 +13,6 @@ import logging import base64 import re -import copy import typing import enum import email.utils @@ -324,17 +323,9 @@ def _get_type_alias_type(module_name: str, alias_name: str): def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update({ - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) - }) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -347,7 +338,7 @@ def _get_model(module_name: str, model_name: str): class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object def __init__(self, data: typing.Dict[str, typing.Any]) -> None: - self._data = copy.deepcopy(data) + self._data = data def __contains__(self, key: typing.Any) -> bool: return key in self._data @@ -386,16 +377,13 @@ def get(self, key: str, default: typing.Any = None) -> typing.Any: return default @typing.overload - def pop(self, key: str) -> typing.Any: - ... + def pop(self, key: str) -> typing.Any: ... @typing.overload - def pop(self, key: str, default: _T) -> _T: - ... + def pop(self, key: str, default: _T) -> _T: ... @typing.overload - def pop(self, key: str, default: typing.Any) -> typing.Any: - ... + def pop(self, key: str, default: typing.Any) -> typing.Any: ... def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: if default is _UNSET: @@ -412,12 +400,10 @@ def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: self._data.update(*args, **kwargs) @typing.overload - def setdefault(self, key: str, default: None = None) -> None: - ... + def setdefault(self, key: str, default: None = None) -> None: ... @typing.overload - def setdefault(self, key: str, default: typing.Any) -> typing.Any: - ... + def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: if default is _UNSET: @@ -550,7 +536,9 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: @classmethod def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @@ -560,9 +548,7 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) discriminator = cls._get_discriminator(exist_discriminators) exist_discriminators.append(discriminator) - mapped_cls = cls.__mapping__.get( - data.get(discriminator), cls - ) # pyright: ignore # pylint: disable=no-member + mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pyright: ignore # pylint: disable=no-member if mapped_cls == cls: return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access @@ -583,7 +569,9 @@ def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing. continue is_multipart_file_input = False try: - is_multipart_file_input = next(rf for rf in self._attr_to_rest_field.values() if rf._rest_name == k)._is_multipart_file_input + is_multipart_file_input = next( + rf for rf in self._attr_to_rest_field.values() if rf._rest_name == k + )._is_multipart_file_input except StopIteration: pass result[k] = v if is_multipart_file_input else Model._as_dict_value(v, exclude_readonly=exclude_readonly) @@ -594,18 +582,63 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return type(v)( - Model._as_dict_value(x, exclude_readonly=exclude_readonly) - for x in v - ) + return type(v)(Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v) if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) - for dk, dv in v.items() - } + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v +def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): + if _is_model(obj): + return obj + return _deserialize(model_deserializer, obj) + + +def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): + if obj is None: + return obj + return _deserialize_with_callable(if_obj_deserializer, obj) + + +def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + +def _deserialize_dict( + value_deserializer: typing.Optional[typing.Callable], + module: typing.Optional[str], + obj: typing.Dict[typing.Any, typing.Any], +): + if obj is None: + return obj + return {k: _deserialize(value_deserializer, v, module) for k, v in obj.items()} + + +def _deserialize_multiple_sequence( + entry_deserializers: typing.List[typing.Optional[typing.Callable]], + module: typing.Optional[str], + obj, +): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers)) + + +def _deserialize_sequence( + deserializer: typing.Optional[typing.Callable], + module: typing.Optional[str], + obj, +): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + + def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], @@ -633,11 +666,6 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, if rf: rf._is_model = True - def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): - if _is_model(obj): - return obj - return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, annotation) # pyright: ignore except Exception: pass @@ -656,11 +684,6 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore ) - def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): - if obj is None: - return obj - return _deserialize_with_callable(if_obj_deserializer, obj) - return functools.partial(_deserialize_with_optional, if_obj_deserializer) except AttributeError: pass @@ -670,18 +693,10 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla deserializers = [ _get_deserialize_callable_from_annotation(arg, module, rf) for arg in sorted( - annotation.__args__, key=lambda x: hasattr(x, "__name__") and x.__name__ == "str" # pyright: ignore - ) + annotation.__args__, key=lambda x: hasattr(x, "__name__") and x.__name__ == "str" # pyright: ignore + ) ] - def _deserialize_with_union(deserializers, obj): - for deserializer in deserializers: - try: - return _deserialize(deserializer, obj) - except DeserializationError: - pass - raise DeserializationError() - return functools.partial(_deserialize_with_union, deserializers) try: @@ -690,20 +705,10 @@ def _deserialize_with_union(deserializers, obj): annotation.__args__[1], module, rf # pyright: ignore ) - def _deserialize_dict( - value_deserializer: typing.Optional[typing.Callable], - obj: typing.Dict[typing.Any, typing.Any], - ): - if obj is None: - return obj - return { - k: _deserialize(value_deserializer, v, module) - for k, v in obj.items() - } - return functools.partial( _deserialize_dict, value_deserializer, + module, ) except (AttributeError, IndexError): pass @@ -711,34 +716,16 @@ def _deserialize_dict( if annotation._name in ["List", "Set", "Tuple", "Sequence"]: # pyright: ignore if len(annotation.__args__) > 1: # pyright: ignore - def _deserialize_multiple_sequence( - entry_deserializers: typing.List[typing.Optional[typing.Callable]], - obj, - ): - if obj is None: - return obj - return type(obj)( - _deserialize(deserializer, entry, module) - for entry, deserializer in zip(obj, entry_deserializers) - ) - entry_deserializers = [ - _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ # pyright: ignore + _get_deserialize_callable_from_annotation(dt, module, rf) + for dt in annotation.__args__ # pyright: ignore ] - return functools.partial(_deserialize_multiple_sequence, entry_deserializers) + return functools.partial(_deserialize_multiple_sequence, entry_deserializers, module) deserializer = _get_deserialize_callable_from_annotation( annotation.__args__[0], module, rf # pyright: ignore ) - def _deserialize_sequence( - deserializer: typing.Optional[typing.Callable], - obj, - ): - if obj is None: - return obj - return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) - - return functools.partial(_deserialize_sequence, deserializer) + return functools.partial(_deserialize_sequence, deserializer, module) except (TypeError, IndexError, AttributeError, SyntaxError): pass @@ -870,7 +857,14 @@ def rest_field( format: typing.Optional[str] = None, is_multipart_file_input: bool = False, ) -> typing.Any: - return _RestField(name=name, type=type, visibility=visibility, default=default, format=format, is_multipart_file_input=is_multipart_file_input) + return _RestField( + name=name, + type=type, + visibility=visibility, + default=default, + format=format, + is_multipart_file_input=is_multipart_file_input, + ) def rest_discriminator( diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py index 5d63b0e4eaa0..51cf0e7ac905 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -11,8 +11,9 @@ from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk + __all__ = [ - 'EventGridClientOperationsMixin', + "EventGridClientOperationsMixin", ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index a2706730432d..66228ba73e21 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -9,9 +9,16 @@ from io import IOBase import json import sys -from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload - -from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from typing import Any, Callable, Dict, IO, List, Optional, Type, TypeVar, Union, overload + +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + map_error, +) from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, HttpResponse from azure.core.tracing.decorator import distributed_trace @@ -27,8 +34,8 @@ from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object -T = TypeVar('T') +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] _SERIALIZER = Serializer() @@ -36,73 +43,59 @@ def build_event_grid_publish_cloud_event_request( # pylint: disable=name-too-long - topic_name: str, - **kwargs: Any + topic_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: str = kwargs.pop('content_type') - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: str = kwargs.pop("content_type") + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}:publish" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_publish_cloud_events_request( # pylint: disable=name-too-long - topic_name: str, - **kwargs: Any + topic_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: str = kwargs.pop('content_type') - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: str = kwargs.pop("content_type") + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}:publish" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['content-type'] = _SERIALIZER.header("content_type", content_type, 'str') - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-long @@ -116,73 +109,59 @@ def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-l _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:receive" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), - "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") if max_events is not None: - _params['maxEvents'] = _SERIALIZER.query("max_events", max_events, 'int') + _params["maxEvents"] = _SERIALIZER.query("max_events", max_events, "int") if max_wait_time is not None: - _params['maxWaitTime'] = _SERIALIZER.query("max_wait_time", max_wait_time, 'int') + _params["maxWaitTime"] = _SERIALIZER.query("max_wait_time", max_wait_time, "int") # Construct headers - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-too-long - topic_name: str, - event_subscription_name: str, - **kwargs: Any + topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), - "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') if content_type is not None: - _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-long @@ -195,123 +174,99 @@ def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-l _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), - "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") if release_delay_in_seconds is not None: - _params['releaseDelayInSeconds'] = _SERIALIZER.query("release_delay_in_seconds", release_delay_in_seconds, 'int') + _params["releaseDelayInSeconds"] = _SERIALIZER.query( + "release_delay_in_seconds", release_delay_in_seconds, "int" + ) # Construct headers - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') if content_type is not None: - _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-long - topic_name: str, - event_subscription_name: str, - **kwargs: Any + topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:reject" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), - "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') if content_type is not None: - _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) def build_event_grid_renew_cloud_event_locks_request( # pylint: disable=name-too-long - topic_name: str, - event_subscription_name: str, - **kwargs: Any + topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - api_version: str = kwargs.pop('api_version', _params.pop('api-version', "2023-10-01-preview")) - accept = _headers.pop('Accept', "application/json") + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + accept = _headers.pop("Accept", "application/json") # Construct URL _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:renewLock" path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, 'str'), - "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, 'str'), + "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), + "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - _headers['Accept'] = _SERIALIZER.header("accept", accept, 'str') if content_type is not None: - _headers['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - **kwargs - ) + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -class EventGridClientOperationsMixin( - EventGridClientMixinABC -): + +class EventGridClientOperationsMixin(EventGridClientMixinABC): @distributed_trace def _publish_cloud_event( # pylint: disable=protected-access - self, - topic_name: str, - event: _models._models.CloudEvent, - **kwargs: Any + self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an @@ -352,20 +307,23 @@ def _publish_cloud_event( # pylint: disable=protected-access generated, in RFC3339 format. } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None + content_type: str = kwargs.pop( + "content_type", _headers.pop("content-type", "application/cloudevents+json; charset=utf-8") ) + cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _content = event + _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -376,22 +334,20 @@ def _publish_cloud_event( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -399,23 +355,17 @@ def _publish_cloud_event( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json() + _models._models.PublishResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @distributed_trace def _publish_cloud_events( # pylint: disable=protected-access - self, - topic_name: str, - events: List[_models._models.CloudEvent], - **kwargs: Any + self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an @@ -460,20 +410,23 @@ def _publish_cloud_events( # pylint: disable=protected-access } ] """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None + content_type: str = kwargs.pop( + "content_type", _headers.pop("content-type", "application/cloudevents-batch+json; charset=utf-8") ) + cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _content = events + _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -484,22 +437,20 @@ def _publish_cloud_events( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -507,17 +458,14 @@ def _publish_cloud_events( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json() + _models._models.PublishResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @distributed_trace def _receive_cloud_events( # pylint: disable=protected-access self, @@ -591,19 +539,19 @@ def _receive_cloud_events( # pylint: disable=protected-access ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models._models.ReceiveResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None - ) + cls: ClsType[_models._models.ReceiveResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _request = build_event_grid_receive_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, @@ -614,22 +562,20 @@ def _receive_cloud_events( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -637,17 +583,14 @@ def _receive_cloud_events( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.ReceiveResult, # pylint: disable=protected-access - response.json() + _models._models.ReceiveResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload def _acknowledge_cloud_events( # pylint: disable=protected-access self, @@ -657,8 +600,7 @@ def _acknowledge_cloud_events( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @overload def _acknowledge_cloud_events( self, @@ -668,8 +610,7 @@ def _acknowledge_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @overload def _acknowledge_cloud_events( self, @@ -679,8 +620,7 @@ def _acknowledge_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @distributed_trace def _acknowledge_cloud_events( @@ -745,18 +685,19 @@ def _acknowledge_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AcknowledgeResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -775,43 +716,36 @@ def _acknowledge_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.AcknowledgeResult, - response.json() - ) + deserialized = _deserialize(_models.AcknowledgeResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) # pylint: disable=protected-access def _release_cloud_events( # pylint: disable=protected-access self, @@ -822,11 +756,10 @@ def _release_cloud_events( # pylint: disable=protected-access release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) def _release_cloud_events( self, @@ -837,11 +770,10 @@ def _release_cloud_events( release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) def _release_cloud_events( self, @@ -852,12 +784,11 @@ def _release_cloud_events( release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @distributed_trace @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) def _release_cloud_events( self, @@ -925,18 +856,19 @@ def _release_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.ReleaseResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ReleaseResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -956,40 +888,33 @@ def _release_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.ReleaseResult, - response.json() - ) + deserialized = _deserialize(_models.ReleaseResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload def _reject_cloud_events( # pylint: disable=protected-access self, @@ -999,8 +924,7 @@ def _reject_cloud_events( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @overload def _reject_cloud_events( self, @@ -1010,8 +934,7 @@ def _reject_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @overload def _reject_cloud_events( self, @@ -1021,8 +944,7 @@ def _reject_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @distributed_trace def _reject_cloud_events( @@ -1086,18 +1008,19 @@ def _reject_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.RejectResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RejectResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -1116,43 +1039,37 @@ def _reject_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.RejectResult, - response.json() - ) + deserialized = _deserialize(_models.RejectResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) # pylint: disable=protected-access def _renew_cloud_event_locks( # pylint: disable=protected-access self, @@ -1162,11 +1079,11 @@ def _renew_cloud_event_locks( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) def _renew_cloud_event_locks( self, @@ -1176,11 +1093,11 @@ def _renew_cloud_event_locks( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) def _renew_cloud_event_locks( self, @@ -1190,12 +1107,12 @@ def _renew_cloud_event_locks( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @distributed_trace @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) def _renew_cloud_event_locks( self, @@ -1260,18 +1177,19 @@ def _renew_cloud_event_locks( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -1290,36 +1208,29 @@ def _renew_cloud_event_locks( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.RenewCloudEventLocksResult, - response.json() - ) + deserialized = _deserialize(_models.RenewCloudEventLocksResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index f1e16a2909ef..4cb6fb5264fb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -12,7 +12,6 @@ Any, Callable, Dict, - IO, List, Optional, TypeVar, @@ -22,12 +21,8 @@ ) from azure.core.exceptions import ( - ClientAuthenticationError, HttpResponseError, - ResourceExistsError, ResourceNotFoundError, - ResourceNotModifiedError, - map_error, ) from azure.core.messaging import CloudEvent from azure.core.tracing.decorator import distributed_trace @@ -36,18 +31,23 @@ from azure.core.utils import case_insensitive_dict from ._operations import EventGridClientOperationsMixin as OperationsMixin -from .._model_base import _deserialize from ..models._patch import ( ReceiveResult, ReceiveDetails, ) from .. import models as _models -from ..models._models import AcknowledgeOptions, ReleaseOptions, RejectOptions, RenewLockOptions +from ..models._models import ( + AcknowledgeOptions, + ReleaseOptions, + RejectOptions, + RenewLockOptions, + CloudEvent as InternalCloudEvent, +) from .._validation import api_version_validation from .._legacy import EventGridEvent -from .._legacy._helpers import _from_cncf_events, _is_eventgrid_event +from .._legacy._helpers import _from_cncf_events, _is_eventgrid_event, _is_cloud_event from .._serialization import Serializer if sys.version_info >= (3, 9): @@ -57,9 +57,7 @@ JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[ - Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any] -] +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] _SERIALIZER = Serializer() _SERIALIZER.client_side_validation = False @@ -98,9 +96,7 @@ def use_standard_only(func): @wraps(func) def wrapper(self, *args, **kwargs): if self._level == "Basic": # pylint: disable=protected-access - raise ValueError( - "The basic client is not supported for this operation." - ) + raise ValueError("The basic client is not supported for this operation.") return func(self, *args, **kwargs) return wrapper @@ -119,8 +115,7 @@ def wrapper(self, *args: Any, **kwargs: Any) -> T: arg: level for level, arguments in kwargs_mapping.items() for arg in arguments - if arg - in kwargs.keys() # pylint: disable=consider-iterating-dictionary + if arg in kwargs.keys() # pylint: disable=consider-iterating-dictionary and selected_client_level != level } @@ -154,8 +149,8 @@ def send( ) -> None: """Send events to the Event Grid Basic Service. - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] :keyword channel_name: The name of the channel to send the event to. :paramtype channel_name: str or None @@ -182,8 +177,8 @@ def send( :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default value is False. :paramtype binary_mode: bool @@ -203,13 +198,13 @@ def send( } ) @distributed_trace - def send(self, *args, **kwargs) -> None: + def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default value is False. @@ -260,9 +255,7 @@ def send(self, *args, **kwargs) -> None: elif len(args) == 1: if events is not None: if topic_name is not None: - raise ValueError( - "topic_name is already passed as a keyword argument." - ) + raise ValueError("topic_name is already passed as a keyword argument.") topic_name = args[0] else: events = args[0] @@ -275,7 +268,6 @@ def send(self, *args, **kwargs) -> None: self._send_binary(topic_name, events, **kwargs) else: # If not binary_mode send whatever event is passed - # If a cloud event dict, convert to CloudEvent for serializing try: if isinstance(events, dict): @@ -286,9 +278,7 @@ def send(self, *args, **kwargs) -> None: pass if self._level == "Standard": - kwargs["content_type"] = kwargs.get( - "content_type", "application/cloudevents-batch+json; charset=utf-8" - ) + kwargs["content_type"] = kwargs.get("content_type", "application/cloudevents-batch+json; charset=utf-8") if not isinstance(events, list): events = [events] @@ -307,29 +297,39 @@ def send(self, *args, **kwargs) -> None: self._http_response_error_handler(exception, "Basic") raise exception - def _send_binary(self, topic_name, events, **kwargs): + def _send_binary(self, topic_name, event, **kwargs): # If data is passed as a dictionary, make sure it is a CloudEvent + if isinstance(event, list): + raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from try: - if isinstance(events, dict): - events = CloudEvent.from_dict(events) + if not isinstance(event, CloudEvent): + try: + # Convert to CloudEvent if it is a dictionary + event = CloudEvent.from_dict(event) + except AttributeError: + # Convert to CloudEvent if it is a CNCF CloudEvent dict + event = CloudEvent.from_dict(_from_cncf_events(event)) except AttributeError: - raise TypeError( # pylint: disable=raise-missing-from - "Binary mode is only supported for type CloudEvent." - ) + raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from # If data is a cloud event, convert to an HTTP Request in binary mode # Content type becomes the data content type - if isinstance(events, CloudEvent): - self._publish(topic_name, events, self._config.api_version, **kwargs) + if isinstance(event, CloudEvent): + http_request = _to_http_request( + topic_name=topic_name, + api_version=self._config.api_version, + event=event, + **kwargs, + ) else: raise TypeError("Binary mode is only supported for type CloudEvent.") + self.send_request(http_request, **kwargs) + def _http_response_error_handler(self, exception, level): if isinstance(exception, HttpResponseError): if exception.status_code == 400: - raise HttpResponseError( - "Invalid event data. Please check the data and try again." - ) from exception + raise HttpResponseError("Invalid event data. Please check the data and try again.") from exception if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " @@ -338,82 +338,6 @@ def _http_response_error_handler(self, exception, level): ) from exception raise exception - def _publish( - self, - topic_name: str, - event: Any, - api_version: str, - **kwargs: Any, - ) -> None: - - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.PublishResult] = kwargs.pop( - "cls", None - ) # pylint: disable=protected-access - - content_type = kwargs.pop( # pylint: disable=unused-variable - "content_type", None - ) - # Given that we know the cloud event is binary mode, we can convert it to a HTTP request - http_request = _to_http_request( - topic_name=topic_name, - api_version=api_version, - headers=_headers, - params=_params, - event=event, - **kwargs, - ) - - _stream = kwargs.pop("stream", False) - - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - http_request.url = self._client.format_url( - http_request.url, **path_format_arguments - ) - - pipeline_response: PipelineResponse = ( - self._client._pipeline.run( # pylint: disable=protected-access - http_request, stream=_stream, **kwargs - ) - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() - else: - deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json(), - ) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - @use_standard_only @distributed_trace def receive_cloud_events( @@ -622,12 +546,12 @@ def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: _content = event.data else: raise TypeError( - "CloudEvent data must be bytes when in binary mode." + "CloudEvent data must be bytes when in binary mode. " "Did you forget to call `json.dumps()` and/or `encode()` on CloudEvent data?" ) except AttributeError as exc: raise TypeError( - "Binary mode is not supported for batch CloudEvents." + "Binary mode is not supported for batch CloudEvents. " " Set `binary_mode` to False when passing in a batch of CloudEvents." ) from exc @@ -636,9 +560,7 @@ def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: raise ValueError("CloudEvent datacontenttype must be set when in binary mode.") content_type: str = event.datacontenttype - api_version: str = kwargs.pop( - "api_version", _params.pop("api-version", "2023-10-01-preview") - ) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -660,24 +582,18 @@ def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: _headers["ce-source"] = _SERIALIZER.header("ce-source", event.source, "str") _headers["ce-type"] = _SERIALIZER.header("ce-type", event.type, "str") if event.specversion: - _headers["ce-specversion"] = _SERIALIZER.header( - "ce-specversion", event.specversion, "str" - ) + _headers["ce-specversion"] = _SERIALIZER.header("ce-specversion", event.specversion, "str") if event.id: _headers["ce-id"] = _SERIALIZER.header("ce-id", event.id, "str") if event.time: _headers["ce-time"] = _SERIALIZER.header("ce-time", event.time, "str") if event.dataschema: - _headers["ce-dataschema"] = _SERIALIZER.header( - "ce-dataschema", event.dataschema, "str" - ) + _headers["ce-dataschema"] = _SERIALIZER.header("ce-dataschema", event.dataschema, "str") if event.subject: _headers["ce-subject"] = _SERIALIZER.header("ce-subject", event.subject, "str") if event.extensions: for extension, value in event.extensions.items(): - _headers[f"ce-{extension}"] = _SERIALIZER.header( - "ce-extensions", value, "str" - ) + _headers[f"ce-{extension}"] = _SERIALIZER.header("ce-extensions", value, "str") return HttpRequest( method="POST", @@ -690,56 +606,43 @@ def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: def _serialize_events(events): - if isinstance(events[0], CloudEvent): - internal_body_list = [] - for item in events: - internal_body_list.append(_serialize_cloud_event(item)) - return json.dumps(internal_body_list) - try: - serialize = Serializer() - body = serialize.body(events, "[object]") - if body is None: - data = None - else: - data = json.dumps(body) - - return data - except AttributeError: - return events - - -def _serialize_cloud_event(event): - try: - data = {} - # CloudEvent required fields but validate they are not set to None - if event.type: - data["type"] = _SERIALIZER.body(event.type, "str") - if event.specversion: - data["specversion"] = _SERIALIZER.body(event.specversion, "str") - if event.source: - data["source"] = _SERIALIZER.body(event.source, "str") - if event.id: - data["id"] = _SERIALIZER.body(event.id, "str") - - # Check if data is bytes and serialize to base64 - if isinstance(event.data, bytes): - data["data_base64"] = _SERIALIZER.serialize_bytearray(event.data) - elif event.data: - data["data"] = _SERIALIZER.body(event.data, "str") - - if event.subject: - data["subject"] = _SERIALIZER.body(event.subject, "str") - if event.time: - data["time"] = _SERIALIZER.body(event.time, "str") - if event.datacontenttype: - data["datacontenttype"] = _SERIALIZER.body(event.datacontenttype, "str") - if event.extensions: - for extension, value in event.extensions.items(): - data[extension] = _SERIALIZER.body(value, "str") - - return data - except AttributeError: - return [_from_cncf_events(e) for e in event] + if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): + # Try to serialize cloud events + try: + internal_body_list = [] + for item in events: + internal_body_list.append(_serialize_cloud_event(item)) + return internal_body_list + except AttributeError: + # Try to serialize CNCF Cloud Events + return [_from_cncf_events(e) for e in events] + else: + # Does not conform to format, send as is + return json.dumps(events) + + +def _serialize_cloud_event(cloud_event): + data_kwargs = {} + + if isinstance(cloud_event.data, bytes): + data_kwargs["data_base64"] = cloud_event.data + else: + data_kwargs["data"] = cloud_event.data + + internal_event = InternalCloudEvent( + id=cloud_event.id, + source=cloud_event.source, + type=cloud_event.type, + specversion=cloud_event.specversion, + time=cloud_event.time, + dataschema=cloud_event.dataschema, + datacontenttype=cloud_event.datacontenttype, + subject=cloud_event.subject, + **data_kwargs, + ) + if cloud_event.extensions: + internal_event.update(cloud_event.extensions) + return internal_event __all__: List[str] = [ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index cadec781c7cb..c4075dd2d3e3 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -47,8 +47,8 @@ class EventGridClient(InternalEventGridClient): :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or ~azure.core.credentials.TokenCredential :keyword api_version: The API version to use for this operation. Default value for namespaces is - "2023-10-01-preview". Default value for basic is "2018-01-01". Note that overriding this default value may result in unsupported - behavior. + "2023-10-01-preview". Default value for basic is "2018-01-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str or None :keyword level: The level of client to use. Known values are `Standard` and `Basic`. Default value is `Standard`. @@ -78,9 +78,7 @@ def __init__( self._send = self._client.send # type:ignore[attr-defined] elif level == ClientLevel.STANDARD: if isinstance(credential, AzureSasCredential): - raise TypeError( - "SAS token authentication is not supported for the standard client." - ) + raise TypeError("SAS token authentication is not supported for the standard client.") super().__init__( endpoint=endpoint, credential=credential, @@ -90,9 +88,7 @@ def __init__( self._send = self._publish_cloud_events else: - raise ValueError( - "Unknown client level. Known values are `Standard` and `Basic`." - ) + raise ValueError("Unknown client level. Known values are `Standard` and `Basic`.") self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index 75e26c415d2c..2f781d740827 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -349,9 +349,7 @@ def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: def as_dict( self, keep_readonly: bool = True, - key_transformer: Callable[ - [str, Dict[str, Any], Any], Any - ] = attribute_transformer, + key_transformer: Callable[[str, Dict[str, Any], Any], Any] = attribute_transformer, **kwargs: Any ) -> JSON: """Return a dict that can be serialized using json.dump. @@ -540,7 +538,7 @@ class Serializer(object): "multiple": lambda x, y: x % y != 0, } - def __init__(self, classes: Optional[Mapping[str, type]]=None): + def __init__(self, classes: Optional[Mapping[str, type]] = None): self.serialize_type = { "iso-8601": Serializer.serialize_iso, "rfc-1123": Serializer.serialize_rfc, @@ -748,7 +746,7 @@ def query(self, name, data, data_type, **kwargs): # Treat the list aside, since we don't want to encode the div separator if data_type.startswith("["): internal_data_type = data_type[1:-1] - do_quote = not kwargs.get('skip_quote', False) + do_quote = not kwargs.get("skip_quote", False) return self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs) # Not a list, regular serialization @@ -907,12 +905,8 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): raise serialized.append(None) - if kwargs.get('do_quote', False): - serialized = [ - '' if s is None else quote(str(s), safe='') - for s - in serialized - ] + if kwargs.get("do_quote", False): + serialized = ["" if s is None else quote(str(s), safe="") for s in serialized] if div: serialized = ["" if s is None else str(s) for s in serialized] @@ -1369,7 +1363,7 @@ class Deserializer(object): valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") - def __init__(self, classes: Optional[Mapping[str, type]]=None): + def __init__(self, classes: Optional[Mapping[str, type]] = None): self.deserialize_type = { "iso-8601": Deserializer.deserialize_iso, "rfc-1123": Deserializer.deserialize_rfc, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py index 102dea177140..752b2822f9d3 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_validation.py @@ -6,6 +6,7 @@ # -------------------------------------------------------------------------- import functools + def api_version_validation(**kwargs): params_added_on = kwargs.pop("params_added_on", {}) method_added_on = kwargs.pop("method_added_on", "") @@ -33,11 +34,17 @@ def wrapper(*args, **kwargs): if parameter in kwargs and api_version > client_api_version } if unsupported: - raise ValueError("".join([ - f"'{param}' is not available in API version {client_api_version}. " - f"Use service API version {version} or newer.\n" - for param, version in unsupported.items() - ])) + raise ValueError( + "".join( + [ + f"'{param}' is not available in API version {client_api_version}. " + f"Use service API version {version} or newer.\n" + for param, version in unsupported.items() + ] + ) + ) return func(*args, **kwargs) + return wrapper + return decorator diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py index 682fa0a3f71f..59d8335b5c63 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py @@ -16,12 +16,11 @@ from ._serialization import Deserializer, Serializer -class EventGridClientMixinABC( - ABC -): + +class EventGridClientMixinABC(ABC): """DO NOT use this class. It is for internal typing use only.""" + _client: "PipelineClient" _config: EventGridClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index 4997406f0693..b578abb501c0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "4.20.0b1" +VERSION = "4.20.1b1" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py index 149d797cbe4e..906ab81c5705 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py @@ -14,8 +14,9 @@ except ImportError: _patch_all = [] from ._patch import patch_sdk as _patch_sdk + __all__ = [ - 'EventGridClient', + "EventGridClient", ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py index 064da9dbacfb..60d39e9d6ade 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py @@ -22,13 +22,14 @@ # pylint: disable=unused-import,ungrouped-imports from azure.core.credentials_async import AsyncTokenCredential + class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword """Azure Messaging EventGrid Client. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Is either a + :param credential: Credential used to authenticate requests to the service. Is either a AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential @@ -39,28 +40,35 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client """ def __init__( - self, - endpoint: str, - credential: Union[AzureKeyCredential, "AsyncTokenCredential"], - **kwargs: Any + self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: - _endpoint = '{endpoint}' + _endpoint = "{endpoint}" self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) - _policies = kwargs.pop('policies', None) + _policies = kwargs.pop("policies", None) if _policies is None: - _policies = [policies.RequestIdPolicy(**kwargs),self._config.headers_policy,self._config.user_agent_policy,self._config.proxy_policy,policies.ContentDecodePolicy(**kwargs),self._config.redirect_policy,self._config.retry_policy,self._config.authentication_policy,self._config.custom_hook_policy,self._config.logging_policy,policies.DistributedTracingPolicy(**kwargs),policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,self._config.http_logging_policy] + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - def send_request( - self, - request: HttpRequest, *, stream: bool = False, - **kwargs: Any + self, request: HttpRequest, *, stream: bool = False, **kwargs: Any ) -> Awaitable[AsyncHttpResponse]: """Runs the network request through the client's chained policies. @@ -81,7 +89,7 @@ def send_request( request_copy = deepcopy(request) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py index 847e9019f9dc..4e99a4348f83 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py @@ -18,7 +18,7 @@ from azure.core.credentials_async import AsyncTokenCredential -class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long +class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long """Configuration for EventGridClient. Note that all parameters used to create this instance are saved as instance @@ -27,7 +27,7 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attri :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. Is either a + :param credential: Credential used to authenticate requests to the service. Is either a AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential @@ -38,12 +38,9 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attri """ def __init__( - self, - endpoint: str, - credential: Union[AzureKeyCredential, "AsyncTokenCredential"], - **kwargs: Any + self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: - api_version: str = kwargs.pop('api_version', "2023-10-01-preview") + api_version: str = kwargs.pop("api_version", "2023-10-01-preview") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") @@ -53,30 +50,29 @@ def __init__( self.endpoint = endpoint self.credential = credential self.api_version = api_version - self.credential_scopes = kwargs.pop('credential_scopes', ['https://eventgrid.azure.net/.default']) - kwargs.setdefault('sdk_moniker', 'eventgrid/{}'.format(VERSION)) + self.credential_scopes = kwargs.pop("credential_scopes", ["https://eventgrid.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "eventgrid/{}".format(VERSION)) self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) def _infer_policy(self, **kwargs): if isinstance(self.credential, AzureKeyCredential): - return policies.AzureKeyCredentialPolicy(self.credential, "Authorization", prefix="SharedAccessKey", **kwargs) - if hasattr(self.credential, 'get_token'): + return policies.AzureKeyCredentialPolicy( + self.credential, "Authorization", prefix="SharedAccessKey", **kwargs + ) + if hasattr(self.credential, "get_token"): return policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) raise TypeError(f"Unsupported credential: {self.credential}") - def _configure( - self, - **kwargs: Any - ) -> None: - self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) - self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) - self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) - self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) - self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) - self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) - self.authentication_policy = kwargs.get('authentication_policy') + def _configure(self, **kwargs: Any) -> None: + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs) + self.authentication_policy = kwargs.get("authentication_policy") if self.credential and not self.authentication_policy: self.authentication_policy = self._infer_policy(**kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py index 5d63b0e4eaa0..51cf0e7ac905 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -11,8 +11,9 @@ from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk + __all__ = [ - 'EventGridClientOperationsMixin', + "EventGridClientOperationsMixin", ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index 8640bcff8730..51895d2634b3 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -9,9 +9,16 @@ from io import IOBase import json import sys -from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload - -from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, map_error +from typing import Any, Callable, Dict, IO, List, Optional, Type, TypeVar, Union, overload + +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + map_error, +) from azure.core.pipeline import PipelineResponse from azure.core.rest import AsyncHttpResponse, HttpRequest from azure.core.tracing.decorator_async import distributed_trace_async @@ -19,7 +26,15 @@ from ... import models as _models from ..._model_base import SdkJSONEncoder, _deserialize -from ..._operations._operations import build_event_grid_acknowledge_cloud_events_request, build_event_grid_publish_cloud_event_request, build_event_grid_publish_cloud_events_request, build_event_grid_receive_cloud_events_request, build_event_grid_reject_cloud_events_request, build_event_grid_release_cloud_events_request, build_event_grid_renew_cloud_event_locks_request +from ..._operations._operations import ( + build_event_grid_acknowledge_cloud_events_request, + build_event_grid_publish_cloud_event_request, + build_event_grid_publish_cloud_events_request, + build_event_grid_receive_cloud_events_request, + build_event_grid_reject_cloud_events_request, + build_event_grid_release_cloud_events_request, + build_event_grid_renew_cloud_event_locks_request, +) from ..._validation import api_version_validation from .._vendor import EventGridClientMixinABC @@ -27,20 +42,16 @@ from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object -T = TypeVar('T') +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] -class EventGridClientOperationsMixin( - EventGridClientMixinABC -): + +class EventGridClientOperationsMixin(EventGridClientMixinABC): @distributed_trace_async async def _publish_cloud_event( # pylint: disable=protected-access - self, - topic_name: str, - event: _models._models.CloudEvent, - **kwargs: Any + self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an @@ -81,20 +92,23 @@ async def _publish_cloud_event( # pylint: disable=protected-access generated, in RFC3339 format. } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents+json; charset=utf-8")) - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None + content_type: str = kwargs.pop( + "content_type", _headers.pop("content-type", "application/cloudevents+json; charset=utf-8") ) + cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _content = event + _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore _request = build_event_grid_publish_cloud_event_request( topic_name=topic_name, @@ -105,22 +119,20 @@ async def _publish_cloud_event( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -128,23 +140,17 @@ async def _publish_cloud_event( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json() + _models._models.PublishResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @distributed_trace_async async def _publish_cloud_events( # pylint: disable=protected-access - self, - topic_name: str, - events: List[_models._models.CloudEvent], - **kwargs: Any + self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an @@ -189,20 +195,23 @@ async def _publish_cloud_events( # pylint: disable=protected-access } ] """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: str = kwargs.pop('content_type', _headers.pop('content-type', "application/cloudevents-batch+json; charset=utf-8")) - cls: ClsType[_models._models.PublishResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None + content_type: str = kwargs.pop( + "content_type", _headers.pop("content-type", "application/cloudevents-batch+json; charset=utf-8") ) + cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _content = events + _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore _request = build_event_grid_publish_cloud_events_request( topic_name=topic_name, @@ -213,22 +222,20 @@ async def _publish_cloud_events( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -236,17 +243,14 @@ async def _publish_cloud_events( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json() + _models._models.PublishResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @distributed_trace_async async def _receive_cloud_events( # pylint: disable=protected-access self, @@ -320,19 +324,19 @@ async def _receive_cloud_events( # pylint: disable=protected-access ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models._models.ReceiveResult] = kwargs.pop( # pylint: disable=protected-access - 'cls', None - ) + cls: ClsType[_models._models.ReceiveResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _request = build_event_grid_receive_cloud_events_request( topic_name=topic_name, event_subscription_name=event_subscription_name, @@ -343,22 +347,20 @@ async def _receive_cloud_events( # pylint: disable=protected-access params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) @@ -366,17 +368,14 @@ async def _receive_cloud_events( # pylint: disable=protected-access deserialized = response.iter_bytes() else: deserialized = _deserialize( - _models._models.ReceiveResult, # pylint: disable=protected-access - response.json() + _models._models.ReceiveResult, response.json() # pylint: disable=protected-access ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload async def _acknowledge_cloud_events( # pylint: disable=protected-access self, @@ -386,8 +385,7 @@ async def _acknowledge_cloud_events( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @overload async def _acknowledge_cloud_events( self, @@ -397,8 +395,7 @@ async def _acknowledge_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @overload async def _acknowledge_cloud_events( self, @@ -408,8 +405,7 @@ async def _acknowledge_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AcknowledgeResult: - ... + ) -> _models.AcknowledgeResult: ... @distributed_trace_async async def _acknowledge_cloud_events( @@ -474,18 +470,19 @@ async def _acknowledge_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.AcknowledgeResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AcknowledgeResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -504,43 +501,36 @@ async def _acknowledge_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.AcknowledgeResult, - response.json() - ) + deserialized = _deserialize(_models.AcknowledgeResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) # pylint: disable=protected-access async def _release_cloud_events( # pylint: disable=protected-access self, @@ -551,11 +541,10 @@ async def _release_cloud_events( # pylint: disable=protected-access release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) async def _release_cloud_events( self, @@ -566,11 +555,10 @@ async def _release_cloud_events( release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @overload @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) async def _release_cloud_events( self, @@ -581,12 +569,11 @@ async def _release_cloud_events( release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any - ) -> _models.ReleaseResult: - ... + ) -> _models.ReleaseResult: ... @distributed_trace_async @api_version_validation( - params_added_on={'2023-10-01-preview': ['release_delay_in_seconds']}, + params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) async def _release_cloud_events( self, @@ -654,18 +641,19 @@ async def _release_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.ReleaseResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ReleaseResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -685,40 +673,33 @@ async def _release_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.ReleaseResult, - response.json() - ) + deserialized = _deserialize(_models.ReleaseResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload async def _reject_cloud_events( # pylint: disable=protected-access self, @@ -728,8 +709,7 @@ async def _reject_cloud_events( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @overload async def _reject_cloud_events( self, @@ -739,8 +719,7 @@ async def _reject_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @overload async def _reject_cloud_events( self, @@ -750,8 +729,7 @@ async def _reject_cloud_events( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RejectResult: - ... + ) -> _models.RejectResult: ... @distributed_trace_async async def _reject_cloud_events( @@ -815,18 +793,19 @@ async def _reject_cloud_events( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.RejectResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RejectResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -845,43 +824,37 @@ async def _reject_cloud_events( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.RejectResult, - response.json() - ) + deserialized = _deserialize(_models.RejectResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) # pylint: disable=protected-access async def _renew_cloud_event_locks( # pylint: disable=protected-access self, @@ -891,11 +864,11 @@ async def _renew_cloud_event_locks( # pylint: disable=protected-access *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) async def _renew_cloud_event_locks( self, @@ -905,11 +878,11 @@ async def _renew_cloud_event_locks( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) async def _renew_cloud_event_locks( self, @@ -919,12 +892,12 @@ async def _renew_cloud_event_locks( *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - ... + ) -> _models.RenewCloudEventLocksResult: ... @distributed_trace_async @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["accept"]}, ) async def _renew_cloud_event_locks( self, @@ -989,18 +962,19 @@ async def _renew_cloud_event_locks( ] } """ - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, 304: ResourceNotModifiedError + error_map: MutableMapping[int, Type[HttpResponseError]] = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, } - error_map.update(kwargs.pop('error_map', {}) or {}) + error_map.update(kwargs.pop("error_map", {}) or {}) _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop('content_type', _headers.pop('Content-Type', None)) - cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop( - 'cls', None - ) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None @@ -1019,36 +993,29 @@ async def _renew_cloud_event_locks( params=_params, ) path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } _request.url = self._client.format_url(_request.url, **path_format_arguments) _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, - stream=_stream, - **kwargs + _request, stream=_stream, **kwargs ) response = pipeline_response.http_response if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + await response.read() # Load the body in memory and close the socket map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize( - _models.RenewCloudEventLocksResult, - response.json() - ) + deserialized = _deserialize(_models.RenewCloudEventLocksResult, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 20c46b61de31..0d96149e63cf 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -5,27 +5,21 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar, IO +from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar import sys from azure.core.messaging import CloudEvent from azure.core.exceptions import ( - ClientAuthenticationError, HttpResponseError, - ResourceExistsError, ResourceNotFoundError, - ResourceNotModifiedError, - map_error, ) from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, AsyncHttpResponse -from azure.core.utils import case_insensitive_dict from ...models._patch import ReceiveResult, ReceiveDetails from ..._operations._patch import _to_http_request, use_standard_only from ._operations import EventGridClientOperationsMixin as OperationsMixin from ... import models as _models from ...models._models import AcknowledgeOptions, ReleaseOptions, RejectOptions, RenewLockOptions -from ..._model_base import _deserialize from ..._validation import api_version_validation from ..._operations._patch import ( @@ -36,7 +30,7 @@ ) from ..._legacy import EventGridEvent -from ..._legacy._helpers import _is_eventgrid_event +from ..._legacy._helpers import _is_eventgrid_event, _from_cncf_events if sys.version_info >= (3, 9): from collections.abc import MutableMapping @@ -44,9 +38,7 @@ from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") -ClsType = Optional[ - Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any] -] +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] class EventGridClientOperationsMixin(OperationsMixin): @@ -62,8 +54,8 @@ async def send( ) -> None: """Send events to the Event Grid Basic Service. - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] :keyword channel_name: The name of the channel to send the event to. :paramtype channel_name: str or None @@ -90,8 +82,8 @@ async def send( :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default value is False. :paramtype binary_mode: bool @@ -111,13 +103,13 @@ async def send( } ) @distributed_trace_async - async def send(self, *args, **kwargs) -> None: + async def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Namespace Service. :param topic_name: The name of the topic to send the event to. :type topic_name: str - :param event: The event to send. - :type event: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] + :param events: The event to send. + :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default value is False. :paramtype binary_mode: bool @@ -167,9 +159,7 @@ async def send(self, *args, **kwargs) -> None: elif len(args) == 1: if events is not None: if topic_name is not None: - raise ValueError( - "topic_name is already passed as a keyword argument." - ) + raise ValueError("topic_name is already passed as a keyword argument.") topic_name = args[0] else: events = args[0] @@ -189,13 +179,11 @@ async def send(self, *args, **kwargs) -> None: events = CloudEvent.from_dict(events) if isinstance(events, list) and isinstance(events[0], dict): events = [CloudEvent.from_dict(e) for e in events] - except Exception: # pylint: disable=broad-except + except Exception: # pylint: disable=broad-except pass if self._level == "Standard": - kwargs["content_type"] = kwargs.get( - "content_type", "application/cloudevents-batch+json; charset=utf-8" - ) + kwargs["content_type"] = kwargs.get("content_type", "application/cloudevents-batch+json; charset=utf-8") if not isinstance(events, list): events = [events] @@ -214,28 +202,37 @@ async def send(self, *args, **kwargs) -> None: self._http_response_error_handler(exception, "Basic") raise exception - async def _send_binary(self, topic_name: str, events: Any, **kwargs: Any) -> None: + async def _send_binary(self, topic_name: str, event: Any, **kwargs: Any) -> None: # If data is passed as a dictionary, make sure it is a CloudEvent + if isinstance(event, list): + raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from try: - if isinstance(events, dict): - events = CloudEvent.from_dict(events) - except AttributeError: - raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from + if not isinstance(event, CloudEvent): + try: + event = CloudEvent.from_dict(event) + except AttributeError: + event = CloudEvent.from_dict(_from_cncf_events(event)) - # If data is a cloud event, convert to an HTTP Request in binary mode - if isinstance(events, CloudEvent): - await self._publish( - topic_name, events, self._config.api_version, **kwargs + except AttributeError: + raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from + + if isinstance(event, CloudEvent): + http_request = _to_http_request( + topic_name=topic_name, + api_version=self._config.api_version, + event=event, + **kwargs, ) else: raise TypeError("Binary mode is only supported for type CloudEvent.") + # If data is a cloud event, convert to an HTTP Request in binary mode + await self.send_request(http_request, **kwargs) + def _http_response_error_handler(self, exception, level): if isinstance(exception, HttpResponseError): if exception.status_code == 400: - raise HttpResponseError( - "Invalid event data. Please check the data and try again." - ) from exception + raise HttpResponseError("Invalid event data. Please check the data and try again.") from exception if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " @@ -321,9 +318,7 @@ async def acknowledge_cloud_events( :raises ~azure.core.exceptions.HttpResponseError: """ options = AcknowledgeOptions(lock_tokens=lock_tokens) - return await super()._acknowledge_cloud_events( - topic_name, subscription_name, options, **kwargs - ) + return await super()._acknowledge_cloud_events(topic_name, subscription_name, options, **kwargs) @use_standard_only @distributed_trace_async @@ -390,9 +385,7 @@ async def reject_cloud_events( :raises ~azure.core.exceptions.HttpResponseError: """ options = RejectOptions(lock_tokens=lock_tokens) - return await super()._reject_cloud_events( - topic_name, subscription_name, options, **kwargs - ) + return await super()._reject_cloud_events(topic_name, subscription_name, options, **kwargs) @use_standard_only @distributed_trace_async @@ -424,78 +417,7 @@ async def renew_cloud_event_locks( :raises ~azure.core.exceptions.HttpResponseError: """ options = RenewLockOptions(lock_tokens=lock_tokens) - return await super()._renew_cloud_event_locks( - topic_name, subscription_name, options, **kwargs - ) - - async def _publish( - self, topic_name: str, event: Any, api_version, **kwargs: Any - ) -> None: - - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.PublishResult] = kwargs.pop( - "cls", None - ) # pylint: disable=protected-access - - content_type = kwargs.pop("content_type", None) # pylint: disable=unused-variable - # Given that we know the cloud event is binary mode, we can convert it to a HTTP request - http_request = _to_http_request( - topic_name=topic_name, - api_version=api_version, - headers=_headers, - params=_params, - event=event, - **kwargs, - ) - - _stream = kwargs.pop("stream", False) - - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - http_request.url = self._client.format_url( - http_request.url, **path_format_arguments - ) - - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - http_request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error( - status_code=response.status_code, response=response, error_map=error_map - ) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() - else: - deserialized = _deserialize( - _models._models.PublishResult, # pylint: disable=protected-access - response.json(), - ) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return await super()._renew_cloud_event_locks(topic_name, subscription_name, options, **kwargs) __all__: List[str] = [ diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index b0a6a7dd9253..ebfe920d986d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -33,8 +33,8 @@ class EventGridClient(InternalEventGridClient): :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: The API version to use for this operation. Default value for namespaces is - "2023-10-01-preview". Default value for basic is "2018-01-01". Note that overriding this default value may result in unsupported - behavior. + "2023-10-01-preview". Default value for basic is "2018-01-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str or None :keyword level: The level of client to use. Known values include: "Basic", "Standard". Default value is "Standard". @@ -46,9 +46,7 @@ class EventGridClient(InternalEventGridClient): def __init__( self, endpoint: str, - credential: Union[ - AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential" - ], + credential: Union[AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential"], *, api_version: Optional[str] = None, level: Union[str, ClientLevel] = "Standard", @@ -59,17 +57,12 @@ def __init__( if level == ClientLevel.BASIC: self._client = EventGridPublisherClient( # type: ignore[assignment] - endpoint, - credential, - api_version=api_version or DEFAULT_BASIC_API_VERSION, - **kwargs + endpoint, credential, api_version=api_version or DEFAULT_BASIC_API_VERSION, **kwargs ) self._send = self._client.send # type: ignore[attr-defined] elif level == ClientLevel.STANDARD: if isinstance(credential, AzureSasCredential): - raise TypeError( - "SAS token authentication is not supported for the standard client." - ) + raise TypeError("SAS token authentication is not supported for the standard client.") super().__init__( endpoint=endpoint, @@ -79,9 +72,7 @@ def __init__( ) self._send = self._publish_cloud_events else: - raise ValueError( - "Unknown client level. Known values are `Standard` and `Basic`." - ) + raise ValueError("Unknown client level. Known values are `Standard` and `Basic`.") self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py index 2f5401a3a2ee..35bd45e3dc6b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py @@ -16,12 +16,11 @@ from .._serialization import Deserializer, Serializer -class EventGridClientMixinABC( - ABC -): + +class EventGridClientMixinABC(ABC): """DO NOT use this class. It is for internal typing use only.""" + _client: "AsyncPipelineClient" _config: EventGridClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py index 2bf8ba7809c7..370a6e7b643d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py @@ -16,13 +16,14 @@ from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk + __all__ = [ - 'AcknowledgeResult', - 'FailedLockToken', - 'RejectResult', - 'ReleaseResult', - 'RenewCloudEventLocksResult', - 'ReleaseDelay', + "AcknowledgeResult", + "FailedLockToken", + "RejectResult", + "ReleaseResult", + "RenewCloudEventLocksResult", + "ReleaseDelay", ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py index 74f1f5e2eaf7..69e6eeb024ea 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py @@ -11,8 +11,7 @@ class ReleaseDelay(int, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported delays for release operation. - """ + """Supported delays for release operation.""" BY0_SECONDS = 0 """Release the event after 0 seconds.""" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index c7fb2c8270fa..ec8f8df9a975 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -31,9 +31,6 @@ class AcknowledgeOptions(_model_base.Model): """Array of lock tokens. Required.""" - - - class AcknowledgeResult(_model_base.Model): """The result of the Acknowledge operation. @@ -54,15 +51,13 @@ class AcknowledgeResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully acknowledged cloud events. Required.""" - @overload def __init__( self, *, failed_lock_tokens: List["_models.FailedLockToken"], succeeded_lock_tokens: List[str], - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -71,10 +66,8 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - class BrokerProperties(_model_base.Model): @@ -94,9 +87,6 @@ class BrokerProperties(_model_base.Model): """The attempt count for delivering the event. Required.""" - - - class CloudEvent(_model_base.Model): """Properties of an event published to an Azure Messaging EventGrid Namespace topic using the CloudEvent 1.0 Schema. @@ -153,9 +143,6 @@ class CloudEvent(_model_base.Model): source).""" - - - class Error(_model_base.Model): """The error object. @@ -186,9 +173,6 @@ class Error(_model_base.Model): """An object containing more specific information than the current object about the error.""" - - - class FailedLockToken(_model_base.Model): """Failed LockToken information. @@ -206,15 +190,13 @@ class FailedLockToken(_model_base.Model): error: "_models._models.Error" = rest_field() """Error information of the failed operation result for the lock token in the request. Required.""" - @overload def __init__( self, *, lock_token: str, error: "_models._models.Error", - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -223,10 +205,8 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - class InnerError(_model_base.Model): @@ -246,17 +226,8 @@ class InnerError(_model_base.Model): """Inner error.""" - - - class PublishResult(_model_base.Model): - """The result of the Publish operation. - - """ - - - - + """The result of the Publish operation.""" class ReceiveDetails(_model_base.Model): @@ -276,9 +247,6 @@ class ReceiveDetails(_model_base.Model): """Cloud Event details. Required.""" - - - class ReceiveResult(_model_base.Model): """Details of the Receive operation response. @@ -292,9 +260,6 @@ class ReceiveResult(_model_base.Model): """Array of receive responses, one per cloud event. Required.""" - - - class RejectOptions(_model_base.Model): """Array of lock tokens for the corresponding received Cloud Events to be rejected. @@ -308,9 +273,6 @@ class RejectOptions(_model_base.Model): """Array of lock tokens. Required.""" - - - class RejectResult(_model_base.Model): """The result of the Reject operation. @@ -331,15 +293,13 @@ class RejectResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully rejected cloud events. Required.""" - @overload def __init__( self, *, failed_lock_tokens: List["_models.FailedLockToken"], succeeded_lock_tokens: List[str], - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -348,10 +308,8 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - class ReleaseOptions(_model_base.Model): @@ -367,9 +325,6 @@ class ReleaseOptions(_model_base.Model): """Array of lock tokens. Required.""" - - - class ReleaseResult(_model_base.Model): """The result of the Release operation. @@ -390,15 +345,13 @@ class ReleaseResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully released cloud events. Required.""" - @overload def __init__( self, *, failed_lock_tokens: List["_models.FailedLockToken"], succeeded_lock_tokens: List[str], - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -407,10 +360,8 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - class RenewCloudEventLocksResult(_model_base.Model): @@ -432,15 +383,13 @@ class RenewCloudEventLocksResult(_model_base.Model): succeeded_lock_tokens: List[str] = rest_field(name="succeededLockTokens") """Array of lock tokens for the successfully renewed locks. Required.""" - @overload def __init__( self, *, failed_lock_tokens: List["_models.FailedLockToken"], succeeded_lock_tokens: List[str], - ): - ... + ): ... @overload def __init__(self, mapping: Mapping[str, Any]): @@ -449,10 +398,8 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__(self, *args: Any, **kwargs: Any) -> None:# pylint: disable=useless-super-delegation + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - class RenewLockOptions(_model_base.Model): @@ -466,6 +413,3 @@ class RenewLockOptions(_model_base.Model): lock_tokens: List[str] = rest_field(name="lockTokens") """Array of lock tokens. Required.""" - - - diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py index ee8fa6387b70..2d1ee31d0d01 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py @@ -41,9 +41,7 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( # pylint: disable=useless-super-delegation - self, *args: Any, **kwargs: Any - ) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) @@ -70,9 +68,7 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( # pylint: disable=useless-super-delegation - self, *args: Any, **kwargs: Any - ) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) @@ -102,9 +98,7 @@ def __init__(self, mapping: Mapping[str, Any]): :type mapping: Mapping[str, Any] """ - def __init__( # pylint: disable=useless-super-delegation - self, *args: Any, **kwargs: Any - ) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py index 0bed8a6ddc74..24c452d0701d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py @@ -34,33 +34,23 @@ client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) -cloud_event_reject = CloudEvent( - data="reject", source="https://example.com", type="example" -) -cloud_event_release = CloudEvent( - data="release", source="https://example.com", type="example" -) -cloud_event_ack = CloudEvent( - data="acknowledge", source="https://example.com", type="example" -) +cloud_event_reject = CloudEvent(data="reject", source="https://example.com", type="example") +cloud_event_release = CloudEvent(data="release", source="https://example.com", type="example") +cloud_event_ack = CloudEvent(data="acknowledge", source="https://example.com", type="example") async def run(): async with client: # Publish a CloudEvent try: - await client.send( - topic_name=TOPIC_NAME, events=cloud_event_reject - ) + await client.send(topic_name=TOPIC_NAME, events=cloud_event_reject) except HttpResponseError: raise # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event_release, cloud_event_ack] - await client.send( - topic_name=TOPIC_NAME, events=list_of_cloud_events - ) + await client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py index 23ddeb5abd90..1e13aaee8f39 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py @@ -40,11 +40,21 @@ async def run(): # Publish a CloudEvent try: # Publish CloudEvent in binary mode with str encoded as bytes - cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} + cloud_event_dict = { + "data": b"HI", + "source": "https://example.com", + "type": "example", + "datacontenttype": "text/plain", + } await client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes - cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") + cloud_event = CloudEvent( + data=json.dumps({"hello": "data"}).encode("utf-8"), + source="https://example.com", + type="example", + datacontenttype="application/json", + ) await client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) receive_result = await client.receive_cloud_events( @@ -60,5 +70,6 @@ async def run(): except HttpResponseError: raise + if __name__ == "__main__": asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py index aae84b550ecc..57469077a263 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py @@ -50,12 +50,9 @@ async def run(): except HttpResponseError: raise - # Publish a CloudEvent try: - cloud_event = CloudEvent( - data="HI", source="https://example.com", type="example" - ) + cloud_event = CloudEvent(data="HI", source="https://example.com", type="example") await client.send(topic_name=TOPIC_NAME, events=cloud_event) except HttpResponseError: raise @@ -63,9 +60,7 @@ async def run(): # Publish a list of CloudEvents try: list_of_cloud_events = [cloud_event, cloud_event] - await client.send( - topic_name=TOPIC_NAME, events=list_of_cloud_events - ) + await client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) except HttpResponseError: raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py index 04cd15696d9e..3b95910942df 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py @@ -42,7 +42,9 @@ async def run(): await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + receive_result = await client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10 + ) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -57,5 +59,6 @@ async def run(): except HttpResponseError: raise + if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) \ No newline at end of file + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py index f0946c2bcd57..ef3a25bf0419 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py @@ -42,7 +42,9 @@ async def run(): await client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 + ) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -59,7 +61,9 @@ async def run(): print("Released Event:", release_events) # Receive CloudEvents again - receive_result = await client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = await client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 + ) print("Received events after release:", receive_result.value) # Acknowledge a LockToken that was released @@ -72,5 +76,6 @@ async def run(): except HttpResponseError: raise + if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) \ No newline at end of file + asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py index 349f18991ee0..7844f9a2c3a8 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py @@ -31,6 +31,7 @@ # Create a client client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) + async def run(): # Renew a lockToken try: @@ -44,5 +45,6 @@ async def run(): except HttpResponseError: raise + if __name__ == "__main__": asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py index 17e110122a95..86fbfaf2b77e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py @@ -24,9 +24,9 @@ queue_name = os.environ["STORAGE_QUEUE_NAME"] with QueueServiceClient.from_connection_string(connection_str) as qsc: - payload = qsc.get_queue_client( - queue=queue_name, message_decode_policy=BinaryBase64DecodePolicy() - ).peek_messages(max_messages=32) + payload = qsc.get_queue_client(queue=queue_name, message_decode_policy=BinaryBase64DecodePolicy()).peek_messages( + max_messages=32 + ) ## deserialize payload into a list of typed Events events: List[CloudEvent] = [CloudEvent.from_json(msg) for msg in payload] diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py index 9a04a87df6d9..1b2db9f0cff4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py @@ -44,9 +44,7 @@ def publish_event(): event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 1)): - sample_members = sample( - services, k=randint(1, 4) - ) # select random subset of team members + sample_members = sample(services, k=randint(1, 4)) # select random subset of team members data_dict = {"team": sample_members} event = CloudEvent( type="Azure.Sdk.Sample", diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py index d30969af523b..dc26284119ce 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py @@ -46,9 +46,7 @@ def publish_event(): # create events and append to list for j in range(randint(1, 3)): - sample_members = sample( - services, k=randint(1, 4) - ) # select random subset of team members + sample_members = sample(services, k=randint(1, 4)) # select random subset of team members event = CloudEvent( type="Azure.Sdk.Demo", source="domainname", diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py index 1f00e36dcf18..3e4a85c77c90 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py @@ -42,9 +42,7 @@ def publish_event(): event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): - sample_members = sample( - services, k=randint(1, 4) - ) # select random subset of team members + sample_members = sample(services, k=randint(1, 4)) # select random subset of team members event = EventGridEvent( subject="Door1", data={"team": sample_members}, diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py index 4afdeebc182b..0ac2a6b894c9 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py @@ -48,9 +48,7 @@ def publish_event(): event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): - sample_members = sample( - services, k=randint(1, 4) - ) # select random subset of team members + sample_members = sample(services, k=randint(1, 4)) # select random subset of team members event = CloudEvent( type="Azure.Sdk.Demo", source="https://egdemo.dev/demowithsignature", diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py index 68b9ea7962d6..31416d97aef5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py @@ -34,15 +34,9 @@ client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) -cloud_event_reject = CloudEvent( - data="reject", source="https://example.com", type="example" -) -cloud_event_release = CloudEvent( - data="release", source="https://example.com", type="example" -) -cloud_event_ack = CloudEvent( - data="acknowledge", source="https://example.com", type="example" -) +cloud_event_reject = CloudEvent(data="reject", source="https://example.com", type="example") +cloud_event_release = CloudEvent(data="release", source="https://example.com", type="example") +cloud_event_ack = CloudEvent(data="acknowledge", source="https://example.com", type="example") # Publish a CloudEvent try: diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py index 8a6a0188a184..d6c2130bbd9d 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py @@ -37,20 +37,30 @@ # Publish a CloudEvent try: # Publish CloudEvent in binary mode with str encoded as bytes - cloud_event_dict = {"data":b"HI", "source":"https://example.com", "type":"example", "datacontenttype":"text/plain"} + cloud_event_dict = { + "data": b"HI", + "source": "https://example.com", + "type": "example", + "datacontenttype": "text/plain", + } client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) # Publish CloudEvent in binary mode with json encoded as bytes - cloud_event = CloudEvent(data=json.dumps({"hello":"data"}).encode("utf-8"), source="https://example.com", type="example", datacontenttype="application/json") + cloud_event = CloudEvent( + data=json.dumps({"hello": "data"}).encode("utf-8"), + source="https://example.com", + type="example", + datacontenttype="application/json", + ) client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) # Receive a CloudEvent - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100) + receive_result = client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100 + ) for receive_details in receive_result.value: cloud_event_received = receive_details.event print("CloudEvent: ", cloud_event_received) print("CloudEvent data: ", cloud_event_received.data) except HttpResponseError: raise - - diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py index 438f88c7b570..6ad93259494b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py @@ -39,7 +39,9 @@ client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10) + receive_result = client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10 + ) lock_tokens_to_renew = [] for item in receive_result.value: lock_tokens_to_renew.append(item.broker_properties.lock_token) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py index 0951efb50a7c..f96132b4c565 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py @@ -39,7 +39,9 @@ client.send(topic_name=TOPIC_NAME, events=cloud_event) # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 + ) lock_tokens_to_release = [] for item in receive_result.value: lock_tokens_to_release.append(item.broker_properties.lock_token) @@ -56,7 +58,9 @@ print("Released Event:", release_events) # Receive CloudEvents again - receive_result = client.receive_cloud_events(topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15) + receive_result = client.receive_cloud_events( + topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 + ) print("Received events after release:", receive_result.value) # Acknowledge a LockToken that was released diff --git a/sdk/eventgrid/azure-eventgrid/setup.py b/sdk/eventgrid/azure-eventgrid/setup.py index ad121db2982c..ee29cfadd35d 100644 --- a/sdk/eventgrid/azure-eventgrid/setup.py +++ b/sdk/eventgrid/azure-eventgrid/setup.py @@ -62,8 +62,8 @@ "azure.eventgrid": ["py.typed"], }, install_requires=[ - "isodate<1.0.0,>=0.6.1", - "azure-core<2.0.0,>=1.30.0", + "isodate>=0.6.1", + "azure-core>=1.30.0", "typing-extensions>=4.6.0", ], python_requires=">=3.8", diff --git a/sdk/eventgrid/azure-eventgrid/swagger/_constants.py b/sdk/eventgrid/azure-eventgrid/swagger/_constants.py index b9ba703da2e4..0a2cfc4503c7 100644 --- a/sdk/eventgrid/azure-eventgrid/swagger/_constants.py +++ b/sdk/eventgrid/azure-eventgrid/swagger/_constants.py @@ -29,7 +29,7 @@ "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/eventgrid/data-plane/Microsoft.Web/stable/2018-01-01/Web.json", "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/eventgrid/data-plane/Microsoft.HealthcareApis/stable/2018-01-01/HealthcareApis.json", "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/eventgrid/data-plane/Microsoft.ApiCenter/stable/2018-01-01/ApiCenter.json", - ] +] ####################################################### @@ -64,9 +64,21 @@ "ServiceBusDeadletterMessagesAvailableWithNoListenerEventName": "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListeners", } -EXCEPTIONS = ['ContainerRegistryArtifactEventData', 'ContainerRegistryEventData', 'ContainerServiceClusterSupportEventData', 'ContainerServiceNodePoolRollingEventData', - 'EventGridMQTTClientEventData', 'AppConfigurationSnapshotEventData', 'HealthResourcesResourceEventData', 'AcsRouterJobEventData', 'AcsRouterWorkerEventData', 'AcsRouterEventData', - 'AvsClusterEventData', 'AvsPrivateCloudEventData', 'AvsScriptExecutionEventData', "AcsMessageEventData" - ] +EXCEPTIONS = [ + "ContainerRegistryArtifactEventData", + "ContainerRegistryEventData", + "ContainerServiceClusterSupportEventData", + "ContainerServiceNodePoolRollingEventData", + "EventGridMQTTClientEventData", + "AppConfigurationSnapshotEventData", + "HealthResourcesResourceEventData", + "AcsRouterJobEventData", + "AcsRouterWorkerEventData", + "AcsRouterEventData", + "AvsClusterEventData", + "AvsPrivateCloudEventData", + "AvsScriptExecutionEventData", + "AcsMessageEventData", +] NAMING_CHANGES = ["AcsMessageDeliveryStatusUpdatedEventName", "AcsMessageReceivedEventName"] diff --git a/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py b/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py index f1a2cd34d400..842afcc14797 100644 --- a/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py +++ b/sdk/eventgrid/azure-eventgrid/swagger/postprocess_eventnames.py @@ -12,8 +12,8 @@ def extract(definitions): return tups = [] for event in definitions: - if event.endswith('Data') and event not in EXCEPTIONS: - key, txt = "Name".join(event.rsplit('Data', 1)), definitions[event]['description'] + if event.endswith("Data") and event not in EXCEPTIONS: + key, txt = "Name".join(event.rsplit("Data", 1)), definitions[event]["description"] if key in NAMING_CHANGES: key = key.replace("Acs", "AcsAdvanced") try: @@ -32,9 +32,7 @@ def extract(definitions): def generate_enum_content(tuples): - print( - "# These names at the top are 'corrected' aliases of duplicate values that appear below, which are" - ) + print("# These names at the top are 'corrected' aliases of duplicate values that appear below, which are") print("# deprecated but maintained for backwards compatibility.") for k, v in backward_compat.items(): print(k + " = '" + v + "'\n") diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index 0676dd77c87d..d95ebca3e613 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -26,13 +26,21 @@ import os import pytest from urllib.parse import urlparse -from devtools_testutils import add_general_string_sanitizer, test_proxy, add_body_key_sanitizer, add_header_regex_sanitizer, add_oauth_response_sanitizer, add_body_regex_sanitizer +from devtools_testutils import ( + add_general_string_sanitizer, + test_proxy, + add_body_key_sanitizer, + add_header_regex_sanitizer, + add_oauth_response_sanitizer, + add_body_regex_sanitizer, +) from devtools_testutils.sanitizers import ( add_remove_header_sanitizer, add_general_regex_sanitizer, set_custom_default_matcher, ) + @pytest.fixture(scope="session", autouse=True) def add_sanitizers(test_proxy): # this can be reverted to set_bodiless_matcher() after tests are re-recorded and don't contain these headers @@ -70,9 +78,9 @@ def add_sanitizers(test_proxy): eventgrid_topic_key = os.getenv("EVENTGRID_TOPIC_KEY", "sanitized") eventgrid_topic_endpoint = os.getenv("EVENTGRID_TOPIC_ENDPOINT", "sanitized") - eventgrid_partner_channel_name=os.getenv("EVENTGRID_PARTNER_CHANNEL_NAME", "sanitized") - eventgrid_partner_namespace_topic_endpoint=os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT", "sanitized") - eventgrid_partner_namespace_topic_key=os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY", "sanitized") + eventgrid_partner_channel_name = os.getenv("EVENTGRID_PARTNER_CHANNEL_NAME", "sanitized") + eventgrid_partner_namespace_topic_endpoint = os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_ENDPOINT", "sanitized") + eventgrid_partner_namespace_topic_key = os.getenv("EVENTGRID_PARTNER_NAMESPACE_TOPIC_KEY", "sanitized") # Need to santize namespace for eventgrid_topic: try: @@ -85,4 +93,3 @@ def add_sanitizers(test_proxy): add_general_string_sanitizer(target=eventgrid_client_id, value="00000000-0000-0000-0000-000000000000") add_general_string_sanitizer(target=eventgrid_client_secret, value="sanitized") add_general_string_sanitizer(target=tenant_id, value="00000000-0000-0000-0000-000000000000") - diff --git a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py index 1343179da503..6b8fcb2b73fc 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py +++ b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py @@ -16,15 +16,9 @@ ID_JSON_FIELD = JsonField(source_field="customId") TOPIC_JSON_FIELD = JsonField(source_field="customTopic") EVENT_TIME_JSON_FIELD = JsonField(source_field="customEventTime") -EVENT_TYPE_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( - source_field="customEventType", default_value="" -) -SUBJECT_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( - source_field="customSubject", default_value="" -) -DATA_VERSION_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault( - source_field="customDataVersion", default_value="" -) +EVENT_TYPE_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field="customEventType", default_value="") +SUBJECT_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field="customSubject", default_value="") +DATA_VERSION_JSON_FIELD_WITH_DEFAULT = JsonFieldWithDefault(source_field="customDataVersion", default_value="") CUSTOM_JSON_INPUT_SCHEMA_MAPPING = JsonInputSchemaMapping( id=ID_JSON_FIELD, topic=TOPIC_JSON_FIELD, @@ -54,4 +48,4 @@ eventgrid_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", eventgrid_topic_name="faketopic", eventgrid_event_subscription_name="fakesub", -) \ No newline at end of file +) diff --git a/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py b/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py index 5ad2958c9b8c..f08902d3aaec 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py +++ b/sdk/eventgrid/azure-eventgrid/tests/perfstress_tests/send.py @@ -25,21 +25,15 @@ def __init__(self, arguments): endpoint = self.get_from_env("EG_TOPIC_HOSTNAME") # Create clients - self.publisher_client = SyncPublisherClient( - endpoint=endpoint, credential=AzureKeyCredential(topic_key) - ) - self.async_publisher_client = AsyncPublisherClient( - endpoint=endpoint, credential=AzureKeyCredential(topic_key) - ) + self.publisher_client = SyncPublisherClient(endpoint=endpoint, credential=AzureKeyCredential(topic_key)) + self.async_publisher_client = AsyncPublisherClient(endpoint=endpoint, credential=AzureKeyCredential(topic_key)) self.event_list = [] for _ in range(self.args.num_events): self.event_list.append( EventGridEvent( event_type="Contoso.Items.ItemReceived", - data={ - "services": ["EventGrid", "ServiceBus", "EventHubs", "Storage"] - }, + data={"services": ["EventGrid", "ServiceBus", "EventHubs", "Storage"]}, subject="Door1", data_version="2.0", ) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py index 87d08b9fdbc7..bf1ba4ac12fe 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py @@ -43,9 +43,7 @@ def test_cloud_event_policy_copies(self): def test_cloud_event_policy_no_copy_if_trace_exists(self): policy = CloudEventDistributedTracingPolicy() - cloud_storage_dict.update( - {"traceparent": "exists", "tracestate": "state_exists"} - ) + cloud_storage_dict.update({"traceparent": "exists", "tracestate": "state_exists"}) body = json.dumps([cloud_storage_dict]) universal_request = HttpRequest("POST", "http://127.0.0.1/", data=body) universal_request.headers["content-type"] = _content_type diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py index dca0af806cb3..e7052226447d 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py @@ -13,16 +13,12 @@ class TestEventGridPublisherClientCncf(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_dict( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -42,9 +38,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_base64_using_data( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -62,9 +56,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_none( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -76,9 +68,7 @@ def test_send_cncf_data_none( @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_str( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -96,9 +86,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_as_list( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -110,9 +98,7 @@ def test_send_cncf_data_as_list( @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_with_extensions( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cncf_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py index a421181f4d82..247317ce074c 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py @@ -15,17 +15,13 @@ class TestEventGridPublisherClientCncf(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_dict_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_dict_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -46,9 +42,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_base64_using_data_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_base64_using_data_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -67,9 +61,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_none_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_none_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -82,9 +74,7 @@ async def test_send_cncf_data_none_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_str_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_str_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -103,9 +93,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_as_list_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_as_list_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -118,9 +106,7 @@ async def test_send_cncf_data_as_list_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_with_extensions_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cncf_data_with_extensions_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py index f05ab6841345..d5fff9e9008a 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py @@ -15,71 +15,85 @@ from eventgrid_preparer import EventGridPreparer +def _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level): + if level == "Standard": + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=100) + tokens = [] + for detail in events.value: + token = detail.broker_properties.lock_token + tokens.append(token) + ack_result = client.acknowledge_cloud_events( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens + ) + class ArgPasser: def __call__(self, fn): def _preparer(test_class, level, **kwargs): fn(test_class, level, **kwargs) + return _preparer + class TestEGDualClient(AzureRecordedTestCase): def create_eg_client(self, endpoint, key, level): - client = EventGridClient( - endpoint=endpoint, credential=AzureKeyCredential(key), level=level - ) + client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key), level=level) return client - @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_publish(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_create_client_publish( + self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + from xml.etree import ElementTree as ET + xml_string = """test""" - tree = xml_string.encode('utf-8') + tree = xml_string.encode("utf-8") event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data=tree, datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - if level=="Basic": + if level == "Basic": with pytest.raises(ValueError): - client.send( - topic_name=eventgrid_topic_name, events=event, binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) else: - client.send( - topic_name=eventgrid_topic_name, events=event, binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_receive(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_create_client_receive( + self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + from xml.etree import ElementTree as ET + xml_string = """test""" - tree = xml_string.encode('utf-8') + tree = xml_string.encode("utf-8") event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data=tree, datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - if level=="Basic": + if level == "Basic": with pytest.raises(ValueError): client.receive_cloud_events( topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name @@ -89,132 +103,172 @@ def test_create_client_receive(self, level, eventgrid_endpoint, eventgrid_key, e topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name ) + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_publish_event(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_topic_key, eventgrid_topic_endpoint): - if level=="Basic": + def test_create_client_publish_event( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_topic_key, + eventgrid_topic_endpoint, + ): + if level == "Basic": client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) else: client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + event = EventGridEvent( id="7f7d", subject="MySubject", - data={ - "test": "data" - }, + data={"test": "data"}, event_type="Contoso.Items.ItemReceived", - data_version="1.0" + data_version="1.0", ) - if level=="Basic": - client.send( - events=event - ) + if level == "Basic": + client.send(events=event) else: with pytest.raises(TypeError): - client.send( - topic_name=eventgrid_topic_name, events=event - ) + client.send(topic_name=eventgrid_topic_name, events=event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_cloud_event(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): - if level=="Basic": - client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + def test_create_client_cloud_event( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, + eventgrid_cloud_event_topic_endpoint, + ): + if level == "Basic": + client = self.create_eg_client( + eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level + ) else: client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data={"test": "data"}, datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - client.send( - topic_name=eventgrid_topic_name, events=event - ) + client.send(topic_name=eventgrid_topic_name, events=event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_channel_name(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_partner_namespace_topic_key, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name): - - client = self.create_eg_client(eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, level=level) - + def test_create_client_channel_name( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_partner_namespace_topic_key, + eventgrid_partner_namespace_topic_endpoint, + eventgrid_partner_channel_name, + ): + + client = self.create_eg_client( + eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, level=level + ) + event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data={"test": "data"}, datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - if level=="Standard": + if level == "Standard": with pytest.raises(ValueError): - client.send( - topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name - ) + client.send(topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name) else: - client.send( - topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name - ) + client.send(topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_publish_endpoint(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): - + def test_publish_endpoint( + self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data={"test": "data"}, datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - if level=="Basic": + if level == "Basic": with pytest.raises(ResourceNotFoundError): - client.send( - topic_name=eventgrid_topic_name, events=event - ) + client.send(topic_name=eventgrid_topic_name, events=event) else: - client.send( - topic_name=eventgrid_topic_name, events=event - ) + client.send(topic_name=eventgrid_topic_name, events=event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_publish_cncf_events(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): - if level=="Basic": - client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + def test_publish_cncf_events( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, + eventgrid_cloud_event_topic_endpoint, + ): + if level == "Basic": + client = self.create_eg_client( + eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level + ) else: client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + attributes = { "type": "com.example.sampletype1", "source": "https://example.com/event-producer", @@ -222,51 +276,68 @@ def test_publish_cncf_events(self, level, eventgrid_endpoint, eventgrid_key, eve data = {"message": "Hello World!"} cloud_event = CNCFCloudEvent(attributes, data) - if level==ClientLevel.STANDARD: - with pytest.raises(HttpResponseError): - client.send( - topic_name=eventgrid_topic_name, events=cloud_event - ) - else: - client.send( - topic_name=eventgrid_topic_name, events=cloud_event - ) - + client.send(topic_name=eventgrid_topic_name, events=cloud_event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + + @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_cloud_event_dict(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, eventgrid_cloud_event_topic_endpoint): - if level=="Basic": - client = self.create_eg_client(eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level) + def test_create_client_cloud_event_dict( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_cloud_event_topic_key, + eventgrid_cloud_event_topic_endpoint, + ): + if level == "Basic": + client = self.create_eg_client( + eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level + ) else: client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = {"type": "Contoso.Items.ItemReceived", + + event = { + "type": "Contoso.Items.ItemReceived", "source": "source", "subject": "MySubject", "data": {"test": "data"}, "datacontenttype": "application/json", - "extensions": {"extension1": "value1", "extension2": "value2"}} + "extension1": "value1", + "extension2": "value2", + } + + client.send(topic_name=eventgrid_topic_name, events=event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - client.send( - topic_name=eventgrid_topic_name, events=event - ) @pytest.mark.live_test_only() @pytest.mark.parametrize("level", ["Standard", "Basic"]) @EventGridPreparer() @ArgPasser() @recorded_by_proxy - def test_create_client_publish_event_dict(self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name, - eventgrid_topic_key, eventgrid_topic_endpoint): - if level=="Basic": + def test_create_client_publish_event_dict( + self, + level, + eventgrid_endpoint, + eventgrid_key, + eventgrid_topic_name, + eventgrid_event_subscription_name, + eventgrid_topic_key, + eventgrid_topic_endpoint, + ): + if level == "Basic": client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) else: client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - + event = { "eventType": "Contoso.Items.ItemReceived", "data": {"itemSku": "Contoso Item SKU #1"}, @@ -276,12 +347,11 @@ def test_create_client_publish_event_dict(self, level, eventgrid_endpoint, event "eventTime": datetime.now(), } - if level==ClientLevel.STANDARD: + if level == ClientLevel.STANDARD: with pytest.raises(TypeError): - client.send( - topic_name=eventgrid_topic_name, events=event - ) + client.send(topic_name=eventgrid_topic_name, events=event) else: - client.send( - topic_name=eventgrid_topic_name, events=event - ) \ No newline at end of file + client.send(topic_name=eventgrid_topic_name, events=event) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) + diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py index 19a90030a072..9a6b3517fdd0 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py @@ -14,79 +14,73 @@ from eventgrid_preparer import EventGridPreparer +def _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name): + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=100) + tokens = [] + for detail in events.value: + token = detail.broker_properties.lock_token + tokens.append(token) + ack = client.acknowledge_cloud_events( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens + ) class TestEGClientExceptions(AzureRecordedTestCase): def create_eg_client(self, endpoint, key): - client = EventGridClient( - endpoint=endpoint, credential=AzureKeyCredential(key) - ) + client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key)) return client - @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy - def test_publish_binary_mode_xml(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_binary_mode_xml( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - + from xml.etree import ElementTree as ET + xml_string = """test""" - tree = xml_string.encode('utf-8') + tree = xml_string.encode("utf-8") event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", data=tree, datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) - client.send( - topic_name=eventgrid_topic_name, events=event, binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) time.sleep(5) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) - - tokens = [] - for detail in events.value: - token = detail.broker_properties.lock_token - tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) - - + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy - def test_publish_binary_mode_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_binary_mode_cloud_event( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", - data=b'this is binary data', - datacontenttype='text/plain' - ) - - client.send( - topic_name= eventgrid_topic_name, events=event, binary_mode=True + data=b"this is binary data", + datacontenttype="text/plain", ) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) - - tokens = [] - for detail in events.value: - token = detail.broker_properties.lock_token - tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) @EventGridPreparer() @recorded_by_proxy - def test_publish_binary_mode_incorrect_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_binary_mode_incorrect_cloud_event( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -94,17 +88,17 @@ def test_publish_binary_mode_incorrect_cloud_event(self, eventgrid_endpoint, eve source="source", subject="MySubject", data={"key": "value"}, - datacontenttype='text/plain' + datacontenttype="text/plain", ) with pytest.raises(TypeError): - client.send( - topic_name=eventgrid_topic_name, events=event, binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) @EventGridPreparer() @recorded_by_proxy - def test_publish_binary_mode_list_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_binary_mode_list_cloud_event( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -112,18 +106,18 @@ def test_publish_binary_mode_list_cloud_event(self, eventgrid_endpoint, eventgri source="source", subject="MySubject", data={"key": "value"}, - datacontenttype='text/plain' + datacontenttype="text/plain", ) with pytest.raises(TypeError): - client.send( - topic_name=eventgrid_topic_name, events=[event], binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=[event], binary_mode=True) @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy - def test_publish_binary_mode_combinations(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_binary_mode_combinations( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -131,79 +125,107 @@ def test_publish_binary_mode_combinations(self, eventgrid_endpoint, eventgrid_ke source="source", subject="MySubject", data=b"hello", - datacontenttype='text/plain' + datacontenttype="text/plain", ) - dict_event = {"type": "Contoso.Items.ItemReceived", "source": "source", "subject": "MySubject", "data": b"hello", "datacontenttype": "text/plain"} + dict_event = { + "type": "Contoso.Items.ItemReceived", + "source": "source", + "subject": "MySubject", + "data": b"hello", + "datacontenttype": "text/plain", + } - - client.send( - topic_name=eventgrid_topic_name, events=event, binary_mode=True - ) + client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - client.send( - topic_name=eventgrid_topic_name, events=dict_event, binary_mode=True - ) - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) - tokens = [] - for detail in events.value: - token = detail.broker_properties.lock_token - tokens.append(token) - rejected_result = client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens) + client.send(topic_name=eventgrid_topic_name, events=dict_event, binary_mode=True) + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy - def test_publish_receive_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_receive_cloud_event( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", - data=b'this is binary data', + data=b"this is binary data", ) - client.send( - topic_name=eventgrid_topic_name, events=[event] - ) + client.send(topic_name=eventgrid_topic_name, events=[event]) time.sleep(5) - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name,max_events=1) + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.acknowledge_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) + ack = client.acknowledge_cloud_events( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token] + ) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 @pytest.mark.live_test_only() @EventGridPreparer() @recorded_by_proxy - def test_publish_release_cloud_event(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_publish_release_cloud_event( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", - data=b'this is binary data', + data=b"this is binary data", ) - client.send( - topic_name=eventgrid_topic_name, events=[event] - ) - - time.sleep(5) + client.send(topic_name=eventgrid_topic_name, events=[event]) events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) lock_token = events.value[0].broker_properties.lock_token - ack = client.release_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token]) + ack = client.release_cloud_events( + eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token] + ) assert len(ack.succeeded_lock_tokens) == 1 assert len(ack.failed_lock_tokens) == 0 events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) - assert events.value[0].broker_properties.delivery_count > 1 \ No newline at end of file + assert events.value[0].broker_properties.delivery_count > 1 + + client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[events.value[0].broker_properties.lock_token]) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) + + + @pytest.mark.live_test_only() + @EventGridPreparer() + @recorded_by_proxy + def test_receive_type( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): + client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) + + event = CloudEvent( + type="Contoso.Items.ItemReceived", + source="source", + subject="MySubject", + data={"key": "value"}, + ) + + client.send(topic_name=eventgrid_topic_name, events=event) + + time.sleep(5) + + events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) + data = events.value[0].event.data + + assert isinstance(data, dict) + + _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py index 2751e0615d23..6dab23edf38b 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py @@ -18,9 +18,7 @@ class TestEGClientExceptions(AzureRecordedTestCase): def create_eg_client(self, endpoint, key): - client = EventGridClient( - endpoint=endpoint, credential=AzureKeyCredential(key) - ) + client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key)) return client @EventGridPreparer() @@ -38,7 +36,7 @@ def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key client.send(topic_name=eventgrid_topic_name, events=[event]) @EventGridPreparer() - @recorded_by_proxy + @recorded_by_proxy def test_publish_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) event = CloudEvent( @@ -61,54 +59,54 @@ def test_receive_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, @EventGridPreparer() @recorded_by_proxy - def test_receive_cloud_event_max_events_negative(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_receive_cloud_event_max_events_negative( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20 - ) + client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20) @EventGridPreparer() @recorded_by_proxy - def test_receive_cloud_event_timeout_negative(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_receive_cloud_event_timeout_negative( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20 - ) + client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20) @EventGridPreparer() @recorded_by_proxy - def test_receive_cloud_event_timeout_max_value(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_receive_cloud_event_timeout_max_value( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121 - ) + client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121) @EventGridPreparer() @recorded_by_proxy - def test_receive_cloud_event_timeout_min_value(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_receive_cloud_event_timeout_min_value( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(HttpResponseError): - client.receive_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9 - ) + client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9) @EventGridPreparer() @recorded_by_proxy - def test_acknowledge_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): + def test_acknowledge_cloud_event_not_found( + self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) with pytest.raises(ResourceNotFoundError): lock_tokens = ["faketoken"] - client.acknowledge_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) + client.acknowledge_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) @EventGridPreparer() @recorded_by_proxy @@ -117,9 +115,7 @@ def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, with pytest.raises(ResourceNotFoundError): lock_tokens = ["faketoken"] - client.release_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) + client.release_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) @EventGridPreparer() @recorded_by_proxy @@ -128,13 +124,13 @@ def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, e lock_tokens = ["faketoken"] with pytest.raises(ResourceNotFoundError): - client.reject_cloud_events( - "faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) + client.reject_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) @EventGridPreparer() @recorded_by_proxy - def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_acknowledge_cloud_event_invalid_token( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] @@ -148,7 +144,9 @@ def test_acknowledge_cloud_event_invalid_token(self, eventgrid_endpoint, eventgr @EventGridPreparer() @recorded_by_proxy - def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_release_cloud_event_invalid_token( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] @@ -162,7 +160,9 @@ def test_release_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_k @EventGridPreparer() @recorded_by_proxy - def test_reject_cloud_event_invalid_token(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name): + def test_reject_cloud_event_invalid_token( + self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name + ): client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) lock_tokens = ["faketoken"] diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py index 4e1910b1bbad..bbd5ad4ac0f4 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_event_get_bytes.py @@ -135,9 +135,7 @@ def test_get_bytes_storage_queue_wrong_content(): string = "This is a random string which must fail" obj = MockQueueMessage(content=string) - with pytest.raises( - ValueError, match="Failed to load JSON content from the object." - ): + with pytest.raises(ValueError, match="Failed to load JSON content from the object."): _get_json_content(obj) @@ -172,9 +170,7 @@ def test_get_bytes_servicebus_wrong_content(): sequence_number=11219, lock_token="233146e3-d5a6-45eb-826f-691d82fb8b13", ) - with pytest.raises( - ValueError, match="Failed to load JSON content from the object." - ): + with pytest.raises(ValueError, match="Failed to load JSON content from the object."): dict = _get_json_content(obj) @@ -188,9 +184,7 @@ def test_get_bytes_eventhubs(): def test_get_bytes_eventhubs_wrong_content(): obj = MockEventhubData(body=MockEhBody(data="random string")) - with pytest.raises( - ValueError, match="Failed to load JSON content from the object." - ): + with pytest.raises(ValueError, match="Failed to load JSON content from the object."): dict = _get_json_content(obj) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index c939ee1d8bc8..69aac887821f 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -35,9 +35,7 @@ class TestEventGridPublisherClient(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @@ -54,9 +52,7 @@ def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_fails_without_full_url( - self, eventgrid_topic_key, eventgrid_topic_endpoint - ): + def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, eventgrid_topic_endpoint): akc_credential = AzureKeyCredential(eventgrid_topic_key) parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, akc_credential) @@ -101,9 +97,7 @@ def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_data_bytes( - self, eventgrid_topic_endpoint - ): + def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -116,9 +110,7 @@ def test_send_event_grid_event_data_bytes( @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_dict_data_bytes( - self, eventgrid_topic_endpoint - ): + def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { "subject": "sample", @@ -149,9 +141,7 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_dict( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -163,13 +153,9 @@ def test_send_cloud_event_data_dict( @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_NULL( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - cloud_event = CloudEvent( - source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" - ) + cloud_event = CloudEvent(source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event") def callback(request): req = json.loads(request.http_request.body) @@ -179,9 +165,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_base64_using_data( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -197,9 +181,7 @@ def callback(request): client.send(cloud_event, raw_response_hook=callback) def test_send_cloud_event_fails_on_providing_data_and_b64(self): - with pytest.raises( - ValueError, match="Unexpected keyword arguments data_base64.*" - ): + with pytest.raises(ValueError, match="Unexpected keyword arguments data_base64.*"): cloud_event = CloudEvent( source="http://samplesource.dev", data_base64=b"cloudevent", @@ -209,20 +191,14 @@ def test_send_cloud_event_fails_on_providing_data_and_b64(self): @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_none( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - cloud_event = CloudEvent( - source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" - ) + cloud_event = CloudEvent(source="http://samplesource.dev", data=None, type="Sample.Cloud.Event") client.send(cloud_event) @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_str( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -233,9 +209,7 @@ def test_send_cloud_event_data_str( @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_bytes( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -246,9 +220,7 @@ def test_send_cloud_event_data_bytes( @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_as_list( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -259,9 +231,7 @@ def test_send_cloud_event_data_as_list( @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_data_with_extensions( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -277,9 +247,7 @@ def test_send_cloud_event_data_with_extensions( @EventGridPreparer() @recorded_by_proxy - def test_send_cloud_event_dict( - self, eventgrid_cloud_event_topic_endpoint - ): + def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { "id": "1234", @@ -294,9 +262,7 @@ def test_send_cloud_event_dict( @recorded_by_proxy def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_endpoint): expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) - signature = generate_sas( - eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc - ) + signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) credential = AzureSasCredential(signature) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( @@ -310,16 +276,12 @@ def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_en @EventGridPreparer() @recorded_by_proxy def test_send_NONE_credential(self, eventgrid_topic_endpoint): - with pytest.raises( - ValueError, match="Parameter 'self._credential' must not be None." - ): + with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) @EventGridPreparer() @recorded_by_proxy - def test_send_custom_schema_event( - self, eventgrid_custom_event_topic_endpoint - ): + def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { "customSubject": "sample", @@ -333,9 +295,7 @@ def test_send_custom_schema_event( @EventGridPreparer() @recorded_by_proxy - def test_send_custom_schema_event_as_list( - self, eventgrid_custom_event_topic_endpoint - ): + def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { "customSubject": "sample", @@ -380,11 +340,14 @@ def test_send_token_credential(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @recorded_by_proxy - def test_send_partner_namespace(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, eventgrid_partner_channel_name): + def test_send_partner_namespace( + self, + eventgrid_partner_namespace_topic_endpoint, + eventgrid_partner_namespace_topic_key, + eventgrid_partner_channel_name, + ): credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) - client = EventGridPublisherClient( - eventgrid_partner_namespace_topic_endpoint, credential - ) + client = EventGridPublisherClient(eventgrid_partner_namespace_topic_endpoint, credential) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index c483097183c7..3eee77aa3ce2 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -31,17 +31,13 @@ class TestEventGridPublisherClient(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_dict_async( - self, eventgrid_topic_endpoint - ): + async def test_send_event_grid_event_data_dict_async(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -54,9 +50,7 @@ async def test_send_event_grid_event_data_dict_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_as_list_async( - self, eventgrid_topic_endpoint - ): + async def test_send_event_grid_event_data_as_list_async(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event1 = EventGridEvent( subject="sample", @@ -93,9 +87,7 @@ async def test_send_event_grid_event_fails_without_full_url_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_str_async( - self, eventgrid_topic_endpoint - ): + async def test_send_event_grid_event_data_str_async(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -108,9 +100,7 @@ async def test_send_event_grid_event_data_str_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_bytes_async( - self, eventgrid_topic_endpoint - ): + async def test_send_event_grid_event_data_bytes_async(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -124,9 +114,7 @@ async def test_send_event_grid_event_data_bytes_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_dict_data_bytes_async( - self, eventgrid_topic_endpoint - ): + async def test_send_event_grid_event_dict_data_bytes_async(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { "subject": "sample", @@ -142,36 +130,25 @@ async def test_send_event_grid_event_dict_data_bytes_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_dict_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_dict_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = {"sample": "cloudevent"}, - type="Sample.Cloud.Event" - ) + source="http://samplesource.dev", data={"sample": "cloudevent"}, type="Sample.Cloud.Event" + ) await client.send(cloud_event) - @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - cloud_event = CloudEvent( - source = "http://samplesource.dev", - data = "cloudevent", - type="Sample.Cloud.Event" - ) + cloud_event = CloudEvent(source="http://samplesource.dev", data="cloudevent", type="Sample.Cloud.Event") await client.send(cloud_event) @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_str_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_str_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -183,9 +160,7 @@ async def test_send_cloud_event_data_str_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_bytes_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_bytes_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -197,9 +172,7 @@ async def test_send_cloud_event_data_bytes_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_as_list_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_as_list_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -211,9 +184,7 @@ async def test_send_cloud_event_data_as_list_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_with_extensions_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_with_extensions_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -230,9 +201,7 @@ async def test_send_cloud_event_data_with_extensions_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_dict_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_dict_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { "id": "1234", @@ -246,26 +215,18 @@ async def test_send_cloud_event_dict_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_none_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_none_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - cloud_event = CloudEvent( - source="http://samplesource.dev", data=None, type="Sample.Cloud.Event" - ) + cloud_event = CloudEvent(source="http://samplesource.dev", data=None, type="Sample.Cloud.Event") await client.send(cloud_event) @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_NULL_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_cloud_event_data_NULL_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) - cloud_event = CloudEvent( - source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event" - ) + cloud_event = CloudEvent(source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event") def callback(request): req = json.loads(request.http_request.body) @@ -276,13 +237,9 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_signature_credential_async( - self, eventgrid_topic_key, eventgrid_topic_endpoint - ): + async def test_send_signature_credential_async(self, eventgrid_topic_key, eventgrid_topic_endpoint): expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) - signature = generate_sas( - eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc - ) + signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) credential = AzureSasCredential(signature) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( @@ -296,9 +253,7 @@ async def test_send_signature_credential_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event_async( - self, eventgrid_custom_event_topic_endpoint - ): + async def test_send_custom_schema_event_async(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { "customSubject": "sample", @@ -313,9 +268,7 @@ async def test_send_custom_schema_event_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event_as_list_async( - self, eventgrid_custom_event_topic_endpoint - ): + async def test_send_custom_schema_event_as_list_async(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { "customSubject": "sample", @@ -338,9 +291,7 @@ async def test_send_custom_schema_event_as_list_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_and_close_async_session_async( - self, eventgrid_cloud_event_topic_endpoint - ): + async def test_send_and_close_async_session_async(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) async with client: # this throws if client can't close cloud_event = CloudEvent( @@ -354,9 +305,7 @@ async def test_send_and_close_async_session_async( @EventGridPreparer() @recorded_by_proxy_async def test_send_NONE_credential_async(self, eventgrid_topic_endpoint): - with pytest.raises( - ValueError, match="Parameter 'self._credential' must not be None." - ): + with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) @pytest.mark.live_test_only @@ -377,11 +326,14 @@ async def test_send_token_credential_async(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @recorded_by_proxy_async - async def test_send_partner_namespace_async(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, eventgrid_partner_channel_name): + async def test_send_partner_namespace_async( + self, + eventgrid_partner_namespace_topic_endpoint, + eventgrid_partner_namespace_topic_key, + eventgrid_partner_channel_name, + ): credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) - client = EventGridPublisherClient( - eventgrid_partner_namespace_topic_endpoint, credential - ) + client = EventGridPublisherClient(eventgrid_partner_namespace_topic_endpoint, credential) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", @@ -392,6 +344,4 @@ def callback(request): req = request.http_request.headers assert req.get("aeg-channel-name") == eventgrid_partner_channel_name - await client.send( - cloud_event, channel_name=eventgrid_partner_channel_name, raw_request_hook=callback - ) + await client.send(cloud_event, channel_name=eventgrid_partner_channel_name, raw_request_hook=callback) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index a6cddbd4bc1e..a19b3dd8e1a1 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -38,9 +38,7 @@ class TestEventGridPublisherClientExceptions(AzureMgmtRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @@ -82,9 +80,7 @@ def test_raise_on_bad_resource(self): def test_raise_on_large_payload(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) - path = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "./large_data.json") - ) + path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./large_data.json")) with open(path) as json_file: data = json.load(json_file) eg_event = EventGridEvent( diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index d69eb481f763..461c17453482 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -42,9 +42,7 @@ class TestEventGridPublisherClientExceptionsAsync(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential( - EventGridPublisherClient, credential=credential, endpoint=endpoint - ) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client @EventGridPreparer() @@ -90,9 +88,7 @@ async def test_raise_on_bad_resource(self): async def test_raise_on_large_payload(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) - path = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "./large_data.json") - ) + path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./large_data.json")) with open(path) as json_file: data = json.load(json_file) eg_event = EventGridEvent( diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py index a83caf6954ae..cebc392e4dea 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py @@ -104,10 +104,7 @@ def test_event_grid_event_raises_on_no_data(self): def test_import_from_system_events(self): var = SystemEventNames.AcsChatMemberAddedToThreadWithUserEventName assert var == "Microsoft.Communication.ChatMemberAddedToThreadWithUser" - assert ( - SystemEventNames.KeyVaultKeyNearExpiryEventName - == "Microsoft.KeyVault.KeyNearExpiry" - ) + assert SystemEventNames.KeyVaultKeyNearExpiryEventName == "Microsoft.KeyVault.KeyNearExpiry" var = SystemEventNames.ServiceBusActiveMessagesAvailableWithNoListenersEventName assert var == "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners" var = SystemEventNames.AcsChatThreadParticipantAddedEventName @@ -131,23 +128,9 @@ def test_servicebus_system_events_alias(self): SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName ) - assert ( - SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName - == val - ) - assert ( - SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName - == val - ) - assert ( - SystemEventNames(val) - == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName - ) - assert ( - SystemEventNames(val) - == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName - ) + assert SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName == val + assert SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName == val + assert SystemEventNames(val) == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenerEventName + assert SystemEventNames(val) == SystemEventNames.ServiceBusDeadletterMessagesAvailableWithNoListenersEventName with pytest.raises(ValueError): - SystemEventNames( - "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener" - ) + SystemEventNames("Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener") diff --git a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py index 2824d8a2251b..f597ca727f2a 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py +++ b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py @@ -10,21 +10,24 @@ from azure.eventgrid.models import * from azure.core.messaging import CloudEvent + class MyTestClass(object): def __init__(self, name): self.name = name + def __str__(self): return self.name - -class TestEGClientExceptions(): - + + +class TestEGClientExceptions: + def test_binary_request_format(self): event = CloudEvent( type="Contoso.Items.ItemReceived", source="source", subject="MySubject", - data=b'this is binary data', - datacontenttype="application/json" + data=b"this is binary data", + datacontenttype="application/json", ) request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) @@ -39,9 +42,9 @@ def test_binary_request_format_with_extensions_and_datacontenttype(self): type="Contoso.Items.ItemReceived", source="source", subject="MySubject", - data=b'this is my data', + data=b"this is my data", datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) @@ -60,9 +63,8 @@ def test_class_binary_request_format_error(self): subject="MySubject", data=test_class, datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"} + extensions={"extension1": "value1", "extension2": "value2"}, ) with pytest.raises(TypeError): _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) - From 303fc88f0bbfe7bc49860b4c659be12b4705458f Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 24 Apr 2024 14:13:00 -0700 Subject: [PATCH 22/43] ver (#35345) --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 2 +- sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 7619f52c83d7..b323a2bf7010 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -## 4.20.1b1 (2024-04-24) +## 4.20.0b2 (2024-04-24) This is a Beta of the EventGridClient diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index b578abb501c0..bbbdd5df00b5 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "4.20.1b1" +VERSION = "4.20.0b2" From ba8a71f3cce0dea81d9d753b59f644eb5fe345bc Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 24 Apr 2024 15:15:40 -0700 Subject: [PATCH 23/43] typo (#35348) --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index b323a2bf7010..1418b373dd5f 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -4,7 +4,7 @@ This is a Beta of the EventGridClient -### Bug Fixes +### Bug Fixed - Fixed serialization issues with CloudEvent and CNCF Cloud Event From e6b05cbe6094fdfbf525a984861573e69dc1ea4a Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 24 Apr 2024 15:57:50 -0700 Subject: [PATCH 24/43] typo (#35351) * typo * update --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 1418b373dd5f..e80ac1effa02 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,10 +1,10 @@ # Release History -## 4.20.0b2 (2024-04-24) +## 4.20.0b2 (2024-04-25) This is a Beta of the EventGridClient -### Bug Fixed +### Bugs Fixed - Fixed serialization issues with CloudEvent and CNCF Cloud Event From 6186af3900fe68c7a12a8e31de4002c9ba1bc106 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 30 May 2024 10:48:14 -0700 Subject: [PATCH 25/43] [EG] Archboard Feedback (#35738) * regen * remove all samples/tests before fixing * move all topic/sub to client level * update * updates * update samples * add other publisher tests * missing * content type * consumerclient * upload consumer tests * updates * update * changes * updates * rename * update * patch * test update * update tests * fix * updates snippets * update readme * try updating api_version * typo Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * typo2 Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> * renames/docs from comments * regen * update patch * remove import * caps --------- Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- sdk/eventgrid/azure-eventgrid/README.md | 16 +- .../azure/eventgrid/__init__.py | 6 +- .../azure/eventgrid/_client.py | 99 +++- .../azure/eventgrid/_configuration.py | 68 ++- .../azure/eventgrid/_legacy/_helpers.py | 2 +- .../eventgrid/_legacy/_publisher_client.py | 4 +- .../_legacy/aio/_publisher_client_async.py | 4 +- .../azure/eventgrid/_model_base.py | 28 +- .../azure/eventgrid/_operations/__init__.py | 6 +- .../eventgrid/_operations/_operations.py | 318 +++++++----- .../azure/eventgrid/_operations/_patch.py | 488 ++++-------------- .../azure-eventgrid/azure/eventgrid/_patch.py | 130 +++-- .../azure/eventgrid/_vendor.py | 15 +- .../azure/eventgrid/aio/__init__.py | 6 +- .../azure/eventgrid/aio/_client.py | 103 +++- .../azure/eventgrid/aio/_configuration.py | 70 ++- .../eventgrid/aio/_operations/__init__.py | 6 +- .../eventgrid/aio/_operations/_operations.py | 296 ++++++----- .../azure/eventgrid/aio/_operations/_patch.py | 346 ++++--------- .../azure/eventgrid/aio/_patch.py | 113 ++-- .../azure/eventgrid/aio/_vendor.py | 15 +- .../azure/eventgrid/models/__init__.py | 4 +- .../azure/eventgrid/models/_enums.py | 12 +- .../azure/eventgrid/models/_models.py | 79 +-- .../azure/eventgrid/models/_patch.py | 29 -- .../azure-eventgrid/samples/README.md | 73 +-- .../sample_acknowledge_operation_async.py | 51 -- .../sample_all_operations_async.py | 127 ----- .../sample_binary_mode_async.py | 75 --- .../sample_publish_operation_async.py | 69 --- .../sample_publish_receive_renew_async.py | 64 --- .../sample_publish_release_receive_async.py | 81 --- .../sample_receive_operation_async.py | 51 -- .../sample_reject_operation_async.py | 51 -- .../sample_release_operation_async.py | 52 -- .../sample_renew_locks_operation_async.py | 50 -- .../sample_authentication_async.py | 19 +- .../sample_consume_process_events_async.py | 136 +++++ ...le_publish_cloud_event_using_dict_async.py | 34 +- .../sample_publish_cncf_cloud_events_async.py | 30 +- ..._publish_custom_schema_to_a_topic_async.py | 4 +- ...ample_publish_eg_event_using_dict_async.py | 4 +- ...ple_publish_eg_events_to_a_domain_async.py | 42 +- ...mple_publish_eg_events_to_a_topic_async.py | 26 +- ...s_to_a_topic_using_sas_credential_async.py | 4 +- ...nts_using_cloud_events_1.0_schema_async.py | 26 +- .../sample_publish_to_channel_async.py | 4 +- .../consume_cloud_events_from_eventhub.py | 4 +- ...ish_cloud_events_to_custom_topic_sample.py | 15 +- ...ish_cloud_events_to_domain_topic_sample.py | 18 +- ...sh_custom_schema_events_to_topic_sample.py | 5 +- ...vent_grid_events_to_custom_topic_sample.py | 17 +- ...ish_with_shared_access_signature_sample.py | 16 +- .../sample_acknowledge_operation.py | 44 -- .../sample_binary_mode.py | 66 --- .../sample_publish_operation.py | 60 --- .../sample_publish_receive_renew.py | 57 -- .../sample_publish_release_receive.py | 74 --- .../sample_receive_operation.py | 44 -- .../sample_reject_operation.py | 43 -- .../sample_release_operation.py | 44 -- .../sample_renew_locks_operation.py | 43 -- .../sync_samples/sample_authentication.py | 22 +- ...ns.py => sample_consume_process_events.py} | 68 +-- .../sample_publish_cloud_event_using_dict.py | 28 +- .../sample_publish_cncf_cloud_events.py | 28 +- ...sample_publish_custom_schema_to_a_topic.py | 4 +- .../sample_publish_eg_event_using_dict.py | 4 +- .../sample_publish_eg_events_to_a_domain.py | 4 +- .../sample_publish_eg_events_to_a_topic.py | 4 +- ..._events_to_a_topic_using_sas_credential.py | 4 +- ...sh_events_using_cloud_events_1.0_schema.py | 4 +- .../sync_samples/sample_publish_to_channel.py | 4 +- .../azure-eventgrid/tests/test_dual_client.py | 357 ------------- .../azure-eventgrid/tests/test_eg_client.py | 231 --------- .../tests/test_eg_client_exceptions.py | 175 ------- .../tests/test_eg_consumer_client.py | 163 ++++++ .../tests/test_eg_consumer_client_async.py | 168 ++++++ .../tests/test_eg_publisher_client.py | 19 +- .../tests/unittests/test_binary_mode.py | 70 --- .../azure-eventgrid/tsp-location.yaml | 2 +- sdk/eventgrid/test-resources.json | 10 +- 82 files changed, 1860 insertions(+), 3395 deletions(-) delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py create mode 100644 sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py delete mode 100644 sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py rename sdk/eventgrid/azure-eventgrid/samples/sync_samples/{eventgrid_client_samples/sample_all_operations.py => sample_consume_process_events.py} (70%) delete mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py delete mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py delete mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py delete mode 100644 sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 1d2fdc57ca42..79ccaba5d902 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -75,11 +75,11 @@ For example, you can use `DefaultAzureCredential` to construct a client which wi ```python from azure.identity import DefaultAzureCredential -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent default_az_credential = DefaultAzureCredential() -endpoint = os.environ["EVENTGRID_ENDPOINT"] -client = EventGridClient(endpoint, default_az_credential) +endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] +client = EventGridPublisherClient(endpoint, default_az_credential) ``` @@ -105,14 +105,14 @@ pass the key as a string into an instance of [AzureKeyCredential][azure-key-cred ```python import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential -key = os.environ["EVENTGRID_KEY"] -endpoint = os.environ["EVENTGRID_ENDPOINT"] +topic_key = os.environ["EVENTGRID_TOPIC_KEY"] +endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -credential_key = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential_key) +credential_key = AzureKeyCredential(topic_key) +client = EventGridPublisherClient(endpoint, credential_key) ``` diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py index dbb47f36735d..7189e7b5a4f9 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py @@ -6,7 +6,8 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClient +from ._patch import EventGridPublisherClient +from ._patch import EventGridConsumerClient from ._version import VERSION __version__ = VERSION @@ -19,7 +20,8 @@ from ._patch import patch_sdk as _patch_sdk __all__ = [ - "EventGridClient", + "EventGridPublisherClient", + "EventGridConsumerClient", ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py index 2d43c8ce7ea4..c6ce28f47f9a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_client.py @@ -14,8 +14,8 @@ from azure.core.pipeline import policies from azure.core.rest import HttpRequest, HttpResponse -from ._configuration import EventGridClientConfiguration -from ._operations import EventGridClientOperationsMixin +from ._configuration import EventGridConsumerClientConfiguration, EventGridPublisherClientConfiguration +from ._operations import EventGridConsumerClientOperationsMixin, EventGridPublisherClientOperationsMixin from ._serialization import Deserializer, Serializer if TYPE_CHECKING: @@ -23,8 +23,10 @@ from azure.core.credentials import TokenCredential -class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword - """Azure Messaging EventGrid Client. +class EventGridPublisherClient( + EventGridPublisherClientOperationsMixin +): # pylint: disable=client-accepts-api-version-keyword + """EventGridPublisherClient. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. @@ -33,15 +35,14 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-10-01-preview". Note that overriding this default value may result in unsupported - behavior. + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: _endpoint = "{endpoint}" - self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + self._config = EventGridPublisherClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) _policies = kwargs.pop("policies", None) if _policies is None: _policies = [ @@ -94,7 +95,87 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: def close(self) -> None: self._client.close() - def __enter__(self) -> "EventGridClient": + def __enter__(self) -> "EventGridPublisherClient": + self._client.__enter__() + return self + + def __exit__(self, *exc_details: Any) -> None: + self._client.__exit__(*exc_details) + + +class EventGridConsumerClient( + EventGridConsumerClientOperationsMixin +): # pylint: disable=client-accepts-api-version-keyword + """EventGridConsumerClient. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: + _endpoint = "{endpoint}" + self._config = EventGridConsumerClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.HttpResponse + """ + + request_copy = deepcopy(request) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore + + def close(self) -> None: + self._client.close() + + def __enter__(self) -> "EventGridConsumerClient": self._client.__enter__() return self diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py index 9f9f76551394..93540c21e18c 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_configuration.py @@ -18,8 +18,8 @@ from azure.core.credentials import TokenCredential -class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long - """Configuration for EventGridClient. +class EventGridPublisherClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long + """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance attributes. @@ -31,14 +31,70 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attribu AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-10-01-preview". Note that overriding this default value may result in unsupported - behavior. + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: - api_version: str = kwargs.pop("api_version", "2023-10-01-preview") + api_version: str = kwargs.pop("api_version", "2024-06-01") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + + self.endpoint = endpoint + self.credential = credential + self.api_version = api_version + self.credential_scopes = kwargs.pop("credential_scopes", ["https://eventgrid.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "eventgrid/{}".format(VERSION)) + self.polling_interval = kwargs.get("polling_interval", 30) + self._configure(**kwargs) + + def _infer_policy(self, **kwargs): + if isinstance(self.credential, AzureKeyCredential): + return policies.AzureKeyCredentialPolicy( + self.credential, "Authorization", prefix="SharedAccessKey", **kwargs + ) + if hasattr(self.credential, "get_token"): + return policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + raise TypeError(f"Unsupported credential: {self.credential}") + + def _configure(self, **kwargs: Any) -> None: + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs) + self.authentication_policy = kwargs.get("authentication_policy") + if self.credential and not self.authentication_policy: + self.authentication_policy = self._infer_policy(**kwargs) + + +class EventGridConsumerClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long + """Configuration for EventGridConsumerClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None: + api_version: str = kwargs.pop("api_version", "2024-06-01") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py index d28317777391..c0623fe16b58 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_helpers.py @@ -97,7 +97,7 @@ def _is_cloud_event(event): return False -def _is_eventgrid_event(event): +def _is_eventgrid_event_format(event): # type: (Any) -> bool required = ("subject", "eventType", "data", "dataVersion", "id", "eventTime") try: diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py index 75d3c8227055..faba67dcbb52 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/_publisher_client.py @@ -34,7 +34,7 @@ from ._helpers import ( _get_authentication_policy, _is_cloud_event, - _is_eventgrid_event, + _is_eventgrid_event_format, _eventgrid_data_typecheck, _build_request, _cloud_event_to_generated, @@ -217,7 +217,7 @@ def send(self, events: SendType, *, channel_name: Optional[str] = None, **kwargs ## this is either a dictionary or a CNCF cloud event events = [_from_cncf_events(e) for e in events] content_type = "application/cloudevents-batch+json; charset=utf-8" - elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): + elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event_format(events[0]): for event in events: _eventgrid_data_typecheck(event) response = self._client.send_request( # pylint: disable=protected-access diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py index ed70d6cdd6ad..de3cbd309291 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_legacy/aio/_publisher_client_async.py @@ -35,7 +35,7 @@ from .._models import EventGridEvent from .._helpers import ( _is_cloud_event, - _is_eventgrid_event, + _is_eventgrid_event_format, _eventgrid_data_typecheck, _build_request, _cloud_event_to_generated, @@ -212,7 +212,7 @@ async def send(self, events: SendType, *, channel_name: Optional[str] = None, ** ## this is either a dictionary or a CNCF cloud event events = [_from_cncf_events(e) for e in events] content_type = "application/cloudevents-batch+json; charset=utf-8" - elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): + elif isinstance(events[0], EventGridEvent) or _is_eventgrid_event_format(events[0]): for event in events: _eventgrid_data_typecheck(event) response = await self._client.send_request( # pylint: disable=protected-access diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py index 4b0f59f73e4c..5cf70733404d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_model_base.py @@ -6,6 +6,7 @@ # -------------------------------------------------------------------------- # pylint: disable=protected-access, arguments-differ, signature-differs, broad-except +import copy import calendar import decimal import functools @@ -639,6 +640,13 @@ def _deserialize_sequence( return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) +def _sorted_annotations(types: typing.List[typing.Any]) -> typing.List[typing.Any]: + return sorted( + types, + key=lambda x: hasattr(x, "__name__") and x.__name__.lower() in ("str", "float", "int", "bool"), + ) + + def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], @@ -680,21 +688,25 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, # is it optional? try: if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore - if_obj_deserializer = _get_deserialize_callable_from_annotation( - next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore - ) - - return functools.partial(_deserialize_with_optional, if_obj_deserializer) + if len(annotation.__args__) <= 2: # pyright: ignore + if_obj_deserializer = _get_deserialize_callable_from_annotation( + next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore + ) + + return functools.partial(_deserialize_with_optional, if_obj_deserializer) + # the type is Optional[Union[...]], we need to remove the None type from the Union + annotation_copy = copy.copy(annotation) + annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a != type(None)] # pyright: ignore + return _get_deserialize_callable_from_annotation(annotation_copy, module, rf) except AttributeError: pass + # is it union? if getattr(annotation, "__origin__", None) is typing.Union: # initial ordering is we make `string` the last deserialization option, because it is often them most generic deserializers = [ _get_deserialize_callable_from_annotation(arg, module, rf) - for arg in sorted( - annotation.__args__, key=lambda x: hasattr(x, "__name__") and x.__name__ == "str" # pyright: ignore - ) + for arg in _sorted_annotations(annotation.__args__) # pyright: ignore ] return functools.partial(_deserialize_with_union, deserializers) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py index 51cf0e7ac905..c716622cb722 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/__init__.py @@ -6,14 +6,16 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClientOperationsMixin +from ._patch import EventGridPublisherClientOperationsMixin +from ._patch import EventGridConsumerClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk __all__ = [ - "EventGridClientOperationsMixin", + "EventGridPublisherClientOperationsMixin", + "EventGridConsumerClientOperationsMixin", ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 66228ba73e21..3ad9c7acf667 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -28,28 +28,27 @@ from .._model_base import SdkJSONEncoder, _deserialize from .._serialization import Serializer from .._validation import api_version_validation -from .._vendor import EventGridClientMixinABC +from .._vendor import EventGridConsumerClientMixinABC, EventGridPublisherClientMixinABC if sys.version_info >= (3, 9): from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +_Unset: Any = object() _SERIALIZER = Serializer() _SERIALIZER.client_side_validation = False -def build_event_grid_publish_cloud_event_request( # pylint: disable=name-too-long - topic_name: str, **kwargs: Any -) -> HttpRequest: +def build_event_grid_publisher_send_request(topic_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: str = kwargs.pop("content_type") - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -70,14 +69,14 @@ def build_event_grid_publish_cloud_event_request( # pylint: disable=name-too-lo return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_publish_cloud_events_request( # pylint: disable=name-too-long +def build_event_grid_publisher_send_events_request( # pylint: disable=name-too-long topic_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: str = kwargs.pop("content_type") - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -98,7 +97,7 @@ def build_event_grid_publish_cloud_events_request( # pylint: disable=name-too-l return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-long +def build_event_grid_consumer_receive_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, *, @@ -109,7 +108,7 @@ def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-l _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -134,14 +133,14 @@ def build_event_grid_receive_cloud_events_request( # pylint: disable=name-too-l return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-too-long +def build_event_grid_consumer_acknowledge_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -164,18 +163,18 @@ def build_event_grid_acknowledge_cloud_events_request( # pylint: disable=name-t return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-long +def build_event_grid_consumer_release_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -191,7 +190,7 @@ def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-l _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") if release_delay_in_seconds is not None: _params["releaseDelayInSeconds"] = _SERIALIZER.query( - "release_delay_in_seconds", release_delay_in_seconds, "int" + "release_delay_in_seconds", release_delay_in_seconds, "str" ) # Construct headers @@ -202,14 +201,14 @@ def build_event_grid_release_cloud_events_request( # pylint: disable=name-too-l return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-long +def build_event_grid_consumer_reject_request( topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -232,14 +231,14 @@ def build_event_grid_reject_cloud_events_request( # pylint: disable=name-too-lo return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_renew_cloud_event_locks_request( # pylint: disable=name-too-long +def build_event_grid_consumer_renew_lock_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -262,25 +261,21 @@ def build_event_grid_renew_cloud_event_locks_request( # pylint: disable=name-to return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -class EventGridClientOperationsMixin(EventGridClientMixinABC): +class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @distributed_trace - def _publish_cloud_event( # pylint: disable=protected-access + def _send( # pylint: disable=protected-access self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Publish a single Cloud Event to a namespace topic. :param topic_name: Topic Name. Required. :type topic_name: str :param event: Single Cloud Event being published. Required. - :type event: ~azure.eventgrid.models.CloudEvent + :type event: ~azure.eventgrid.models._models.CloudEvent :return: PublishResult. The PublishResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.PublishResult + :rtype: ~azure.eventgrid.models._models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -325,7 +320,7 @@ def _publish_cloud_event( # pylint: disable=protected-access _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_publish_cloud_event_request( + _request = build_event_grid_publisher_send_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -364,22 +359,18 @@ def _publish_cloud_event( # pylint: disable=protected-access return deserialized # type: ignore @distributed_trace - def _publish_cloud_events( # pylint: disable=protected-access + def _send_events( # pylint: disable=protected-access self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long - """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Publish a batch of Cloud Events to a namespace topic. :param topic_name: Topic Name. Required. :type topic_name: str :param events: Array of Cloud Events being published. Required. - :type events: list[~azure.eventgrid.models.CloudEvent] + :type events: list[~azure.eventgrid.models._models.CloudEvent] :return: PublishResult. The PublishResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.PublishResult + :rtype: ~azure.eventgrid.models._models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -428,7 +419,7 @@ def _publish_cloud_events( # pylint: disable=protected-access _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_publish_cloud_events_request( + _request = build_event_grid_publisher_send_events_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -466,8 +457,11 @@ def _publish_cloud_events( # pylint: disable=protected-access return deserialized # type: ignore + +class EventGridConsumerClientOperationsMixin(EventGridConsumerClientMixinABC): + @distributed_trace - def _receive_cloud_events( # pylint: disable=protected-access + def _receive( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, @@ -477,7 +471,7 @@ def _receive_cloud_events( # pylint: disable=protected-access **kwargs: Any ) -> _models._models.ReceiveResult: # pylint: disable=line-too-long - """Receive Batch of Cloud Events from the Event Subscription. + """Receive a batch of Cloud Events from a subscription. :param topic_name: Topic Name. Required. :type topic_name: str @@ -493,7 +487,7 @@ def _receive_cloud_events( # pylint: disable=protected-access 60 seconds. Default value is None. :paramtype max_wait_time: int :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReceiveResult + :rtype: ~azure.eventgrid.models._models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -552,7 +546,7 @@ def _receive_cloud_events( # pylint: disable=protected-access cls: ClsType[_models._models.ReceiveResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _request = build_event_grid_receive_cloud_events_request( + _request = build_event_grid_consumer_receive_request( topic_name=topic_name, event_subscription_name=event_subscription_name, max_events=max_events, @@ -592,56 +586,59 @@ def _receive_cloud_events( # pylint: disable=protected-access return deserialized # type: ignore @overload - def _acknowledge_cloud_events( # pylint: disable=protected-access + def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: _models._models.AcknowledgeOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @overload - def _acknowledge_cloud_events( + def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @overload - def _acknowledge_cloud_events( + def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @distributed_trace - def _acknowledge_cloud_events( + def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models._models.AcknowledgeOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. + """Acknowledge a batch of Cloud Events. The response will include the set of successfully + acknowledged lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully acknowledged events will no longer be available to be received by any + consumer. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Is one of the following types: - AcknowledgeOptions, JSON, IO[bytes] Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: @@ -650,7 +647,7 @@ def _acknowledge_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - acknowledge_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -699,14 +696,19 @@ def _acknowledge_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(acknowledge_options, (IOBase, bytes)): - _content = acknowledge_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(acknowledge_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_acknowledge_cloud_events_request( + _request = build_event_grid_consumer_acknowledge_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -746,14 +748,14 @@ def _acknowledge_cloud_events( @overload @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, - ) # pylint: disable=protected-access - def _release_cloud_events( # pylint: disable=protected-access + ) + def _release( self, topic_name: str, event_subscription_name: str, - release_options: _models._models.ReleaseOptions, + body: JSON, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -761,13 +763,13 @@ def _release_cloud_events( # pylint: disable=protected-access @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - def _release_cloud_events( + def _release( self, topic_name: str, event_subscription_name: str, - release_options: JSON, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + lock_tokens: List[str], + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -775,13 +777,13 @@ def _release_cloud_events( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - def _release_cloud_events( + def _release( self, topic_name: str, event_subscription_name: str, - release_options: IO[bytes], + body: IO[bytes], *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -790,29 +792,31 @@ def _release_cloud_events( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - def _release_cloud_events( + def _release( self, topic_name: str, event_subscription_name: str, - release_options: Union[_models._models.ReleaseOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + lock_tokens: List[str] = _Unset, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. + """Release a batch of Cloud Events. The response will include the set of successfully released + lock tokens, along with other failed lock tokens with their corresponding error information. + Successfully released events can be received by consumers. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, - IO[bytes] Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + Known values are: "0", "10", "60", "600", and "3600". Default value is None. + :paramtype release_delay_in_seconds: str or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -821,7 +825,7 @@ def _release_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - release_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -870,14 +874,19 @@ def _release_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(release_options, (IOBase, bytes)): - _content = release_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_event_grid_release_cloud_events_request( + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + print(_content) + _request = build_event_grid_consumer_release_request( topic_name=topic_name, event_subscription_name=event_subscription_name, release_delay_in_seconds=release_delay_in_seconds, @@ -916,55 +925,58 @@ def _release_cloud_events( return deserialized # type: ignore @overload - def _reject_cloud_events( # pylint: disable=protected-access + def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: _models._models.RejectOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @overload - def _reject_cloud_events( + def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @overload - def _reject_cloud_events( + def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @distributed_trace - def _reject_cloud_events( + def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models._models.RejectOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. + """Reject a batch of Cloud Events. The response will include the set of successfully rejected lock + tokens, along with other failed lock tokens with their corresponding error information. + Successfully rejected events will be dead-lettered and can no longer be received by a consumer. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, - IO[bytes] Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: @@ -973,7 +985,7 @@ def _reject_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - reject_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -1022,14 +1034,19 @@ def _reject_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.RejectResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(reject_options, (IOBase, bytes)): - _content = reject_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(reject_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_reject_cloud_events_request( + _request = build_event_grid_consumer_reject_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -1069,80 +1086,90 @@ def _reject_cloud_events( @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, - ) # pylint: disable=protected-access - def _renew_cloud_event_locks( # pylint: disable=protected-access + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, + ) + def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: _models._models.RenewLockOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - def _renew_cloud_event_locks( + def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - def _renew_cloud_event_locks( + def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @distributed_trace @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - def _renew_cloud_event_locks( + def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models._models.RenewLockOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. + ) -> _models.RenewLocksResult: + """Renew locks for a batch of Cloud Events. The response will include the set of successfully + renewed lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully renewed locks will ensure that the associated event is only available + to the consumer that holds the renewed lock. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, - JSON, IO[bytes] Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO[bytes] - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] + :return: RenewLocksResult. The RenewLocksResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: Example: .. code-block:: python # JSON input template you can fill out and use as your body input. - renew_lock_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -1189,16 +1216,21 @@ def _renew_cloud_event_locks( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop("cls", None) + cls: ClsType[_models.RenewLocksResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(renew_lock_options, (IOBase, bytes)): - _content = renew_lock_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(renew_lock_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_renew_cloud_event_locks_request( + _request = build_event_grid_consumer_renew_lock_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -1228,7 +1260,7 @@ def _renew_cloud_event_locks( if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize(_models.RenewCloudEventLocksResult, response.json()) + deserialized = _deserialize(_models.RenewLocksResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 4cb6fb5264fb..7b9a22176a7a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -30,24 +30,22 @@ from azure.core.rest import HttpRequest, HttpResponse from azure.core.utils import case_insensitive_dict -from ._operations import EventGridClientOperationsMixin as OperationsMixin +from ._operations import ( + EventGridPublisherClientOperationsMixin as PublisherOperationsMixin, + EventGridConsumerClientOperationsMixin as ConsumerOperationsMixin, +) from ..models._patch import ( - ReceiveResult, ReceiveDetails, ) from .. import models as _models from ..models._models import ( - AcknowledgeOptions, - ReleaseOptions, - RejectOptions, - RenewLockOptions, CloudEvent as InternalCloudEvent, ) from .._validation import api_version_validation from .._legacy import EventGridEvent -from .._legacy._helpers import _from_cncf_events, _is_eventgrid_event, _is_cloud_event +from .._legacy._helpers import _from_cncf_events, _is_eventgrid_event_format, _is_cloud_event from .._serialization import Serializer if sys.version_info >= (3, 9): @@ -64,23 +62,6 @@ if TYPE_CHECKING: from cloudevents.http.event import CloudEvent as CNCFCloudEvent -EVENT_TYPES_BASIC = Union[ - CloudEvent, - List[CloudEvent], - Dict[str, Any], - List[Dict[str, Any]], - EventGridEvent, - List[EventGridEvent], - "CNCFCloudEvent", - List["CNCFCloudEvent"], -] -EVENT_TYPES_STD = Union[ - CloudEvent, - List[CloudEvent], - Dict[str, Any], - List[Dict[str, Any]], -] - def use_standard_only(func): """Use the standard client only. @@ -102,103 +83,26 @@ def wrapper(self, *args, **kwargs): return wrapper -def validate_args(**kwargs: Any): - kwargs_mapping = kwargs.pop("kwargs_mapping", None) - - def decorator(func): - @wraps(func) - def wrapper(self, *args: Any, **kwargs: Any) -> T: - selected_client_level = self._level # pylint: disable=protected-access - - if kwargs_mapping: - unsupported_kwargs = { - arg: level - for level, arguments in kwargs_mapping.items() - for arg in arguments - if arg in kwargs.keys() # pylint: disable=consider-iterating-dictionary - and selected_client_level != level - } - - error_strings = [] - if unsupported_kwargs: - error_strings += [ - f"'{param}' is not available for the {selected_client_level} client. " - f"Use the {level} client.\n" - for param, level in unsupported_kwargs.items() - ] - if len(error_strings) > 0: - raise ValueError("".join(error_strings)) - - return func(self, *args, **kwargs) - - return wrapper - - return decorator - +class EventGridPublisherClientOperationsMixin(PublisherOperationsMixin): -class EventGridClientOperationsMixin(OperationsMixin): - - @overload + @distributed_trace def send( self, - events: EVENT_TYPES_BASIC, + events: Union[ + CloudEvent, + List[CloudEvent], + Dict[str, Any], + List[Dict[str, Any]], + "CNCFCloudEvent", + List["CNCFCloudEvent"], + EventGridEvent, + List[EventGridEvent], + ], *, channel_name: Optional[str] = None, content_type: Optional[str] = None, **kwargs: Any, - ) -> None: - """Send events to the Event Grid Basic Service. - - :param events: The event to send. - :type events: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] - or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] - :keyword channel_name: The name of the channel to send the event to. - :paramtype channel_name: str or None - :keyword content_type: The content type of the event. If not specified, the default value is - "application/cloudevents+json; charset=utf-8". - :paramtype content_type: str or None - - :return: None - :rtype: None - """ - ... - - @overload - def send( - self, - topic_name: str, - events: EVENT_TYPES_STD, - *, - binary_mode: bool = False, - content_type: Optional[str] = None, - **kwargs: Any, - ) -> None: - """Send events to the Event Grid Namespace Service. - - :param topic_name: The name of the topic to send the event to. - :type topic_name: str - :param events: The event to send. - :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] - :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default - value is False. - :paramtype binary_mode: bool - :keyword content_type: The content type of the event. If not specified, the default value is - "application/cloudevents+json; charset=utf-8". - :paramtype content_type: str or None - - :return: None - :rtype: None - """ - ... - - @validate_args( - kwargs_mapping={ - "Basic": ["channel_name"], - "Standard": ["binary_mode"], - } - ) - @distributed_trace - def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param + ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. :param topic_name: The name of the topic to send the event to. @@ -206,10 +110,7 @@ def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-k :param events: The event to send. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] - :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default - value is False. - :paramtype binary_mode: bool - :keyword channel_name: The name of the channel to send the event to. + :keyword channel_name: The name of the channel to send the event to. Event Grid Basic Resource only. :paramtype channel_name: str or None :keyword content_type: The content type of the event. If not specified, the default value is "application/cloudevents+json; charset=utf-8". @@ -217,114 +118,40 @@ def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-k :return: None :rtype: None - - A single instance or a list of dictionaries, CloudEvents are accepted. In the case of an Azure Event Grid - Basic Resource, EventGridEvent(s) and CNCFCloudEvents are also accepted. - - .. admonition:: Example: - - .. literalinclude:: ../samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py - :start-after: [START publish_cloud_event] - :end-before: [END publish_cloud_event] - :language: python - :dedent: 0 - :caption: Publishing a Cloud Event to a Namespace Topic. - - .. literalinclude:: ../samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py - :start-after: [START publish_cloud_event_to_topic] - :end-before: [END publish_cloud_event_to_topic] - :language: python - :dedent: 0 - :caption: Publishing a CloudEvent to a Basic Topic. """ - # Check kwargs - channel_name = kwargs.pop("channel_name", None) - binary_mode = kwargs.pop("binary_mode", False) - topic_name = kwargs.pop("topic_name", None) - events = kwargs.pop("events", None) - - # both there - if len(args) > 1: - if events is not None: - raise ValueError("events is already passed as a keyword argument.") - if topic_name is not None: - raise ValueError("topic_name is already passed as a keyword argument.") - events = args[1] - topic_name = args[0] - - elif len(args) == 1: - if events is not None: - if topic_name is not None: - raise ValueError("topic_name is already passed as a keyword argument.") - topic_name = args[0] - else: - events = args[0] - - if self._level == "Standard" and topic_name is None: - raise ValueError("Topic name is required for standard level client.") - - # check binary mode - if binary_mode: - self._send_binary(topic_name, events, **kwargs) - else: - # If not binary_mode send whatever event is passed - # If a cloud event dict, convert to CloudEvent for serializing - try: - if isinstance(events, dict): - events = CloudEvent.from_dict(events) - if isinstance(events, list) and isinstance(events[0], dict): - events = [CloudEvent.from_dict(e) for e in events] - except Exception: # pylint: disable=broad-except - pass - - if self._level == "Standard": - kwargs["content_type"] = kwargs.get("content_type", "application/cloudevents-batch+json; charset=utf-8") - if not isinstance(events, list): - events = [events] - - if isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): - raise TypeError("EventGridEvent is not supported for standard level client.") - try: - # Try to send via namespace - self._send(topic_name, _serialize_events(events), **kwargs) - except Exception as exception: # pylint: disable=broad-except - self._http_response_error_handler(exception, "Standard") - raise exception - else: - try: - self._send(events, channel_name=channel_name, **kwargs) - except Exception as exception: - self._http_response_error_handler(exception, "Basic") - raise exception - - def _send_binary(self, topic_name, event, **kwargs): - # If data is passed as a dictionary, make sure it is a CloudEvent - if isinstance(event, list): - raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from + if self._namespace and channel_name: + raise ValueError("Channel name is not supported for Event Grid Namespaces.") + try: - if not isinstance(event, CloudEvent): - try: - # Convert to CloudEvent if it is a dictionary - event = CloudEvent.from_dict(event) - except AttributeError: - # Convert to CloudEvent if it is a CNCF CloudEvent dict - event = CloudEvent.from_dict(_from_cncf_events(event)) - except AttributeError: - raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from - - # If data is a cloud event, convert to an HTTP Request in binary mode - # Content type becomes the data content type - if isinstance(event, CloudEvent): - http_request = _to_http_request( - topic_name=topic_name, - api_version=self._config.api_version, - event=event, - **kwargs, + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + if isinstance(events, list) and isinstance(events[0], dict): + events = [CloudEvent.from_dict(e) for e in events] + except Exception: # pylint: disable=broad-except + pass + + if self._namespace: + kwargs["content_type"] = ( + content_type if content_type else "application/cloudevents-batch+json; charset=utf-8" ) - else: - raise TypeError("Binary mode is only supported for type CloudEvent.") + if not isinstance(events, list): + events = [events] - self.send_request(http_request, **kwargs) + if isinstance(events[0], EventGridEvent) or _is_eventgrid_event_format(events[0]): + raise TypeError("EventGridEvent is not supported for Event Grid Namespaces.") + try: + # Try to send via namespace + self._publish(self._namespace, _serialize_events(events), **kwargs) + except Exception as exception: # pylint: disable=broad-except + self._http_response_error_handler(exception, "Namespaces") + raise exception + else: + kwargs["content_type"] = content_type if content_type else "application/json; charset=utf-8" + try: + self._publish(events, channel_name=channel_name, **kwargs) + except Exception as exception: + self._http_response_error_handler(exception, "Basic") + raise exception def _http_response_error_handler(self, exception, level): if isinstance(exception, HttpResponseError): @@ -333,28 +160,24 @@ def _http_response_error_handler(self, exception, level): if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - f"Please check that the level set on the client, {level}, corresponds to the correct " + f"Please check that the tier you are using, corresponds to the correct " "endpoint and/or topic name." ) from exception raise exception - @use_standard_only + +class EventGridConsumerClientOperationsMixin(ConsumerOperationsMixin): + @distributed_trace - def receive_cloud_events( + def receive( self, - topic_name: str, - subscription_name: str, *, max_events: Optional[int] = None, max_wait_time: Optional[int] = None, **kwargs: Any, - ) -> ReceiveResult: + ) -> List[ReceiveDetails]: """Receive Batch of Cloud Events from the Event Subscription. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value is 100 events. If not specified, the default value is 1. Default value is None. :paramtype max_events: int @@ -364,20 +187,20 @@ def receive_cloud_events( value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReceiveResult + :return: Receive Details. + :rtype: list[~azure.eventgrid.models.ReceiveDetails] :raises ~azure.core.exceptions.HttpResponseError: """ detail_items = [] - received_result = self._receive_cloud_events( - topic_name, - subscription_name, + received_result = self._receive( + self._namespace, + self._subscription, max_events=max_events, max_wait_time=max_wait_time, **kwargs, ) - for detail_item in received_result.value: + for detail_item in received_result.details: deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) detail_item.event = deserialized_cloud_event detail_items.append( @@ -386,225 +209,119 @@ def receive_cloud_events( event=detail_item.event, ) ) - receive_result_deserialized = ReceiveResult(value=detail_items) - return receive_result_deserialized + return detail_items - @use_standard_only @distributed_trace - def acknowledge_cloud_events( + def acknowledge( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. + """Acknowledge a batch of Cloud Events. The response will include the set of successfully + acknowledged lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully acknowledged events will no longer be available to be received by any + consumer. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = AcknowledgeOptions(lock_tokens=lock_tokens) - return super()._acknowledge_cloud_events( - topic_name=topic_name, - event_subscription_name=subscription_name, - acknowledge_options=options, + return super()._acknowledge( + topic_name=self._namespace, + event_subscription_name=self._subscription, + lock_tokens=lock_tokens, **kwargs, ) - @use_standard_only - @distributed_trace @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay"]}, ) - def release_cloud_events( + def release( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], release_delay: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any, ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. + """Release a batch of Cloud Events. The response will include the set of successfully released + lock tokens, along with other failed lock tokens with their corresponding error information. + Successfully released events can be received by consumers. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :keyword release_delay: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. + Known values are: 0, 10, 60, 600, and 3600. Default value is None, indicating no delay. :paramtype release_delay: int or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = ReleaseOptions(lock_tokens=lock_tokens) - return super()._release_cloud_events( - topic_name=topic_name, - event_subscription_name=subscription_name, - release_options=options, + return super()._release( + topic_name=self._namespace, + event_subscription_name=self._subscription, + lock_tokens=lock_tokens, release_delay_in_seconds=release_delay, **kwargs, ) - @use_standard_only @distributed_trace - def reject_cloud_events( + def reject( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. + """Reject a batch of Cloud Events. The response will include the set of successfully rejected lock + tokens, along with other failed lock tokens with their corresponding error information. + Successfully rejected events will be dead-lettered and can no longer be received by a consumer. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = RejectOptions(lock_tokens=lock_tokens) - return super()._reject_cloud_events( - topic_name=topic_name, - event_subscription_name=subscription_name, - reject_options=options, + return super()._reject( + topic_name=self._namespace, + event_subscription_name=self._subscription, + lock_tokens=lock_tokens, **kwargs, ) - @use_standard_only @distributed_trace @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["api_version", "content_type", "accept"]}, ) - def renew_cloud_event_locks( + def renew_locks( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, - ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. + ) -> _models.RenewLocksResult: + """Renew locks for a batch of Cloud Events. The response will include the set of successfully + renewed lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully renewed locks will ensure that the associated event is only available + to the consumer that holds the renewed lock. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + :return: RenewLocksResult. The RenewLocksResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = RenewLockOptions(lock_tokens=lock_tokens) - return super()._renew_cloud_event_locks( - topic_name=topic_name, - event_subscription_name=subscription_name, - renew_lock_options=options, + return super()._renew_lock( + topic_name=self._namespace, + event_subscription_name=self._subscription, + lock_tokens=lock_tokens, **kwargs, ) -def _to_http_request(topic_name: str, **kwargs: Any) -> HttpRequest: - # Create a HTTP request for a binary mode CloudEvent - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - event = kwargs.pop("event") - - # Content of the request is the data, if already in binary - no work needed - try: - if isinstance(event.data, bytes): - _content = event.data - else: - raise TypeError( - "CloudEvent data must be bytes when in binary mode. " - "Did you forget to call `json.dumps()` and/or `encode()` on CloudEvent data?" - ) - except AttributeError as exc: - raise TypeError( - "Binary mode is not supported for batch CloudEvents. " - " Set `binary_mode` to False when passing in a batch of CloudEvents." - ) from exc - - # content_type must be CloudEvent DataContentType when in binary mode - if not event.datacontenttype: - raise ValueError("CloudEvent datacontenttype must be set when in binary mode.") - content_type: str = event.datacontenttype - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-10-01-preview")) - accept = _headers.pop("Accept", "application/json") - - # Construct URL - _url = "/topics/{topicName}:publish" - path_format_arguments = { - "topicName": _SERIALIZER.url("topic_name", topic_name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - # Construct headers - _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str") - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - # Cloud Headers - _headers["ce-source"] = _SERIALIZER.header("ce-source", event.source, "str") - _headers["ce-type"] = _SERIALIZER.header("ce-type", event.type, "str") - if event.specversion: - _headers["ce-specversion"] = _SERIALIZER.header("ce-specversion", event.specversion, "str") - if event.id: - _headers["ce-id"] = _SERIALIZER.header("ce-id", event.id, "str") - if event.time: - _headers["ce-time"] = _SERIALIZER.header("ce-time", event.time, "str") - if event.dataschema: - _headers["ce-dataschema"] = _SERIALIZER.header("ce-dataschema", event.dataschema, "str") - if event.subject: - _headers["ce-subject"] = _SERIALIZER.header("ce-subject", event.subject, "str") - if event.extensions: - for extension, value in event.extensions.items(): - _headers[f"ce-{extension}"] = _SERIALIZER.header("ce-extensions", value, "str") - - return HttpRequest( - method="POST", - url=_url, - params=_params, - headers=_headers, - content=_content, # pass through content - **kwargs, - ) - - def _serialize_events(events): if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): # Try to serialize cloud events @@ -646,7 +363,8 @@ def _serialize_cloud_event(cloud_event): __all__: List[str] = [ - "EventGridClientOperationsMixin" + "EventGridPublisherClientOperationsMixin", + "EventGridConsumerClientOperationsMixin", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index c4075dd2d3e3..1b7a8b79dc0b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -7,54 +7,49 @@ """ from typing import List, Union, Optional, Any -from enum import Enum +from azure.core.credentials import AzureKeyCredential, AzureSasCredential, TokenCredential -from azure.core import CaseInsensitiveEnumMeta -from azure.core.credentials import ( - AzureKeyCredential, - TokenCredential, - AzureSasCredential, +from ._client import ( + EventGridPublisherClient as InternalEventGridPublisherClient, + EventGridConsumerClient as InternalEventGridConsumerClient, ) - from ._legacy import ( - EventGridPublisherClient, + EventGridPublisherClient as LegacyEventGridPublisherClient, SystemEventNames, EventGridEvent, generate_sas, ) -from ._client import ( - EventGridClient as InternalEventGridClient, -) -from ._serialization import Serializer, Deserializer +from ._serialization import Deserializer, Serializer -class ClientLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): - STANDARD = ("Standard",) - BASIC = "Basic" +DEFAULT_STANDARD_API_VERSION = "2024-06-01" +DEFAULT_BASIC_API_VERSION = "2018-01-01" -DEFAULT_STANDARD_API_VERSION = "2023-10-01-preview" -DEFAULT_BASIC_API_VERSION = "2018-01-01" +class EventGridPublisherClient(InternalEventGridPublisherClient): + """EventGridPublisherClient. + Sends events to a basic topic, basic domain, or a namespace topic + specified during the client initialization. -class EventGridClient(InternalEventGridClient): - """ - Azure Messaging EventGrid Client. + A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. + If a list is provided, the list must contain only one type of event. + If dictionaries are provided and sending to a namespace topic, + the dictionary must follow the CloudEvent schema. - :param endpoint: The endpoint to the Event Grid resource. + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential - :keyword api_version: The API version to use for this operation. Default value for namespaces is - "2023-10-01-preview". Default value for basic is "2018-01-01". + :keyword namespace_topic: The name of the topic to publish events to. Required for EventGrid Namespaces. + Default value is None, which is used for EventGrid Basic. + :paramtype namespace_topic: str or None + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str or None - :keyword level: The level of client to use. Known values are - `Standard` and `Basic`. Default value is `Standard`. - `Standard` is used for working with a namespace topic. - `Basic` is used for working with a basic topic. - :paramtype level: str + :paramtype api_version: str """ def __init__( @@ -62,37 +57,83 @@ def __init__( endpoint: str, credential: Union[AzureKeyCredential, AzureSasCredential, "TokenCredential"], *, + namespace_topic: Optional[str] = None, api_version: Optional[str] = None, - level: Union[str, ClientLevel] = "Standard", - **kwargs: Any + **kwargs: Any, ) -> None: - _endpoint = "{endpoint}" - self._level = level + self._namespace = namespace_topic + self._credential = credential - if level == ClientLevel.BASIC: - self._client = EventGridPublisherClient( + if not self._namespace: + self._client = LegacyEventGridPublisherClient( endpoint, credential, api_version=api_version or DEFAULT_BASIC_API_VERSION, ) # type:ignore[assignment] - self._send = self._client.send # type:ignore[attr-defined] - elif level == ClientLevel.STANDARD: + self._publish = self._client.send # type:ignore[attr-defined] + else: if isinstance(credential, AzureSasCredential): raise TypeError("SAS token authentication is not supported for the standard client.") super().__init__( endpoint=endpoint, credential=credential, api_version=api_version or DEFAULT_STANDARD_API_VERSION, - **kwargs + **kwargs, ) - self._send = self._publish_cloud_events - else: - raise ValueError("Unknown client level. Known values are `Standard` and `Basic`.") + self._publish = self._send_events self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False + def __repr__(self) -> str: + return ( + f"" + ) + + +class EventGridConsumerClient(InternalEventGridConsumerClient): + """EventGridConsumerClient. + + Consumes and manages events from a namespace topic + and event subscription specified during the client initialization. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials.TokenCredential + :keyword namespace_topic: The name of the topic to consume events from. Required. + :paramtype namespace_topic: str + :subscription: The name of the subscription to consume events from. Required. + :paramtype subscription: str + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: Union[AzureKeyCredential, "TokenCredential"], + *, + namespace_topic: str, + subscription: str, + api_version: Optional[str] = None, + **kwargs: Any, + ) -> None: + self._namespace = namespace_topic + self._subscription = subscription + self._credential = credential + super().__init__( + endpoint=endpoint, credential=credential, api_version=api_version or DEFAULT_STANDARD_API_VERSION, **kwargs + ) + + def __repr__(self) -> str: + return f"" + def patch_sdk(): """Do not remove from this file. @@ -104,9 +145,8 @@ def patch_sdk(): __all__: List[str] = [ "EventGridPublisherClient", + "EventGridConsumerClient", "SystemEventNames", "EventGridEvent", "generate_sas", - "EventGridClient", - "ClientLevel", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py index 59d8335b5c63..e76c249bb07a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_vendor.py @@ -8,7 +8,7 @@ from abc import ABC from typing import TYPE_CHECKING -from ._configuration import EventGridClientConfiguration +from ._configuration import EventGridConsumerClientConfiguration, EventGridPublisherClientConfiguration if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -17,10 +17,19 @@ from ._serialization import Deserializer, Serializer -class EventGridClientMixinABC(ABC): +class EventGridPublisherClientMixinABC(ABC): """DO NOT use this class. It is for internal typing use only.""" _client: "PipelineClient" - _config: EventGridClientConfiguration + _config: EventGridPublisherClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" + + +class EventGridConsumerClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + + _client: "PipelineClient" + _config: EventGridConsumerClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py index 906ab81c5705..bcf16d1a1ec6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/__init__.py @@ -6,7 +6,8 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClient +from ._patch import EventGridPublisherClient +from ._patch import EventGridConsumerClient try: from ._patch import __all__ as _patch_all @@ -16,7 +17,8 @@ from ._patch import patch_sdk as _patch_sdk __all__ = [ - "EventGridClient", + "EventGridPublisherClient", + "EventGridConsumerClient", ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py index 60d39e9d6ade..07db6072d782 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_client.py @@ -15,16 +15,18 @@ from azure.core.rest import AsyncHttpResponse, HttpRequest from .._serialization import Deserializer, Serializer -from ._configuration import EventGridClientConfiguration -from ._operations import EventGridClientOperationsMixin +from ._configuration import EventGridConsumerClientConfiguration, EventGridPublisherClientConfiguration +from ._operations import EventGridConsumerClientOperationsMixin, EventGridPublisherClientOperationsMixin if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports from azure.core.credentials_async import AsyncTokenCredential -class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword - """Azure Messaging EventGrid Client. +class EventGridPublisherClient( + EventGridPublisherClientOperationsMixin +): # pylint: disable=client-accepts-api-version-keyword + """EventGridPublisherClient. :param endpoint: The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net. Required. @@ -33,9 +35,8 @@ class EventGridClient(EventGridClientOperationsMixin): # pylint: disable=client AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-10-01-preview". Note that overriding this default value may result in unsupported - behavior. + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ @@ -43,7 +44,7 @@ def __init__( self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: _endpoint = "{endpoint}" - self._config = EventGridClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + self._config = EventGridPublisherClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) _policies = kwargs.pop("policies", None) if _policies is None: _policies = [ @@ -98,7 +99,91 @@ def send_request( async def close(self) -> None: await self._client.close() - async def __aenter__(self) -> "EventGridClient": + async def __aenter__(self) -> "EventGridPublisherClient": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self._client.__aexit__(*exc_details) + + +class EventGridConsumerClient( + EventGridConsumerClientOperationsMixin +): # pylint: disable=client-accepts-api-version-keyword + """EventGridConsumerClient. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__( + self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any + ) -> None: + _endpoint = "{endpoint}" + self._config = EventGridConsumerClientConfiguration(endpoint=endpoint, credential=credential, **kwargs) + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + def send_request( + self, request: HttpRequest, *, stream: bool = False, **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = await client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.AsyncHttpResponse + """ + + request_copy = deepcopy(request) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "EventGridConsumerClient": await self._client.__aenter__() return self diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py index 4e99a4348f83..db6bd48f5aa3 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_configuration.py @@ -18,8 +18,8 @@ from azure.core.credentials_async import AsyncTokenCredential -class EventGridClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long - """Configuration for EventGridClient. +class EventGridPublisherClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long + """Configuration for EventGridPublisherClient. Note that all parameters used to create this instance are saved as instance attributes. @@ -31,16 +31,74 @@ class EventGridClientConfiguration: # pylint: disable=too-many-instance-attribu AzureKeyCredential type or a TokenCredential type. Required. :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "2023-10-01-preview". Note that overriding this default value may result in unsupported - behavior. + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ def __init__( self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any ) -> None: - api_version: str = kwargs.pop("api_version", "2023-10-01-preview") + api_version: str = kwargs.pop("api_version", "2024-06-01") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + + self.endpoint = endpoint + self.credential = credential + self.api_version = api_version + self.credential_scopes = kwargs.pop("credential_scopes", ["https://eventgrid.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "eventgrid/{}".format(VERSION)) + self.polling_interval = kwargs.get("polling_interval", 30) + self._configure(**kwargs) + + def _infer_policy(self, **kwargs): + if isinstance(self.credential, AzureKeyCredential): + return policies.AzureKeyCredentialPolicy( + self.credential, "Authorization", prefix="SharedAccessKey", **kwargs + ) + if hasattr(self.credential, "get_token"): + return policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + raise TypeError(f"Unsupported credential: {self.credential}") + + def _configure(self, **kwargs: Any) -> None: + self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs) + self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs) + self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs) + self.authentication_policy = kwargs.get("authentication_policy") + if self.credential and not self.authentication_policy: + self.authentication_policy = self._infer_policy(**kwargs) + + +class EventGridConsumerClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long + """Configuration for EventGridConsumerClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a TokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__( + self, endpoint: str, credential: Union[AzureKeyCredential, "AsyncTokenCredential"], **kwargs: Any + ) -> None: + api_version: str = kwargs.pop("api_version", "2024-06-01") if endpoint is None: raise ValueError("Parameter 'endpoint' must not be None.") diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py index 51cf0e7ac905..c716622cb722 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/__init__.py @@ -6,14 +6,16 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._patch import EventGridClientOperationsMixin +from ._patch import EventGridPublisherClientOperationsMixin +from ._patch import EventGridConsumerClientOperationsMixin from ._patch import __all__ as _patch_all from ._patch import * # pylint: disable=unused-wildcard-import from ._patch import patch_sdk as _patch_sdk __all__ = [ - "EventGridClientOperationsMixin", + "EventGridPublisherClientOperationsMixin", + "EventGridConsumerClientOperationsMixin", ] __all__.extend([p for p in _patch_all if p not in __all__]) _patch_sdk() diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index 51895d2634b3..eb240583f902 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -27,45 +27,42 @@ from ... import models as _models from ..._model_base import SdkJSONEncoder, _deserialize from ..._operations._operations import ( - build_event_grid_acknowledge_cloud_events_request, - build_event_grid_publish_cloud_event_request, - build_event_grid_publish_cloud_events_request, - build_event_grid_receive_cloud_events_request, - build_event_grid_reject_cloud_events_request, - build_event_grid_release_cloud_events_request, - build_event_grid_renew_cloud_event_locks_request, + build_event_grid_consumer_acknowledge_request, + build_event_grid_consumer_receive_request, + build_event_grid_consumer_reject_request, + build_event_grid_consumer_release_request, + build_event_grid_consumer_renew_lock_request, + build_event_grid_publisher_send_events_request, + build_event_grid_publisher_send_request, ) from ..._validation import api_version_validation -from .._vendor import EventGridClientMixinABC +from .._vendor import EventGridConsumerClientMixinABC, EventGridPublisherClientMixinABC if sys.version_info >= (3, 9): from collections.abc import MutableMapping else: from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +_Unset: Any = object() -class EventGridClientOperationsMixin(EventGridClientMixinABC): +class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC): @distributed_trace_async - async def _publish_cloud_event( # pylint: disable=protected-access + async def _send( # pylint: disable=protected-access self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long - """Publish Single Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Publish a single Cloud Event to a namespace topic. :param topic_name: Topic Name. Required. :type topic_name: str :param event: Single Cloud Event being published. Required. - :type event: ~azure.eventgrid.models.CloudEvent + :type event: ~azure.eventgrid.models._models.CloudEvent :return: PublishResult. The PublishResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.PublishResult + :rtype: ~azure.eventgrid.models._models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -110,7 +107,7 @@ async def _publish_cloud_event( # pylint: disable=protected-access _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_publish_cloud_event_request( + _request = build_event_grid_publisher_send_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -149,22 +146,18 @@ async def _publish_cloud_event( # pylint: disable=protected-access return deserialized # type: ignore @distributed_trace_async - async def _publish_cloud_events( # pylint: disable=protected-access + async def _send_events( # pylint: disable=protected-access self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any ) -> _models._models.PublishResult: # pylint: disable=line-too-long - """Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an - HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return - various error codes. For example, 401: which indicates authorization failure, 403: which - indicates quota exceeded or message is too large, 410: which indicates that specific topic is - not found, 400: for bad request, and 500: for internal server error. + """Publish a batch of Cloud Events to a namespace topic. :param topic_name: Topic Name. Required. :type topic_name: str :param events: Array of Cloud Events being published. Required. - :type events: list[~azure.eventgrid.models.CloudEvent] + :type events: list[~azure.eventgrid.models._models.CloudEvent] :return: PublishResult. The PublishResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.PublishResult + :rtype: ~azure.eventgrid.models._models.PublishResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -213,7 +206,7 @@ async def _publish_cloud_events( # pylint: disable=protected-access _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_publish_cloud_events_request( + _request = build_event_grid_publisher_send_events_request( topic_name=topic_name, content_type=content_type, api_version=self._config.api_version, @@ -251,8 +244,11 @@ async def _publish_cloud_events( # pylint: disable=protected-access return deserialized # type: ignore + +class EventGridConsumerClientOperationsMixin(EventGridConsumerClientMixinABC): + @distributed_trace_async - async def _receive_cloud_events( # pylint: disable=protected-access + async def _receive( # pylint: disable=protected-access self, topic_name: str, event_subscription_name: str, @@ -262,7 +258,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access **kwargs: Any ) -> _models._models.ReceiveResult: # pylint: disable=line-too-long - """Receive Batch of Cloud Events from the Event Subscription. + """Receive a batch of Cloud Events from a subscription. :param topic_name: Topic Name. Required. :type topic_name: str @@ -278,7 +274,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access 60 seconds. Default value is None. :paramtype max_wait_time: int :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReceiveResult + :rtype: ~azure.eventgrid.models._models.ReceiveResult :raises ~azure.core.exceptions.HttpResponseError: Example: @@ -337,7 +333,7 @@ async def _receive_cloud_events( # pylint: disable=protected-access cls: ClsType[_models._models.ReceiveResult] = kwargs.pop("cls", None) # pylint: disable=protected-access - _request = build_event_grid_receive_cloud_events_request( + _request = build_event_grid_consumer_receive_request( topic_name=topic_name, event_subscription_name=event_subscription_name, max_events=max_events, @@ -377,56 +373,59 @@ async def _receive_cloud_events( # pylint: disable=protected-access return deserialized # type: ignore @overload - async def _acknowledge_cloud_events( # pylint: disable=protected-access + async def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: _models._models.AcknowledgeOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @overload - async def _acknowledge_cloud_events( + async def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @overload - async def _acknowledge_cloud_events( + async def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any ) -> _models.AcknowledgeResult: ... @distributed_trace_async - async def _acknowledge_cloud_events( + async def _acknowledge( self, topic_name: str, event_subscription_name: str, - acknowledge_options: Union[_models._models.AcknowledgeOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. + """Acknowledge a batch of Cloud Events. The response will include the set of successfully + acknowledged lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully acknowledged events will no longer be available to be received by any + consumer. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param acknowledge_options: AcknowledgeOptions. Is one of the following types: - AcknowledgeOptions, JSON, IO[bytes] Required. - :type acknowledge_options: ~azure.eventgrid.models.AcknowledgeOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: @@ -435,7 +434,7 @@ async def _acknowledge_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - acknowledge_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -484,14 +483,19 @@ async def _acknowledge_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.AcknowledgeResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(acknowledge_options, (IOBase, bytes)): - _content = acknowledge_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(acknowledge_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_acknowledge_cloud_events_request( + _request = build_event_grid_consumer_acknowledge_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -531,14 +535,14 @@ async def _acknowledge_cloud_events( @overload @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, - ) # pylint: disable=protected-access - async def _release_cloud_events( # pylint: disable=protected-access + ) + async def _release( self, topic_name: str, event_subscription_name: str, - release_options: _models._models.ReleaseOptions, + body: JSON, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -546,13 +550,13 @@ async def _release_cloud_events( # pylint: disable=protected-access @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - async def _release_cloud_events( + async def _release( self, topic_name: str, event_subscription_name: str, - release_options: JSON, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + lock_tokens: List[str], + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -560,13 +564,13 @@ async def _release_cloud_events( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - async def _release_cloud_events( + async def _release( self, topic_name: str, event_subscription_name: str, - release_options: IO[bytes], + body: IO[bytes], *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, content_type: str = "application/json", **kwargs: Any ) -> _models.ReleaseResult: ... @@ -575,29 +579,31 @@ async def _release_cloud_events( @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]}, ) - async def _release_cloud_events( + async def _release( self, topic_name: str, event_subscription_name: str, - release_options: Union[_models._models.ReleaseOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, *, - release_delay_in_seconds: Optional[Union[int, _models.ReleaseDelay]] = None, + lock_tokens: List[str] = _Unset, + release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None, **kwargs: Any ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. + """Release a batch of Cloud Events. The response will include the set of successfully released + lock tokens, along with other failed lock tokens with their corresponding error information. + Successfully released events can be received by consumers. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param release_options: ReleaseOptions. Is one of the following types: ReleaseOptions, JSON, - IO[bytes] Required. - :type release_options: ~azure.eventgrid.models.ReleaseOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. - :paramtype release_delay_in_seconds: int or ~azure.eventgrid.models.ReleaseDelay + Known values are: "0", "10", "60", "600", and "3600". Default value is None. + :paramtype release_delay_in_seconds: str or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: @@ -606,7 +612,7 @@ async def _release_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - release_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -655,14 +661,19 @@ async def _release_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.ReleaseResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(release_options, (IOBase, bytes)): - _content = release_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(release_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_release_cloud_events_request( + _request = build_event_grid_consumer_release_request( topic_name=topic_name, event_subscription_name=event_subscription_name, release_delay_in_seconds=release_delay_in_seconds, @@ -701,55 +712,58 @@ async def _release_cloud_events( return deserialized # type: ignore @overload - async def _reject_cloud_events( # pylint: disable=protected-access + async def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: _models._models.RejectOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @overload - async def _reject_cloud_events( + async def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @overload - async def _reject_cloud_events( + async def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any ) -> _models.RejectResult: ... @distributed_trace_async - async def _reject_cloud_events( + async def _reject( self, topic_name: str, event_subscription_name: str, - reject_options: Union[_models._models.RejectOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. + """Reject a batch of Cloud Events. The response will include the set of successfully rejected lock + tokens, along with other failed lock tokens with their corresponding error information. + Successfully rejected events will be dead-lettered and can no longer be received by a consumer. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param reject_options: RejectOptions. Is one of the following types: RejectOptions, JSON, - IO[bytes] Required. - :type reject_options: ~azure.eventgrid.models.RejectOptions or JSON or IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: @@ -758,7 +772,7 @@ async def _reject_cloud_events( .. code-block:: python # JSON input template you can fill out and use as your body input. - reject_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -807,14 +821,19 @@ async def _reject_cloud_events( content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.RejectResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(reject_options, (IOBase, bytes)): - _content = reject_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(reject_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_reject_cloud_events_request( + _request = build_event_grid_consumer_reject_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -854,80 +873,90 @@ async def _reject_cloud_events( @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, - ) # pylint: disable=protected-access - async def _renew_cloud_event_locks( # pylint: disable=protected-access + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, + ) + async def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: _models._models.RenewLockOptions, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - async def _renew_cloud_event_locks( + async def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: JSON, *, + lock_tokens: List[str], content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @overload @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - async def _renew_cloud_event_locks( + async def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: IO[bytes], + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: ... + ) -> _models.RenewLocksResult: ... @distributed_trace_async @api_version_validation( method_added_on="2023-10-01-preview", - params_added_on={"2023-10-01-preview": ["accept"]}, + params_added_on={ + "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] + }, ) - async def _renew_cloud_event_locks( + async def _renew_lock( self, topic_name: str, event_subscription_name: str, - renew_lock_options: Union[_models._models.RenewLockOptions, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + lock_tokens: List[str] = _Unset, **kwargs: Any - ) -> _models.RenewCloudEventLocksResult: - """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - renewed lockTokens, along with other failed lockTokens with their corresponding error - information. + ) -> _models.RenewLocksResult: + """Renew locks for a batch of Cloud Events. The response will include the set of successfully + renewed lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully renewed locks will ensure that the associated event is only available + to the consumer that holds the renewed lock. :param topic_name: Topic Name. Required. :type topic_name: str :param event_subscription_name: Event Subscription Name. Required. :type event_subscription_name: str - :param renew_lock_options: RenewLockOptions. Is one of the following types: RenewLockOptions, - JSON, IO[bytes] Required. - :type renew_lock_options: ~azure.eventgrid.models.RenewLockOptions or JSON or IO[bytes] - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with - MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword lock_tokens: Array of lock tokens. Required. + :paramtype lock_tokens: list[str] + :return: RenewLocksResult. The RenewLocksResult is compatible with MutableMapping + :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: Example: .. code-block:: python # JSON input template you can fill out and use as your body input. - renew_lock_options = { + body = { "lockTokens": [ "str" # Array of lock tokens. Required. ] @@ -974,16 +1003,21 @@ async def _renew_cloud_event_locks( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RenewCloudEventLocksResult] = kwargs.pop("cls", None) + cls: ClsType[_models.RenewLocksResult] = kwargs.pop("cls", None) + if body is _Unset: + if lock_tokens is _Unset: + raise TypeError("missing required argument: lock_tokens") + body = {"lockTokens": lock_tokens} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(renew_lock_options, (IOBase, bytes)): - _content = renew_lock_options + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(renew_lock_options, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_renew_cloud_event_locks_request( + _request = build_event_grid_consumer_renew_lock_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, @@ -1013,7 +1047,7 @@ async def _renew_cloud_event_locks( if _stream: deserialized = response.iter_bytes() else: - deserialized = _deserialize(_models.RenewCloudEventLocksResult, response.json()) + deserialized = _deserialize(_models.RenewLocksResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 0d96149e63cf..71e5202a6b72 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -5,7 +5,7 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import List, overload, Union, Any, Optional, Callable, Dict, TypeVar +from typing import List, Union, Any, Optional, Callable, Dict, TypeVar, TYPE_CHECKING import sys from azure.core.messaging import CloudEvent from azure.core.exceptions import ( @@ -15,22 +15,21 @@ from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, AsyncHttpResponse -from ...models._patch import ReceiveResult, ReceiveDetails -from ..._operations._patch import _to_http_request, use_standard_only -from ._operations import EventGridClientOperationsMixin as OperationsMixin +from ...models._patch import ReceiveDetails +from ..._operations._patch import use_standard_only +from ._operations import ( + EventGridPublisherClientOperationsMixin as PublisherOperationsMixin, + EventGridConsumerClientOperationsMixin as ConsumerOperationsMixin, +) from ... import models as _models -from ...models._models import AcknowledgeOptions, ReleaseOptions, RejectOptions, RenewLockOptions from ..._validation import api_version_validation from ..._operations._patch import ( _serialize_events, - EVENT_TYPES_BASIC, - EVENT_TYPES_STD, - validate_args, ) from ..._legacy import EventGridEvent -from ..._legacy._helpers import _is_eventgrid_event, _from_cncf_events +from ..._legacy._helpers import _is_eventgrid_event_format, _from_cncf_events if sys.version_info >= (3, 9): from collections.abc import MutableMapping @@ -40,80 +39,38 @@ T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] +if TYPE_CHECKING: + from cloudevents.http.event import CloudEvent as CNCFCloudEvent -class EventGridClientOperationsMixin(OperationsMixin): - - @overload - async def send( - self, - events: EVENT_TYPES_BASIC, - *, - channel_name: Optional[str] = None, - content_type: Optional[str] = None, - **kwargs: Any, - ) -> None: - """Send events to the Event Grid Basic Service. - :param events: The event to send. - :type events: CloudEvent or List[CloudEvent] or EventGridEvent or List[EventGridEvent] - or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] - :keyword channel_name: The name of the channel to send the event to. - :paramtype channel_name: str or None - :keyword content_type: The content type of the event. If not specified, the default value is - "application/cloudevents+json; charset=utf-8". - :paramtype content_type: str or None - - :return: None - :rtype: None - """ - ... +class EventGridPublisherClientOperationsMixin(PublisherOperationsMixin): - @overload + @distributed_trace_async async def send( self, - topic_name: str, - events: EVENT_TYPES_STD, + events: Union[ + CloudEvent, + List[CloudEvent], + Dict[str, Any], + List[Dict[str, Any]], + "CNCFCloudEvent", + List["CNCFCloudEvent"], + EventGridEvent, + List[EventGridEvent], + ], *, - binary_mode: bool = False, + channel_name: Optional[str] = None, content_type: Optional[str] = None, **kwargs: Any, - ) -> None: - """Send events to the Event Grid Namespace Service. + ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param + """Send events to the Event Grid Service. :param topic_name: The name of the topic to send the event to. :type topic_name: str :param events: The event to send. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] - :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default - value is False. - :paramtype binary_mode: bool - :keyword content_type: The content type of the event. If not specified, the default value is - "application/cloudevents+json; charset=utf-8". - :paramtype content_type: str or None - - :return: None - :rtype: None - """ - ... - - @validate_args( - kwargs_mapping={ - "Basic": ["channel_name"], - "Standard": ["binary_mode"], - } - ) - @distributed_trace_async - async def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param - """Send events to the Event Grid Namespace Service. - - :param topic_name: The name of the topic to send the event to. - :type topic_name: str - :param events: The event to send. - :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] - :keyword binary_mode: Whether to send the event in binary mode. If not specified, the default - value is False. - :paramtype binary_mode: bool - :keyword channel_name: The name of the channel to send the event to. + or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] + :keyword channel_name: The name of the channel to send the event to. Event Grid Basic Resource only. :paramtype channel_name: str or None :keyword content_type: The content type of the event. If not specified, the default value is "application/cloudevents+json; charset=utf-8". @@ -121,113 +78,41 @@ async def send(self, *args, **kwargs) -> None: # pylint: disable=docstring-shoul :return: None :rtype: None - - A single instance or a list of dictionaries, CloudEvents are accepted. In the case of an Azure Event Grid - Basic Resource, EventGridEvent(s) and CNCFCloudEvents are also accepted. - - .. admonition:: Example: - - .. literalinclude:: ../samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py - :start-after: [START publish_cloud_event_async] - :end-before: [END publish_cloud_event_async] - :language: python - :dedent: 0 - :caption: Publishing a Cloud Event to a Namespace Topic. - - .. literalinclude:: ../samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py - :start-after: [START publish_cloud_event_to_topic_async] - :end-before: [END publish_cloud_event_to_topic_async] - :language: python - :dedent: 0 - :caption: Publishing a CloudEvent to a Basic Topic. """ - # Check kwargs - channel_name = kwargs.pop("channel_name", None) - binary_mode = kwargs.pop("binary_mode", False) - topic_name = kwargs.pop("topic_name", None) - events = kwargs.pop("events", None) - - # both there - if len(args) > 1: - if events is not None: - raise ValueError("events is already passed as a keyword argument.") - if topic_name is not None: - raise ValueError("topic_name is already passed as a keyword argument.") - events = args[1] - topic_name = args[0] - - elif len(args) == 1: - if events is not None: - if topic_name is not None: - raise ValueError("topic_name is already passed as a keyword argument.") - topic_name = args[0] - else: - events = args[0] - - if self._level == "Standard" and topic_name is None: - raise ValueError("Topic name is required for standard level client.") - - # check binary mode - if binary_mode: - await self._send_binary(topic_name, events, **kwargs) - else: - # If no binary_mode is set, send whatever event is passed - - # If a cloud event dict, convert to CloudEvent for serializing - try: - if isinstance(events, dict): - events = CloudEvent.from_dict(events) - if isinstance(events, list) and isinstance(events[0], dict): - events = [CloudEvent.from_dict(e) for e in events] - except Exception: # pylint: disable=broad-except - pass - - if self._level == "Standard": - kwargs["content_type"] = kwargs.get("content_type", "application/cloudevents-batch+json; charset=utf-8") - if not isinstance(events, list): - events = [events] - - if isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]): - raise TypeError("EventGridEvent is not supported for standard level client.") - try: - # Try to send via namespace - await self._send(topic_name, _serialize_events(events), **kwargs) - except Exception as exception: # pylint: disable=broad-except - self._http_response_error_handler(exception, "Standard") - raise exception - else: - try: - await self._send(events, channel_name=channel_name, **kwargs) - except Exception as exception: - self._http_response_error_handler(exception, "Basic") - raise exception + if self._namespace and channel_name: + raise ValueError("Channel name is not supported for Event Grid Namespaces.") - async def _send_binary(self, topic_name: str, event: Any, **kwargs: Any) -> None: - # If data is passed as a dictionary, make sure it is a CloudEvent - if isinstance(event, list): - raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from + # If a cloud event dict, convert to CloudEvent for serializing try: - if not isinstance(event, CloudEvent): - try: - event = CloudEvent.from_dict(event) - except AttributeError: - event = CloudEvent.from_dict(_from_cncf_events(event)) - - except AttributeError: - raise TypeError("Binary mode is only supported for type CloudEvent.") # pylint: disable=raise-missing-from - - if isinstance(event, CloudEvent): - http_request = _to_http_request( - topic_name=topic_name, - api_version=self._config.api_version, - event=event, - **kwargs, + if isinstance(events, dict): + events = CloudEvent.from_dict(events) + if isinstance(events, list) and isinstance(events[0], dict): + events = [CloudEvent.from_dict(e) for e in events] + except Exception: # pylint: disable=broad-except + pass + + if self._namespace: + kwargs["content_type"] = ( + content_type if content_type else "application/cloudevents-batch+json; charset=utf-8" ) - else: - raise TypeError("Binary mode is only supported for type CloudEvent.") + if not isinstance(events, list): + events = [events] - # If data is a cloud event, convert to an HTTP Request in binary mode - await self.send_request(http_request, **kwargs) + if isinstance(events[0], EventGridEvent) or _is_eventgrid_event_format(events[0]): + raise TypeError("EventGridEvent is not supported for Event Grid Namespaces.") + try: + # Try to send via namespace + await self._publish(self._namespace, _serialize_events(events), **kwargs) + except Exception as exception: # pylint: disable=broad-except + self._http_response_error_handler(exception, "Namespaces") + raise exception + else: + kwargs["content_type"] = content_type if content_type else "application/json; charset=utf-8" + try: + await self._publish(events, channel_name=channel_name, **kwargs) + except Exception as exception: + self._http_response_error_handler(exception, "Basic") + raise exception def _http_response_error_handler(self, exception, level): if isinstance(exception, HttpResponseError): @@ -236,28 +121,24 @@ def _http_response_error_handler(self, exception, level): if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - f"Please check that the level set on the client, {level}, corresponds to the correct " + f"Please check that the tier you are using, corresponds to the correct " "endpoint and/or topic name." ) from exception raise exception - @use_standard_only + +class EventGridConsumerClientOperationsMixin(ConsumerOperationsMixin): + @distributed_trace_async - async def receive_cloud_events( + async def receive( self, - topic_name: str, - subscription_name: str, *, max_events: Optional[int] = None, max_wait_time: Optional[int] = None, **kwargs: Any, - ) -> ReceiveResult: + ) -> List[ReceiveDetails]: """Receive Batch of Cloud Events from the Event Subscription. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value is 100 events. If not specified, the default value is 1. Default value is None. :paramtype max_events: int @@ -267,20 +148,20 @@ async def receive_cloud_events( value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is 60 seconds. Default value is None. :paramtype max_wait_time: int - :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.ReceiveResult + :return: ReceiveDetails + :rtype: list[~azure.eventgrid.models.ReceiveDetails] :raises ~azure.core.exceptions.HttpResponseError: """ detail_items = [] - receive_result = await self._receive_cloud_events( - topic_name, - subscription_name, + receive_result = await self._receive( + self._namespace, + self._subscription, max_events=max_events, max_wait_time=max_wait_time, **kwargs, ) - for detail_item in receive_result.value: + for detail_item in receive_result.details: deserialized_cloud_event = CloudEvent.from_dict(detail_item.event) detail_item.event = deserialized_cloud_event detail_items.append( @@ -289,139 +170,108 @@ async def receive_cloud_events( event=detail_item.event, ) ) - receive_result_deserialized = ReceiveResult(value=detail_items) - return receive_result_deserialized + return detail_items - @use_standard_only @distributed_trace_async - async def acknowledge_cloud_events( + async def acknowledge( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, ) -> _models.AcknowledgeResult: - """Acknowledge batch of Cloud Events. The server responds with an HTTP 200 status code if the - request is successfully accepted. The response body will include the set of successfully - acknowledged lockTokens, along with other failed lockTokens with their corresponding error - information. Successfully acknowledged events will no longer be available to any consumer. + """Acknowledge a batch of Cloud Events. The response will include the set of successfully + acknowledged lock tokens, along with other failed lock tokens with their corresponding error + information. Successfully acknowledged events will no longer be available to be received by any + consumer. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.AcknowledgeResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = AcknowledgeOptions(lock_tokens=lock_tokens) - return await super()._acknowledge_cloud_events(topic_name, subscription_name, options, **kwargs) + return await super()._acknowledge(self._namespace, self._subscription, lock_tokens=lock_tokens, **kwargs) - @use_standard_only @distributed_trace_async @api_version_validation( params_added_on={"2023-10-01-preview": ["release_delay"]}, ) - async def release_cloud_events( + async def release( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], release_delay: Optional[Union[int, _models.ReleaseDelay]] = None, **kwargs: Any, ) -> _models.ReleaseResult: - """Release batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully released - lockTokens, along with other failed lockTokens with their corresponding error information. + """Release a batch of Cloud Events. The response will include the set of successfully released + lock tokens, along with other failed lock tokens with their corresponding error information. + Successfully released events can be received by consumers. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :keyword release_delay: Release cloud events with the specified delay in seconds. - Known values are: 0, 10, 60, 600, and 3600. Default value is None. + Known values are: 0, 10, 60, 600, and 3600. Default value is None, indicating no delay. :paramtype release_delay: int or ~azure.eventgrid.models.ReleaseDelay :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.ReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = ReleaseOptions(lock_tokens=lock_tokens) - return await super()._release_cloud_events( - topic_name, - subscription_name, - options, + return await super()._release( + self._namespace, + self._subscription, + lock_tokens=lock_tokens, release_delay_in_seconds=release_delay, **kwargs, ) - @use_standard_only @distributed_trace_async - async def reject_cloud_events( + async def reject( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, ) -> _models.RejectResult: - """Reject batch of Cloud Events. The server responds with an HTTP 200 status code if the request - is successfully accepted. The response body will include the set of successfully rejected - lockTokens, along with other failed lockTokens with their corresponding error information. + """Reject a batch of Cloud Events. The response will include the set of successfully rejected lock + tokens, along with other failed lock tokens with their corresponding error information. + Successfully rejected events will be dead-lettered and can no longer be received by a consumer. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] :return: RejectResult. The RejectResult is compatible with MutableMapping :rtype: ~azure.eventgrid.models.RejectResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = RejectOptions(lock_tokens=lock_tokens) - return await super()._reject_cloud_events(topic_name, subscription_name, options, **kwargs) + return await super()._reject(self._namespace, self._subscription, lock_tokens=lock_tokens, **kwargs) - @use_standard_only @distributed_trace_async @api_version_validation( method_added_on="2023-10-01-preview", + params_added_on={"2023-10-01-preview": ["api_version", "content_type", "accept"]}, ) - async def renew_cloud_event_locks( + async def renew_locks( self, - topic_name: str, - subscription_name: str, *, lock_tokens: List[str], **kwargs: Any, - ) -> _models.RenewCloudEventLocksResult: + ) -> _models.RenewLocksResult: """Renew lock for batch of Cloud Events. The server responds with an HTTP 200 status code if the request is successfully accepted. The response body will include the set of successfully renewed lockTokens, along with other failed lockTokens with their corresponding error information. - :param topic_name: Topic Name. Required. - :type topic_name: str - :param subscription_name: Event Subscription Name. Required. - :type subscription_name: str :keyword lock_tokens: Array of lock tokens of Cloud Events. Required. :paramtype lock_tokens: List[str] - :return: RenewCloudEventLocksResult. The RenewCloudEventLocksResult is compatible with + :return: RenewLocksResult. The RenewLocksResult is compatible with MutableMapping - :rtype: ~azure.eventgrid.models.RenewCloudEventLocksResult + :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: """ - options = RenewLockOptions(lock_tokens=lock_tokens) - return await super()._renew_cloud_event_locks(topic_name, subscription_name, options, **kwargs) + return await super()._renew_lock(self._namespace, self._subscription, lock_tokens=lock_tokens, **kwargs) __all__: List[str] = [ - "EventGridClientOperationsMixin" + "EventGridPublisherClientOperationsMixin", + "EventGridConsumerClientOperationsMixin", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index ebfe920d986d..c07ebfc3d80d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -10,11 +10,13 @@ from azure.core.credentials import AzureKeyCredential, AzureSasCredential -from .._legacy.aio import EventGridPublisherClient -from ._client import EventGridClient as InternalEventGridClient +from .._legacy.aio import EventGridPublisherClient as LegacyEventGridPublisherClient +from ._client import ( + EventGridPublisherClient as InternalEventGridPublisherClient, + EventGridConsumerClient as InternalEventGridConsumerClient, +) from .._serialization import Deserializer, Serializer from .._patch import ( - ClientLevel, DEFAULT_BASIC_API_VERSION, DEFAULT_STANDARD_API_VERSION, ) @@ -24,23 +26,30 @@ from azure.core.credentials_async import AsyncTokenCredential -class EventGridClient(InternalEventGridClient): - """Azure Messaging EventGrid Client. +class EventGridPublisherClient(InternalEventGridPublisherClient): + """EventGridPublisherClient. + + Sends events to a basic topic, basic domain, or a namespace topic + specified during the client initialization. + + A single instance or a list of dictionaries, CloudEvents or EventGridEvents are accepted. + If a list is provided, the list must contain only one type of event. + If dictionaries are provided and sending to a namespace topic, + the dictionary must follow the CloudEvent schema. - :param endpoint: The endpoint to the Event Grid resource. + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. :type endpoint: str - :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a AsyncTokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: The API version to use for this operation. Default value for namespaces is - "2023-10-01-preview". Default value for basic is "2018-01-01". + :keyword namespace_topic: The name of the topic to publish events to. Required for EventGrid Namespaces. + Default value is None, which is used for EventGrid Basic. + :paramtype namespace_topic: str or None + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str or None - :keyword level: The level of client to use. - Known values include: "Basic", "Standard". Default value is "Standard". - `Standard` is used for working with a namespace topic. - `Basic` is used for working with a basic topic. - :paramtype level: str + :paramtype api_version: str """ def __init__( @@ -48,19 +57,19 @@ def __init__( endpoint: str, credential: Union[AzureKeyCredential, AzureSasCredential, "AsyncTokenCredential"], *, + namespace_topic: Optional[str] = None, api_version: Optional[str] = None, - level: Union[str, ClientLevel] = "Standard", - **kwargs: Any + **kwargs: Any, ) -> None: - _endpoint = "{endpoint}" - self._level = level + self._namespace = namespace_topic + self._credential = credential - if level == ClientLevel.BASIC: - self._client = EventGridPublisherClient( # type: ignore[assignment] + if not self._namespace: + self._client = LegacyEventGridPublisherClient( # type: ignore[assignment] endpoint, credential, api_version=api_version or DEFAULT_BASIC_API_VERSION, **kwargs ) - self._send = self._client.send # type: ignore[attr-defined] - elif level == ClientLevel.STANDARD: + self._publish = self._client.send # type: ignore[attr-defined] + else: if isinstance(credential, AzureSasCredential): raise TypeError("SAS token authentication is not supported for the standard client.") @@ -68,15 +77,61 @@ def __init__( endpoint=endpoint, credential=credential, api_version=api_version or DEFAULT_STANDARD_API_VERSION, - **kwargs + **kwargs, ) - self._send = self._publish_cloud_events - else: - raise ValueError("Unknown client level. Known values are `Standard` and `Basic`.") + self._publish = self._send_events self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False + def __repr__(self) -> str: + return ( + f"" + ) + + +class EventGridConsumerClient(InternalEventGridConsumerClient): + """EventGridConsumerClient. + + Consumes and manages events from a namespace topic + and event subscription specified during the client initialization. + + :param endpoint: The host name of the namespace, e.g. + namespaceName1.westus-1.eventgrid.azure.net. Required. + :type endpoint: str + :param credential: Credential used to authenticate requests to the service. Is either a + AzureKeyCredential type or a AsyncTokenCredential type. Required. + :type credential: ~azure.core.credentials.AzureKeyCredential or + ~azure.core.credentials_async.AsyncTokenCredential + :keyword namespace_topic: The name of the topic to consume events from. Required. + :paramtype namespace_topic: str + :subscription: The name of the subscription to consume events from. Required. + :paramtype subscription: str + :keyword api_version: The API version to use for this operation. Default value is "2024-06-01". + Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__( + self, + endpoint: str, + credential: Union[AzureKeyCredential, "AsyncTokenCredential"], + *, + namespace_topic: str, + subscription: str, + api_version: Optional[str] = None, + **kwargs: Any, + ) -> None: + self._namespace = namespace_topic + self._subscription = subscription + self._credential = credential + super().__init__( + endpoint=endpoint, credential=credential, api_version=api_version or DEFAULT_STANDARD_API_VERSION, **kwargs + ) + + def __repr__(self) -> str: + return f"" + def patch_sdk(): """Do not remove from this file. @@ -87,6 +142,6 @@ def patch_sdk(): __all__: List[str] = [ - "EventGridClient", + "EventGridConsumerClient", "EventGridPublisherClient", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py index 35bd45e3dc6b..4bf238ec554f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_vendor.py @@ -8,7 +8,7 @@ from abc import ABC from typing import TYPE_CHECKING -from ._configuration import EventGridClientConfiguration +from ._configuration import EventGridConsumerClientConfiguration, EventGridPublisherClientConfiguration if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -17,10 +17,19 @@ from .._serialization import Deserializer, Serializer -class EventGridClientMixinABC(ABC): +class EventGridPublisherClientMixinABC(ABC): """DO NOT use this class. It is for internal typing use only.""" _client: "AsyncPipelineClient" - _config: EventGridClientConfiguration + _config: EventGridPublisherClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" + + +class EventGridConsumerClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + + _client: "AsyncPipelineClient" + _config: EventGridConsumerClientConfiguration _serialize: "Serializer" _deserialize: "Deserializer" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py index 370a6e7b643d..c687c94b6e9b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/__init__.py @@ -10,7 +10,7 @@ from ._models import FailedLockToken from ._models import RejectResult from ._models import ReleaseResult -from ._models import RenewCloudEventLocksResult +from ._models import RenewLocksResult from ._enums import ReleaseDelay from ._patch import __all__ as _patch_all @@ -22,7 +22,7 @@ "FailedLockToken", "RejectResult", "ReleaseResult", - "RenewCloudEventLocksResult", + "RenewLocksResult", "ReleaseDelay", ] __all__.extend([p for p in _patch_all if p not in __all__]) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py index 69e6eeb024ea..207504715bf6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_enums.py @@ -10,16 +10,16 @@ from azure.core import CaseInsensitiveEnumMeta -class ReleaseDelay(int, Enum, metaclass=CaseInsensitiveEnumMeta): +class ReleaseDelay(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Supported delays for release operation.""" - BY0_SECONDS = 0 + NO_DELAY = "0" """Release the event after 0 seconds.""" - BY10_SECONDS = 10 + TEN_SECONDS = "10" """Release the event after 10 seconds.""" - BY60_SECONDS = 60 + ONE_MINUTE = "60" """Release the event after 60 seconds.""" - BY600_SECONDS = 600 + TEN_MINUTES = "600" """Release the event after 600 seconds.""" - BY3600_SECONDS = 3600 + ONE_HOUR = "3600" """Release the event after 3600 seconds.""" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py index ec8f8df9a975..a84b330a8112 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_models.py @@ -8,27 +8,21 @@ # -------------------------------------------------------------------------- import datetime +import sys from typing import Any, List, Mapping, Optional, TYPE_CHECKING, overload from .. import _model_base from .._model_base import rest_field +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports + if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports from .. import models as _models - - -class AcknowledgeOptions(_model_base.Model): - """Array of lock tokens for the corresponding received Cloud Events to be acknowledged. - - All required parameters must be populated in order to send to server. - - :ivar lock_tokens: Array of lock tokens. Required. - :vartype lock_tokens: list[str] - """ - - lock_tokens: List[str] = rest_field(name="lockTokens") - """Array of lock tokens. Required.""" +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object class AcknowledgeResult(_model_base.Model): @@ -155,10 +149,10 @@ class Error(_model_base.Model): :ivar target: The target of the error. :vartype target: str :ivar details: An array of details about specific errors that led to this reported error. - :vartype details: list[~azure.eventgrid.models.Error] + :vartype details: list[~azure.eventgrid.models._models.Error] :ivar innererror: An object containing more specific information than the current object about the error. - :vartype innererror: ~azure.eventgrid.models.InnerError + :vartype innererror: ~azure.eventgrid.models._models.InnerError """ code: str = rest_field() @@ -182,7 +176,7 @@ class FailedLockToken(_model_base.Model): :vartype lock_token: str :ivar error: Error information of the failed operation result for the lock token in the request. Required. - :vartype error: ~azure.eventgrid.models.Error + :vartype error: ~azure.eventgrid.models._models.Error """ lock_token: str = rest_field(name="lockToken") @@ -217,7 +211,7 @@ class InnerError(_model_base.Model): :ivar code: One of a server-defined set of error codes. :vartype code: str :ivar innererror: Inner error. - :vartype innererror: ~azure.eventgrid.models.InnerError + :vartype innererror: ~azure.eventgrid.models._models.InnerError """ code: Optional[str] = rest_field() @@ -236,9 +230,9 @@ class ReceiveDetails(_model_base.Model): All required parameters must be populated in order to send to server. :ivar broker_properties: The Event Broker details. Required. - :vartype broker_properties: ~azure.eventgrid.models.BrokerProperties + :vartype broker_properties: ~azure.eventgrid.models._models.BrokerProperties :ivar event: Cloud Event details. Required. - :vartype event: ~azure.eventgrid.models.CloudEvent + :vartype event: ~azure.eventgrid.models._models.CloudEvent """ broker_properties: "_models._models.BrokerProperties" = rest_field(name="brokerProperties") @@ -252,27 +246,14 @@ class ReceiveResult(_model_base.Model): All required parameters must be populated in order to send to server. - :ivar value: Array of receive responses, one per cloud event. Required. - :vartype value: list[~azure.eventgrid.models.ReceiveDetails] + :ivar details: Array of receive responses, one per cloud event. Required. + :vartype details: list[~azure.eventgrid.models._models.ReceiveDetails] """ - value: List["_models._models.ReceiveDetails"] = rest_field() + details: List["_models._models.ReceiveDetails"] = rest_field(name="value") """Array of receive responses, one per cloud event. Required.""" -class RejectOptions(_model_base.Model): - """Array of lock tokens for the corresponding received Cloud Events to be rejected. - - All required parameters must be populated in order to send to server. - - :ivar lock_tokens: Array of lock tokens. Required. - :vartype lock_tokens: list[str] - """ - - lock_tokens: List[str] = rest_field(name="lockTokens") - """Array of lock tokens. Required.""" - - class RejectResult(_model_base.Model): """The result of the Reject operation. @@ -312,19 +293,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useles super().__init__(*args, **kwargs) -class ReleaseOptions(_model_base.Model): - """Array of lock tokens for the corresponding received Cloud Events to be released. - - All required parameters must be populated in order to send to server. - - :ivar lock_tokens: Array of lock tokens. Required. - :vartype lock_tokens: list[str] - """ - - lock_tokens: List[str] = rest_field(name="lockTokens") - """Array of lock tokens. Required.""" - - class ReleaseResult(_model_base.Model): """The result of the Release operation. @@ -364,7 +332,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useles super().__init__(*args, **kwargs) -class RenewCloudEventLocksResult(_model_base.Model): +class RenewLocksResult(_model_base.Model): """The result of the RenewLock operation. All required parameters must be populated in order to send to server. @@ -400,16 +368,3 @@ def __init__(self, mapping: Mapping[str, Any]): def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation super().__init__(*args, **kwargs) - - -class RenewLockOptions(_model_base.Model): - """Array of lock tokens for the corresponding received Cloud Events to be renewed. - - All required parameters must be populated in order to send to server. - - :ivar lock_tokens: Array of lock tokens. Required. - :vartype lock_tokens: list[str] - """ - - lock_tokens: List[str] = rest_field(name="lockTokens") - """Array of lock tokens. Required.""" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py index 2d1ee31d0d01..0772b43bb722 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/models/_patch.py @@ -10,7 +10,6 @@ from azure.core.messaging import CloudEvent from ._models import ( ReceiveDetails as InternalReceiveDetails, - ReceiveResult as InternalReceiveResult, BrokerProperties as InternalBrokerProperties, ) @@ -45,33 +44,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useles super().__init__(*args, **kwargs) -class ReceiveResult(InternalReceiveResult): - """Details of the Receive operation response. - - All required parameters must be populated in order to send to Azure. - - :ivar value: Array of receive responses, one per cloud event. Required. - :vartype value: list[~azure.eventgrid.models.ReceiveDetails] - """ - - @overload - def __init__( - self, - *, - value: List["ReceiveDetails"], - ): ... - - @overload - def __init__(self, mapping: Mapping[str, Any]): - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation - super().__init__(*args, **kwargs) - - class BrokerProperties(InternalBrokerProperties): """Properties of the Event Broker operation. @@ -104,7 +76,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useles __all__: List[str] = [ "ReceiveDetails", - "ReceiveResult", "BrokerProperties", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/eventgrid/azure-eventgrid/samples/README.md b/sdk/eventgrid/azure-eventgrid/samples/README.md index 4a456ff13937..226c849d8d08 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/README.md +++ b/sdk/eventgrid/azure-eventgrid/samples/README.md @@ -10,30 +10,7 @@ urlFragment: eventgrid-samples # Azure Event Grid Client Library Python Samples -## Namespace Sync samples -These code samples show common champion scenario operations with the Azure Event Grid client library. - -* Authenticate the client: [sample_authentication.py][python-eg-auth] -* Publish events to a namespace topic:[sample_publish_operation.py][python-eg-client-publish-sample] -* Publish events in binary mode to a namespace topic: [sample_binary_mode.py][python-eg-client-binary-mode-sample] -* Receive events from a namespace topic: [sample_receive_operation.py][python-eg-client-receive-sample] -* Acknowledge events from a namespace topic: [sample_acknowledge_operation.py][python-eg-client-ack-sample] -* Release events from a namespace topic: [sample_release_operation.py][python-eg-client-release-sample] -* Reject events from a namespace topic: [sample_reject_operation.py][python-eg-client-reject-sample] -* Renew locks: [sample_renew_locks_operation.py][python-eg-client-renew-locks-sample] - -## Namespace Async samples - -* Publish events to a namespace topic:[sample_publish_operation_async.py][python-eg-client-publish-sample-async] -* Publish events in binary mode to a namespace topic: [sample_binary_mode_async.py][python-eg-client-binary-mode-sample-async] -* Receive events from a namespace topic: [sample_receive_operation_async.py][python-eg-client-receive-sample-async] -* Acknowledge events from a namespace topic: [sample_acknowledge_operation_async.py][python-eg-client-ack-sample-async] -* Release events from a namespace topic: [sample_release_operation_async.py][python-eg-client-release-sample-async] -* Reject events from a namespace topic: [sample_reject_operation_async.py][python-eg-client-reject-sample-async] -* Renew locks: [sample_renew_locks_operation_async.py][python-eg-client-renew-locks-sample-async] - - -## Basic Sync samples +## Sync samples These code samples show common champion scenario operations with the Azure Event Grid client library. * Generate Shared Access Signature: [sample_generate_sas.py][python-eg-generate-sas] @@ -52,7 +29,7 @@ To publish events, dict representation of the models could also be used as follo * Consume a Custom Payload of raw cloudevent data: [sample_consume_custom_payload.py][python-eg-sample-consume-custom-payload] -## Basic Async samples +## Async samples These code samples show common champion scenario operations with the Azure Event Grid client library using the async client. * Authenticate the client: [sample_authentication_async.py][python-eg-auth-async] @@ -97,49 +74,3 @@ To publish events, dict representation of the models could also be used as follo [python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts - -[python-eg-client-sync-samples]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples -[python-eg-client-async-samples]:https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples - -[python-eg-client-ack-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py - -[python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py - -[python-eg-client-binary-mode-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py - -[python-eg-client-publish-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py - -[python-eg-client-receive-renew-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py - -[python-eg-client-release-receive-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py - -[python-eg-client-receive-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py - -[python-eg-client-release-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py - - -[python-eg-client-reject-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py - -[python-eg-client-renew-locks-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py - - -[python-eg-client-ack-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py - -[python-eg-client-all-ops-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py - -[python-eg-client-binary-mode-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py - -[python-eg-client-publish-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py - -[python-eg-client-receive-renew-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py - -[python-eg-client-release-receive-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py - -[python-eg-client-receive-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py - -[python-eg-client-release-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py - - -[python-eg-client-reject-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py - -[python-eg-client-renew-locks-sample-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py \ No newline at end of file diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py deleted file mode 100644 index fc4556b55a65..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_acknowledge_operation_async.py +++ /dev/null @@ -1,51 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_acknowledge_operation_async.py -DESCRIPTION: - These samples demonstrate acknowledging CloudEvent lock tokens. -USAGE: - python sample_acknowledge_operation_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - # Acknowledge a batch of CloudEvents - try: - async with client: - lock_tokens = ["token"] - ack_events = await client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, - ) - print(ack_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py deleted file mode 100644 index 24c452d0701d..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_all_operations_async.py +++ /dev/null @@ -1,127 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_all_operations_async.py -DESCRIPTION: - These samples demonstrate sending, receiving, acknowledging, and releasing CloudEvents. -USAGE: - python sample_all_operations_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError -from azure.eventgrid.aio import EventGridClient - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -cloud_event_reject = CloudEvent(data="reject", source="https://example.com", type="example") -cloud_event_release = CloudEvent(data="release", source="https://example.com", type="example") -cloud_event_ack = CloudEvent(data="acknowledge", source="https://example.com", type="example") - - -async def run(): - async with client: - # Publish a CloudEvent - try: - await client.send(topic_name=TOPIC_NAME, events=cloud_event_reject) - except HttpResponseError: - raise - - # Publish a list of CloudEvents - try: - list_of_cloud_events = [cloud_event_release, cloud_event_ack] - await client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) - except HttpResponseError: - raise - - # Receive Published Cloud Events - try: - receive_results = await client.receive_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - max_events=10, - max_wait_time=10, - ) - except HttpResponseError: - raise - - # Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject: - - release_events = [] - acknowledge_events = [] - reject_events = [] - - for detail in receive_results.value: - data = detail.event.data - broker_properties = detail.broker_properties - if data == "release": - release_events.append(broker_properties.lock_token) - elif data == "acknowledge": - acknowledge_events.append(broker_properties.lock_token) - else: - reject_events.append(broker_properties.lock_token) - - # Release/Acknowledge/Reject events - - if len(release_events) > 0: - try: - release_result = await client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=release_events, - ) - except HttpResponseError: - raise - - for succeeded_lock_token in release_result.succeeded_lock_tokens: - print(f"Succeeded Lock Token:{succeeded_lock_token}") - - if len(acknowledge_events) > 0: - try: - ack_result = await client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=acknowledge_events, - ) - except HttpResponseError: - raise - - for succeeded_lock_token in ack_result.succeeded_lock_tokens: - print(f"Succeeded Lock Token:{succeeded_lock_token}") - - if len(reject_events) > 0: - try: - reject_result = await client.reject_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=reject_events, - ) - except HttpResponseError: - raise - - for succeeded_lock_token in reject_result.succeeded_lock_tokens: - print(f"Succeeded Lock Token:{succeeded_lock_token}") - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py deleted file mode 100644 index 1e13aaee8f39..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_binary_mode_async.py +++ /dev/null @@ -1,75 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_binary_mode_async.py -DESCRIPTION: - These samples demonstrate sending CloudEvents in binary mode. -USAGE: - python sample_binary_mode_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -import json -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - async with client: - # Publish a CloudEvent - try: - # Publish CloudEvent in binary mode with str encoded as bytes - cloud_event_dict = { - "data": b"HI", - "source": "https://example.com", - "type": "example", - "datacontenttype": "text/plain", - } - await client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) - - # Publish CloudEvent in binary mode with json encoded as bytes - cloud_event = CloudEvent( - data=json.dumps({"hello": "data"}).encode("utf-8"), - source="https://example.com", - type="example", - datacontenttype="application/json", - ) - await client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) - - receive_result = await client.receive_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - max_events=10, - max_wait_time=10, - ) - for details in receive_result.value: - cloud_event_received = details.event - print("CloudEvent: ", cloud_event_received) - print("Data: ", cloud_event_received.data) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py deleted file mode 100644 index 57469077a263..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_operation_async.py +++ /dev/null @@ -1,69 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_operation_async.py -DESCRIPTION: - These samples demonstrate sending CloudEvents. -USAGE: - python sample_publish_operation_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - async with client: - - # Publish a CloudEvent as dict - try: - cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} - await client.send(topic_name=TOPIC_NAME, events=cloud_event_dict) - except HttpResponseError: - raise - - # Publish a list of CloudEvents as dict - try: - await client.send(topic_name=TOPIC_NAME, events=[cloud_event_dict, cloud_event_dict]) - except HttpResponseError: - raise - - # Publish a CloudEvent - try: - cloud_event = CloudEvent(data="HI", source="https://example.com", type="example") - await client.send(topic_name=TOPIC_NAME, events=cloud_event) - except HttpResponseError: - raise - - # Publish a list of CloudEvents - try: - list_of_cloud_events = [cloud_event, cloud_event] - await client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py deleted file mode 100644 index 3b95910942df..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_receive_renew_async.py +++ /dev/null @@ -1,64 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_receive_renew_async.py -DESCRIPTION: - These samples demonstrate sending, receiving, and renewing CloudEvents. -USAGE: - python sample_publish_receive_renew_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - - -async def run(): - # Create a client - client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - async with client: - try: - # Publish a CloudEvent - cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - await client.send(topic_name=TOPIC_NAME, events=cloud_event) - - # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10 - ) - lock_tokens_to_release = [] - for item in receive_result.value: - lock_tokens_to_release.append(item.broker_properties.lock_token) - - # Renew lock tokens - renew_events = await client.renew_cloud_event_locks( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens_to_release, - ) - print("Renewed Event:", renew_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py deleted file mode 100644 index ef3a25bf0419..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_publish_release_receive_async.py +++ /dev/null @@ -1,81 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_release_receive_async.py -DESCRIPTION: - These samples demonstrate sending, receiving, and releasing CloudEvents. -USAGE: - python sample_publish_release_receive_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - - -async def run(): - # Create a client - client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - async with client: - try: - # Publish a CloudEvent - cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - await client.send(topic_name=TOPIC_NAME, events=cloud_event) - - # Receive CloudEvents and parse out lock tokens - receive_result = await client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 - ) - lock_tokens_to_release = [] - for item in receive_result.value: - lock_tokens_to_release.append(item.broker_properties.lock_token) - - print("Received events:", receive_result.value) - - # Release a LockToken - release_events = await client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay=60, - lock_tokens=lock_tokens_to_release, - ) - print("Released Event:", release_events) - - # Receive CloudEvents again - receive_result = await client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 - ) - print("Received events after release:", receive_result.value) - - # Acknowledge a LockToken that was released - acknowledge_events = await client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens_to_release, - ) - print("Acknowledged events after release:", acknowledge_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py deleted file mode 100644 index 03ce721b4199..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_receive_operation_async.py +++ /dev/null @@ -1,51 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_receive_operation_async.py -DESCRIPTION: - These samples demonstrate receiving CloudEvents. -USAGE: - python sample_receive_operations_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - # Receive CloudEvents - try: - async with client: - receive_result = await client.receive_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - max_events=10, - max_wait_time=10, - ) - print(receive_result) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py deleted file mode 100644 index 194c78bfaae3..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_reject_operation_async.py +++ /dev/null @@ -1,51 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_reject_operation_async.py -DESCRIPTION: - These samples demonstrate rejecting CloudEvents. -USAGE: - python sample_reject_operation_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - # Reject a LockToken - try: - async with client: - tokens = ["token"] - reject_events = await client.reject_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=tokens, - ) - print(reject_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py deleted file mode 100644 index d0d4ce112959..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_release_operation_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_release_operation_async.py -DESCRIPTION: - These samples demonstrate releasing CloudEvents. -USAGE: - python sample_release_operation_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - # Release a LockToken - try: - async with client: - tokens = ["token"] - release_events = await client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay=10, - lock_tokens=tokens, - ) - print(release_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py deleted file mode 100644 index 7844f9a2c3a8..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/eventgrid_client_samples/sample_renew_locks_operation_async.py +++ /dev/null @@ -1,50 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_renew_locks_operation_async.py -DESCRIPTION: - These samples demonstrate renewing CloudEvents locks. -USAGE: - python sample_renew_locks_operation_async.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import asyncio -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -async def run(): - # Renew a lockToken - try: - lock_tokens = ["token"] - release_events = await client.renew_cloud_event_locks( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, - ) - print(release_events) - except HttpResponseError: - raise - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py index 54075cdbf128..1ee669f2ad63 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py @@ -17,41 +17,36 @@ """ # [START client_auth_with_key_cred_async] import os -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_key = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential_key, level="Basic") +client = EventGridPublisherClient(endpoint, credential_key) # [END client_auth_with_key_cred_async] # [START client_auth_with_sas_cred_async] import os -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureSasCredential signature = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_sas = AzureSasCredential(signature) -client = EventGridClient(endpoint, credential_sas, level="Basic") +client = EventGridPublisherClient(endpoint, credential_sas) # [END client_auth_with_sas_cred_async] # [START client_auth_with_token_cred_async] from azure.identity.aio import DefaultAzureCredential -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.eventgrid import EventGridEvent -event = EventGridEvent( - data={"team": "azure-sdk"}, - subject="Door1", - event_type="Azure.Sdk.Demo", - data_version="2.0", -) +event = EventGridEvent(data={"team": "azure-sdk"}, subject="Door1", event_type="Azure.Sdk.Demo", data_version="2.0") default_az_credential = DefaultAzureCredential() endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -client = EventGridClient(endpoint, default_az_credential, level="Basic") +client = EventGridPublisherClient(endpoint, default_az_credential) # [END client_auth_with_token_cred_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py new file mode 100644 index 000000000000..1cc281397446 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py @@ -0,0 +1,136 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +""" +FILE: sample_all_operations.py +DESCRIPTION: + These samples demonstrate sending, receiving, releasing, and acknowledging CloudEvents. +USAGE: + python sample_all_operations.py + Set the environment variables with your own values before running the sample: + 1) EVENTGRID_KEY - The access key of your eventgrid account. + 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format + "https://..eventgrid.azure.net". + 3) EVENTGRID_TOPIC_NAME - The namespace topic name. + 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. +""" +import os +import asyncio +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.models import * +from azure.core.messaging import CloudEvent +from azure.core.exceptions import HttpResponseError +from azure.eventgrid.aio import EventGridConsumerClient, EventGridPublisherClient + +EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] +EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] +TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] +EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + + +async def run(): + # Create a client + publisher = EventGridPublisherClient( + EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY), namespace_topic=TOPIC_NAME + ) + client = EventGridConsumerClient( + EVENTGRID_ENDPOINT, + AzureKeyCredential(EVENTGRID_KEY), + namespace_topic=TOPIC_NAME, + subscription=EVENT_SUBSCRIPTION_NAME, + ) + + cloud_event_reject = CloudEvent(data="reject", source="https://example.com", type="example") + cloud_event_release = CloudEvent(data="release", source="https://example.com", type="example") + cloud_event_ack = CloudEvent(data="acknowledge", source="https://example.com", type="example") + cloud_event_renew = CloudEvent(data="renew", source="https://example.com", type="example") + + # Send Cloud Events + await publisher.send( + [ + cloud_event_reject, + cloud_event_release, + cloud_event_ack, + cloud_event_renew, + ] + ) + + # Receive Published Cloud Events + try: + receive_results = await client.receive( + max_events=10, + max_wait_time=10, + ) + except HttpResponseError: + raise + + # Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject/renew: + + release_events = [] + acknowledge_events = [] + reject_events = [] + renew_events = [] + + for detail in receive_results: + data = detail.event.data + broker_properties = detail.broker_properties + if data == "release": + release_events.append(broker_properties.lock_token) + elif data == "acknowledge": + acknowledge_events.append(broker_properties.lock_token) + elif data == "renew": + renew_events.append(broker_properties.lock_token) + else: + reject_events.append(broker_properties.lock_token) + + # Release/Acknowledge/Reject/Renew events + + if len(release_events) > 0: + try: + release_result = await client.release( + lock_tokens=release_events, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in release_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + if len(acknowledge_events) > 0: + try: + ack_result = await client.acknowledge( + lock_tokens=acknowledge_events, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in ack_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + if len(reject_events) > 0: + try: + reject_result = await client.reject( + lock_tokens=reject_events, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in reject_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + if len(renew_events) > 0: + try: + renew_result = await client.renew_locks( + lock_tokens=renew_events, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in renew_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py index 5e2be47c8c7c..1c341e44d183 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py @@ -18,16 +18,17 @@ import os import asyncio from azure.core.messaging import CloudEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential -topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] -endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] - async def publish(): + # To Event Grid Basic + topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] + endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] + credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) # [START publish_cloud_event_dict_async] async with client: @@ -45,6 +46,29 @@ async def publish(): ) # [END publish_cloud_event_dict_async] + # To Event Grid Namespaces + topic_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_key = os.environ["EVENTGRID_KEY"] + topic_name = os.environ["EVENTGRID_TOPIC_NAME"] + sub = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + + credential = AzureKeyCredential(topic_key) + client = EventGridPublisherClient(topic_endpoint, credential, namespace_topic=topic_name) + + async with client: + await client.send( + [ + { + "type": "Contoso.Items.ItemReceived", + "source": "/contoso/items", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "specversion": "1.0", + "id": "randomclouduuid11", + } + ] + ) + if __name__ == "__main__": asyncio.run(publish()) diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py index a72484e27301..f777f4ffd67b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cncf_cloud_events_async.py @@ -16,17 +16,37 @@ """ import os import asyncio -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential from cloudevents.http import CloudEvent -topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] -endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] - async def publish(): + + # To Event Grid Basic + topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] + endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] + + credential = AzureKeyCredential(topic_key) + client = EventGridPublisherClient(endpoint, credential) + await client.send( + [ + CloudEvent( + attributes={"type": "cloudevent", "source": "/cncf/cloud/event/1.0", "subject": "testing-cncf-event"}, + data=b"This is a cncf cloud event.", + ) + ] + ) + + # To Event Grid Namespaces + + topic_endpoint = os.environ["EVENTGRID_ENDPOINT"] + topic_key = os.environ["EVENTGRID_KEY"] + topic_name = os.environ["EVENTGRID_TOPIC_NAME"] + credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(topic_endpoint, credential, namespace_topic=topic_name) + async with client: await client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py index 40f268f84112..2d7ccbb8cbcf 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py @@ -23,7 +23,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -33,7 +33,7 @@ async def publish_event(): # authenticate client # [START publish_custom_schema_async] credential = AzureKeyCredential(key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) custom_schema_event = { "customSubject": "sample", diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py index 605c0b3f5236..8909b5717b2b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py @@ -20,7 +20,7 @@ import asyncio from datetime import datetime from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -29,7 +29,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) # [START publish_eg_event_dict_async] event0 = { diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py index ace029405cda..48272cb30166 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential domain_key = os.environ["EVENTGRID_DOMAIN_KEY"] @@ -27,26 +27,26 @@ async def publish(): credential = AzureKeyCredential(domain_key) - client = EventGridClient(domain_hostname, credential, level="Basic") - async with client: - await client.send( - [ - EventGridEvent( - topic="MyCustomDomainTopic1", - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - data_version="2.0", - ), - EventGridEvent( - topic="MyCustomDomainTopic2", - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #2"}, - subject="Door1", - data_version="2.0", - ), - ] - ) + client = EventGridPublisherClient(domain_hostname, credential) + + await client.send( + [ + EventGridEvent( + topic="MyCustomDomainTopic1", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ), + EventGridEvent( + topic="MyCustomDomainTopic2", + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #2"}, + subject="Door1", + data_version="2.0", + ), + ] + ) if __name__ == "__main__": diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py index 8628477492ce..4ab76f2a81fa 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -27,18 +27,18 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") - async with client: - await client.send( - [ - EventGridEvent( - event_type="Contoso.Items.ItemReceived", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - data_version="2.0", - ) - ] - ) + client = EventGridPublisherClient(endpoint, credential) + + await client.send( + [ + EventGridEvent( + event_type="Contoso.Items.ItemReceived", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + data_version="2.0", + ) + ] + ) # [END publish_eg_event_to_topic_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py index d56ce6c5f265..c70bfd11aef4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py @@ -17,7 +17,7 @@ import os import asyncio from azure.eventgrid import EventGridEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureSasCredential sas = os.environ["EVENTGRID_SAS"] @@ -26,7 +26,7 @@ async def publish(): credential = AzureSasCredential(sas) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) async with client: await client.send( diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py index 93f953a7ba9b..1d3ea0337e33 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py @@ -18,7 +18,7 @@ import os import asyncio from azure.core.messaging import CloudEvent -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] @@ -27,18 +27,18 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") - async with client: - await client.send( - [ - CloudEvent( - type="Contoso.Items.ItemReceived", - source="/contoso/items", - data={"itemSku": "Contoso Item SKU #1"}, - subject="Door1", - ) - ] - ) + client = EventGridPublisherClient(endpoint, credential) + + await client.send( + [ + CloudEvent( + type="Contoso.Items.ItemReceived", + source="/contoso/items", + data={"itemSku": "Contoso Item SKU #1"}, + subject="Door1", + ) + ] + ) # [END publish_cloud_event_to_topic_async] diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py index 8cf418b53207..f12070c35a1e 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_to_channel_async.py @@ -18,7 +18,7 @@ # [START publish_cloud_event_to_topic] import os import asyncio -from azure.eventgrid.aio import EventGridClient +from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -30,7 +30,7 @@ async def publish(): credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) async with client: await client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py index 5dca03859841..e5933ec205ef 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_eventhub.py @@ -39,7 +39,5 @@ def on_event(partition_context, event): with consumer_client: event_list = consumer_client.receive( - on_event=on_event, - starting_position="-1", # "-1" is from the beginning of the partition. - prefetch=5, + on_event=on_event, starting_position="-1", prefetch=5 # "-1" is from the beginning of the partition. ) diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py index 1b2db9f0cff4..fba40a378241 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py @@ -21,21 +21,16 @@ from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] # authenticate client credential = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) -services = [ - "EventGrid", - "ServiceBus", - "EventHubs", - "Storage", -] # possible values for data field +services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field def publish_event(): @@ -47,9 +42,7 @@ def publish_event(): sample_members = sample(services, k=randint(1, 4)) # select random subset of team members data_dict = {"team": sample_members} event = CloudEvent( - type="Azure.Sdk.Sample", - source="https://egsample.dev/sampleevent", - data={"team": sample_members}, + type="Azure.Sdk.Sample", source="https://egsample.dev/sampleevent", data={"team": sample_members} ) event_list.append(event) diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py index dc26284119ce..ba9182a40beb 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py @@ -22,7 +22,7 @@ from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient domain_key = os.environ["EVENTGRID_CLOUD_EVENT_DOMAIN_KEY"] domain_endpoint = os.environ["EVENTGRID_CLOUD_EVENT_DOMAIN_ENDPOINT"] @@ -30,28 +30,20 @@ # authenticate client credential = AzureKeyCredential(domain_key) -client = EventGridClient(domain_endpoint, credential, level="Basic") +client = EventGridPublisherClient(domain_endpoint, credential) def publish_event(): # publish events for _ in range(3): + event_list = [] # list of events to publish - services = [ - "EventGrid", - "ServiceBus", - "EventHubs", - "Storage", - ] # possible values for data field + services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field # create events and append to list for j in range(randint(1, 3)): sample_members = sample(services, k=randint(1, 4)) # select random subset of team members - event = CloudEvent( - type="Azure.Sdk.Demo", - source="domainname", - data={"team": sample_members}, - ) + event = CloudEvent(type="Azure.Sdk.Demo", source="domainname", data={"team": sample_members}) event_list.append(event) # publish list of events diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py index 8a25456e45cb..0ab11a428c5a 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_custom_schema_events_to_topic_sample.py @@ -22,7 +22,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -31,7 +31,7 @@ def publish_event(): # authenticate client credential = AzureKeyCredential(key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) custom_schema_event = { "customSubject": "sample", @@ -44,6 +44,7 @@ def publish_event(): # publish events for _ in range(3): + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py index 3e4a85c77c90..16247a4763bf 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_event_grid_events_to_custom_topic_sample.py @@ -20,34 +20,27 @@ import time from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] # authenticate client credential = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential, level="Basic") -services = [ - "EventGrid", - "ServiceBus", - "EventHubs", - "Storage", -] # possible values for data field +client = EventGridPublisherClient(endpoint, credential) +services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field def publish_event(): # publish events for _ in range(3): + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): sample_members = sample(services, k=randint(1, 4)) # select random subset of team members event = EventGridEvent( - subject="Door1", - data={"team": sample_members}, - event_type="Azure.Sdk.Demo", - data_version="2.0", + subject="Door1", data={"team": sample_members}, event_type="Azure.Sdk.Demo", data_version="2.0" ) event_list.append(event) diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py index 0ac2a6b894c9..fc57050087f3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py @@ -22,7 +22,7 @@ from datetime import datetime, timedelta from azure.core.credentials import AzureSasCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridClient, generate_sas +from azure.eventgrid import EventGridPublisherClient, generate_sas key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] @@ -32,27 +32,21 @@ # authenticate client credential = AzureSasCredential(signature) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) -services = [ - "EventGrid", - "ServiceBus", - "EventHubs", - "Storage", -] # possible values for data field +services = ["EventGrid", "ServiceBus", "EventHubs", "Storage"] # possible values for data field def publish_event(): # publish events for _ in range(3): + event_list = [] # list of events to publish # create events and append to list for j in range(randint(1, 3)): sample_members = sample(services, k=randint(1, 4)) # select random subset of team members event = CloudEvent( - type="Azure.Sdk.Demo", - source="https://egdemo.dev/demowithsignature", - data={"team": sample_members}, + type="Azure.Sdk.Demo", source="https://egdemo.dev/demowithsignature", data={"team": sample_members} ) event_list.append(event) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py deleted file mode 100644 index 68d57ae30bda..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_acknowledge_operation.py +++ /dev/null @@ -1,44 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_acknowledge_operation.py -DESCRIPTION: - These samples demonstrate acknowledging CloudEvents. -USAGE: - python sample_acknowledge_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -# Acknowledge a CloudEvent -try: - lock_tokens = ["token"] - ack_events = client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, - ) - print(ack_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py deleted file mode 100644 index d6c2130bbd9d..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +++ /dev/null @@ -1,66 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_binary_mode.py -DESCRIPTION: - These samples demonstrate sending CloudEvents in binary mode. -USAGE: - python sample_binary_mode.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -import json -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -# Publish a CloudEvent -try: - # Publish CloudEvent in binary mode with str encoded as bytes - cloud_event_dict = { - "data": b"HI", - "source": "https://example.com", - "type": "example", - "datacontenttype": "text/plain", - } - client.send(topic_name=TOPIC_NAME, events=cloud_event_dict, binary_mode=True) - - # Publish CloudEvent in binary mode with json encoded as bytes - cloud_event = CloudEvent( - data=json.dumps({"hello": "data"}).encode("utf-8"), - source="https://example.com", - type="example", - datacontenttype="application/json", - ) - client.send(topic_name=TOPIC_NAME, events=cloud_event, binary_mode=True) - - # Receive a CloudEvent - receive_result = client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=100 - ) - for receive_details in receive_result.value: - cloud_event_received = receive_details.event - print("CloudEvent: ", cloud_event_received) - print("CloudEvent data: ", cloud_event_received.data) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py deleted file mode 100644 index d6ce90dee42b..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_operation.py +++ /dev/null @@ -1,60 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_operation.py -DESCRIPTION: - These samples demonstrate sending CloudEvents. -USAGE: - python sample_publish_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - -# Publish a CloudEvent as dict -try: - cloud_event_dict = {"data": "hello", "source": "https://example.com", "type": "example"} - client.send(topic_name=TOPIC_NAME, events=cloud_event_dict) -except HttpResponseError: - raise - -# Publish a list of CloudEvents as dict -try: - client.send(topic_name=TOPIC_NAME, events=[cloud_event_dict, cloud_event_dict]) -except HttpResponseError: - raise - -# Publish a CloudEvent -try: - cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.send(topic_name=TOPIC_NAME, events=cloud_event) -except HttpResponseError: - raise - -# Publish a list of CloudEvents -try: - list_of_cloud_events = [cloud_event, cloud_event] - client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py deleted file mode 100644 index 6ad93259494b..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_receive_renew.py +++ /dev/null @@ -1,57 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_receive_renew.py -DESCRIPTION: - These samples demonstrate sending, receiving and renewing CloudEvents. -USAGE: - python sample_publish_receive_renew.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -try: - # Publish a CloudEvent - cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.send(topic_name=TOPIC_NAME, events=cloud_event) - - # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=10, max_wait_time=10 - ) - lock_tokens_to_renew = [] - for item in receive_result.value: - lock_tokens_to_renew.append(item.broker_properties.lock_token) - - # Renew a lock token - renew_events = client.renew_cloud_event_locks( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens_to_renew, - ) - print("Renewed Event:", renew_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py deleted file mode 100644 index f96132b4c565..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_publish_release_receive.py +++ /dev/null @@ -1,74 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_publish_release_receive.py -DESCRIPTION: - These samples demonstrate sending, receiving and releasing CloudEvents. -USAGE: - python sample_publish_release_receive.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.exceptions import HttpResponseError - - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -try: - # Publish a CloudEvent - cloud_event = CloudEvent(data="hello", source="https://example.com", type="example") - client.send(topic_name=TOPIC_NAME, events=cloud_event) - - # Receive CloudEvents and parse out lock tokens - receive_result = client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 - ) - lock_tokens_to_release = [] - for item in receive_result.value: - lock_tokens_to_release.append(item.broker_properties.lock_token) - - print("Received events:", receive_result.value) - - # Release a LockToken - release_events = client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay=60, - lock_tokens=lock_tokens_to_release, - ) - print("Released Event:", release_events) - - # Receive CloudEvents again - receive_result = client.receive_cloud_events( - topic_name=TOPIC_NAME, subscription_name=EVENT_SUBSCRIPTION_NAME, max_events=1, max_wait_time=15 - ) - print("Received events after release:", receive_result.value) - - # Acknowledge a LockToken that was released - acknowledge_events = client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens_to_release, - ) - print("Acknowledged events after release:", acknowledge_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py deleted file mode 100644 index 0e091aa883b8..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_receive_operation.py +++ /dev/null @@ -1,44 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_receive_operation.py -DESCRIPTION: - These samples demonstrate receiving CloudEvents. -USAGE: - python sample_receive_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - - -# Receive CloudEvents -try: - receive_result = client.receive_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - max_events=10, - max_wait_time=10, - ) - print(receive_result) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py deleted file mode 100644 index 35700a827266..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_reject_operation.py +++ /dev/null @@ -1,43 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_reject_operation.py -DESCRIPTION: - These samples demonstrate rejecting CloudEvents. -USAGE: - python sample_reject_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - -# Release a LockToken -try: - lock_tokens = ["token"] - reject_events = client.reject_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, - ) - print(reject_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py deleted file mode 100644 index efb00fb374e9..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_release_operation.py +++ /dev/null @@ -1,44 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_release_operation.py -DESCRIPTION: - These samples demonstrate releasing CloudEvents. -USAGE: - python sample_release_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - -# Release a LockToken -try: - lock_tokens = ["token"] - release_events = client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - release_delay=3600, - lock_tokens=lock_tokens, - ) - print(release_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py deleted file mode 100644 index 3fb2e502f03d..000000000000 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_renew_locks_operation.py +++ /dev/null @@ -1,43 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -""" -FILE: sample_renew_locks_operation.py -DESCRIPTION: - These samples demonstrate renew locks CloudEvents. -USAGE: - python sample_renew_locks_operation.py - Set the environment variables with your own values before running the sample: - 1) EVENTGRID_KEY - The access key of your eventgrid account. - 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format - "https://..eventgrid.azure.net". - 3) EVENTGRID_TOPIC_NAME - The namespace topic name. - 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. -""" -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.exceptions import HttpResponseError - -EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] -EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] -TOPIC_NAME: str = os.environ["EVENTGRID_TOPIC_NAME"] -EVENT_SUBSCRIPTION_NAME: str = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] - -# Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) - -# Renew a lockToken -try: - lock_tokens = ["token"] - release_events = client.renew_cloud_event_locks( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, - lock_tokens=lock_tokens, - ) - print(release_events) -except HttpResponseError: - raise diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py index a70aa2965b75..eb54049d0925 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py @@ -6,7 +6,7 @@ """ FILE: sample_authentication.py DESCRIPTION: - These samples demonstrate authenticating an EventGridClient. + These samples demonstrate authenticating an EventGridPublisherClient. USAGE: python sample_authentication.py Set the environment variables with your own values before running the sample: @@ -17,33 +17,33 @@ """ # [START client_auth_with_key_cred] import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential -key = os.environ["EVENTGRID_KEY"] -endpoint = os.environ["EVENTGRID_ENDPOINT"] +topic_key = os.environ["EVENTGRID_TOPIC_KEY"] +endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] -credential_key = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential_key) +credential_key = AzureKeyCredential(topic_key) +client = EventGridPublisherClient(endpoint, credential_key) # [END client_auth_with_key_cred] # [START client_auth_with_sas_cred] import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureSasCredential signature = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential_sas = AzureSasCredential(signature) -client = EventGridClient(endpoint, credential_sas, level="Basic") +client = EventGridPublisherClient(endpoint, credential_sas) # [END client_auth_with_sas_cred] # [START client_auth_with_token_cred] from azure.identity import DefaultAzureCredential -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent default_az_credential = DefaultAzureCredential() -endpoint = os.environ["EVENTGRID_ENDPOINT"] -client = EventGridClient(endpoint, default_az_credential) +endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] +client = EventGridPublisherClient(endpoint, default_az_credential) # [END client_auth_with_token_cred] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py similarity index 70% rename from sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py rename to sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py index 31416d97aef5..8ffd7e26c8df 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py @@ -17,12 +17,11 @@ 4) EVENTGRID_EVENT_SUBSCRIPTION_NAME - The event subscription name. """ import os -import asyncio from azure.core.credentials import AzureKeyCredential from azure.eventgrid.models import * from azure.core.messaging import CloudEvent from azure.core.exceptions import HttpResponseError -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridConsumerClient, EventGridPublisherClient EVENTGRID_KEY: str = os.environ["EVENTGRID_KEY"] EVENTGRID_ENDPOINT: str = os.environ["EVENTGRID_ENDPOINT"] @@ -31,60 +30,64 @@ # Create a client -client = EventGridClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY)) +publisher = EventGridPublisherClient(EVENTGRID_ENDPOINT, AzureKeyCredential(EVENTGRID_KEY), namespace_topic=TOPIC_NAME) +client = EventGridConsumerClient( + EVENTGRID_ENDPOINT, + AzureKeyCredential(EVENTGRID_KEY), + namespace_topic=TOPIC_NAME, + subscription=EVENT_SUBSCRIPTION_NAME, +) cloud_event_reject = CloudEvent(data="reject", source="https://example.com", type="example") cloud_event_release = CloudEvent(data="release", source="https://example.com", type="example") cloud_event_ack = CloudEvent(data="acknowledge", source="https://example.com", type="example") +cloud_event_renew = CloudEvent(data="renew", source="https://example.com", type="example") -# Publish a CloudEvent -try: - client.send(topic_name=TOPIC_NAME, events=cloud_event_reject) -except HttpResponseError: - raise +# Send Cloud Events +publisher.send( + [ + cloud_event_reject, + cloud_event_release, + cloud_event_ack, + cloud_event_renew, + ] +) -# Publish a list of CloudEvents -try: - list_of_cloud_events = [cloud_event_release, cloud_event_ack] - client.send(topic_name=TOPIC_NAME, events=list_of_cloud_events) -except HttpResponseError: - raise # Receive Published Cloud Events try: - receive_results = client.receive_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, + receive_results = client.receive( max_events=10, max_wait_time=10, ) except HttpResponseError: raise -# Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject: +# Iterate through the results and collect the lock tokens for events we want to release/acknowledge/reject/renew: release_events = [] acknowledge_events = [] reject_events = [] +renew_events = [] -for detail in receive_results.value: +for detail in receive_results: data = detail.event.data broker_properties = detail.broker_properties if data == "release": release_events.append(broker_properties.lock_token) elif data == "acknowledge": acknowledge_events.append(broker_properties.lock_token) + elif data == "renew": + renew_events.append(broker_properties.lock_token) else: reject_events.append(broker_properties.lock_token) -# Release/Acknowledge/Reject events +# Release/Acknowledge/Reject/Renew events if len(release_events) > 0: try: - release_result = client.release_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, + release_result = client.release( lock_tokens=release_events, ) except HttpResponseError: @@ -95,9 +98,7 @@ if len(acknowledge_events) > 0: try: - ack_result = client.acknowledge_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, + ack_result = client.acknowledge( lock_tokens=acknowledge_events, ) except HttpResponseError: @@ -108,9 +109,7 @@ if len(reject_events) > 0: try: - reject_result = client.reject_cloud_events( - topic_name=TOPIC_NAME, - subscription_name=EVENT_SUBSCRIPTION_NAME, + reject_result = client.reject( lock_tokens=reject_events, ) except HttpResponseError: @@ -118,3 +117,14 @@ for succeeded_lock_token in reject_result.succeeded_lock_tokens: print(f"Succeeded Lock Token:{succeeded_lock_token}") + +if len(renew_events) > 0: + try: + renew_result = client.renew_locks( + lock_tokens=renew_events, + ) + except HttpResponseError: + raise + + for succeeded_lock_token in renew_result.succeeded_lock_tokens: + print(f"Succeeded Lock Token:{succeeded_lock_token}") diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py index 260bf1b16ff2..50c313c51fc3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py @@ -16,14 +16,16 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient, EventGridConsumerClient from azure.core.credentials import AzureKeyCredential + +# To Event Grid Basic topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) # [START publish_cloud_event_dict] client.send( @@ -39,3 +41,25 @@ ] ) # [END publish_cloud_event_dict] + +# To Event Grid Namespaces +topic_endpoint = os.environ["EVENTGRID_ENDPOINT"] +topic_key = os.environ["EVENTGRID_KEY"] +topic_name = os.environ["EVENTGRID_TOPIC_NAME"] +sub = os.environ["EVENTGRID_EVENT_SUBSCRIPTION_NAME"] + +credential = AzureKeyCredential(topic_key) +client = EventGridPublisherClient(topic_endpoint, credential, namespace_topic=topic_name) + +client.send( + [ + { + "type": "Contoso.Items.ItemReceived", + "source": "/contoso/items", + "data": {"itemSku": "Contoso Item SKU #1"}, + "subject": "Door1", + "specversion": "1.0", + "id": "randomclouduuid11", + } + ] +) diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py index 5fdecaf7ecf2..ffb49eb077c2 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cncf_cloud_events.py @@ -15,24 +15,38 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential from cloudevents.http import CloudEvent +# To EventGrid Basic topic_key = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) client.send( [ CloudEvent( - attributes={ - "type": "cloudevent", - "source": "/cncf/cloud/event/1.0", - "subject": "testing-cncf-event", - }, + attributes={"type": "cloudevent", "source": "/cncf/cloud/event/1.0", "subject": "testing-cncf-event"}, + data=b"This is a cncf cloud event.", + ) + ] +) + +# To Event Grid Namespaces +topic_endpoint = os.environ["EVENTGRID_ENDPOINT"] +topic_key = os.environ["EVENTGRID_KEY"] +topic_name = os.environ["EVENTGRID_TOPIC_NAME"] + +credential = AzureKeyCredential(topic_key) +client = EventGridPublisherClient(topic_endpoint, credential, namespace_topic=topic_name) + +client.send( + [ + CloudEvent( + attributes={"type": "cloudevent", "source": "/cncf/cloud/event/1.0", "subject": "testing-cncf-event"}, data=b"This is a cncf cloud event.", ) ] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py index 978a9002bc45..4650aae15d61 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py @@ -22,7 +22,7 @@ import datetime as dt from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient key = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_CUSTOM_EVENT_TOPIC_ENDPOINT"] @@ -31,7 +31,7 @@ def publish_event(): # authenticate client credential = AzureKeyCredential(key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) # [START publish_custom_schema] custom_schema_event = { diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py index 4fc92b61b925..b7154a0e07b8 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py @@ -19,7 +19,7 @@ import os from datetime import datetime from msrest.serialization import UTC -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] @@ -29,7 +29,7 @@ def publish(): # [START publish_eg_event_dict] credential = AzureKeyCredential(topic_key) - client = EventGridClient(endpoint, credential, level="Basic") + client = EventGridPublisherClient(endpoint, credential) event0 = { "eventType": "Contoso.Items.ItemReceived", diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py index 67c7bc725dbd..960f91aeae70 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py @@ -15,14 +15,14 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent from azure.core.credentials import AzureKeyCredential domain_key = os.environ["EVENTGRID_DOMAIN_KEY"] domain_hostname = os.environ["EVENTGRID_DOMAIN_ENDPOINT"] credential = AzureKeyCredential(domain_key) -client = EventGridClient(domain_hostname, credential, level="Basic") +client = EventGridPublisherClient(domain_hostname, credential) client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py index 742a2080bb19..a0e3ab58b6dc 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py @@ -16,14 +16,14 @@ """ # [START publish_eg_event_to_topic] import os -from azure.eventgrid import EventGridClient, EventGridEvent +from azure.eventgrid import EventGridPublisherClient, EventGridEvent from azure.core.credentials import AzureKeyCredential topic_key = os.environ["EVENTGRID_TOPIC_KEY"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py index 48a66df61e8a..6051d883fbd4 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py @@ -16,14 +16,14 @@ "https://..eventgrid.azure.net/api/events". """ import os -from azure.eventgrid import EventGridClient, EventGridEvent, generate_sas +from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas from azure.core.credentials import AzureKeyCredential, AzureSasCredential sas = os.environ["EVENTGRID_SAS"] endpoint = os.environ["EVENTGRID_TOPIC_ENDPOINT"] credential = AzureSasCredential(sas) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py index abc4bec0cb3f..a0297f9950a3 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py @@ -16,7 +16,7 @@ """ # [START publish_cloud_event_to_topic] import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -24,7 +24,7 @@ endpoint = os.environ["EVENTGRID_CLOUD_EVENT_TOPIC_ENDPOINT"] credential = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py index 1bed2ad38113..433ce0fefe72 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_to_channel.py @@ -17,7 +17,7 @@ """ # [START publish_cloud_event_to_topic] import os -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent @@ -27,7 +27,7 @@ channel_name = os.environ["EVENTGRID_PARTNER_CHANNEL_NAME"] credential = AzureKeyCredential(topic_key) -client = EventGridClient(endpoint, credential, level="Basic") +client = EventGridPublisherClient(endpoint, credential) client.send( [ diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py deleted file mode 100644 index d5fff9e9008a..000000000000 --- a/sdk/eventgrid/azure-eventgrid/tests/test_dual_client.py +++ /dev/null @@ -1,357 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -import pytest -from datetime import datetime -from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.eventgrid import EventGridClient, EventGridEvent, ClientLevel -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.credentials import AzureKeyCredential -from azure.core.exceptions import HttpResponseError, ResourceNotFoundError -from cloudevents.http import CloudEvent as CNCFCloudEvent - -from eventgrid_preparer import EventGridPreparer - -def _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level): - if level == "Standard": - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=100) - tokens = [] - for detail in events.value: - token = detail.broker_properties.lock_token - tokens.append(token) - ack_result = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens - ) - -class ArgPasser: - def __call__(self, fn): - def _preparer(test_class, level, **kwargs): - fn(test_class, level, **kwargs) - - return _preparer - - -class TestEGDualClient(AzureRecordedTestCase): - def create_eg_client(self, endpoint, key, level): - client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key), level=level) - return client - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_publish( - self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - from xml.etree import ElementTree as ET - - xml_string = """test""" - tree = xml_string.encode("utf-8") - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=tree, - datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - if level == "Basic": - with pytest.raises(ValueError): - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - else: - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_receive( - self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - from xml.etree import ElementTree as ET - - xml_string = """test""" - tree = xml_string.encode("utf-8") - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=tree, - datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - if level == "Basic": - with pytest.raises(ValueError): - client.receive_cloud_events( - topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name - ) - else: - client.receive_cloud_events( - topic_name=eventgrid_topic_name, subscription_name=eventgrid_event_subscription_name - ) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_publish_event( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_topic_key, - eventgrid_topic_endpoint, - ): - if level == "Basic": - client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) - else: - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = EventGridEvent( - id="7f7d", - subject="MySubject", - data={"test": "data"}, - event_type="Contoso.Items.ItemReceived", - data_version="1.0", - ) - - if level == "Basic": - client.send(events=event) - else: - with pytest.raises(TypeError): - client.send(topic_name=eventgrid_topic_name, events=event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_cloud_event( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, - eventgrid_cloud_event_topic_endpoint, - ): - if level == "Basic": - client = self.create_eg_client( - eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level - ) - else: - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"test": "data"}, - datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - client.send(topic_name=eventgrid_topic_name, events=event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_channel_name( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_partner_namespace_topic_key, - eventgrid_partner_namespace_topic_endpoint, - eventgrid_partner_channel_name, - ): - - client = self.create_eg_client( - eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_namespace_topic_key, level=level - ) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"test": "data"}, - datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - if level == "Standard": - with pytest.raises(ValueError): - client.send(topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name) - else: - client.send(topic_name=eventgrid_topic_name, events=event, channel_name=eventgrid_partner_channel_name) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_publish_endpoint( - self, level, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"test": "data"}, - datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - if level == "Basic": - with pytest.raises(ResourceNotFoundError): - client.send(topic_name=eventgrid_topic_name, events=event) - else: - client.send(topic_name=eventgrid_topic_name, events=event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_publish_cncf_events( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, - eventgrid_cloud_event_topic_endpoint, - ): - if level == "Basic": - client = self.create_eg_client( - eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level - ) - else: - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - attributes = { - "type": "com.example.sampletype1", - "source": "https://example.com/event-producer", - } - data = {"message": "Hello World!"} - cloud_event = CNCFCloudEvent(attributes, data) - - client.send(topic_name=eventgrid_topic_name, events=cloud_event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_cloud_event_dict( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_cloud_event_topic_key, - eventgrid_cloud_event_topic_endpoint, - ): - if level == "Basic": - client = self.create_eg_client( - eventgrid_cloud_event_topic_endpoint, eventgrid_cloud_event_topic_key, level=level - ) - else: - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = { - "type": "Contoso.Items.ItemReceived", - "source": "source", - "subject": "MySubject", - "data": {"test": "data"}, - "datacontenttype": "application/json", - "extension1": "value1", - "extension2": "value2", - } - - client.send(topic_name=eventgrid_topic_name, events=event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - - - @pytest.mark.live_test_only() - @pytest.mark.parametrize("level", ["Standard", "Basic"]) - @EventGridPreparer() - @ArgPasser() - @recorded_by_proxy - def test_create_client_publish_event_dict( - self, - level, - eventgrid_endpoint, - eventgrid_key, - eventgrid_topic_name, - eventgrid_event_subscription_name, - eventgrid_topic_key, - eventgrid_topic_endpoint, - ): - if level == "Basic": - client = self.create_eg_client(eventgrid_topic_endpoint, eventgrid_topic_key, level=level) - else: - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key, level=level) - - event = { - "eventType": "Contoso.Items.ItemReceived", - "data": {"itemSku": "Contoso Item SKU #1"}, - "subject": "Door1", - "dataVersion": "2.0", - "id": "randomuuid11", - "eventTime": datetime.now(), - } - - if level == ClientLevel.STANDARD: - with pytest.raises(TypeError): - client.send(topic_name=eventgrid_topic_name, events=event) - else: - client.send(topic_name=eventgrid_topic_name, events=event) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name, level) - diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py deleted file mode 100644 index 9a6b3517fdd0..000000000000 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client.py +++ /dev/null @@ -1,231 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -import pytest -import os -import time -from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.credentials import AzureKeyCredential - -from eventgrid_preparer import EventGridPreparer - -def _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name): - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=100) - tokens = [] - for detail in events.value: - token = detail.broker_properties.lock_token - tokens.append(token) - ack = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=tokens - ) - -class TestEGClientExceptions(AzureRecordedTestCase): - def create_eg_client(self, endpoint, key): - client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key)) - return client - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_publish_binary_mode_xml( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - from xml.etree import ElementTree as ET - - xml_string = """test""" - tree = xml_string.encode("utf-8") - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=tree, - datacontenttype="text/xml", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - - time.sleep(5) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_publish_binary_mode_cloud_event( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"this is binary data", - datacontenttype="text/plain", - ) - - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) - - @EventGridPreparer() - @recorded_by_proxy - def test_publish_binary_mode_incorrect_cloud_event( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"key": "value"}, - datacontenttype="text/plain", - ) - - with pytest.raises(TypeError): - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - - @EventGridPreparer() - @recorded_by_proxy - def test_publish_binary_mode_list_cloud_event( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"key": "value"}, - datacontenttype="text/plain", - ) - - with pytest.raises(TypeError): - client.send(topic_name=eventgrid_topic_name, events=[event], binary_mode=True) - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_publish_binary_mode_combinations( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"hello", - datacontenttype="text/plain", - ) - - dict_event = { - "type": "Contoso.Items.ItemReceived", - "source": "source", - "subject": "MySubject", - "data": b"hello", - "datacontenttype": "text/plain", - } - - client.send(topic_name=eventgrid_topic_name, events=event, binary_mode=True) - - client.send(topic_name=eventgrid_topic_name, events=dict_event, binary_mode=True) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_publish_receive_cloud_event( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"this is binary data", - ) - - client.send(topic_name=eventgrid_topic_name, events=[event]) - - time.sleep(5) - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) - lock_token = events.value[0].broker_properties.lock_token - - ack = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token] - ) - assert len(ack.succeeded_lock_tokens) == 1 - assert len(ack.failed_lock_tokens) == 0 - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_publish_release_cloud_event( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"this is binary data", - ) - - client.send(topic_name=eventgrid_topic_name, events=[event]) - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) - lock_token = events.value[0].broker_properties.lock_token - - ack = client.release_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[lock_token] - ) - assert len(ack.succeeded_lock_tokens) == 1 - assert len(ack.failed_lock_tokens) == 0 - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) - assert events.value[0].broker_properties.delivery_count > 1 - - client.reject_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=[events.value[0].broker_properties.lock_token]) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) - - - @pytest.mark.live_test_only() - @EventGridPreparer() - @recorded_by_proxy - def test_receive_type( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data={"key": "value"}, - ) - - client.send(topic_name=eventgrid_topic_name, events=event) - - time.sleep(5) - - events = client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=1) - data = events.value[0].event.data - - assert isinstance(data, dict) - - _clean_up(client, eventgrid_topic_name, eventgrid_event_subscription_name) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py deleted file mode 100644 index 6dab23edf38b..000000000000 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_client_exceptions.py +++ /dev/null @@ -1,175 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -import pytest -import os -import time -from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.eventgrid import EventGridClient -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent -from azure.core.credentials import AzureKeyCredential -from azure.core.exceptions import HttpResponseError, ResourceNotFoundError - -from eventgrid_preparer import EventGridPreparer - - -class TestEGClientExceptions(AzureRecordedTestCase): - def create_eg_client(self, endpoint, key): - client = EventGridClient(endpoint=endpoint, credential=AzureKeyCredential(key)) - return client - - @EventGridPreparer() - @recorded_by_proxy - def test_publish_cloud_event_bad_request(self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source=None, - subject="MySubject", - data={"itemSku": "Contoso Item SKU #1"}, - ) - - with pytest.raises(HttpResponseError): - client.send(topic_name=eventgrid_topic_name, events=[event]) - - @EventGridPreparer() - @recorded_by_proxy - def test_publish_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source=None, - subject="MySubject", - data={"itemSku": "Contoso Item SKU #1"}, - ) - - with pytest.raises(ResourceNotFoundError): - client.send(topic_name="faketopic", events=[event]) - - @EventGridPreparer() - @recorded_by_proxy - def test_receive_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(ResourceNotFoundError): - client.receive_cloud_events("faketopic", eventgrid_event_subscription_name) - - @EventGridPreparer() - @recorded_by_proxy - def test_receive_cloud_event_max_events_negative( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(HttpResponseError): - client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_events=-20) - - @EventGridPreparer() - @recorded_by_proxy - def test_receive_cloud_event_timeout_negative( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(HttpResponseError): - client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=-20) - - @EventGridPreparer() - @recorded_by_proxy - def test_receive_cloud_event_timeout_max_value( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(HttpResponseError): - client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=121) - - @EventGridPreparer() - @recorded_by_proxy - def test_receive_cloud_event_timeout_min_value( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(HttpResponseError): - client.receive_cloud_events(eventgrid_topic_name, eventgrid_event_subscription_name, max_wait_time=9) - - @EventGridPreparer() - @recorded_by_proxy - def test_acknowledge_cloud_event_not_found( - self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(ResourceNotFoundError): - lock_tokens = ["faketoken"] - client.acknowledge_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) - - @EventGridPreparer() - @recorded_by_proxy - def test_release_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - with pytest.raises(ResourceNotFoundError): - lock_tokens = ["faketoken"] - client.release_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) - - @EventGridPreparer() - @recorded_by_proxy - def test_reject_cloud_event_not_found(self, eventgrid_endpoint, eventgrid_key, eventgrid_event_subscription_name): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = ["faketoken"] - - with pytest.raises(ResourceNotFoundError): - client.reject_cloud_events("faketopic", eventgrid_event_subscription_name, lock_tokens=lock_tokens) - - @EventGridPreparer() - @recorded_by_proxy - def test_acknowledge_cloud_event_invalid_token( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - lock_tokens = ["faketoken"] - ack = client.acknowledge_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) - assert type(ack) == AcknowledgeResult - assert ack.succeeded_lock_tokens == [] - assert type(ack.failed_lock_tokens[0]) == FailedLockToken - assert ack.failed_lock_tokens[0].lock_token == "faketoken" - - @EventGridPreparer() - @recorded_by_proxy - def test_release_cloud_event_invalid_token( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - - lock_tokens = ["faketoken"] - release = client.release_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) - assert type(release) == ReleaseResult - assert release.succeeded_lock_tokens == [] - assert type(release.failed_lock_tokens[0]) == FailedLockToken - assert release.failed_lock_tokens[0].lock_token == "faketoken" - - @EventGridPreparer() - @recorded_by_proxy - def test_reject_cloud_event_invalid_token( - self, eventgrid_endpoint, eventgrid_key, eventgrid_topic_name, eventgrid_event_subscription_name - ): - client = self.create_eg_client(eventgrid_endpoint, eventgrid_key) - lock_tokens = ["faketoken"] - - reject = client.reject_cloud_events( - eventgrid_topic_name, eventgrid_event_subscription_name, lock_tokens=lock_tokens - ) - assert type(reject) == RejectResult - assert reject.succeeded_lock_tokens == [] - assert type(reject.failed_lock_tokens[0]) == FailedLockToken - assert reject.failed_lock_tokens[0].lock_token == "faketoken" diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py new file mode 100644 index 000000000000..b04175ed32fc --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py @@ -0,0 +1,163 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import logging +import sys +import os +import json +import pytest +import uuid +from msrest.serialization import UTC +import datetime as dt + +from devtools_testutils import AzureRecordedTestCase +from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridConsumerClient, EventGridPublisherClient +from eventgrid_preparer import ( + EventGridPreparer, +) + + +class TestEventGridConsumerClient(AzureRecordedTestCase): + def create_eg_publisher_client(self, endpoint, topic=None): + credential = self.get_credential(EventGridPublisherClient) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic + ) + return client + + def create_eg_consumer_client(self, endpoint, topic, subscription): + credential = self.get_credential(EventGridConsumerClient) + client = self.create_client_from_credential( + EventGridConsumerClient, + credential=credential, + endpoint=endpoint, + namespace_topic=topic, + subscription=subscription, + ) + return client + + @pytest.mark.live_test_only + @EventGridPreparer() + def test_receive_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + publisher.send(cloud_event) + + received_event = consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + ack_result = consumer.acknowledge(lock_tokens=[event.broker_properties.lock_token]) + assert ack_result.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + def test_receive_renew_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + publisher.send(cloud_event) + + received_event = consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + renew_lock = consumer.renew_locks(lock_tokens=[event.broker_properties.lock_token]) + ack_result = consumer.acknowledge(lock_tokens=[event.broker_properties.lock_token]) + assert ack_result.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + def test_receive_release_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + publisher.send(cloud_event) + + received_event = consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + release = consumer.release(lock_tokens=[event.broker_properties.lock_token]) + assert release.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + def test_receive_reject_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + publisher.send(cloud_event) + + received_event = consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + reject = consumer.reject(lock_tokens=[event.broker_properties.lock_token]) + assert reject.succeeded_lock_tokens == [event.broker_properties.lock_token] diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py new file mode 100644 index 000000000000..a73452700184 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py @@ -0,0 +1,168 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import logging +import sys +import os +import json +import pytest +import asyncio +import uuid +from msrest.serialization import UTC +import datetime as dt + +from devtools_testutils import AzureRecordedTestCase +from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid.aio import EventGridConsumerClient, EventGridPublisherClient +from eventgrid_preparer import ( + EventGridPreparer, +) + + +class TestEventGridConsumerClientAsync(AzureRecordedTestCase): + def create_eg_publisher_client(self, endpoint, topic=None): + credential = self.get_credential(EventGridPublisherClient) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic + ) + return client + + def create_eg_consumer_client(self, endpoint, topic, subscription): + credential = self.get_credential(EventGridConsumerClient) + client = self.create_client_from_credential( + EventGridConsumerClient, + credential=credential, + endpoint=endpoint, + namespace_topic=topic, + subscription=subscription, + ) + return client + + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_receive_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + await publisher.send(cloud_event) + + received_event = await consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + ack_result = await consumer.acknowledge(lock_tokens=[event.broker_properties.lock_token]) + assert ack_result.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_receive_renew_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + await publisher.send(cloud_event) + + received_event = await consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + renew_lock = await consumer.renew_locks(lock_tokens=[event.broker_properties.lock_token]) + ack_result = await consumer.acknowledge(lock_tokens=[event.broker_properties.lock_token]) + assert ack_result.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_receive_release_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + await publisher.send(cloud_event) + + received_event = await consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + release = await consumer.release(lock_tokens=[event.broker_properties.lock_token]) + assert release.succeeded_lock_tokens == [event.broker_properties.lock_token] + + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_receive_reject_data(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + await publisher.send(cloud_event) + + received_event = await consumer.receive(max_events=1) + assert len(received_event) == 1 + + for event in received_event: + reject = await consumer.reject(lock_tokens=[event.broker_properties.lock_token]) + assert reject.succeeded_lock_tokens == [event.broker_properties.lock_token] diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 69aac887821f..1c1f7c80b0d7 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -33,9 +33,11 @@ class TestEventGridPublisherClient(AzureRecordedTestCase): - def create_eg_publisher_client(self, endpoint): + def create_eg_publisher_client(self, endpoint, topic=None): credential = self.get_credential(EventGridPublisherClient) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential( + EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic + ) return client @EventGridPreparer() @@ -150,6 +152,19 @@ def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): ) client.send(cloud_event) + @pytest.mark.live_test_only + @EventGridPreparer() + def test_send_cloud_event_data_dict_namespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + client.send(cloud_event) + @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @EventGridPreparer() @recorded_by_proxy diff --git a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py b/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py deleted file mode 100644 index f597ca727f2a..000000000000 --- a/sdk/eventgrid/azure-eventgrid/tests/unittests/test_binary_mode.py +++ /dev/null @@ -1,70 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- -import pytest -import json -import base64 -from azure.eventgrid._operations._patch import _to_http_request -from azure.eventgrid.models import * -from azure.core.messaging import CloudEvent - - -class MyTestClass(object): - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - -class TestEGClientExceptions: - - def test_binary_request_format(self): - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"this is binary data", - datacontenttype="application/json", - ) - - request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) - - assert request.data == b"this is binary data" - assert request.headers.get("ce-source") == "source" - assert request.headers.get("ce-subject") == "MySubject" - assert request.headers.get("ce-type") == "Contoso.Items.ItemReceived" - - def test_binary_request_format_with_extensions_and_datacontenttype(self): - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=b"this is my data", - datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - request = _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) - - assert request.data == b"this is my data" - assert request.headers.get("ce-source") == "source" - assert request.headers.get("ce-subject") == "MySubject" - assert request.headers.get("ce-type") == "Contoso.Items.ItemReceived" - assert request.headers.get("ce-extension1") == "value1" - - def test_class_binary_request_format_error(self): - test_class = MyTestClass("test") - event = CloudEvent( - type="Contoso.Items.ItemReceived", - source="source", - subject="MySubject", - data=test_class, - datacontenttype="application/json", - extensions={"extension1": "value1", "extension2": "value2"}, - ) - - with pytest.raises(TypeError): - _to_http_request("https://MYTOPIC.westus2-1.eventgrid.azure.net/api/events", event=event) diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml index 3f8ef6b354e8..3163e6090c1a 100644 --- a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -1,4 +1,4 @@ cleanup: false -commit: f56fd0ca360a8545e4a9e108b84abf01ba195d2d +commit: 3098514b6f9a29ce0aca59b673c415dbbbb89b28 directory: specification/eventgrid/Azure.Messaging.EventGrid repo: Azure/azure-rest-api-specs \ No newline at end of file diff --git a/sdk/eventgrid/test-resources.json b/sdk/eventgrid/test-resources.json index a346523e7fd9..46be17ef3e17 100644 --- a/sdk/eventgrid/test-resources.json +++ b/sdk/eventgrid/test-resources.json @@ -49,7 +49,7 @@ "resources": [ { "type": "Microsoft.EventGrid/namespaces", - "apiVersion": "2023-12-15-preview", + "apiVersion": "2024-06-01-preview", "name": "[variables('namespaceName')]", "location": "[resourceGroup().location]", "sku": { @@ -63,7 +63,7 @@ }, { "type": "Microsoft.EventGrid/namespaces/topics", - "apiVersion": "2023-12-15-preview", + "apiVersion": "2024-06-01-preview", "name": "[format('{0}/{1}', variables('namespaceName'), variables('topicName'))]", "properties": { "publisherType": "Custom", @@ -76,7 +76,7 @@ }, { "type": "Microsoft.EventGrid/namespaces/topics/eventSubscriptions", - "apiVersion": "2023-12-15-preview", + "apiVersion": "2024-06-01-preview", "name": "[format('{0}/{1}/{2}', variables('namespaceName'), variables('topicName'), variables('subscriptionName'))]", "properties": { "deliveryConfiguration": { @@ -283,11 +283,11 @@ }, "EVENTGRID_KEY": { "type": "string", - "value": "[listKeys(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-12-15-preview').key1]" + "value": "[listKeys(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2024-06-01-preview').key1]" }, "EVENTGRID_ENDPOINT": { "type": "string", - "value": "[format('https://{0}', reference(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2023-12-15-preview').topicsConfiguration.hostname)]" + "value": "[format('https://{0}', reference(resourceId('Microsoft.EventGrid/namespaces', variables('namespaceName')), '2024-06-01-preview').topicsConfiguration.hostname)]" }, "EVENTGRID_TOPIC_NAME": { "type": "string", From 7181462b92e30c72fd94a835f1b79b87fdbf6283 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 31 May 2024 08:43:50 -0700 Subject: [PATCH 26/43] [EG] Update tests (#35833) * [EG] Update tests (#35752) * test * typo * update recordings * mark live * kwarg fix * updates * revert * kwargs * continue skip * rename * naming * remove _async * nit * typo * remove async --- sdk/eventgrid/azure-eventgrid/assets.json | 2 +- .../azure-eventgrid/tests/conftest.py | 2 +- .../tests/eventgrid_preparer.py | 9 ++- .../azure-eventgrid/tests/test_cncf_events.py | 13 ++-- .../tests/test_cncf_events_async.py | 15 +++-- .../tests/test_eg_publisher_client.py | 24 +++---- .../tests/test_eg_publisher_client_async.py | 63 +++++++++---------- .../azure-eventgrid/tests/test_exceptions.py | 41 +++++------- .../tests/test_exceptions_async.py | 36 +++-------- 9 files changed, 82 insertions(+), 123 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/assets.json b/sdk/eventgrid/azure-eventgrid/assets.json index d7404dd2fdd0..7d595dc4f34e 100644 --- a/sdk/eventgrid/azure-eventgrid/assets.json +++ b/sdk/eventgrid/azure-eventgrid/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/eventgrid/azure-eventgrid", - "Tag": "python/eventgrid/azure-eventgrid_f155c8ac2d" + "Tag": "python/eventgrid/azure-eventgrid_3ae14bceff" } diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index d95ebca3e613..dffb2825e3ba 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -51,7 +51,7 @@ def add_sanitizers(test_proxy): add_remove_header_sanitizer(headers="aeg-sas-key, aeg-sas-token, aeg-channel-name") add_general_regex_sanitizer( value="fakeresource", - regex="(?<=\\/\\/)[.*]+(?=\\.eastus-1\\.eventgrid\\.azure\\.net/api/events)", + regex="(?<=\\/\\/)[a-z-]+(?=\\.eastus-1\\.eventgrid\\.azure\\.net/api/events)" ) add_oauth_response_sanitizer() diff --git a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py index 6b8fcb2b73fc..b92b99686ae8 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py +++ b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py @@ -1,5 +1,5 @@ import functools -from devtools_testutils import PowerShellPreparer, EnvironmentVariableLoader +from devtools_testutils import EnvironmentVariableLoader from azure.mgmt.eventgrid.models import ( Topic, @@ -9,8 +9,8 @@ JsonFieldWithDefault, ) -EVENTGRID_TOPIC_PARAM = "eventgrid_topic" -EVENTGRID_TOPIC_LOCATION = "eastus" +EVENTGRID_TOPIC_PARAM = 'eventgrid_topic' +EVENTGRID_TOPIC_LOCATION = 'westus' CLOUD_EVENT_SCHEMA = InputSchema.cloud_event_schema_v1_0 CUSTOM_EVENT_SCHEMA = InputSchema.custom_event_schema ID_JSON_FIELD = JsonField(source_field="customId") @@ -29,8 +29,7 @@ ) EventGridPreparer = functools.partial( - PowerShellPreparer, - "eventgrid", + EnvironmentVariableLoader, "eventgrid", eventgrid_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", eventgrid_domain_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py index e7052226447d..06b2fc949305 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events.py @@ -1,7 +1,6 @@ import json from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.eventgrid import EventGridPublisherClient from cloudevents.http import CloudEvent @@ -18,7 +17,7 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_dict(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -38,7 +37,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -56,7 +55,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_none(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -68,7 +67,7 @@ def test_send_cncf_data_none(self, eventgrid_cloud_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_str(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -86,7 +85,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_as_list(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -98,7 +97,7 @@ def test_send_cncf_data_as_list(self, eventgrid_cloud_event_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_cncf_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): + def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py index 247317ce074c..a4c34a8cafd9 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cncf_events_async.py @@ -1,9 +1,8 @@ import json import pytest -from devtools_testutils import AzureRecordedTestCase, CachedResourceGroupPreparer +from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.eventgrid.aio import EventGridPublisherClient from cloudevents.http import CloudEvent @@ -21,7 +20,7 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_dict_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -42,7 +41,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_base64_using_data_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_base64_using_data(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -61,7 +60,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_none_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -74,7 +73,7 @@ async def test_send_cncf_data_none_async(self, eventgrid_cloud_event_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_str_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -93,7 +92,7 @@ def callback(request): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_as_list_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", @@ -106,7 +105,7 @@ async def test_send_cncf_data_as_list_async(self, eventgrid_cloud_event_topic_en @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cncf_data_with_extensions_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) attributes = { "type": "com.example.sampletype1", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 1c1f7c80b0d7..68b66ae5cd05 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -21,7 +21,7 @@ from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.core.credentials import AzureKeyCredential, AzureSasCredential +from azure.core.credentials import AzureSasCredential from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas @@ -54,10 +54,10 @@ def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_key, eventgrid_topic_endpoint): - akc_credential = AzureKeyCredential(eventgrid_topic_key) + def test_send_event_grid_event_fails_without_full_url(self,eventgrid_topic_endpoint): + credential = self.get_credential(EventGridPublisherClient) parsed_url = urlparse(eventgrid_topic_endpoint) - client = EventGridPublisherClient(parsed_url.netloc, akc_credential) + client = EventGridPublisherClient(parsed_url.netloc, credential) eg_event = EventGridEvent( subject="sample", data={"sample": "eventgridevent"}, @@ -273,9 +273,11 @@ def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): } client.send(cloud_event1) + @pytest.mark.live_test_only @EventGridPreparer() - @recorded_by_proxy - def test_send_signature_credential(self, eventgrid_topic_key, eventgrid_topic_endpoint): + def test_send_signature_credential(self, **kwargs): + eventgrid_topic_endpoint = kwargs.pop("eventgrid_topic_endpoint") + eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) credential = AzureSasCredential(signature) @@ -355,14 +357,8 @@ def test_send_token_credential(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @recorded_by_proxy - def test_send_partner_namespace( - self, - eventgrid_partner_namespace_topic_endpoint, - eventgrid_partner_namespace_topic_key, - eventgrid_partner_channel_name, - ): - credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) - client = EventGridPublisherClient(eventgrid_partner_namespace_topic_endpoint, credential) + def test_send_partner_namespace(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name): + client = self.create_eg_publisher_client(eventgrid_partner_namespace_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index 3eee77aa3ce2..d7ab21ec1e11 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -18,7 +18,7 @@ from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from azure.core.credentials import AzureKeyCredential, AzureSasCredential +from azure.core.credentials import AzureSasCredential from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridEvent, generate_sas @@ -37,7 +37,7 @@ def create_eg_publisher_client(self, endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_dict_async(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -50,7 +50,7 @@ async def test_send_event_grid_event_data_dict_async(self, eventgrid_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_as_list_async(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_as_list(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event1 = EventGridEvent( subject="sample", @@ -69,12 +69,10 @@ async def test_send_event_grid_event_data_as_list_async(self, eventgrid_topic_en @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_fails_without_full_url_async( - self, eventgrid_topic_key, eventgrid_topic_endpoint - ): - akc_credential = AzureKeyCredential(eventgrid_topic_key) + async def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_endpoint): + credential = self.get_credential(EventGridPublisherClient, is_async=True) parsed_url = urlparse(eventgrid_topic_endpoint) - client = EventGridPublisherClient(parsed_url.netloc, akc_credential) + client = EventGridPublisherClient(parsed_url.netloc, credential) eg_event = EventGridEvent( subject="sample", data={"sample": "eventgridevent"}, @@ -87,7 +85,7 @@ async def test_send_event_grid_event_fails_without_full_url_async( @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_str_async(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_str(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -100,7 +98,7 @@ async def test_send_event_grid_event_data_str_async(self, eventgrid_topic_endpoi @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_data_bytes_async(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = EventGridEvent( subject="sample", @@ -114,7 +112,7 @@ async def test_send_event_grid_event_data_bytes_async(self, eventgrid_topic_endp @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_event_grid_event_dict_data_bytes_async(self, eventgrid_topic_endpoint): + async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_topic_endpoint) eg_event = { "subject": "sample", @@ -130,7 +128,7 @@ async def test_send_event_grid_event_dict_data_bytes_async(self, eventgrid_topic @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_dict_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, type="Sample.Cloud.Event" @@ -148,7 +146,7 @@ async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpo @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_str_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -160,7 +158,7 @@ async def test_send_cloud_event_data_str_async(self, eventgrid_cloud_event_topic @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_bytes_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_bytes(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -172,7 +170,7 @@ async def test_send_cloud_event_data_bytes_async(self, eventgrid_cloud_event_top @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_as_list_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_as_list(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -184,7 +182,7 @@ async def test_send_cloud_event_data_as_list_async(self, eventgrid_cloud_event_t @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_with_extensions_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_with_extensions(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", @@ -201,7 +199,7 @@ async def test_send_cloud_event_data_with_extensions_async(self, eventgrid_cloud @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_dict_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event1 = { "id": "1234", @@ -215,7 +213,7 @@ async def test_send_cloud_event_dict_async(self, eventgrid_cloud_event_topic_end @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_none_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_none(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent(source="http://samplesource.dev", data=None, type="Sample.Cloud.Event") await client.send(cloud_event) @@ -224,7 +222,7 @@ async def test_send_cloud_event_data_none_async(self, eventgrid_cloud_event_topi @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_cloud_event_data_NULL_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_cloud_event_data_NULL(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) cloud_event = CloudEvent(source="http://samplesource.dev", data=NULL, type="Sample.Cloud.Event") @@ -234,10 +232,12 @@ def callback(request): await client.send(cloud_event, raw_request_hook=callback) + @pytest.mark.live_test_only @EventGridPreparer() - @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_signature_credential_async(self, eventgrid_topic_key, eventgrid_topic_endpoint): + async def test_send_signature_credential(self, **kwargs): + eventgrid_topic_endpoint = kwargs.pop("eventgrid_topic_endpoint") + eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") expiration_date_utc = dt.datetime.now(UTC()) + timedelta(hours=1) signature = generate_sas(eventgrid_topic_endpoint, eventgrid_topic_key, expiration_date_utc) credential = AzureSasCredential(signature) @@ -253,7 +253,7 @@ async def test_send_signature_credential_async(self, eventgrid_topic_key, eventg @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event_async(self, eventgrid_custom_event_topic_endpoint): + async def test_send_custom_schema_event(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event = { "customSubject": "sample", @@ -268,7 +268,7 @@ async def test_send_custom_schema_event_async(self, eventgrid_custom_event_topic @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_custom_schema_event_as_list_async(self, eventgrid_custom_event_topic_endpoint): + async def test_send_custom_schema_event_as_list(self, eventgrid_custom_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_custom_event_topic_endpoint) custom_event1 = { "customSubject": "sample", @@ -291,7 +291,7 @@ async def test_send_custom_schema_event_as_list_async(self, eventgrid_custom_eve @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_and_close_async_session_async(self, eventgrid_cloud_event_topic_endpoint): + async def test_send_and_close_async_session(self, eventgrid_cloud_event_topic_endpoint): client = self.create_eg_publisher_client(eventgrid_cloud_event_topic_endpoint) async with client: # this throws if client can't close cloud_event = CloudEvent( @@ -304,7 +304,7 @@ async def test_send_and_close_async_session_async(self, eventgrid_cloud_event_to @pytest.mark.skip() @EventGridPreparer() @recorded_by_proxy_async - def test_send_NONE_credential_async(self, eventgrid_topic_endpoint): + def test_send_NONE_credential(self, eventgrid_topic_endpoint): with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): client = EventGridPublisherClient(eventgrid_topic_endpoint, None) @@ -312,7 +312,7 @@ def test_send_NONE_credential_async(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_token_credential_async(self, eventgrid_topic_endpoint): + async def test_send_token_credential(self, eventgrid_topic_endpoint): credential = self.get_credential(EventGridPublisherClient) client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) eg_event = EventGridEvent( @@ -326,14 +326,9 @@ async def test_send_token_credential_async(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @recorded_by_proxy_async - async def test_send_partner_namespace_async( - self, - eventgrid_partner_namespace_topic_endpoint, - eventgrid_partner_namespace_topic_key, - eventgrid_partner_channel_name, - ): - credential = AzureKeyCredential(eventgrid_partner_namespace_topic_key) - client = EventGridPublisherClient(eventgrid_partner_namespace_topic_endpoint, credential) + @pytest.mark.asyncio + async def test_send_partner_namespace(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name): + client = self.create_eg_publisher_client(eventgrid_partner_namespace_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", data="cloudevent", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index a19b3dd8e1a1..b634cdfc48bd 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -4,31 +4,18 @@ # license information. # -------------------------------------------------------------------------- -import logging -import sys import os import json import pytest -import uuid -from datetime import datetime, timedelta from azure.core.exceptions import ( HttpResponseError, ClientAuthenticationError, - ServiceRequestError, ) -from msrest.serialization import UTC -import datetime as dt - -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse from devtools_testutils import AzureMgmtRecordedTestCase, recorded_by_proxy from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridPublisherClient, EventGridEvent -from azure.core.messaging import CloudEvent from eventgrid_preparer import ( EventGridPreparer, @@ -41,9 +28,10 @@ def create_eg_publisher_client(self, endpoint): client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client + @pytest.mark.live_test_only @EventGridPreparer() - @recorded_by_proxy - def test_raise_on_auth_error(self, eventgrid_topic_endpoint): + def test_raise_on_auth_error(self, **kwargs): + eventgrid_topic_endpoint = kwargs.pop("eventgrid_topic_endpoint") akc_credential = AzureKeyCredential("bad credential") client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) eg_event = EventGridEvent( @@ -60,18 +48,17 @@ def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.skip("Fix during MQ - skip to unblock pipeline") @pytest.mark.live_test_only - def test_raise_on_bad_resource(self): - credential = AzureKeyCredential(os.environ["EVENTGRID_TOPIC_KEY"]) - client = EventGridPublisherClient( - "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", - credential, - ) - eg_event = CloudEvent( - subject="sample", - data={"sample": "eventgridevent"}, - source="source", - type="Sample.Cloud.Event", - ) + @EventGridPreparer() + def test_raise_on_bad_resource(self, **kwargs): + eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") + akc_credential = AzureKeyCredential(eventgrid_topic_key) + client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) + eg_event = EventGridEvent( + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0" + ) with pytest.raises(HttpResponseError): client.send(eg_event) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index 461c17453482..635ae83dd9b3 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -4,35 +4,20 @@ # license information. # -------------------------------------------------------------------------- -import logging -import sys import os import json import pytest -import uuid -from datetime import datetime, timedelta -from azure.core.exceptions import ( - HttpResponseError, - ClientAuthenticationError, - ServiceRequestError, -) +from azure.core.exceptions import HttpResponseError, ClientAuthenticationError from msrest.serialization import UTC import datetime as dt -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from azure.core.credentials import AzureKeyCredential, AzureSasCredential -from azure.core.messaging import CloudEvent -from azure.core.serialization import NULL -from azure.eventgrid import EventGridEvent, generate_sas +from azure.core.credentials import AzureKeyCredential +from azure.eventgrid import EventGridEvent from azure.eventgrid.aio import EventGridPublisherClient -from azure.eventgrid._legacy._helpers import _cloud_event_to_generated from eventgrid_preparer import ( EventGridPreparer, @@ -45,10 +30,11 @@ def create_eg_publisher_client(self, endpoint): client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) return client + @pytest.mark.live_test_only @EventGridPreparer() - @recorded_by_proxy_async @pytest.mark.asyncio - async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): + async def test_raise_on_auth_error(self, **kwargs): + eventgrid_topic_endpoint = kwargs.pop("eventgrid_topic_endpoint") akc_credential = AzureKeyCredential("bad credential") client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) eg_event = EventGridEvent( @@ -67,12 +53,10 @@ async def test_raise_on_auth_error(self, eventgrid_topic_endpoint): @pytest.mark.live_test_only @EventGridPreparer() @pytest.mark.asyncio - async def test_raise_on_bad_resource(self): - credential = AzureKeyCredential(os.environ["EVENTGRID_TOPIC_KEY"]) - client = EventGridPublisherClient( - "https://bad-resource.eastus-1.eventgrid.azure.net/api/events", - credential, - ) + async def test_raise_on_bad_resource(self, **kwargs): + eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") + akc_credential = AzureKeyCredential(eventgrid_topic_key) + client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) eg_event = EventGridEvent( subject="sample", data={"sample": "eventgridevent"}, From 66bafef027ff437af52352051fb6a682762f9750 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 31 May 2024 10:38:49 -0700 Subject: [PATCH 27/43] remove print (#35855) --- .../azure-eventgrid/azure/eventgrid/_operations/_operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 3ad9c7acf667..5ad00112f55a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -885,7 +885,7 @@ def _release( _content = body else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - print(_content) + _request = build_event_grid_consumer_release_request( topic_name=topic_name, event_subscription_name=event_subscription_name, From 6190bde905364887809a68ff201b24e7c2765676 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 3 Jun 2024 09:36:09 -0700 Subject: [PATCH 28/43] [EG] update pyproject and samples (#35857) * update * pylint changes --- scripts/devops_tasks/test_run_samples.py | 13 ------------- .../azure/eventgrid/_operations/_patch.py | 12 ++++-------- .../azure-eventgrid/azure/eventgrid/_patch.py | 3 ++- .../azure/eventgrid/aio/_operations/_patch.py | 13 +++++-------- .../azure-eventgrid/azure/eventgrid/aio/_patch.py | 3 ++- sdk/eventgrid/azure-eventgrid/pyproject.toml | 4 +--- 6 files changed, 14 insertions(+), 34 deletions(-) diff --git a/scripts/devops_tasks/test_run_samples.py b/scripts/devops_tasks/test_run_samples.py index 26cc5d023434..0894ea943771 100644 --- a/scripts/devops_tasks/test_run_samples.py +++ b/scripts/devops_tasks/test_run_samples.py @@ -93,19 +93,6 @@ "consume_eventgrid_events_from_service_bus_queue.py", "sample_publish_events_to_a_topic_using_sas_credential.py", "sample_publish_events_to_a_topic_using_sas_credential_async.py", - 'sample_publish_operation.py', - 'sample_receive_operation.py', - 'sample_reject_operation.py', - 'sample_eg_client_authentication.py', - 'sample_all_operations.py', - 'sample_release_operation.py', - 'sample_acknowledge_operation.py', - 'sample_publish_operation_async.py', - 'sample_release_operation_async.py', - 'sample_reject_operation_async.py', - 'sample_acknowledge_operation_async.py', - 'sample_receive_operation_async.py', - 'sample_all_operations_async.py' ], "azure-eventhub": [ "client_identity_authentication.py", # TODO: remove after fixing issue #29177 diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 7b9a22176a7a..5d759bb3216a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -16,7 +16,6 @@ Optional, TypeVar, Union, - overload, TYPE_CHECKING, ) @@ -28,7 +27,6 @@ from azure.core.tracing.decorator import distributed_trace from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, HttpResponse -from azure.core.utils import case_insensitive_dict from ._operations import ( EventGridPublisherClientOperationsMixin as PublisherOperationsMixin, @@ -105,8 +103,6 @@ def send( ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. - :param topic_name: The name of the topic to send the event to. - :type topic_name: str :param events: The event to send. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] @@ -143,24 +139,24 @@ def send( # Try to send via namespace self._publish(self._namespace, _serialize_events(events), **kwargs) except Exception as exception: # pylint: disable=broad-except - self._http_response_error_handler(exception, "Namespaces") + self._http_response_error_handler(exception) raise exception else: kwargs["content_type"] = content_type if content_type else "application/json; charset=utf-8" try: self._publish(events, channel_name=channel_name, **kwargs) except Exception as exception: - self._http_response_error_handler(exception, "Basic") + self._http_response_error_handler(exception) raise exception - def _http_response_error_handler(self, exception, level): + def _http_response_error_handler(self, exception): if isinstance(exception, HttpResponseError): if exception.status_code == 400: raise HttpResponseError("Invalid event data. Please check the data and try again.") from exception if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - f"Please check that the tier you are using, corresponds to the correct " + "Please check that the tier you are using, corresponds to the correct " "endpoint and/or topic name." ) from exception raise exception diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py index 1b7a8b79dc0b..b63baf75804a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_patch.py @@ -132,7 +132,8 @@ def __init__( ) def __repr__(self) -> str: - return f"" + return f"" def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 71e5202a6b72..e856d18de501 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -16,7 +16,6 @@ from azure.core.pipeline import PipelineResponse from azure.core.rest import HttpRequest, AsyncHttpResponse from ...models._patch import ReceiveDetails -from ..._operations._patch import use_standard_only from ._operations import ( EventGridPublisherClientOperationsMixin as PublisherOperationsMixin, EventGridConsumerClientOperationsMixin as ConsumerOperationsMixin, @@ -29,7 +28,7 @@ ) from ..._legacy import EventGridEvent -from ..._legacy._helpers import _is_eventgrid_event_format, _from_cncf_events +from ..._legacy._helpers import _is_eventgrid_event_format if sys.version_info >= (3, 9): from collections.abc import MutableMapping @@ -65,8 +64,6 @@ async def send( ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. - :param topic_name: The name of the topic to send the event to. - :type topic_name: str :param events: The event to send. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] @@ -104,24 +101,24 @@ async def send( # Try to send via namespace await self._publish(self._namespace, _serialize_events(events), **kwargs) except Exception as exception: # pylint: disable=broad-except - self._http_response_error_handler(exception, "Namespaces") + self._http_response_error_handler(exception) raise exception else: kwargs["content_type"] = content_type if content_type else "application/json; charset=utf-8" try: await self._publish(events, channel_name=channel_name, **kwargs) except Exception as exception: - self._http_response_error_handler(exception, "Basic") + self._http_response_error_handler(exception) raise exception - def _http_response_error_handler(self, exception, level): + def _http_response_error_handler(self, exception): if isinstance(exception, HttpResponseError): if exception.status_code == 400: raise HttpResponseError("Invalid event data. Please check the data and try again.") from exception if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - f"Please check that the tier you are using, corresponds to the correct " + "Please check that the tier you are using, corresponds to the correct " "endpoint and/or topic name." ) from exception raise exception diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py index c07ebfc3d80d..c82fcc0033d0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_patch.py @@ -130,7 +130,8 @@ def __init__( ) def __repr__(self) -> str: - return f"" + return f"" def patch_sdk(): diff --git a/sdk/eventgrid/azure-eventgrid/pyproject.toml b/sdk/eventgrid/azure-eventgrid/pyproject.toml index 1753fb8036e7..ab509fcf3611 100644 --- a/sdk/eventgrid/azure-eventgrid/pyproject.toml +++ b/sdk/eventgrid/azure-eventgrid/pyproject.toml @@ -1,5 +1,3 @@ [tool.azure-sdk-build] pyright = false -verifytypes = false -strict_sphinx = false -pylint = false \ No newline at end of file +verifytypes = false \ No newline at end of file From 14bfdaffe7172022ec12437c87261e56a0c8360d Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 3 Jun 2024 10:23:41 -0700 Subject: [PATCH 29/43] update readme + version --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 7 ++ sdk/eventgrid/azure-eventgrid/README.md | 115 ++++++++---------- .../azure/eventgrid/_version.py | 2 +- 3 files changed, 59 insertions(+), 65 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index e80ac1effa02..2e65032ffaa0 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,5 +1,12 @@ # Release History +## 4.20.0 (Unreleased) + +### Features Added +### Breaking Changes +### Bugs Fixed +### Other Changes + ## 4.20.0b2 (2024-04-25) This is a Beta of the EventGridClient diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 79ccaba5d902..efd86c202c67 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -12,7 +12,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ## _Disclaimer_ -This is a beta release of Azure EventGrid's `EventGridClient`. `EventGridClient` supports `send`, `receive_cloud_events`, `acknowledge_cloud_events` , `release_cloud_events`, `reject_cloud_events`, and `renew_cloud_event_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples) for further information. +This is a GA release of Azure EventGrid's `EventGridConsumerClient`. `EventGridConsumerClient` supports `receive`, `acknowledge` , `release`, `reject`, and `renew_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples) for further information. ## Getting started @@ -55,10 +55,10 @@ az eventgrid namespace create topic --location --resource-group [azure_cli_link]: https://pypi.org/project/azure-cli/ -[python-eg-src]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid +[python-eg-src]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid [python-eg-pypi]: https://pypi.org/project/azure-eventgrid [python-eg-product-docs]: https://docs.microsoft.com/azure/event-grid/overview [python-eg-ref-docs]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-eventgrid/latest/index.html [publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts -[python-eg-samples]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples -[python-eg-changelog]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +[python-eg-samples]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples +[python-eg-changelog]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/CHANGELOG.md [pip]: https://pypi.org/project/pip/ [azure_portal_create_EG_resource]: https://ms.portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.EventGrid%2Ftopics [azure-key-credential]: https://aka.ms/azsdk/python/core/azurekeycredential [azure_core_exceptions]: https://aka.ms/azsdk/python/core/docs#module-azure.core.exceptions [python_logging]: https://docs.python.org/3/library/logging.html -[azure_core_ref_docs]: https://github.com/Azure/azure-sdk-for-python/tree/feature/eventgrid/sdk/core/azure-core#configurations +[azure_core_ref_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core#configurations [azure_subscription]: https://azure.microsoft.com/free/ -[python-eg-auth]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py -[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py -[python-eg-sample-send-using-sas]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py -[python-eg-sample-eg-event]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py -[python-eg-sample-eg-event-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py -[python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py -[python-eg-publish-custom-schema]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py -[python-eg-sample-send-eg-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py -[python-eg-sample-send-cloudevent-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py - -[python-eg-auth-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py -[python-eg-sample-send-using-sas-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py -[python-eg-sample-eg-event-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py -[python-eg-sample-eg-event-to-domain-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py -[python-eg-sample-send-cloudevent-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py -[python-eg-publish-custom-schema-async]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py -[python-eg-sample-send-eg-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py -[python-eg-sample-send-cloudevent-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py - -[python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/publish_samples -[python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/consume_samples -[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py - - -[python-eg-client-all-ops-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_all_operations.py - -[python-eg-client-binary-mode-sample]:https://github.com/Azure/azure-sdk-for-python/blob/feature/eventgrid/sdk/eventgrid/azure-eventgrid/samples/sync_samples/eventgrid_client_samples/sample_binary_mode.py +[python-eg-auth]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +[python-eg-generate-sas]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_generate_sas.py +[python-eg-sample-send-using-sas]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_to_a_topic_using_sas_credential.py +[python-eg-sample-eg-event]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_topic.py +[python-eg-sample-eg-event-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_events_to_a_domain.py +[python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +[python-eg-publish-custom-schema]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_custom_schema_to_a_topic.py +[python-eg-sample-send-eg-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_eg_event_using_dict.py +[python-eg-sample-send-cloudevent-as-dict]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_cloud_event_using_dict.py + +[python-eg-auth-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_authentication_async.py +[python-eg-sample-send-using-sas-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_to_a_topic_using_sas_credential_async.py +[python-eg-sample-eg-event-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_topic_async.py +[python-eg-sample-eg-event-to-domain-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_events_to_a_domain_async.py +[python-eg-sample-send-cloudevent-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +[python-eg-publish-custom-schema-async]:https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_custom_schema_to_a_topic_async.py +[python-eg-sample-send-eg-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_eg_event_using_dict_async.py +[python-eg-sample-send-cloudevent-as-dict-async]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py + +[python-eg-publish-samples]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/publish_samples +[python-eg-consume-samples]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/consume_samples +[python-eg-sample-consume-custom-payload]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py [cla]: https://cla.microsoft.com diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index bbbdd5df00b5..c615ce560cb1 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "4.20.0b2" +VERSION = "4.20.0" From bd911178ac246687b0d4adb156c5b7a7f75f37b6 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 3 Jun 2024 14:34:45 -0700 Subject: [PATCH 30/43] regen --- .../azure/eventgrid/_operations/_operations.py | 12 ++++++------ .../azure/eventgrid/_serialization.py | 2 +- .../azure/eventgrid/aio/_operations/_operations.py | 12 ++++++------ sdk/eventgrid/azure-eventgrid/tests/conftest.py | 3 +-- .../azure-eventgrid/tests/eventgrid_preparer.py | 7 ++++--- .../tests/test_eg_publisher_client.py | 2 +- .../tests/test_eg_publisher_client_async.py | 4 +++- .../azure-eventgrid/tests/test_exceptions.py | 11 +++++------ .../azure-eventgrid/tests/test_exceptions_async.py | 4 +++- sdk/eventgrid/azure-eventgrid/tsp-location.yaml | 2 +- 10 files changed, 31 insertions(+), 28 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py index 5ad00112f55a..b2094313f8e6 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_operations.py @@ -231,7 +231,7 @@ def build_event_grid_consumer_reject_request( return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_event_grid_consumer_renew_lock_request( # pylint: disable=name-too-long +def build_event_grid_consumer_renew_locks_request( # pylint: disable=name-too-long topic_name: str, event_subscription_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -1090,7 +1090,7 @@ def _reject( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - def _renew_lock( + def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -1106,7 +1106,7 @@ def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - def _renew_lock( + def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -1122,7 +1122,7 @@ def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - def _renew_lock( + def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -1139,7 +1139,7 @@ def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - def _renew_lock( + def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -1230,7 +1230,7 @@ def _renew_lock( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_consumer_renew_lock_request( + _request = build_event_grid_consumer_renew_locks_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py index 2f781d740827..f0c6180722c8 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_serialization.py @@ -1441,7 +1441,7 @@ def _deserialize(self, target_obj, data): elif isinstance(response, type) and issubclass(response, Enum): return self.deserialize_enum(data, response) - if data is None: + if data is None or data is CoreNull: return data try: attributes = response._attribute_map # type: ignore diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py index eb240583f902..e10006e75b52 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_operations.py @@ -31,7 +31,7 @@ build_event_grid_consumer_receive_request, build_event_grid_consumer_reject_request, build_event_grid_consumer_release_request, - build_event_grid_consumer_renew_lock_request, + build_event_grid_consumer_renew_locks_request, build_event_grid_publisher_send_events_request, build_event_grid_publisher_send_request, ) @@ -877,7 +877,7 @@ async def _reject( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - async def _renew_lock( + async def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -893,7 +893,7 @@ async def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - async def _renew_lock( + async def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -909,7 +909,7 @@ async def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - async def _renew_lock( + async def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -926,7 +926,7 @@ async def _renew_lock( "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"] }, ) - async def _renew_lock( + async def _renew_locks( self, topic_name: str, event_subscription_name: str, @@ -1017,7 +1017,7 @@ async def _renew_lock( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_event_grid_consumer_renew_lock_request( + _request = build_event_grid_consumer_renew_locks_request( topic_name=topic_name, event_subscription_name=event_subscription_name, content_type=content_type, diff --git a/sdk/eventgrid/azure-eventgrid/tests/conftest.py b/sdk/eventgrid/azure-eventgrid/tests/conftest.py index dffb2825e3ba..ac07bea363d3 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/conftest.py +++ b/sdk/eventgrid/azure-eventgrid/tests/conftest.py @@ -50,8 +50,7 @@ def add_sanitizers(test_proxy): ) add_remove_header_sanitizer(headers="aeg-sas-key, aeg-sas-token, aeg-channel-name") add_general_regex_sanitizer( - value="fakeresource", - regex="(?<=\\/\\/)[a-z-]+(?=\\.eastus-1\\.eventgrid\\.azure\\.net/api/events)" + value="fakeresource", regex="(?<=\\/\\/)[a-z-]+(?=\\.eastus-1\\.eventgrid\\.azure\\.net/api/events)" ) add_oauth_response_sanitizer() diff --git a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py index 8d079cc2b233..917325fbd094 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py +++ b/sdk/eventgrid/azure-eventgrid/tests/eventgrid_preparer.py @@ -4,8 +4,8 @@ from azure.mgmt.eventgrid.models import Topic, InputSchema, JsonInputSchemaMapping, JsonField, JsonFieldWithDefault -EVENTGRID_TOPIC_PARAM = 'eventgrid_topic' -EVENTGRID_TOPIC_LOCATION = 'westus' +EVENTGRID_TOPIC_PARAM = "eventgrid_topic" +EVENTGRID_TOPIC_LOCATION = "westus" CLOUD_EVENT_SCHEMA = InputSchema.cloud_event_schema_v1_0 CUSTOM_EVENT_SCHEMA = InputSchema.custom_event_schema ID_JSON_FIELD = JsonField(source_field="customId") @@ -24,7 +24,8 @@ ) EventGridPreparer = functools.partial( - EnvironmentVariableLoader, "eventgrid", + EnvironmentVariableLoader, + "eventgrid", eventgrid_topic_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", eventgrid_topic_key="fakekeyfakekeyfakekeyfakekeyfakekeyfakekeyA=", eventgrid_domain_endpoint="https://fakeresource.eastus-1.eventgrid.azure.net/api/events", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 68b66ae5cd05..fc32e17c2710 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -54,7 +54,7 @@ def test_send_event_grid_event_data_dict(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy - def test_send_event_grid_event_fails_without_full_url(self,eventgrid_topic_endpoint): + def test_send_event_grid_event_fails_without_full_url(self, eventgrid_topic_endpoint): credential = self.get_credential(EventGridPublisherClient) parsed_url = urlparse(eventgrid_topic_endpoint) client = EventGridPublisherClient(parsed_url.netloc, credential) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index d7ab21ec1e11..ce7e07326953 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -327,7 +327,9 @@ async def test_send_token_credential(self, eventgrid_topic_endpoint): @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio - async def test_send_partner_namespace(self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name): + async def test_send_partner_namespace( + self, eventgrid_partner_namespace_topic_endpoint, eventgrid_partner_channel_name + ): client = self.create_eg_publisher_client(eventgrid_partner_namespace_topic_endpoint) cloud_event = CloudEvent( source="http://samplesource.dev", diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py index b634cdfc48bd..c6a6686b85b9 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions.py @@ -52,13 +52,12 @@ def test_raise_on_auth_error(self, **kwargs): def test_raise_on_bad_resource(self, **kwargs): eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") akc_credential = AzureKeyCredential(eventgrid_topic_key) - client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) + client = EventGridPublisherClient( + "https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential + ) eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) + subject="sample", data={"sample": "eventgridevent"}, event_type="Sample.EventGrid.Event", data_version="2.0" + ) with pytest.raises(HttpResponseError): client.send(eg_event) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py index 635ae83dd9b3..915e28bc2205 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_exceptions_async.py @@ -56,7 +56,9 @@ async def test_raise_on_auth_error(self, **kwargs): async def test_raise_on_bad_resource(self, **kwargs): eventgrid_topic_key = kwargs.pop("eventgrid_topic_key") akc_credential = AzureKeyCredential(eventgrid_topic_key) - client = EventGridPublisherClient("https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential) + client = EventGridPublisherClient( + "https://bad-resource.westus-1.eventgrid.azure.net/api/events", akc_credential + ) eg_event = EventGridEvent( subject="sample", data={"sample": "eventgridevent"}, diff --git a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml index 3163e6090c1a..b956ab4af3a0 100644 --- a/sdk/eventgrid/azure-eventgrid/tsp-location.yaml +++ b/sdk/eventgrid/azure-eventgrid/tsp-location.yaml @@ -1,4 +1,4 @@ cleanup: false -commit: 3098514b6f9a29ce0aca59b673c415dbbbb89b28 +commit: 871324004185488ac0beddf5cab7165e7432f317 directory: specification/eventgrid/Azure.Messaging.EventGrid repo: Azure/azure-rest-api-specs \ No newline at end of file From 6a821f35b34c85c5e02621b34a9ee1317cd5b7b8 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 3 Jun 2024 14:35:28 -0700 Subject: [PATCH 31/43] Update scripts/devops_tasks/test_run_samples.py --- scripts/devops_tasks/test_run_samples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/devops_tasks/test_run_samples.py b/scripts/devops_tasks/test_run_samples.py index 0894ea943771..054085f48202 100644 --- a/scripts/devops_tasks/test_run_samples.py +++ b/scripts/devops_tasks/test_run_samples.py @@ -92,7 +92,7 @@ "consume_cloud_events_from_eventhub.py", "consume_eventgrid_events_from_service_bus_queue.py", "sample_publish_events_to_a_topic_using_sas_credential.py", - "sample_publish_events_to_a_topic_using_sas_credential_async.py", + "sample_publish_events_to_a_topic_using_sas_credential_async.py" ], "azure-eventhub": [ "client_identity_authentication.py", # TODO: remove after fixing issue #29177 From 9a80b90720403942a3441bbf89002ac3626501d2 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Mon, 3 Jun 2024 15:13:33 -0700 Subject: [PATCH 32/43] readme --- sdk/eventgrid/azure-eventgrid/README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index efd86c202c67..772fa83ed0c9 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -12,7 +12,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allow ## _Disclaimer_ -This is a GA release of Azure EventGrid's `EventGridConsumerClient`. `EventGridConsumerClient` supports `receive`, `acknowledge` , `release`, `reject`, and `renew_locks` operations. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples) for further information. +This is a GA release of Azure Event Grid's `EventGridPublisherClient` and `EventGridConsumerClient`. `EventGridPublisherClient` supports `send` for Event Grid Basic and Event Grid Namespaces. `EventGridConsumerClient` supports `receive`, `acknowledge` , `release`, `reject`, and `renew_locks` operations for Event Grid Namespaces. Please refer to the [samples](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/eventgrid/azure-eventgrid/samples) for further information. ## Getting started @@ -55,10 +55,19 @@ az eventgrid namespace create topic --location --resource-group Date: Mon, 3 Jun 2024 15:35:53 -0700 Subject: [PATCH 33/43] typo --- .../azure-eventgrid/azure/eventgrid/_operations/_patch.py | 2 +- .../azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 5d759bb3216a..714dead66c16 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -310,7 +310,7 @@ def renew_locks( :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: """ - return super()._renew_lock( + return super()._renew_locks( topic_name=self._namespace, event_subscription_name=self._subscription, lock_tokens=lock_tokens, diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index e856d18de501..77f802a0b5c7 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -263,7 +263,7 @@ async def renew_locks( :rtype: ~azure.eventgrid.models.RenewLocksResult :raises ~azure.core.exceptions.HttpResponseError: """ - return await super()._renew_lock(self._namespace, self._subscription, lock_tokens=lock_tokens, **kwargs) + return await super()._renew_locks(self._namespace, self._subscription, lock_tokens=lock_tokens, **kwargs) __all__: List[str] = [ From 3dd74c37ba557aaf19e1bf93db519f4ce33b35e1 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 10:29:52 -0700 Subject: [PATCH 34/43] update --- .../azure/eventgrid/_operations/_patch.py | 25 +++---------------- .../azure/eventgrid/aio/_operations/_patch.py | 3 ++- .../sample_consume_process_events_async.py | 4 +-- .../sample_consume_process_events.py | 5 ++-- 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 714dead66c16..317100f730ee 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -61,26 +61,6 @@ from cloudevents.http.event import CloudEvent as CNCFCloudEvent -def use_standard_only(func): - """Use the standard client only. - - This decorator raises an AttributeError if the client is not a standard client. - - :param func: The function to decorate. - :type func: Callable - :return: The decorated function. - :rtype: Callable - """ - - @wraps(func) - def wrapper(self, *args, **kwargs): - if self._level == "Basic": # pylint: disable=protected-access - raise ValueError("The basic client is not supported for this operation.") - return func(self, *args, **kwargs) - - return wrapper - - class EventGridPublisherClientOperationsMixin(PublisherOperationsMixin): @distributed_trace @@ -103,7 +83,8 @@ def send( ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. - :param events: The event to send. + :param events: The event(s) to send. If sending to an Event Grid Namespace, the dict or list of dicts + should be in the format of a CloudEvent. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] :keyword channel_name: The name of the channel to send the event to. Event Grid Basic Resource only. @@ -331,7 +312,7 @@ def _serialize_events(events): return [_from_cncf_events(e) for e in events] else: # Does not conform to format, send as is - return json.dumps(events) + raise ValueError("Invalid event data. Please check the data is of Cloud Event format and try again.") def _serialize_cloud_event(cloud_event): diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index 77f802a0b5c7..d5fefd748437 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -64,7 +64,8 @@ async def send( ) -> None: # pylint: disable=docstring-should-be-keyword, docstring-missing-param """Send events to the Event Grid Service. - :param events: The event to send. + :param events: The event(s) to send. If sending to an Event Grid Namespace, the dict or list of dicts + should be in the format of a CloudEvent. :type events: CloudEvent or List[CloudEvent] or Dict[str, Any] or List[Dict[str, Any]] or CNCFCloudEvent or List[CNCFCloudEvent] or EventGridEvent or List[EventGridEvent] :keyword channel_name: The name of the channel to send the event to. Event Grid Basic Resource only. diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py index 1cc281397446..a44dfe010460 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_consume_process_events_async.py @@ -4,11 +4,11 @@ # license information. # -------------------------------------------------------------------------- """ -FILE: sample_all_operations.py +FILE: sample_consume_process_events_async.py DESCRIPTION: These samples demonstrate sending, receiving, releasing, and acknowledging CloudEvents. USAGE: - python sample_all_operations.py + python sample_consume_process_events_async.py Set the environment variables with your own values before running the sample: 1) EVENTGRID_KEY - The access key of your eventgrid account. 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py index 8ffd7e26c8df..c10f8196fcea 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_process_events.py @@ -4,11 +4,11 @@ # license information. # -------------------------------------------------------------------------- """ -FILE: sample_all_operations.py +FILE: sample_consume_process_events.py DESCRIPTION: These samples demonstrate sending, receiving, releasing, and acknowledging CloudEvents. USAGE: - python sample_all_operations.py + python sample_consume_process_events.py Set the environment variables with your own values before running the sample: 1) EVENTGRID_KEY - The access key of your eventgrid account. 2) EVENTGRID_ENDPOINT - The namespace endpoint. Typically it exists in the format @@ -54,7 +54,6 @@ ] ) - # Receive Published Cloud Events try: receive_results = client.receive( From 77abc560bfe32aa6de2c74415b1bcb6b74d24722 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 10:42:31 -0700 Subject: [PATCH 35/43] add tests --- .../tests/test_eg_publisher_client.py | 32 ++++++++++++ .../tests/test_eg_publisher_client_async.py | 51 ++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index fc32e17c2710..1312fc0ab114 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -139,6 +139,24 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): } client.send(eg_event) + + @pytest.mark.live_test_only + @EventGridPreparer() + def test_send_event_grid_namespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + eg_event = { + "subject": "sample", + "data": {"key1": "Sample.EventGrid.Event"}, + "eventType": "Sample.EventGrid.Event", + "dataVersion": "2.0", + "id": uuid.uuid4(), + "eventTime": datetime.now(), + } + with pytest.raises(TypeError): + client.send(eg_event) + ### CLOUD EVENT TESTS @EventGridPreparer() @@ -165,6 +183,20 @@ def test_send_cloud_event_data_dict_namespace(self, **kwargs): ) client.send(cloud_event) + @pytest.mark.live_test_only + @EventGridPreparer() + def test_send_cloud_event_data_channel_name_namespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data={"sample": "cloudevent"}, + type="Sample.Cloud.Event", + ) + with pytest.raises(ValueError): + client.send(cloud_event, channel_name="testchannel") + @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @EventGridPreparer() @recorded_by_proxy diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index ce7e07326953..729ab18878ef 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -29,9 +29,9 @@ class TestEventGridPublisherClient(AzureRecordedTestCase): - def create_eg_publisher_client(self, endpoint): + def create_eg_publisher_client(self, endpoint, topic=None): credential = self.get_credential(EventGridPublisherClient, is_async=True) - client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint) + client = self.create_client_from_credential(EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic) return client @EventGridPreparer() @@ -125,6 +125,24 @@ async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpo with pytest.raises(TypeError, match="Data in EventGridEvent cannot be bytes*"): await client.send(eg_event) + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_send_event_grid_namespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + eg_event = { + "subject": "sample", + "data": {"key1": "Sample.EventGrid.Event"}, + "eventType": "Sample.EventGrid.Event", + "dataVersion": "2.0", + "id": "id-1234", + "eventTime": dt.datetime.now(), + } + with pytest.raises(TypeError): + client.send(eg_event) + @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio @@ -155,6 +173,20 @@ async def test_send_cloud_event_data_str(self, eventgrid_cloud_event_topic_endpo ) await client.send(cloud_event) + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_send_cloud_event_namespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) + await client.send(cloud_event) + @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio @@ -210,6 +242,21 @@ async def test_send_cloud_event_dict(self, eventgrid_cloud_event_topic_endpoint) } await client.send(cloud_event1) + @pytest.mark.live_test_only + @EventGridPreparer() + @pytest.mark.asyncio + async def test_send_cloud_event_channel_namenamespace(self, **kwargs): + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + cloud_event = CloudEvent( + source="http://samplesource.dev", + data="cloudevent", + type="Sample.Cloud.Event", + ) + with pytest.raises(ValueError): + await client.send(cloud_event, channel_name="testchannel") + @EventGridPreparer() @recorded_by_proxy_async @pytest.mark.asyncio From 1b85d9e9ce915bb8c735b45c19d5cf01e5b675c7 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 10:57:24 -0700 Subject: [PATCH 36/43] updates tests 2 --- .../tests/test_eg_consumer_client.py | 77 ++++++------------ .../tests/test_eg_consumer_client_async.py | 81 ++++++------------- 2 files changed, 50 insertions(+), 108 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py index b04175ed32fc..b0d383e126c0 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py @@ -15,7 +15,6 @@ from devtools_testutils import AzureRecordedTestCase from azure.core.messaging import CloudEvent -from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridConsumerClient, EventGridPublisherClient from eventgrid_preparer import ( EventGridPreparer, @@ -44,19 +43,12 @@ def create_eg_consumer_client(self, endpoint, topic, subscription): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -74,19 +66,12 @@ def test_receive_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_renew_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -105,19 +90,12 @@ def test_receive_renew_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_release_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -135,19 +113,12 @@ def test_receive_release_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_reject_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py index a73452700184..35c87ed73ef4 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py @@ -16,7 +16,6 @@ from devtools_testutils import AzureRecordedTestCase from azure.core.messaging import CloudEvent -from azure.core.credentials import AzureKeyCredential from azure.eventgrid.aio import EventGridConsumerClient, EventGridPublisherClient from eventgrid_preparer import ( EventGridPreparer, @@ -25,14 +24,14 @@ class TestEventGridConsumerClientAsync(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint, topic=None): - credential = self.get_credential(EventGridPublisherClient) + credential = self.get_credential(EventGridPublisherClient, is_async=True) client = self.create_client_from_credential( EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic ) return client def create_eg_consumer_client(self, endpoint, topic, subscription): - credential = self.get_credential(EventGridConsumerClient) + credential = self.get_credential(EventGridConsumerClient, is_async=True) client = self.create_client_from_credential( EventGridConsumerClient, credential=credential, @@ -46,19 +45,12 @@ def create_eg_consumer_client(self, endpoint, topic, subscription): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -77,19 +69,12 @@ async def test_receive_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_renew_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -109,19 +94,12 @@ async def test_receive_renew_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_release_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -140,19 +118,12 @@ async def test_receive_release_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_reject_data(self, **kwargs): - eventgrid_endpoint = kwargs["eventgrid_endpoint"] - eventgrid_key = kwargs["eventgrid_key"] - eventgrid_topic_name = kwargs["eventgrid_topic_name"] - eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + eventgrid_endpoint = kwargs.get("eventgrid_endpoint") + eventgrid_key = kwargs.get("eventgrid_key") + eventgrid_topic_name = kwargs.get("eventgrid_topic_name") + eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, From 1b9ed9b2c2a2be3273b51ea1459b943b2a6e1cfe Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 12:26:38 -0700 Subject: [PATCH 37/43] Revert "updates tests 2" This reverts commit 1b85d9e9ce915bb8c735b45c19d5cf01e5b675c7. --- .../tests/test_eg_consumer_client.py | 77 ++++++++++++------ .../tests/test_eg_consumer_client_async.py | 81 +++++++++++++------ 2 files changed, 108 insertions(+), 50 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py index b0d383e126c0..b04175ed32fc 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py @@ -15,6 +15,7 @@ from devtools_testutils import AzureRecordedTestCase from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential from azure.eventgrid import EventGridConsumerClient, EventGridPublisherClient from eventgrid_preparer import ( EventGridPreparer, @@ -43,12 +44,19 @@ def create_eg_consumer_client(self, endpoint, topic, subscription): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -66,12 +74,19 @@ def test_receive_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_renew_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -90,12 +105,19 @@ def test_receive_renew_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_release_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -113,12 +135,19 @@ def test_receive_release_data(self, **kwargs): @pytest.mark.live_test_only @EventGridPreparer() def test_receive_reject_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py index 35c87ed73ef4..a73452700184 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py @@ -16,6 +16,7 @@ from devtools_testutils import AzureRecordedTestCase from azure.core.messaging import CloudEvent +from azure.core.credentials import AzureKeyCredential from azure.eventgrid.aio import EventGridConsumerClient, EventGridPublisherClient from eventgrid_preparer import ( EventGridPreparer, @@ -24,14 +25,14 @@ class TestEventGridConsumerClientAsync(AzureRecordedTestCase): def create_eg_publisher_client(self, endpoint, topic=None): - credential = self.get_credential(EventGridPublisherClient, is_async=True) + credential = self.get_credential(EventGridPublisherClient) client = self.create_client_from_credential( EventGridPublisherClient, credential=credential, endpoint=endpoint, namespace_topic=topic ) return client def create_eg_consumer_client(self, endpoint, topic, subscription): - credential = self.get_credential(EventGridConsumerClient, is_async=True) + credential = self.get_credential(EventGridConsumerClient) client = self.create_client_from_credential( EventGridConsumerClient, credential=credential, @@ -45,12 +46,19 @@ def create_eg_consumer_client(self, endpoint, topic, subscription): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -69,12 +77,19 @@ async def test_receive_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_renew_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -94,12 +109,19 @@ async def test_receive_renew_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_release_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -118,12 +140,19 @@ async def test_receive_release_data(self, **kwargs): @EventGridPreparer() @pytest.mark.asyncio async def test_receive_reject_data(self, **kwargs): - eventgrid_endpoint = kwargs.get("eventgrid_endpoint") - eventgrid_key = kwargs.get("eventgrid_key") - eventgrid_topic_name = kwargs.get("eventgrid_topic_name") - eventgrid_event_subscription_name = kwargs.get("eventgrid_event_subscription_name") - publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) - consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + eventgrid_endpoint = kwargs["eventgrid_endpoint"] + eventgrid_key = kwargs["eventgrid_key"] + eventgrid_topic_name = kwargs["eventgrid_topic_name"] + eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] + publisher = EventGridPublisherClient( + eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name + ) + consumer = EventGridConsumerClient( + eventgrid_endpoint, + AzureKeyCredential(eventgrid_key), + namespace_topic=eventgrid_topic_name, + subscription=eventgrid_event_subscription_name, + ) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, From 06d4bef9806d0e502777f93a0779615f4f282577 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 12:34:18 -0700 Subject: [PATCH 38/43] try --- .../azure-eventgrid/tests/test_eg_publisher_client.py | 4 ++-- .../azure-eventgrid/tests/test_eg_publisher_client_async.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 1312fc0ab114..270e4c1d76d3 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -21,7 +21,7 @@ from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from azure.core.credentials import AzureSasCredential +from azure.core.credentials import AzureSasCredential, AzureKeyCredential from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas @@ -145,7 +145,7 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): def test_send_event_grid_namespace(self, **kwargs): eventgrid_endpoint = kwargs["eventgrid_endpoint"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] - client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + client = EventGridPublisherClient(eventgrid_endpoint, AzureKeyCredential(kwargs["eventgrid_key"]), namespace_topic=eventgrid_topic_name) eg_event = { "subject": "sample", "data": {"key1": "Sample.EventGrid.Event"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index 729ab18878ef..45688fa6c4a8 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -18,7 +18,7 @@ from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from azure.core.credentials import AzureSasCredential +from azure.core.credentials import AzureSasCredential, AzureKeyCredential from azure.core.messaging import CloudEvent from azure.core.serialization import NULL from azure.eventgrid import EventGridEvent, generate_sas @@ -131,7 +131,7 @@ async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpo async def test_send_event_grid_namespace(self, **kwargs): eventgrid_endpoint = kwargs["eventgrid_endpoint"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] - client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + client = EventGridPublisherClient(eventgrid_endpoint, AzureKeyCredential(kwargs["eventgrid_key"]), namespace_topic=eventgrid_topic_name) eg_event = { "subject": "sample", "data": {"key1": "Sample.EventGrid.Event"}, From e74d7b4394ce3a3fb734d4b0980483f20e4da8f9 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 13:11:39 -0700 Subject: [PATCH 39/43] typeError --- .../azure-eventgrid/azure/eventgrid/_operations/_patch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 317100f730ee..de86c1454880 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -311,8 +311,8 @@ def _serialize_events(events): # Try to serialize CNCF Cloud Events return [_from_cncf_events(e) for e in events] else: - # Does not conform to format, send as is - raise ValueError("Invalid event data. Please check the data is of Cloud Event format and try again.") + # Does not conform to format + raise TypeError("Invalid event data. Please check the data is of Cloud Event type/format and try again.") def _serialize_cloud_event(cloud_event): From a56bf9e8ce612fdaceb00c6749b144138a447c8b Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 4 Jun 2024 13:31:10 -0700 Subject: [PATCH 40/43] missing await --- .../azure-eventgrid/tests/test_eg_publisher_client_async.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index 45688fa6c4a8..f91b0e4aa257 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -141,7 +141,7 @@ async def test_send_event_grid_namespace(self, **kwargs): "eventTime": dt.datetime.now(), } with pytest.raises(TypeError): - client.send(eg_event) + await client.send(eg_event) @EventGridPreparer() @recorded_by_proxy_async From 1cd9f27e53f9b7b1b68933d63cc2a8000f78c565 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Wed, 5 Jun 2024 10:30:57 -0700 Subject: [PATCH 41/43] unused import --- .../azure-eventgrid/azure/eventgrid/_operations/_patch.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index de86c1454880..7f838894136c 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -5,9 +5,7 @@ """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -import json import sys -from functools import wraps from typing import ( Any, Callable, From 4909e832e526d1401311051a0ffdaf5ea43c6849 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Thu, 6 Jun 2024 14:05:46 -0700 Subject: [PATCH 42/43] test rbac (#35953) * test rbac * update * update error msg --- .../azure/eventgrid/_operations/_patch.py | 4 +- .../azure/eventgrid/aio/_operations/_patch.py | 4 +- .../tests/test_eg_consumer_client.py | 47 +++++-------------- .../tests/test_eg_consumer_client_async.py | 44 ++++------------- .../tests/test_eg_publisher_client.py | 2 +- .../tests/test_eg_publisher_client_async.py | 2 +- sdk/eventgrid/test-resources.json | 12 ++++- 7 files changed, 36 insertions(+), 79 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py index 7f838894136c..0606157136ab 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_operations/_patch.py @@ -135,8 +135,8 @@ def _http_response_error_handler(self, exception): if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - "Please check that the tier you are using, corresponds to the correct " - "endpoint and/or topic name." + "For Event Grid Namespaces, please specify the namespace_topic name on the client. " + "For Event Grid Basic, do not specify the namespace_topic name." ) from exception raise exception diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py index d5fefd748437..4cd5f859561d 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_operations/_patch.py @@ -119,8 +119,8 @@ def _http_response_error_handler(self, exception): if exception.status_code == 404: raise ResourceNotFoundError( "Resource not found. " - "Please check that the tier you are using, corresponds to the correct " - "endpoint and/or topic name." + "For Event Grid Namespaces, please specify the namespace_topic name on the client. " + "For Event Grid Basic, do not specify the namespace_topic name." ) from exception raise exception diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py index b04175ed32fc..07798d0b8b35 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client.py @@ -48,15 +48,8 @@ def test_receive_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -78,15 +71,9 @@ def test_receive_renew_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -109,15 +96,9 @@ def test_receive_release_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -139,15 +120,9 @@ def test_receive_reject_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) + cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py index a73452700184..b3bd78a78fdd 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_consumer_client_async.py @@ -50,15 +50,8 @@ async def test_receive_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -81,15 +74,8 @@ async def test_receive_renew_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -113,15 +99,8 @@ async def test_receive_release_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, @@ -144,15 +123,8 @@ async def test_receive_reject_data(self, **kwargs): eventgrid_key = kwargs["eventgrid_key"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] eventgrid_event_subscription_name = kwargs["eventgrid_event_subscription_name"] - publisher = EventGridPublisherClient( - eventgrid_endpoint, AzureKeyCredential(eventgrid_key), namespace_topic=eventgrid_topic_name - ) - consumer = EventGridConsumerClient( - eventgrid_endpoint, - AzureKeyCredential(eventgrid_key), - namespace_topic=eventgrid_topic_name, - subscription=eventgrid_event_subscription_name, - ) + publisher = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) + consumer = self.create_eg_consumer_client(eventgrid_endpoint, eventgrid_topic_name, eventgrid_event_subscription_name) cloud_event = CloudEvent( source="http://samplesource.dev", data={"sample": "cloudevent"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 270e4c1d76d3..b3bdd2aad738 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -145,7 +145,7 @@ def test_send_event_grid_event_dict_data_dict(self, eventgrid_topic_endpoint): def test_send_event_grid_namespace(self, **kwargs): eventgrid_endpoint = kwargs["eventgrid_endpoint"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] - client = EventGridPublisherClient(eventgrid_endpoint, AzureKeyCredential(kwargs["eventgrid_key"]), namespace_topic=eventgrid_topic_name) + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) eg_event = { "subject": "sample", "data": {"key1": "Sample.EventGrid.Event"}, diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index f91b0e4aa257..760e7e81e9d6 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -131,7 +131,7 @@ async def test_send_event_grid_event_dict_data_bytes(self, eventgrid_topic_endpo async def test_send_event_grid_namespace(self, **kwargs): eventgrid_endpoint = kwargs["eventgrid_endpoint"] eventgrid_topic_name = kwargs["eventgrid_topic_name"] - client = EventGridPublisherClient(eventgrid_endpoint, AzureKeyCredential(kwargs["eventgrid_key"]), namespace_topic=eventgrid_topic_name) + client = self.create_eg_publisher_client(eventgrid_endpoint, eventgrid_topic_name) eg_event = { "subject": "sample", "data": {"key1": "Sample.EventGrid.Event"}, diff --git a/sdk/eventgrid/test-resources.json b/sdk/eventgrid/test-resources.json index 92d9078abce6..d54dbcb65e59 100644 --- a/sdk/eventgrid/test-resources.json +++ b/sdk/eventgrid/test-resources.json @@ -38,6 +38,7 @@ "partnerChannelName": "[concat(parameters('baseName'), 'partner-channel')]", "partnerTopicName": "[concat(parameters('baseName'), 'partner-topic')]", "eventGridDataSenderRoleId": "d5a91429-5739-47e2-a06b-3470a27159e7", + "eventGridDataContributorRoleId": "1d8c3fe3-8864-474b-8749-01e3783e8157" }, "resources": [ { @@ -218,8 +219,17 @@ "principalId": "[parameters('testApplicationOid')]", "scope": "[resourceGroup().id]" } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2019-04-01-preview", + "name": "[guid(resourceGroup().id, parameters('testApplicationOid'), variables('eventGridDataContributorRoleId'))]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('eventGridDataContributorRoleId'))]", + "principalId": "[parameters('testApplicationOid')]", + "scope": "[resourceGroup().id]" + } } - ], "outputs": { "EVENTGRID_TOPIC_KEY": { From eea539336e70cd176780a0e48fe284637ba8d391 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Fri, 7 Jun 2024 08:58:45 -0700 Subject: [PATCH 43/43] readme updates --- sdk/eventgrid/azure-eventgrid/README.md | 88 +++++++++---------------- 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 772fa83ed0c9..f6d8bba39a6e 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -2,7 +2,7 @@ Azure Event Grid is a fully-managed intelligent event routing service that allows for uniform event consumption using a publish-subscribe model. -| [Source code][python-eg-src] +[Source code][python-eg-src] | [Package (PyPI)][python-eg-pypi] | [Package (Conda)](https://anaconda.org/microsoft/azure-eventgrid/) | [API reference documentation][python-eg-ref-docs] @@ -57,14 +57,17 @@ In order to interact with the Event Grid service, you will need to create an ins An **endpoint** and **credential** are necessary to instantiate the client object. -The default EventGridPublisherClient created is compatible with an Event Grid Basic Resource. To create an Event Grid Namespace compatible Client, specify `namespace_topic="YOUR_TOPIC_NAME"` when instantiating the client. +The default EventGridPublisherClient created is compatible with an Event Grid Basic Resource. To create an Event Grid Namespace compatible client, specify `namespace_topic="YOUR_TOPIC_NAME"` when instantiating the client. ```python # Event Grid Namespace client client = EventGridPublisherClient(endpoint, credential, namespace_topic=YOUR_TOPIC_NAME) + +# Event Grid Basic Client +client = EventGridPublisherClient(endpoint, credential) ``` -EventGridConsumerClient only supports EventGrid Namespaces. +EventGridConsumerClient only supports Event Grid Namespaces. ```python # Event Grid Namespace Client client = EventGridConsumerClient(endpoint, credential, namespace_topic=YOUR_TOPIC_NAME, subscription=YOUR_SUBSCRIPTION_NAME) @@ -74,9 +77,11 @@ client = EventGridConsumerClient(endpoint, credential, namespace_topic=YOUR_TOPI Azure Event Grid provides integration with Azure Active Directory (Azure AD) for identity-based authentication of requests. With Azure AD, you can use role-based access control (RBAC) to grant access to your Azure Event Grid resources to users, groups, or applications. -To send events to a topic or domain with a `TokenCredential`, the authenticated identity should have the "EventGrid Data Sender" role assigned. -To receive events to a topic with a `TokenCredential`, the authenticated identity should have the "EventGrid Data Receiver" role assigned. -To send and receive events to/from a topic with a `TokenCredential`, the authenticated identity should have the "EventGrid Data Contributor" role assigned. +To send events to a topic or domain with a `TokenCredential`, the authenticated identity should have the "Event Grid Data Sender" role assigned. +To receive events from a topic event subscription with a `TokenCredential`, the authenticated identity should have the "Event Grid Data Receiver" role assigned. +To send and receive events to/from a topic with a `TokenCredential`, the authenticated identity should have the "Event Grid Data Contributor" role assigned. + +More about RBAC setup can be found [here](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-steps). With the `azure-identity` package, you can seamlessly authorize requests in both development and production environments. To learn more about Azure Active Directory, see the [`azure-identity` README](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity/README.md). @@ -134,7 +139,7 @@ client = EventGridPublisherClient(endpoint, credential_key) ## Key concepts -### *Event Grid Namespace* +### Event Grid Namespace A **[namespace](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#namespaces)** is a management container for other resources. It allows for grouping of related resources in order to manage them under one subscription. @@ -147,10 +152,10 @@ A **[namespace topic](https://learn.microsoft.com/azure/event-grid/concepts-even An **[event subscription](https://learn.microsoft.com/azure/event-grid/concepts-event-grid-namespaces#event-subscriptions)** is a configuration resource associated with a single topic. -### *Event Grid Basic* +### Event Grid Basic #### Topic -A **[topic](https://docs.microsoft.com/azure/event-grid/concepts#topics)** is a channel within the EventGrid service to send events. The event schema that a topic accepts is decided at topic creation time. If events of a schema type are sent to a topic that requires a different schema type, errors will be raised. +A **[topic](https://docs.microsoft.com/azure/event-grid/concepts#topics)** is a channel within the Event Grid service to send events. The event schema that a topic accepts is decided at topic creation time. If events of a schema type are sent to a topic that requires a different schema type, errors will be raised. #### Domain An event **[domain](https://docs.microsoft.com/azure/event-grid/event-domains)** is a management tool for large numbers of Event Grid topics related to the same application. They allow you to publish events to thousands of topics. Domains also give you authorization and authentication control over each topic. For more information, visit [Event domain overview](https://docs.microsoft.com/azure/event-grid/event-domains). @@ -174,7 +179,7 @@ For complete list of recognizable system topics, visit [System Topics](https://d If you are using Event Grid Basic, regardless of the schema that your topic or domain is configured to use, `EventGridPublisherClient` will be used to publish events to it. Use the `send` method to publish events. -The following formats of events are allowed to be sent to an EventGrid Basic resource: +The following formats of events are allowed to be sent to an Event Grid Basic resource: - A list or a single instance of strongly typed EventGridEvents. - A dict representation of a serialized EventGridEvent object. - A list or a single instance of strongly typed CloudEvents. @@ -182,7 +187,7 @@ The following formats of events are allowed to be sent to an EventGrid Basic res - A dict representation of any Custom Schema. -The following formats of events are allowed to be sent to an EventGrid Namespace resource, when a namespace topic is specified: +The following formats of events are allowed to be sent to an Event Grid Namespace resource, when a namespace topic is specified: * A list of single instance of strongly typed CloudEvents. * A dict representation of a serialized CloudEvent object. @@ -209,10 +214,10 @@ This example publishes a Cloud event. import os from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient -key = os.environ["EVENTGRID_NAMESPACE_KEY"] -endpoint = os.environ["EVENTGRID_NAMESPACE_ENDPOINT"] +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] topic_name = os.environ["EVENTGRID_TOPIC_NAME"] @@ -223,7 +228,7 @@ event = CloudEvent( ) credential = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential, namespace_topic=topic_name) +client = EventGridPublisherClient(endpoint, credential, namespace_topic=topic_name) client.send(event) ``` @@ -238,10 +243,10 @@ It is possible to send events as a batch when sending multiple events to a topic import os from azure.core.credentials import AzureKeyCredential from azure.core.messaging import CloudEvent -from azure.eventgrid import EventGridClient +from azure.eventgrid import EventGridPublisherClient -key = os.environ["EVENTGRID_NAMESPACE_KEY"] -endpoint = os.environ["EVENTGRID_NAMESPACE_ENDPOINT"] +key = os.environ["EVENTGRID_KEY"] +endpoint = os.environ["EVENTGRID_ENDPOINT"] topic_name = os.environ["EVENTGRID_TOPIC_NAME"] event0 = CloudEvent( @@ -258,14 +263,14 @@ event1 = CloudEvent( events = [event0, event1] credential = AzureKeyCredential(key) -client = EventGridClient(endpoint, credential, namespace_topic=topic_name) +client = EventGridPublisherClient(endpoint, credential, namespace_topic=topic_name) client.send(events) ``` ### Receive and Process Events from Namespace -Use EventGridClient's receive function to receive CloudEvents from a Namespace event subscription. Then try to acknowledge, reject, release or renew the locks. +Use EventGridConsumerClient's receive function to receive CloudEvents from a Namespace event subscription. Then try to acknowledge, reject, release or renew the locks. ```python import os @@ -315,40 +320,13 @@ reject_result = client.reject( ``` -### Legacy EventGrid operations -#### Send an Event Grid Event - - -This example publishes an Event Grid event. - -```python -import os -from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, EventGridEvent - -key = os.environ["EG_ACCESS_KEY"] -endpoint = os.environ["EG_TOPIC_HOSTNAME"] - -event = EventGridEvent( - data={"team": "azure-sdk"}, - subject="Door1", - event_type="Azure.Sdk.Demo", - data_version="2.0" -) - -credential = AzureKeyCredential(key) -client = EventGridPublisherClient(endpoint, credential) - -client.send(event) -``` - -## Distributed Tracing with EventGrid +## Distributed Tracing with Event Grid -You can use OpenTelemetry for Python as usual with EventGrid since it's compatible with azure-core tracing integration. +You can use OpenTelemetry for Python as usual with Event Grid since it's compatible with azure-core tracing integration. Here is an example of using OpenTelemetry to trace sending a CloudEvent. -First, set OpenTelemetry as enabled tracing plugin for EventGrid. +First, set OpenTelemetry as enabled tracing plugin for Event Grid. ```python from azure.core.settings import settings @@ -423,13 +401,7 @@ The following section provides several code snippets illustrating common pattern These code samples show common champion scenario operations with the Azure Event Grid client library. -#### Namespaces EventGrid Scenarios - -* Authenticate the client: [sample_authentication.py][python-eg-auth] -* Sample of all operations: [sample_all_operations.py][python-eg-client-all-ops-sample] -* Publish cloud event in binary mode: [sample_binary_mode_operation.py][python-eg-client-binary-mode-sample] - -#### Basic EventGrid Scenarios +#### Basic Event Grid Scenarios * Generate Shared Access Signature: [sample_generate_sas.py][python-eg-generate-sas] @@ -437,7 +409,7 @@ These code samples show common champion scenario operations with the Azure Event * Publish events to a topic using SAS: [sample_publish_events_to_a_topic_using_sas_credential_async.py][python-eg-sample-send-using-sas] ([async_version][python-eg-sample-send-using-sas-async]) * Publish Event Grid Events to a topic: [sample_publish_eg_events_to_a_topic.py][python-eg-sample-eg-event] ([async_version][python-eg-sample-eg-event-async]) -* Publish EventGrid Events to a domain topic: [sample_publish_eg_events_to_a_domain_topic.py][python-eg-sample-eg-event-to-domain] ([async_version][python-eg-sample-eg-event-to-domain-async]) +* Publish Event Grid Events to a domain topic: [sample_publish_eg_events_to_a_domain_topic.py][python-eg-sample-eg-event-to-domain] ([async_version][python-eg-sample-eg-event-to-domain-async]) * Publish a Cloud Event: [sample_publish_events_using_cloud_events_1.0_schema.py][python-eg-sample-send-cloudevent] ([async_version][python-eg-sample-send-cloudevent-async]) * Publish a Custom Schema: [sample_publish_custom_schema_to_a_topic.py][python-eg-publish-custom-schema] ([async_version][python-eg-publish-custom-schema-async])