Skip to content

Commit

Permalink
Send spec (#13143)
Browse files Browse the repository at this point in the history
* Event grid track 2 (#12768)

* genereated python client for event grid

* updated readme to use track2 generator

* added sas key auth sample

* added consume sample, not final

* removing old eg

* added track 2 changes needed for api view

* add consumer operations

* cleanup client versions for api view

* remove _initialize_mapping() in BaseEventType class in models

* track 2 design manual changes

* added publisher wrapper in azure/eventgrid for demo

* modified naming for publish sample for demo

* final sample fix for demo

* added response to publish_events(), still need to fix

* added decoder for apiview

* renamed consumer, added Deserialized/CustomEvent

* final for Board Review

* testing changes

* added EventGridSharedAccessSignatureCredential,Policy and modified samples

* added eg_client test

* moving generated code out from event_grid_publisher_client nested folder

* added consumption function samples

* removed eg required package and removed service bus dependency in consumer

* removed unnecessary functions

* changed consumer deserialize_event() to take,return single event of one type of (string, bytes string, dict). changed DeserializedEvent to have to_json() method, instead of extending DictMixin

* added publish tests

* fixed PR, added CustomEvent, added tests/samples

* updated swagger, removed unnecessary imports

* removed unnecessary reqs in dev_requirements

* changed async publisher import path, added type hints

* modified typehints for publishers, based on apiview

* added newlines

* added shared_reqs file

* moved shared_requirement

* fixed non live test

* added changelog, test fix

* changed topic preparer

* added samples to exclude to setup.py

* Packaging update of azure-eventgrid

* Packaging update of azure-eventgrid

* tests fix (#13026)

* other fixes

* p2 compat

* Packaging update of azure-eventgrid

* Event grid v2 (#13051)

* other fixes

* auto update

* Send spec initial

* recordings

* tests fix

* Update sdk/eventgrid/azure-eventgrid/tests/recordings/test_eg_publisher_client.test_eg_publisher_client_publish_event_grid_event_data_dict.yaml

* Apply suggestions from code review

* Update sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py

* analyze

* Apply suggestions from code review

Co-authored-by: KieranBrantnerMagee <kibrantn@microsoft.com>

* async tests

* no async for py2

* comment

* Apply suggestions from code review

Co-authored-by: KieranBrantnerMagee <kibrantn@microsoft.com>

* Apply suggestions from code review

Co-authored-by: KieranBrantnerMagee <kibrantn@microsoft.com>

* Apply suggestions from code review

Co-authored-by: KieranBrantnerMagee <kibrantn@microsoft.com>

Co-authored-by: t-swpill <66144935+t-swpill@users.noreply.github.com>
Co-authored-by: Azure SDK Bot <adxpysdk@microsoft.com>
Co-authored-by: KieranBrantnerMagee <kibrantn@microsoft.com>
  • Loading branch information
4 people committed Aug 27, 2020
1 parent bf9d44f commit 9f4bbb0
Show file tree
Hide file tree
Showing 26 changed files with 1,088 additions and 27 deletions.
8 changes: 8 additions & 0 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,11 @@ def _get_authentication_policy(credential):
if isinstance(credential, EventGridSharedAccessSignatureCredential):
authentication_policy = EventGridSharedAccessSignatureCredentialPolicy(credential=credential, name=constants.EVENTGRID_TOKEN_HEADER)
return authentication_policy

def _is_cloud_event(event):
# type: dict -> bool
required = ('id', 'source', 'specversion', 'type')
try:
return all([_ in event for _ in required]) and event['specversion'] == "1.0"
except TypeError:
return False
30 changes: 23 additions & 7 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,24 @@

if TYPE_CHECKING:
# pylint: disable=unused-import,ungrouped-imports
from typing import Any
from typing import Any, Union, Dict, List
SendType = Union[
CloudEvent,
EventGridEvent,
CustomEvent,
Dict,
List[CloudEvent],
List[EventGridEvent],
List[CustomEvent],
List[Dict]
]

from ._models import CloudEvent, EventGridEvent, CustomEvent
from ._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy
from ._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy, _is_cloud_event
from ._generated._event_grid_publisher_client import EventGridPublisherClient as EventGridPublisherClientImpl
from . import _constants as constants


class EventGridPublisherClient(object):
"""EventGrid Python Publisher Client.
Expand All @@ -36,20 +47,25 @@ def __init__(self, topic_hostname, credential, **kwargs):
self._topic_hostname = topic_hostname
auth_policy = _get_authentication_policy(credential)
self._client = EventGridPublisherClientImpl(authentication_policy=auth_policy, **kwargs)

def send(self, events, **kwargs):
# type: (Union[List[CloudEvent], List[EventGridEvent], List[CustomEvent]], Any) -> None
# type: (SendType, Any) -> None
"""Sends event data to topic hostname specified during client initialization.
:param events: A list of CloudEvent/EventGridEvent/CustomEvent to be sent.
:type events: Union[List[models.CloudEvent], List[models.EventGridEvent], List[models.CustomEvent]]
:keyword str content_type: The type of content to be used to send the events.
Has default value "application/json; charset=utf-8" for EventGridEvents, with "cloudevents-batch+json" for CloudEvents
:rtype: None
raise: :class:`ValueError`, when events do not follow specified SendType.
:raise: :class:`ValueError`, when events do not follow specified SendType.
"""
if not isinstance(events, list):
events = [events]

if all(isinstance(e, CloudEvent) for e in events):
if all(isinstance(e, CloudEvent) for e in events) or all(_is_cloud_event(e) for e in events):
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
self._client.publish_cloud_event_events(self._topic_hostname, events, **kwargs)
elif all(isinstance(e, EventGridEvent) for e in events):
elif all(isinstance(e, EventGridEvent) for e in events) or all(isinstance(e, dict) for e in events):
kwargs.setdefault("content_type", "application/json; charset=utf-8")
self._client.publish_events(self._topic_hostname, events, **kwargs)
elif all(isinstance(e, CustomEvent) for e in events):
serialized_events = [dict(e) for e in events]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,31 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import Any
from typing import Any, TYPE_CHECKING

from azure.core import AsyncPipelineClient
from msrest import Deserializer, Serializer

from .._models import CloudEvent, EventGridEvent
from .._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy
from .._models import CloudEvent, EventGridEvent, CustomEvent
from .._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy, _is_cloud_event
from azure.core.pipeline.policies import AzureKeyCredentialPolicy
from azure.core.credentials import AzureKeyCredential
from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync
from .. import _constants as constants

if TYPE_CHECKING:
# pylint: disable=unused-import,ungrouped-imports
from typing import Any, Union, Dict, List
SendType = Union[
CloudEvent,
EventGridEvent,
CustomEvent,
Dict,
List[CloudEvent],
List[EventGridEvent],
List[CustomEvent],
List[Dict]
]

class EventGridPublisherClient(object):
"""Asynchronous EventGrid Python Publisher Client.
Expand All @@ -30,23 +43,30 @@ class EventGridPublisherClient(object):
def __init__(self, topic_hostname, credential, **kwargs):
# type: (str, Union[AzureKeyCredential, EventGridSharedAccessSignatureCredential], Any) -> None
auth_policy = _get_authentication_policy(credential)
self._client = EventGridPublisherClientAsync(authentication_policy=auth_policy)
self._client = EventGridPublisherClientAsync(authentication_policy=auth_policy, **kwargs)
topic_hostname = _get_topic_hostname_only_fqdn(topic_hostname)
self._topic_hostname = topic_hostname


async def send(self, events, **kwargs):
# type: (Union[List[CloudEvent], List[EventGridEvent], List[CustomEvent]], Any) -> None
# type: (SendType) -> None
"""Sends event data to topic hostname specified during client initialization.
:param events: A list of CloudEvent/EventGridEvent/CustomEvent to be sent.
:type events: Union[List[models.CloudEvent], List[models.EventGridEvent], List[models.CustomEvent]]
:keyword str content_type: The type of content to be used to send the events.
Has default value "application/json; charset=utf-8" for EventGridEvents, with "cloudevents-batch+json" for CloudEvents
:rtype: None
raise: :class:`ValueError`, when events do not follow specified SendType.
:raise: :class:`ValueError`, when events do not follow specified SendType.
"""
if not isinstance(events, list):
events = [events]

if all(isinstance(e, CloudEvent) for e in events):
if all(isinstance(e, CloudEvent) for e in events) or all(_is_cloud_event(e) for e in events):
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
await self._client.publish_cloud_event_events(self._topic_hostname, events, **kwargs)
elif all(isinstance(e, EventGridEvent) for e in events):
elif all(isinstance(e, EventGridEvent) for e in events) or all(isinstance(e, dict) for e in events):
kwargs.setdefault("content_type", "application/json; charset=utf-8")
await self._client.publish_events(self._topic_hostname, events, **kwargs)
elif all(isinstance(e, CustomEvent) for e in events):
serialized_events = [dict(e) for e in events]
Expand Down
33 changes: 33 additions & 0 deletions sdk/eventgrid/azure-eventgrid/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------
import platform
import sys


# Ignore async tests for Python < 3.5
collect_ignore_glob = []
if sys.version_info < (3, 5):
collect_ignore_glob.append("*_async.py")
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: '[{"id": "3dc4b913-4bc2-41f8-be9b-bf1f67069806", "source": "http://samplesource.dev",
"data": "cloudevent", "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:41.947462Z",
"specversion": "1.0"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '198'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
aeg-sas-key:
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
method: POST
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
response:
body:
string: ''
headers:
api-supported-versions:
- '2018-01-01'
content-length:
- '0'
date:
- Wed, 19 Aug 2020 03:36:43 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: '[{"id": "51c18497-2a25-45f1-b9ba-fdaf08c00263", "source": "http://samplesource.dev",
"data": {"sample": "cloudevent"}, "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:42.304479Z",
"specversion": "1.0"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '210'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
aeg-sas-key:
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
method: POST
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
response:
body:
string: ''
headers:
api-supported-versions:
- '2018-01-01'
content-length:
- '0'
date:
- Wed, 19 Aug 2020 03:36:43 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: '[{"id": "6a315e93-a59c-4eca-b2f2-6bf3b8f27984", "source": "http://samplesource.dev",
"data": "cloudevent", "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:42.629467Z",
"specversion": "1.0"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '198'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
aeg-sas-key:
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
method: POST
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
response:
body:
string: ''
headers:
api-supported-versions:
- '2018-01-01'
content-length:
- '0'
date:
- Wed, 19 Aug 2020 03:36:43 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
interactions:
- request:
body: '[{"id": "1234", "source": "http://samplesource.dev", "data": "cloudevent",
"type": "Sample.Cloud.Event", "specversion": "1.0"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '127'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
aeg-sas-key:
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
method: POST
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
response:
body:
string: ''
headers:
api-supported-versions:
- '2018-01-01'
content-length:
- '0'
date:
- Wed, 19 Aug 2020 03:36:44 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interactions:
- request:
body: '[{"customSubject": "sample", "customEventType": "sample.event", "customDataVersion":
"2.0", "customId": "1234", "customEventTime": "2020-08-19T03:36:56.936961+00:00",
"customData": "sample data"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '196'
Content-Type:
- application/json
User-Agent:
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
aeg-sas-key:
- uPQPJHQHsAhBxWOWtRXslz3sXf7TJ5lcqLZ6SC4QzJ4=
method: POST
uri: https://customeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
response:
body:
string: ''
headers:
api-supported-versions:
- '2018-01-01'
content-length:
- '0'
date:
- Wed, 19 Aug 2020 03:36:57 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Loading

0 comments on commit 9f4bbb0

Please sign in to comment.