Skip to content

Commit 9f4bbb0

Browse files
Rakshith Bhyravabhotlat-swpillAutorestCIKieranBrantnerMagee
authored
Send spec (#13143)
* 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 <[email protected]> * async tests * no async for py2 * comment * Apply suggestions from code review Co-authored-by: KieranBrantnerMagee <[email protected]> * Apply suggestions from code review Co-authored-by: KieranBrantnerMagee <[email protected]> * Apply suggestions from code review Co-authored-by: KieranBrantnerMagee <[email protected]> Co-authored-by: t-swpill <[email protected]> Co-authored-by: Azure SDK Bot <[email protected]> Co-authored-by: KieranBrantnerMagee <[email protected]>
1 parent bf9d44f commit 9f4bbb0

File tree

26 files changed

+1088
-27
lines changed

26 files changed

+1088
-27
lines changed

sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py

+8
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,11 @@ def _get_authentication_policy(credential):
7070
if isinstance(credential, EventGridSharedAccessSignatureCredential):
7171
authentication_policy = EventGridSharedAccessSignatureCredentialPolicy(credential=credential, name=constants.EVENTGRID_TOKEN_HEADER)
7272
return authentication_policy
73+
74+
def _is_cloud_event(event):
75+
# type: dict -> bool
76+
required = ('id', 'source', 'specversion', 'type')
77+
try:
78+
return all([_ in event for _ in required]) and event['specversion'] == "1.0"
79+
except TypeError:
80+
return False

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

+23-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,24 @@
1313

1414
if TYPE_CHECKING:
1515
# pylint: disable=unused-import,ungrouped-imports
16-
from typing import Any
16+
from typing import Any, Union, Dict, List
17+
SendType = Union[
18+
CloudEvent,
19+
EventGridEvent,
20+
CustomEvent,
21+
Dict,
22+
List[CloudEvent],
23+
List[EventGridEvent],
24+
List[CustomEvent],
25+
List[Dict]
26+
]
1727

1828
from ._models import CloudEvent, EventGridEvent, CustomEvent
19-
from ._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy
29+
from ._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy, _is_cloud_event
2030
from ._generated._event_grid_publisher_client import EventGridPublisherClient as EventGridPublisherClientImpl
2131
from . import _constants as constants
2232

33+
2334
class EventGridPublisherClient(object):
2435
"""EventGrid Python Publisher Client.
2536
@@ -36,20 +47,25 @@ def __init__(self, topic_hostname, credential, **kwargs):
3647
self._topic_hostname = topic_hostname
3748
auth_policy = _get_authentication_policy(credential)
3849
self._client = EventGridPublisherClientImpl(authentication_policy=auth_policy, **kwargs)
39-
4050
def send(self, events, **kwargs):
41-
# type: (Union[List[CloudEvent], List[EventGridEvent], List[CustomEvent]], Any) -> None
51+
# type: (SendType, Any) -> None
4252
"""Sends event data to topic hostname specified during client initialization.
4353
4454
:param events: A list of CloudEvent/EventGridEvent/CustomEvent to be sent.
4555
:type events: Union[List[models.CloudEvent], List[models.EventGridEvent], List[models.CustomEvent]]
56+
:keyword str content_type: The type of content to be used to send the events.
57+
Has default value "application/json; charset=utf-8" for EventGridEvents, with "cloudevents-batch+json" for CloudEvents
4658
:rtype: None
47-
raise: :class:`ValueError`, when events do not follow specified SendType.
59+
:raise: :class:`ValueError`, when events do not follow specified SendType.
4860
"""
61+
if not isinstance(events, list):
62+
events = [events]
4963

50-
if all(isinstance(e, CloudEvent) for e in events):
64+
if all(isinstance(e, CloudEvent) for e in events) or all(_is_cloud_event(e) for e in events):
65+
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
5166
self._client.publish_cloud_event_events(self._topic_hostname, events, **kwargs)
52-
elif all(isinstance(e, EventGridEvent) for e in events):
67+
elif all(isinstance(e, EventGridEvent) for e in events) or all(isinstance(e, dict) for e in events):
68+
kwargs.setdefault("content_type", "application/json; charset=utf-8")
5369
self._client.publish_events(self._topic_hostname, events, **kwargs)
5470
elif all(isinstance(e, CustomEvent) for e in events):
5571
serialized_events = [dict(e) for e in events]

sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py

+28-8
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,31 @@
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

9-
from typing import Any
9+
from typing import Any, TYPE_CHECKING
1010

1111
from azure.core import AsyncPipelineClient
1212
from msrest import Deserializer, Serializer
1313

14-
from .._models import CloudEvent, EventGridEvent
15-
from .._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy
14+
from .._models import CloudEvent, EventGridEvent, CustomEvent
15+
from .._helpers import _get_topic_hostname_only_fqdn, _get_authentication_policy, _is_cloud_event
1616
from azure.core.pipeline.policies import AzureKeyCredentialPolicy
1717
from azure.core.credentials import AzureKeyCredential
1818
from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync
1919
from .. import _constants as constants
2020

21+
if TYPE_CHECKING:
22+
# pylint: disable=unused-import,ungrouped-imports
23+
from typing import Any, Union, Dict, List
24+
SendType = Union[
25+
CloudEvent,
26+
EventGridEvent,
27+
CustomEvent,
28+
Dict,
29+
List[CloudEvent],
30+
List[EventGridEvent],
31+
List[CustomEvent],
32+
List[Dict]
33+
]
2134

2235
class EventGridPublisherClient(object):
2336
"""Asynchronous EventGrid Python Publisher Client.
@@ -30,23 +43,30 @@ class EventGridPublisherClient(object):
3043
def __init__(self, topic_hostname, credential, **kwargs):
3144
# type: (str, Union[AzureKeyCredential, EventGridSharedAccessSignatureCredential], Any) -> None
3245
auth_policy = _get_authentication_policy(credential)
33-
self._client = EventGridPublisherClientAsync(authentication_policy=auth_policy)
46+
self._client = EventGridPublisherClientAsync(authentication_policy=auth_policy, **kwargs)
47+
topic_hostname = _get_topic_hostname_only_fqdn(topic_hostname)
3448
self._topic_hostname = topic_hostname
3549

3650

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

47-
if all(isinstance(e, CloudEvent) for e in events):
65+
if all(isinstance(e, CloudEvent) for e in events) or all(_is_cloud_event(e) for e in events):
66+
kwargs.setdefault("content_type", "application/cloudevents-batch+json; charset=utf-8")
4867
await self._client.publish_cloud_event_events(self._topic_hostname, events, **kwargs)
49-
elif all(isinstance(e, EventGridEvent) for e in events):
68+
elif all(isinstance(e, EventGridEvent) for e in events) or all(isinstance(e, dict) for e in events):
69+
kwargs.setdefault("content_type", "application/json; charset=utf-8")
5070
await self._client.publish_events(self._topic_hostname, events, **kwargs)
5171
elif all(isinstance(e, CustomEvent) for e in events):
5272
serialized_events = [dict(e) for e in events]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# --------------------------------------------------------------------------
2+
#
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
#
5+
# The MIT License (MIT)
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the ""Software""), to
9+
# deal in the Software without restriction, including without limitation the
10+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11+
# sell copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23+
# IN THE SOFTWARE.
24+
#
25+
# --------------------------------------------------------------------------
26+
import platform
27+
import sys
28+
29+
30+
# Ignore async tests for Python < 3.5
31+
collect_ignore_glob = []
32+
if sys.version_info < (3, 5):
33+
collect_ignore_glob.append("*_async.py")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
interactions:
2+
- request:
3+
body: '[{"id": "3dc4b913-4bc2-41f8-be9b-bf1f67069806", "source": "http://samplesource.dev",
4+
"data": "cloudevent", "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:41.947462Z",
5+
"specversion": "1.0"}]'
6+
headers:
7+
Accept:
8+
- '*/*'
9+
Accept-Encoding:
10+
- gzip, deflate
11+
Connection:
12+
- keep-alive
13+
Content-Length:
14+
- '198'
15+
Content-Type:
16+
- application/cloudevents-batch+json; charset=utf-8
17+
User-Agent:
18+
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
19+
aeg-sas-key:
20+
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
21+
method: POST
22+
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
23+
response:
24+
body:
25+
string: ''
26+
headers:
27+
api-supported-versions:
28+
- '2018-01-01'
29+
content-length:
30+
- '0'
31+
date:
32+
- Wed, 19 Aug 2020 03:36:43 GMT
33+
server:
34+
- Microsoft-HTTPAPI/2.0
35+
strict-transport-security:
36+
- max-age=31536000; includeSubDomains
37+
status:
38+
code: 200
39+
message: OK
40+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
interactions:
2+
- request:
3+
body: '[{"id": "51c18497-2a25-45f1-b9ba-fdaf08c00263", "source": "http://samplesource.dev",
4+
"data": {"sample": "cloudevent"}, "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:42.304479Z",
5+
"specversion": "1.0"}]'
6+
headers:
7+
Accept:
8+
- '*/*'
9+
Accept-Encoding:
10+
- gzip, deflate
11+
Connection:
12+
- keep-alive
13+
Content-Length:
14+
- '210'
15+
Content-Type:
16+
- application/cloudevents-batch+json; charset=utf-8
17+
User-Agent:
18+
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
19+
aeg-sas-key:
20+
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
21+
method: POST
22+
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
23+
response:
24+
body:
25+
string: ''
26+
headers:
27+
api-supported-versions:
28+
- '2018-01-01'
29+
content-length:
30+
- '0'
31+
date:
32+
- Wed, 19 Aug 2020 03:36:43 GMT
33+
server:
34+
- Microsoft-HTTPAPI/2.0
35+
strict-transport-security:
36+
- max-age=31536000; includeSubDomains
37+
status:
38+
code: 200
39+
message: OK
40+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
interactions:
2+
- request:
3+
body: '[{"id": "6a315e93-a59c-4eca-b2f2-6bf3b8f27984", "source": "http://samplesource.dev",
4+
"data": "cloudevent", "type": "Sample.Cloud.Event", "time": "2020-08-19T03:36:42.629467Z",
5+
"specversion": "1.0"}]'
6+
headers:
7+
Accept:
8+
- '*/*'
9+
Accept-Encoding:
10+
- gzip, deflate
11+
Connection:
12+
- keep-alive
13+
Content-Length:
14+
- '198'
15+
Content-Type:
16+
- application/cloudevents-batch+json; charset=utf-8
17+
User-Agent:
18+
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
19+
aeg-sas-key:
20+
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
21+
method: POST
22+
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
23+
response:
24+
body:
25+
string: ''
26+
headers:
27+
api-supported-versions:
28+
- '2018-01-01'
29+
content-length:
30+
- '0'
31+
date:
32+
- Wed, 19 Aug 2020 03:36:43 GMT
33+
server:
34+
- Microsoft-HTTPAPI/2.0
35+
strict-transport-security:
36+
- max-age=31536000; includeSubDomains
37+
status:
38+
code: 200
39+
message: OK
40+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
interactions:
2+
- request:
3+
body: '[{"id": "1234", "source": "http://samplesource.dev", "data": "cloudevent",
4+
"type": "Sample.Cloud.Event", "specversion": "1.0"}]'
5+
headers:
6+
Accept:
7+
- '*/*'
8+
Accept-Encoding:
9+
- gzip, deflate
10+
Connection:
11+
- keep-alive
12+
Content-Length:
13+
- '127'
14+
Content-Type:
15+
- application/cloudevents-batch+json; charset=utf-8
16+
User-Agent:
17+
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
18+
aeg-sas-key:
19+
- dHUaOOg5xRj+D7iH/AC92GyHweLx9ugrDuMDg4e5Xvw=
20+
method: POST
21+
uri: https://cloudeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
22+
response:
23+
body:
24+
string: ''
25+
headers:
26+
api-supported-versions:
27+
- '2018-01-01'
28+
content-length:
29+
- '0'
30+
date:
31+
- Wed, 19 Aug 2020 03:36:44 GMT
32+
server:
33+
- Microsoft-HTTPAPI/2.0
34+
strict-transport-security:
35+
- max-age=31536000; includeSubDomains
36+
status:
37+
code: 200
38+
message: OK
39+
version: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
interactions:
2+
- request:
3+
body: '[{"customSubject": "sample", "customEventType": "sample.event", "customDataVersion":
4+
"2.0", "customId": "1234", "customEventTime": "2020-08-19T03:36:56.936961+00:00",
5+
"customData": "sample data"}]'
6+
headers:
7+
Accept:
8+
- '*/*'
9+
Accept-Encoding:
10+
- gzip, deflate
11+
Connection:
12+
- keep-alive
13+
Content-Length:
14+
- '196'
15+
Content-Type:
16+
- application/json
17+
User-Agent:
18+
- azsdk-python-eventgridpublisherclient/unknown Python/3.7.3 (Windows-10-10.0.18362-SP0)
19+
aeg-sas-key:
20+
- uPQPJHQHsAhBxWOWtRXslz3sXf7TJ5lcqLZ6SC4QzJ4=
21+
method: POST
22+
uri: https://customeventgridtestegtopic.westus-1.eventgrid.azure.net/api/events?api-version=2018-01-01
23+
response:
24+
body:
25+
string: ''
26+
headers:
27+
api-supported-versions:
28+
- '2018-01-01'
29+
content-length:
30+
- '0'
31+
date:
32+
- Wed, 19 Aug 2020 03:36:57 GMT
33+
server:
34+
- Microsoft-HTTPAPI/2.0
35+
strict-transport-security:
36+
- max-age=31536000; includeSubDomains
37+
status:
38+
code: 200
39+
message: OK
40+
version: 1

0 commit comments

Comments
 (0)