Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions sdk/eventgrid/azure-eventgrid/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Release History
## 4.6.1 (Unreleased)

## 4.7.0 (Unreleased)

### Features Added

- Added support for publishing native CNCF cloudevents (https://pypi.org/project/cloudevents/).

### Breaking Changes

### Bugs Fixed
Expand Down
13 changes: 13 additions & 0 deletions sdk/eventgrid/azure-eventgrid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ For complete list of recognizable system topics, visit [System Topics](https://d

Event Grid on Kubernetes with Azure Arc is an offering that allows you to run Event Grid on your own Kubernetes cluster. This capability is enabled by the use of Azure Arc enabled Kubernetes. Through Azure Arc enabled Kubernetes, a supported Kubernetes cluster connects to Azure. Once connected, you are able to install Event Grid on it. Learn more about it [here](https://docs.microsoft.com/azure/event-grid/kubernetes/overview).

### Support for CNCF Cloud Events

Starting with v4.7.0, this package also supports publishing a CNCF cloud event from https://pypi.org/project/cloudevents/. You would be able to pass a CloudEvent object from this library to the `send` API.

```python

from cloudevents.http import CloudEvent

event = CloudEvent(...)

client.send(event)
```

## Examples

The following sections provide several code snippets covering some of the most common Event Grid tasks, including:
Expand Down
18 changes: 17 additions & 1 deletion sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from urllib2 import quote # type: ignore

from msrest import Serializer
from azure.core.exceptions import raise_with_traceback
from azure.core.pipeline.transport import HttpRequest
from azure.core.pipeline.policies import AzureKeyCredentialPolicy, BearerTokenCredentialPolicy
from azure.core.credentials import AzureKeyCredential, AzureSasCredential
Expand Down Expand Up @@ -98,7 +99,6 @@ def _is_cloud_event(event):
except TypeError:
return False


def _is_eventgrid_event(event):
# type: (Any) -> bool
required = ("subject", "eventType", "data", "dataVersion", "id", "eventTime")
Expand Down Expand Up @@ -142,6 +142,22 @@ def _cloud_event_to_generated(cloud_event, **kwargs):
**kwargs
)

def _from_cncf_events(event):
"""This takes in a CNCF cloudevent and returns a dictionary.
If cloud events library is not installed, the event is returned back.
"""
try:
from cloudevents.http import to_json
return json.loads(to_json(event))
except (AttributeError, ImportError):
# means this is not a CNCF event
return event
except Exception as err: # pylint: disable=broad-except
msg = """Failed to serialize the event. Please ensure your
CloudEvents is correctly formatted (https://pypi.org/project/cloudevents/)"""
raise_with_traceback(ValueError, msg, err)


def _build_request(endpoint, content_type, events):
serialize = Serializer()
header_parameters = {} # type: Dict[str, Any]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
_eventgrid_data_typecheck,
_build_request,
_cloud_event_to_generated,
_from_cncf_events,
)
from ._generated._event_grid_publisher_client import (
EventGridPublisherClient as EventGridPublisherClientImpl,
Expand Down Expand Up @@ -192,7 +193,10 @@ def send(self, events, **kwargs):
for e in events # pylint: disable=protected-access
]
except AttributeError:
pass # means it's a dictionary
## 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]):
for event in events:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# regenerated.
# --------------------------------------------------------------------------

VERSION = "4.6.1"
VERSION = "4.7.0"
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
_build_request,
_cloud_event_to_generated,
_get_authentication_policy,
_from_cncf_events,
)
from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync
from .._version import VERSION
Expand Down Expand Up @@ -192,7 +193,10 @@ async def send(self, events: SendType, **kwargs: Any) -> None:
for e in events # pylint: disable=protected-access
]
except AttributeError:
pass # means it's a dictionary
## 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]):
for event in events:
Expand Down
1 change: 1 addition & 0 deletions sdk/eventgrid/azure-eventgrid/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
-e ../../identity/azure-identity
-e ../azure-mgmt-eventgrid
azure-storage-queue
cloudevents<=2.0.0; python_version >= "3.6"
aiohttp>=3.0; python_version >= '3.5'
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
"""
FILE: sample_publish_cncf_cloud_events_async.py
DESCRIPTION:
This sample demonstrates creating sending a cloud event from the CNCF library.
USAGE:
python sample_publish_cncf_cloud_events_async.py
Set the environment variables with your own values before running the sample:
1) CLOUD_ACCESS_KEY - The access key of your eventgrid account.
2) CLOUD_TOPIC_HOSTNAME - The topic hostname. Typically it exists in the format
"https://<YOUR-TOPIC-NAME>.<REGION-NAME>.eventgrid.azure.net/api/events".
"""
import os
import asyncio
from azure.eventgrid.aio import EventGridPublisherClient
from azure.core.credentials import AzureKeyCredential
from cloudevents.http import CloudEvent

topic_key = os.environ["CLOUD_ACCESS_KEY"]
endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"]


async def publish():

credential = AzureKeyCredential(topic_key)
client = EventGridPublisherClient(endpoint, credential)
await client.send([
CloudEvent(
attributes={
"type": "cloudevent",
"source": "/cncf/cloud/event/1.0",
"subject": "testingcncfevent"
},
data=b'This is a cncf cloud event.',
)
])

if __name__ == '__main__':
asyncio.run(publish())
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# --------------------------------------------------------------------------
# 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_cncf_cloud_events.py
DESCRIPTION:
This sample demonstrates creating sending a cloud event from the CNCF library.
USAGE:
python sample_publish_cncf_cloud_events.py
Set the environment variables with your own values before running the sample:
1) CLOUD_ACCESS_KEY - The access key of your eventgrid account.
2) CLOUD_TOPIC_HOSTNAME - The topic hostname. Typically it exists in the format
"https://<YOUR-TOPIC-NAME>.<REGION-NAME>.eventgrid.azure.net/api/events".
"""
import os
from azure.eventgrid import EventGridPublisherClient
from azure.core.credentials import AzureKeyCredential
from cloudevents.http import CloudEvent

topic_key = os.environ["CLOUD_ACCESS_KEY"]
endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"]

credential = AzureKeyCredential(topic_key)
client = EventGridPublisherClient(endpoint, credential)

client.send([
CloudEvent(
attributes={
"type": "cloudevent",
"source": "/cncf/cloud/event/1.0",
"subject": "testingcncfevent"
},
data=b'This is a cncf cloud event.',
)
])
1 change: 1 addition & 0 deletions sdk/eventgrid/azure-eventgrid/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@
collect_ignore_glob = []
if sys.version_info < (3, 5):
collect_ignore_glob.append("*_async.py")
collect_ignore_glob.append("test_cncf*")
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
interactions:
- request:
body: '[{"type": "com.example.sampletype1", "source": "https://example.com/event-producer",
"specversion": "1.0", "id": "84b41e66-8127-4f46-850e-d62e8386e87e", "time":
"2021-10-25T03:07:58.245751+00:00", "data": "hello world"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '220'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgrid/4.7.0 Python/3.7.3 (Windows-10-10.0.18362-SP0)
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:
- Mon, 25 Oct 2021 03:07:57 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,38 @@
interactions:
- request:
body: '[{"type": "com.example.sampletype1", "source": "https://example.com/event-producer",
"specversion": "1.0", "id": "630d2dfe-6a48-455b-bd59-7c08cd070226", "time":
"2021-10-25T03:07:58.780277+00:00", "data_base64": "b''hello world''"}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '230'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgrid/4.7.0 Python/3.7.3 (Windows-10-10.0.18362-SP0)
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:
- Mon, 25 Oct 2021 03:07:58 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,38 @@
interactions:
- request:
body: '[{"type": "com.example.sampletype1", "source": "https://example.com/event-producer",
"specversion": "1.0", "id": "f687bede-e758-4bbd-aec9-d3f284b92238", "time":
"2021-10-25T03:07:59.100133+00:00", "data": {"message": "Hello World!"}}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '234'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgrid/4.7.0 Python/3.7.3 (Windows-10-10.0.18362-SP0)
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:
- Mon, 25 Oct 2021 03:07:59 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,38 @@
interactions:
- request:
body: '[{"type": "com.example.sampletype1", "source": "https://example.com/event-producer",
"specversion": "1.0", "id": "0adea5e4-44e6-4c88-83f2-ab009c09ac43", "time":
"2021-10-25T03:07:59.496961+00:00", "data": null}]'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '211'
Content-Type:
- application/cloudevents-batch+json; charset=utf-8
User-Agent:
- azsdk-python-eventgrid/4.7.0 Python/3.7.3 (Windows-10-10.0.18362-SP0)
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:
- Mon, 25 Oct 2021 03:07:59 GMT
server:
- Microsoft-HTTPAPI/2.0
strict-transport-security:
- max-age=31536000; includeSubDomains
status:
code: 200
message: OK
version: 1
Loading