From 2b8283ed7854bec0d0b0c0baad8175ff3e79fe77 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 23 Jun 2021 12:36:05 -0700 Subject: [PATCH 1/9] Improved error message in the `from_dict` --- sdk/core/azure-core/CHANGELOG.md | 3 ++ sdk/core/azure-core/azure/core/messaging.py | 10 ++++++ .../tests/test_messaging_cloud_event.py | 34 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md index 10e242697b12..ff3163d6f9b4 100644 --- a/sdk/core/azure-core/CHANGELOG.md +++ b/sdk/core/azure-core/CHANGELOG.md @@ -2,6 +2,9 @@ ## 1.15.1 (Unreleased) +### Bug Fixes + +- Improved error message in the `from_dict` method of `CloudEvent` when a wrong schema is sent. ## 1.15.0 (2021-06-04) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 9131a7b46d69..0a285dd64bcd 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -122,6 +122,16 @@ def from_dict(cls, event): :type event: dict :rtype: CloudEvent """ + if not all([_ in event for _ in ("source", "type")]): + if all([_ in event for _ in (("subject", "eventType", "data", "dataVersion", "id", "eventTime"))]): + raise ValueError( + "The event does not conform to the cloud event spec." + + " Try using the EventGridEvent from azure-eventgrid library" + ) + raise ValueError( + "The event does not conform to the cloud event spec. source and type are required." + ) + kwargs = {} # type: Dict[Any, Any] reserved_attr = [ "data", diff --git a/sdk/core/azure-core/tests/test_messaging_cloud_event.py b/sdk/core/azure-core/tests/test_messaging_cloud_event.py index c82fa4f55370..8cf7a4d705bd 100644 --- a/sdk/core/azure-core/tests/test_messaging_cloud_event.py +++ b/sdk/core/azure-core/tests/test_messaging_cloud_event.py @@ -436,3 +436,37 @@ def test_cloud_custom_dict_ms_precision_is_eq_six_z_not(): assert date_obj.day == 18 assert date_obj.hour == 20 assert date_obj.microsecond == 123456 + +def test_eventgrid_event_schema_raises(): + cloud_custom_dict = { + "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "data":{"team": "event grid squad"}, + "dataVersion": "1.0", + "subject":"Azure.Sdk.Sample", + "eventTime":"2020-08-07T02:06:08.11969Z", + "eventType":"pull request", + } + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. Try using the EventGridEvent from azure-eventgrid library"): + CloudEvent.from_dict(cloud_custom_dict) + +def test_wrong_schema_raises_no_source(): + cloud_custom_dict = { + "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "data":{"team": "event grid squad"}, + "type":"Azure.Sdk.Sample", + "time":"2020-08-07T02:06:08.11969Z", + "specversion":"1.0", + } + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. source and type are required."): + CloudEvent.from_dict(cloud_custom_dict) + +def test_wrong_schema_raises_no_type(): + cloud_custom_dict = { + "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "data":{"team": "event grid squad"}, + "source":"Azure/Sdk/Sample", + "time":"2020-08-07T02:06:08.11969Z", + "specversion":"1.0", + } + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. source and type are required."): + CloudEvent.from_dict(cloud_custom_dict) \ No newline at end of file From e3fc8e6f991be3112e1a822e2c6b2351ccf28599 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 23 Jun 2021 14:09:17 -0700 Subject: [PATCH 2/9] lint --- sdk/core/azure-core/azure/core/messaging.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 0a285dd64bcd..96f9caac57e5 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -122,10 +122,12 @@ def from_dict(cls, event): :type event: dict :rtype: CloudEvent """ + # https://github.com/cloudevents/spec Cloud event spec requires source, type, + # specversion. We autopopulate everything other than source, type. if not all([_ in event for _ in ("source", "type")]): - if all([_ in event for _ in (("subject", "eventType", "data", "dataVersion", "id", "eventTime"))]): + if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): raise ValueError( - "The event does not conform to the cloud event spec." + + "The event does not conform to the cloud event spec." + " Try using the EventGridEvent from azure-eventgrid library" ) raise ValueError( From f09c3c8db451772abeb716cb565dc4603eb29760 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 23 Jun 2021 14:11:34 -0700 Subject: [PATCH 3/9] spec lin --- sdk/core/azure-core/azure/core/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 96f9caac57e5..68f52d1de781 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -127,7 +127,7 @@ def from_dict(cls, event): if not all([_ in event for _ in ("source", "type")]): if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): raise ValueError( - "The event does not conform to the cloud event spec." + + "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + " Try using the EventGridEvent from azure-eventgrid library" ) raise ValueError( From 18b3999f56b228627bbe9461d99508c2f9b3be15 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 23 Jun 2021 14:46:52 -0700 Subject: [PATCH 4/9] tests --- sdk/core/azure-core/azure/core/messaging.py | 3 ++- sdk/core/azure-core/tests/test_messaging_cloud_event.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 68f52d1de781..a9c33beb31e0 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -131,7 +131,8 @@ def from_dict(cls, event): " Try using the EventGridEvent from azure-eventgrid library" ) raise ValueError( - "The event does not conform to the cloud event spec. source and type are required." + "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + + " source and type are required." ) kwargs = {} # type: Dict[Any, Any] diff --git a/sdk/core/azure-core/tests/test_messaging_cloud_event.py b/sdk/core/azure-core/tests/test_messaging_cloud_event.py index 8cf7a4d705bd..fcbf1f52185b 100644 --- a/sdk/core/azure-core/tests/test_messaging_cloud_event.py +++ b/sdk/core/azure-core/tests/test_messaging_cloud_event.py @@ -446,7 +446,7 @@ def test_eventgrid_event_schema_raises(): "eventTime":"2020-08-07T02:06:08.11969Z", "eventType":"pull request", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. Try using the EventGridEvent from azure-eventgrid library"): + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. Try using the EventGridEvent from azure-eventgrid library"): CloudEvent.from_dict(cloud_custom_dict) def test_wrong_schema_raises_no_source(): @@ -457,7 +457,7 @@ def test_wrong_schema_raises_no_source(): "time":"2020-08-07T02:06:08.11969Z", "specversion":"1.0", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. source and type are required."): + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. source and type are required."): CloudEvent.from_dict(cloud_custom_dict) def test_wrong_schema_raises_no_type(): @@ -468,5 +468,5 @@ def test_wrong_schema_raises_no_type(): "time":"2020-08-07T02:06:08.11969Z", "specversion":"1.0", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec. source and type are required."): + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. source and type are required."): CloudEvent.from_dict(cloud_custom_dict) \ No newline at end of file From 1cc83d9f91fa789d599748d43c5ebe434a4dce0a Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 23 Jun 2021 15:47:18 -0700 Subject: [PATCH 5/9] Add AAD support --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 4 ++- sdk/eventgrid/azure-eventgrid/README.md | 28 +++++++++++++++ .../azure/eventgrid/_constants.py | 1 + .../azure/eventgrid/_helpers.py | 11 ++++-- .../azure/eventgrid/_publisher_client.py | 9 ++--- .../azure/eventgrid/_version.py | 2 +- .../azure/eventgrid/aio/_helpers_async.py | 34 +++++++++++++++++++ .../eventgrid/aio/_publisher_client_async.py | 16 +++++---- .../sample_authentication_async.py | 17 ++++++++++ .../sync_samples/sample_authentication.py | 16 +++++++++ .../tests/test_eg_publisher_client.py | 14 ++++++++ .../tests/test_eg_publisher_client_async.py | 17 +++++++++- 12 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index cc404231f475..a62f996fb727 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,9 +1,11 @@ # Release History -## 4.3.1 (Unreleased) +## 4.4.0 (Unreleased) ### Features Added +- `EventGridPublisherClient` now supports Azure Active Directory (AAD) for authentication. + ### Breaking Changes ### Key Bugs Fixed diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 713b1f75e622..622ae9a12e4a 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -38,6 +38,34 @@ az eventgrid domain --create --location --resource-group ..eventgrid.azure.net/api/events"` diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py index 0d26f09c4bdb..c246323f9476 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- +DEFAULT_EVENTGRID_SCOPE = "https://eventgrid.azure.net/.default" EVENTGRID_KEY_HEADER = "aeg-sas-key" EVENTGRID_TOKEN_HEADER = "aeg-sas-token" DEFAULT_API_VERSION = "2018-01-01" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py index bc7b15bf089f..fb1e0f2f4435 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py @@ -16,7 +16,7 @@ from msrest import Serializer from azure.core.pipeline.transport import HttpRequest -from azure.core.pipeline.policies import AzureKeyCredentialPolicy +from azure.core.pipeline.policies import AzureKeyCredentialPolicy, BearerTokenCredentialPolicy from azure.core.credentials import AzureKeyCredential, AzureSasCredential from ._signature_credential_policy import EventGridSasCredentialPolicy from . import _constants as constants @@ -27,7 +27,7 @@ if TYPE_CHECKING: from datetime import datetime - + from azure.core.credentials import TokenCredential def generate_sas(endpoint, shared_access_key, expiration_date_utc, **kwargs): # type: (str, str, datetime, Any) -> str @@ -73,6 +73,11 @@ def _generate_hmac(key, message): def _get_authentication_policy(credential): if credential is None: raise ValueError("Parameter 'self._credential' must not be None.") + if isinstance(credential, TokenCredential): + return BearerTokenCredentialPolicy( + credential, + scopes=constants.DEFAULT_EVENTGRID_SCOPE + ) if isinstance(credential, AzureKeyCredential): return AzureKeyCredentialPolicy( credential=credential, name=constants.EVENTGRID_KEY_HEADER @@ -82,7 +87,7 @@ def _get_authentication_policy(credential): credential=credential, name=constants.EVENTGRID_TOKEN_HEADER ) raise ValueError( - "The provided credential should be an instance of AzureSasCredential or AzureKeyCredential" + "The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential" ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py index 9c9b6abcec4b..6e7eb1b0ee18 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from azure.core.credentials import AzureKeyCredential, AzureSasCredential + from azure.core.credentials import AzureKeyCredential, AzureSasCredential, TokenCredential SendType = Union[ CloudEvent, @@ -60,8 +60,9 @@ class EventGridPublisherClient(object): :param str endpoint: The topic endpoint to send the events to. :param credential: The credential object used for authentication which - implements SAS key authentication or SAS token authentication. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential + implements SAS key authentication or SAS token authentication or a TokenCredential. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + ~azure.core.credentials.TokenCredential :rtype: None .. admonition:: Example: @@ -82,7 +83,7 @@ class EventGridPublisherClient(object): """ def __init__(self, endpoint, credential, **kwargs): - # type: (str, Union[AzureKeyCredential, AzureSasCredential], Any) -> None + # type: (str, Union[AzureKeyCredential, AzureSasCredential, TokenCredential], Any) -> None self._endpoint = endpoint self._client = EventGridPublisherClientImpl( policies=EventGridPublisherClient._policies(credential, **kwargs), **kwargs diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index 6d23ac4acdeb..b5234b1c4677 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -9,4 +9,4 @@ # regenerated. # -------------------------------------------------------------------------- -VERSION = "4.3.1" +VERSION = "4.4.0" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py new file mode 100644 index 000000000000..f6e6b9a164d5 --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py @@ -0,0 +1,34 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +from typing import TYPE_CHECKING +from azure.core.pipeline.policies import AzureKeyCredentialPolicy, AsyncBearerTokenCredentialPolicy +from azure.core.credentials import AzureKeyCredential, AzureSasCredential + +from .. import _constants as constants +from .._signature_credential_policy import EventGridSasCredentialPolicy + +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential + + +def _get_authentication_policy_async(credential): + if credential is None: + raise ValueError("Parameter 'self._credential' must not be None.") + if isinstance(credential, AsyncTokenCredential): + return AsyncBearerTokenCredentialPolicy( + credential, + scopes=constants.DEFAULT_EVENTGRID_SCOPE + ) + if isinstance(credential, AzureKeyCredential): + return AzureKeyCredentialPolicy( + credential=credential, name=constants.EVENTGRID_KEY_HEADER + ) + if isinstance(credential, AzureSasCredential): + return EventGridSasCredentialPolicy( + credential=credential, name=constants.EVENTGRID_TOKEN_HEADER + ) + raise ValueError( + "The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential" + ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py index 7846bb27aae4..0539afe0d1de 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, Union, List, Dict, cast +from typing import Any, Union, List, Dict, TYPE_CHECKING, cast from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.messaging import CloudEvent @@ -23,10 +23,10 @@ HttpLoggingPolicy, UserAgentPolicy, ) +from ._helpers_async import _get_authentication_policy_async from .._policies import CloudEventDistributedTracingPolicy from .._models import EventGridEvent from .._helpers import ( - _get_authentication_policy, _is_cloud_event, _is_eventgrid_event, _eventgrid_data_typecheck, @@ -36,6 +36,9 @@ from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync from .._version import VERSION +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential + SendType = Union[ CloudEvent, EventGridEvent, Dict, List[CloudEvent], List[EventGridEvent], List[Dict] ] @@ -49,8 +52,9 @@ class EventGridPublisherClient: :param str endpoint: The topic endpoint to send the events to. :param credential: The credential object used for authentication which implements - SAS key authentication or SAS token authentication. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential + SAS key authentication or SAS token authentication or an AsyncTokenCredential. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or + ~azure.core.credentials_async.AsyncTokenCredential :rtype: None .. admonition:: Example: @@ -73,7 +77,7 @@ class EventGridPublisherClient: def __init__( self, endpoint: str, - credential: Union[AzureKeyCredential, AzureSasCredential], + credential: Union[AzureKeyCredential, AzureSasCredential, AsyncTokenCredential], **kwargs: Any ) -> None: self._client = EventGridPublisherClientAsync( @@ -85,7 +89,7 @@ def __init__( def _policies( credential: Union[AzureKeyCredential, AzureSasCredential], **kwargs: Any ) -> List[Any]: - auth_policy = _get_authentication_policy(credential) + auth_policy = _get_authentication_policy_async(credential) sdk_moniker = "eventgridpublisherclient/{}".format(VERSION) policies = [ RequestIdPolicy(**kwargs), 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 99480bb2e3bc..efe9df4efebe 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 @@ -38,3 +38,20 @@ credential = AzureSasCredential(signature) client = EventGridPublisherClient(endpoint, credential) # [END client_auth_with_sas_cred_async] + +# [START client_auth_with_token_cred_async] +from azure.identity.aio import DefaultAzureCredential +from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid import EventGridEvent + +event = EventGridEvent( + data={"team": "azure-sdk"}, + subject="Door1", + event_type="Azure.Sdk.Demo", + data_version="2.0" +) + +credential = DefaultAzureCredential() +endpoint = os.environ["EG_TOPIC_HOSTNAME"] +client = EventGridPublisherClient(endpoint, credential) +# [END client_auth_with_token_cred_async] \ No newline at end of file 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 5751bd14ed70..cbac75ae9ab5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py @@ -38,3 +38,19 @@ credential = AzureSasCredential(signature) client = EventGridPublisherClient(endpoint, credential) # [END client_auth_with_sas_cred] + +# [START client_auth_with_token_cred] +from azure.identity import DefaultAzureCredential +from azure.eventgrid import EventGridPublisherClient, EventGridEvent + +event = EventGridEvent( + data={"team": "azure-sdk"}, + subject="Door1", + event_type="Azure.Sdk.Demo", + data_version="2.0" +) + +credential = DefaultAzureCredential() +endpoint = os.environ["EG_TOPIC_HOSTNAME"] +client = EventGridPublisherClient(endpoint, credential) +# [END client_auth_with_token_cred] \ No newline at end of file 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 27af5f816442..ab64fc5c4bf5 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -8,6 +8,7 @@ import sys import os import json +from azure.identity import DefaultAzureCredential import pytest import uuid from datetime import datetime, timedelta @@ -345,3 +346,16 @@ def test_send_throws_with_bad_credential(self): bad_credential = "I am a bad credential" with pytest.raises(ValueError, match="The provided credential should be an instance of AzureSasCredential or AzureKeyCredential"): client = EventGridPublisherClient("eventgrid_endpoint", bad_credential) + + @CachedResourceGroupPreparer(name_prefix='eventgridtest') + @CachedEventGridTopicPreparer(name_prefix='eventgridtest') + def test_send_signature_credential(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): + credential = DefaultAzureCredential() + client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) + eg_event = EventGridEvent( + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0" + ) + client.send(eg_event) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index 656c0c7fa0db..b3bd497424c5 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -9,6 +9,7 @@ import sys import os import json +from azure.identity.aio import DefaultAzureCredential import pytest from datetime import timedelta from msrest.serialization import UTC @@ -328,4 +329,18 @@ async def test_send_and_close_async_session(self, resource_group, eventgrid_topi @pytest.mark.asyncio def test_send_NONE_credential_async(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): - client = EventGridPublisherClient(eventgrid_topic_endpoint, None) \ No newline at end of file + client = EventGridPublisherClient(eventgrid_topic_endpoint, None) + + @CachedResourceGroupPreparer(name_prefix='eventgridtest') + @CachedEventGridTopicPreparer(name_prefix='eventgridtest') + @pytest.mark.asyncio + async def test_send_signature_credential(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): + credential = DefaultAzureCredential() + client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) + eg_event = EventGridEvent( + subject="sample", + data={"sample": "eventgridevent"}, + event_type="Sample.EventGrid.Event", + data_version="2.0" + ) + await client.send(eg_event) \ No newline at end of file From 3091e9cf7941cff525110ae9619ccfdb328064fa Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Fri, 25 Jun 2021 16:15:07 -0700 Subject: [PATCH 6/9] eafp --- sdk/core/azure-core/azure/core/messaging.py | 43 ++++++++++--------- .../tests/test_messaging_cloud_event.py | 3 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index a9c33beb31e0..3277f590eabb 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -122,19 +122,6 @@ def from_dict(cls, event): :type event: dict :rtype: CloudEvent """ - # https://github.com/cloudevents/spec Cloud event spec requires source, type, - # specversion. We autopopulate everything other than source, type. - if not all([_ in event for _ in ("source", "type")]): - if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): - raise ValueError( - "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + - " Try using the EventGridEvent from azure-eventgrid library" - ) - raise ValueError( - "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + - " source and type are required." - ) - kwargs = {} # type: Dict[Any, Any] reserved_attr = [ "data", @@ -171,11 +158,25 @@ def from_dict(cls, event): if extensions: kwargs["extensions"] = extensions - return cls( - id=event.get("id"), - source=event["source"], - type=event["type"], - specversion=event.get("specversion"), - time=_convert_to_isoformat(event.get("time")), - **kwargs - ) + try: + return cls( + id=event.get("id"), + source=event["source"], + type=event["type"], + specversion=event.get("specversion"), + time=_convert_to_isoformat(event.get("time")), + **kwargs + ) + except KeyError: + # https://github.com/cloudevents/spec Cloud event spec requires source, type, + # specversion. We autopopulate everything other than source, type. + if not all([_ in event for _ in ("source", "type")]): + if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): + raise ValueError( + "It looks like your event is of EventGrid schema. You can parse EventGrid events " + + "using EventGridEvent.from_dict of the azure-eventgrid library." + ) + raise ValueError( + "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + + " source and type are required." + ) diff --git a/sdk/core/azure-core/tests/test_messaging_cloud_event.py b/sdk/core/azure-core/tests/test_messaging_cloud_event.py index fcbf1f52185b..0fe853f809f0 100644 --- a/sdk/core/azure-core/tests/test_messaging_cloud_event.py +++ b/sdk/core/azure-core/tests/test_messaging_cloud_event.py @@ -446,8 +446,7 @@ def test_eventgrid_event_schema_raises(): "eventTime":"2020-08-07T02:06:08.11969Z", "eventType":"pull request", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. Try using the EventGridEvent from azure-eventgrid library"): - CloudEvent.from_dict(cloud_custom_dict) + with pytest.raises(ValueError, match="It looks like your event is of EventGrid schema. You can parse EventGrid events using EventGridEvent.from_dict of the azure-eventgrid library.") def test_wrong_schema_raises_no_source(): cloud_custom_dict = { From 53660ec80e88310545beb8c173ed67692ffce298 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Fri, 25 Jun 2021 16:18:22 -0700 Subject: [PATCH 7/9] Revert "Add AAD support" This reverts commit 1cc83d9f91fa789d599748d43c5ebe434a4dce0a. --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 4 +-- sdk/eventgrid/azure-eventgrid/README.md | 28 --------------- .../azure/eventgrid/_constants.py | 1 - .../azure/eventgrid/_helpers.py | 11 ++---- .../azure/eventgrid/_publisher_client.py | 9 +++-- .../azure/eventgrid/_version.py | 2 +- .../azure/eventgrid/aio/_helpers_async.py | 34 ------------------- .../eventgrid/aio/_publisher_client_async.py | 16 ++++----- .../sample_authentication_async.py | 17 ---------- .../sync_samples/sample_authentication.py | 16 --------- .../tests/test_eg_publisher_client.py | 14 -------- .../tests/test_eg_publisher_client_async.py | 17 +--------- 12 files changed, 16 insertions(+), 153 deletions(-) delete mode 100644 sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index a62f996fb727..cc404231f475 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -1,11 +1,9 @@ # Release History -## 4.4.0 (Unreleased) +## 4.3.1 (Unreleased) ### Features Added -- `EventGridPublisherClient` now supports Azure Active Directory (AAD) for authentication. - ### Breaking Changes ### Key Bugs Fixed diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 622ae9a12e4a..713b1f75e622 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -38,34 +38,6 @@ az eventgrid domain --create --location --resource-group ..eventgrid.azure.net/api/events"` diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py index c246323f9476..0d26f09c4bdb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_constants.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -DEFAULT_EVENTGRID_SCOPE = "https://eventgrid.azure.net/.default" EVENTGRID_KEY_HEADER = "aeg-sas-key" EVENTGRID_TOKEN_HEADER = "aeg-sas-token" DEFAULT_API_VERSION = "2018-01-01" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py index fb1e0f2f4435..bc7b15bf089f 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py @@ -16,7 +16,7 @@ from msrest import Serializer from azure.core.pipeline.transport import HttpRequest -from azure.core.pipeline.policies import AzureKeyCredentialPolicy, BearerTokenCredentialPolicy +from azure.core.pipeline.policies import AzureKeyCredentialPolicy from azure.core.credentials import AzureKeyCredential, AzureSasCredential from ._signature_credential_policy import EventGridSasCredentialPolicy from . import _constants as constants @@ -27,7 +27,7 @@ if TYPE_CHECKING: from datetime import datetime - from azure.core.credentials import TokenCredential + def generate_sas(endpoint, shared_access_key, expiration_date_utc, **kwargs): # type: (str, str, datetime, Any) -> str @@ -73,11 +73,6 @@ def _generate_hmac(key, message): def _get_authentication_policy(credential): if credential is None: raise ValueError("Parameter 'self._credential' must not be None.") - if isinstance(credential, TokenCredential): - return BearerTokenCredentialPolicy( - credential, - scopes=constants.DEFAULT_EVENTGRID_SCOPE - ) if isinstance(credential, AzureKeyCredential): return AzureKeyCredentialPolicy( credential=credential, name=constants.EVENTGRID_KEY_HEADER @@ -87,7 +82,7 @@ def _get_authentication_policy(credential): credential=credential, name=constants.EVENTGRID_TOKEN_HEADER ) raise ValueError( - "The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential" + "The provided credential should be an instance of AzureSasCredential or AzureKeyCredential" ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py index 6e7eb1b0ee18..9c9b6abcec4b 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from azure.core.credentials import AzureKeyCredential, AzureSasCredential, TokenCredential + from azure.core.credentials import AzureKeyCredential, AzureSasCredential SendType = Union[ CloudEvent, @@ -60,9 +60,8 @@ class EventGridPublisherClient(object): :param str endpoint: The topic endpoint to send the events to. :param credential: The credential object used for authentication which - implements SAS key authentication or SAS token authentication or a TokenCredential. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or - ~azure.core.credentials.TokenCredential + implements SAS key authentication or SAS token authentication. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential :rtype: None .. admonition:: Example: @@ -83,7 +82,7 @@ class EventGridPublisherClient(object): """ def __init__(self, endpoint, credential, **kwargs): - # type: (str, Union[AzureKeyCredential, AzureSasCredential, TokenCredential], Any) -> None + # type: (str, Union[AzureKeyCredential, AzureSasCredential], Any) -> None self._endpoint = endpoint self._client = EventGridPublisherClientImpl( policies=EventGridPublisherClient._policies(credential, **kwargs), **kwargs diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py index b5234b1c4677..6d23ac4acdeb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_version.py @@ -9,4 +9,4 @@ # regenerated. # -------------------------------------------------------------------------- -VERSION = "4.4.0" +VERSION = "4.3.1" diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py deleted file mode 100644 index f6e6b9a164d5..000000000000 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_helpers_async.py +++ /dev/null @@ -1,34 +0,0 @@ -# -------------------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# -------------------------------------------------------------------------------------------- -from typing import TYPE_CHECKING -from azure.core.pipeline.policies import AzureKeyCredentialPolicy, AsyncBearerTokenCredentialPolicy -from azure.core.credentials import AzureKeyCredential, AzureSasCredential - -from .. import _constants as constants -from .._signature_credential_policy import EventGridSasCredentialPolicy - -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential - - -def _get_authentication_policy_async(credential): - if credential is None: - raise ValueError("Parameter 'self._credential' must not be None.") - if isinstance(credential, AsyncTokenCredential): - return AsyncBearerTokenCredentialPolicy( - credential, - scopes=constants.DEFAULT_EVENTGRID_SCOPE - ) - if isinstance(credential, AzureKeyCredential): - return AzureKeyCredentialPolicy( - credential=credential, name=constants.EVENTGRID_KEY_HEADER - ) - if isinstance(credential, AzureSasCredential): - return EventGridSasCredentialPolicy( - credential=credential, name=constants.EVENTGRID_TOKEN_HEADER - ) - raise ValueError( - "The provided credential should be an instance of a TokenCredential, AzureSasCredential or AzureKeyCredential" - ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py index 0539afe0d1de..7846bb27aae4 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py @@ -6,7 +6,7 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, Union, List, Dict, TYPE_CHECKING, cast +from typing import Any, Union, List, Dict, cast from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.messaging import CloudEvent @@ -23,10 +23,10 @@ HttpLoggingPolicy, UserAgentPolicy, ) -from ._helpers_async import _get_authentication_policy_async from .._policies import CloudEventDistributedTracingPolicy from .._models import EventGridEvent from .._helpers import ( + _get_authentication_policy, _is_cloud_event, _is_eventgrid_event, _eventgrid_data_typecheck, @@ -36,9 +36,6 @@ from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync from .._version import VERSION -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential - SendType = Union[ CloudEvent, EventGridEvent, Dict, List[CloudEvent], List[EventGridEvent], List[Dict] ] @@ -52,9 +49,8 @@ class EventGridPublisherClient: :param str endpoint: The topic endpoint to send the events to. :param credential: The credential object used for authentication which implements - SAS key authentication or SAS token authentication or an AsyncTokenCredential. - :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential or - ~azure.core.credentials_async.AsyncTokenCredential + SAS key authentication or SAS token authentication. + :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.AzureSasCredential :rtype: None .. admonition:: Example: @@ -77,7 +73,7 @@ class EventGridPublisherClient: def __init__( self, endpoint: str, - credential: Union[AzureKeyCredential, AzureSasCredential, AsyncTokenCredential], + credential: Union[AzureKeyCredential, AzureSasCredential], **kwargs: Any ) -> None: self._client = EventGridPublisherClientAsync( @@ -89,7 +85,7 @@ def __init__( def _policies( credential: Union[AzureKeyCredential, AzureSasCredential], **kwargs: Any ) -> List[Any]: - auth_policy = _get_authentication_policy_async(credential) + auth_policy = _get_authentication_policy(credential) sdk_moniker = "eventgridpublisherclient/{}".format(VERSION) policies = [ RequestIdPolicy(**kwargs), 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 efe9df4efebe..99480bb2e3bc 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 @@ -38,20 +38,3 @@ credential = AzureSasCredential(signature) client = EventGridPublisherClient(endpoint, credential) # [END client_auth_with_sas_cred_async] - -# [START client_auth_with_token_cred_async] -from azure.identity.aio import DefaultAzureCredential -from azure.eventgrid.aio import EventGridPublisherClient -from azure.eventgrid import EventGridEvent - -event = EventGridEvent( - data={"team": "azure-sdk"}, - subject="Door1", - event_type="Azure.Sdk.Demo", - data_version="2.0" -) - -credential = DefaultAzureCredential() -endpoint = os.environ["EG_TOPIC_HOSTNAME"] -client = EventGridPublisherClient(endpoint, credential) -# [END client_auth_with_token_cred_async] \ No newline at end of file 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 cbac75ae9ab5..5751bd14ed70 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_authentication.py @@ -38,19 +38,3 @@ credential = AzureSasCredential(signature) client = EventGridPublisherClient(endpoint, credential) # [END client_auth_with_sas_cred] - -# [START client_auth_with_token_cred] -from azure.identity import DefaultAzureCredential -from azure.eventgrid import EventGridPublisherClient, EventGridEvent - -event = EventGridEvent( - data={"team": "azure-sdk"}, - subject="Door1", - event_type="Azure.Sdk.Demo", - data_version="2.0" -) - -credential = DefaultAzureCredential() -endpoint = os.environ["EG_TOPIC_HOSTNAME"] -client = EventGridPublisherClient(endpoint, credential) -# [END client_auth_with_token_cred] \ No newline at end of file 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 ab64fc5c4bf5..27af5f816442 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -8,7 +8,6 @@ import sys import os import json -from azure.identity import DefaultAzureCredential import pytest import uuid from datetime import datetime, timedelta @@ -346,16 +345,3 @@ def test_send_throws_with_bad_credential(self): bad_credential = "I am a bad credential" with pytest.raises(ValueError, match="The provided credential should be an instance of AzureSasCredential or AzureKeyCredential"): client = EventGridPublisherClient("eventgrid_endpoint", bad_credential) - - @CachedResourceGroupPreparer(name_prefix='eventgridtest') - @CachedEventGridTopicPreparer(name_prefix='eventgridtest') - def test_send_signature_credential(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): - credential = DefaultAzureCredential() - client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) - eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) - client.send(eg_event) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index b3bd497424c5..656c0c7fa0db 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -9,7 +9,6 @@ import sys import os import json -from azure.identity.aio import DefaultAzureCredential import pytest from datetime import timedelta from msrest.serialization import UTC @@ -329,18 +328,4 @@ async def test_send_and_close_async_session(self, resource_group, eventgrid_topi @pytest.mark.asyncio def test_send_NONE_credential_async(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): with pytest.raises(ValueError, match="Parameter 'self._credential' must not be None."): - client = EventGridPublisherClient(eventgrid_topic_endpoint, None) - - @CachedResourceGroupPreparer(name_prefix='eventgridtest') - @CachedEventGridTopicPreparer(name_prefix='eventgridtest') - @pytest.mark.asyncio - async def test_send_signature_credential(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): - credential = DefaultAzureCredential() - client = EventGridPublisherClient(eventgrid_topic_endpoint, credential) - eg_event = EventGridEvent( - subject="sample", - data={"sample": "eventgridevent"}, - event_type="Sample.EventGrid.Event", - data_version="2.0" - ) - await client.send(eg_event) \ No newline at end of file + client = EventGridPublisherClient(eventgrid_topic_endpoint, None) \ No newline at end of file From b43d1a36808ea278987988804edcb75ddd44099d Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Fri, 25 Jun 2021 16:49:22 -0700 Subject: [PATCH 8/9] language --- sdk/core/azure-core/azure/core/messaging.py | 6 +++--- sdk/core/azure-core/tests/test_messaging_cloud_event.py | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 3277f590eabb..0e6a01394e9c 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -173,10 +173,10 @@ def from_dict(cls, event): if not all([_ in event for _ in ("source", "type")]): if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): raise ValueError( - "It looks like your event is of EventGrid schema. You can parse EventGrid events " + - "using EventGridEvent.from_dict of the azure-eventgrid library." + "The event you are trying to parse follows the Eventgrid Schema. You can parse EventGrid events " + + "using EventGridEvent.from_dict method in the azure-eventgrid library." ) raise ValueError( "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + - " source and type are required." + " The `source` and `type` params are required." ) diff --git a/sdk/core/azure-core/tests/test_messaging_cloud_event.py b/sdk/core/azure-core/tests/test_messaging_cloud_event.py index 0fe853f809f0..bf35931c6565 100644 --- a/sdk/core/azure-core/tests/test_messaging_cloud_event.py +++ b/sdk/core/azure-core/tests/test_messaging_cloud_event.py @@ -446,7 +446,8 @@ def test_eventgrid_event_schema_raises(): "eventTime":"2020-08-07T02:06:08.11969Z", "eventType":"pull request", } - with pytest.raises(ValueError, match="It looks like your event is of EventGrid schema. You can parse EventGrid events using EventGridEvent.from_dict of the azure-eventgrid library.") + with pytest.raises(ValueError, match="The event you are trying to parse follows the Eventgrid Schema. You can parse EventGrid events using EventGridEvent.from_dict method in the azure-eventgrid library."): + CloudEvent.from_dict(cloud_custom_dict) def test_wrong_schema_raises_no_source(): cloud_custom_dict = { @@ -456,7 +457,7 @@ def test_wrong_schema_raises_no_source(): "time":"2020-08-07T02:06:08.11969Z", "specversion":"1.0", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. source and type are required."): + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. The `source` and `type` params are required."): CloudEvent.from_dict(cloud_custom_dict) def test_wrong_schema_raises_no_type(): @@ -467,5 +468,5 @@ def test_wrong_schema_raises_no_type(): "time":"2020-08-07T02:06:08.11969Z", "specversion":"1.0", } - with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. source and type are required."): + with pytest.raises(ValueError, match="The event does not conform to the cloud event spec https://github.com/cloudevents/spec. The `source` and `type` params are required."): CloudEvent.from_dict(cloud_custom_dict) \ No newline at end of file From 10d2d0d4aacf5d6a3124fe38ba5ae2c057b6af18 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Sun, 27 Jun 2021 00:30:30 -0700 Subject: [PATCH 9/9] lint --- sdk/core/azure-core/azure/core/messaging.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sdk/core/azure-core/azure/core/messaging.py b/sdk/core/azure-core/azure/core/messaging.py index 0e6a01394e9c..f619724b18c7 100644 --- a/sdk/core/azure-core/azure/core/messaging.py +++ b/sdk/core/azure-core/azure/core/messaging.py @@ -159,7 +159,7 @@ def from_dict(cls, event): kwargs["extensions"] = extensions try: - return cls( + event_obj = cls( id=event.get("id"), source=event["source"], type=event["type"], @@ -173,10 +173,11 @@ def from_dict(cls, event): if not all([_ in event for _ in ("source", "type")]): if all([_ in event for _ in ("subject", "eventType", "data", "dataVersion", "id", "eventTime")]): raise ValueError( - "The event you are trying to parse follows the Eventgrid Schema. You can parse EventGrid events " + - "using EventGridEvent.from_dict method in the azure-eventgrid library." + "The event you are trying to parse follows the Eventgrid Schema. You can parse" + + " EventGrid events using EventGridEvent.from_dict method in the azure-eventgrid library." ) raise ValueError( "The event does not conform to the cloud event spec https://github.com/cloudevents/spec." + " The `source` and `type` params are required." ) + return event_obj