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",