Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arch preview feedback #16441

Merged
merged 27 commits into from
Feb 3, 2021
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
8 changes: 3 additions & 5 deletions sdk/eventgrid/azure-eventgrid/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

**Breaking Changes**
- `EventGridSharedAccessSignatureCredential` is deprecated in favor of `AzureSasCredential`.
- `EventGridConsumer` is now renamed to `EventGridDeserializer`.
- `decode_cloud_event` is renamed to `deserialize_cloud_events`.
- `decode_eventgrid_event` is renamed to `deserialize_eventgrid_events`.
- `azure.eventgrid.models` namespace along with all the models in it are now removed. `azure.eventgrid.SystemEventMappings` can be used to get the event model type mapping.
- `azure.eventgrid.models` namespace along with all the models in it are now removed. `azure.eventgrid.SystemEventNames` can be used to get the event model type mapping.
- `topic_hostname` is renamed to `endpoint` in the `EventGridPublisherClient`.
- `data` is now a required param for `CloudEvent`.
- `azure.eventgrid.generate_shared_access_signature` method is now renamed to `generate_sas`.
- `EventGridConsumer`is now removed. Please see the samples to see how events can be deserialized.
- `CustomEvent` model is removed. Dictionaries must be used to send a custom schema.

**Bug Fixes**
- `EventGridEvent` has two additional required positional parameters namely, `data` and `data_version`.
Expand Down
67 changes: 1 addition & 66 deletions sdk/eventgrid/azure-eventgrid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ Information about the key concepts on Event Grid, see [Concepts in Azure Event G

### EventGridPublisherClient
`EventGridPublisherClient` provides operations to send event data to topic hostname specified during client initialization.
Either a list or a single instance of CloudEvent/EventGridEvent/CustomEvent can be sent.

### EventGridDeserializer
`EventGridDeserializer` is used to desrialize an event received.
CloudEvents and EventGridEvents can be sent either as a single event or a list of respective typed objects or their equivalent dict representations. To send a custom schema, a dict representation can be used. Please have a look at the [samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/eventgrid/azure-eventgrid/samples) for detailed examples.

## Examples

Expand Down Expand Up @@ -123,62 +120,6 @@ client = EventGridPublisherClient(endpoint, credential)
client.send(event)
```

### Consume an Event Grid Event

This example demonstrates consuming and deserializing an eventgrid event.

```Python
import os
from azure.eventgrid import EventGridDeserializer

consumer = EventGridDeserializer()

eg_storage_dict = {
"id":"bbab625-dc56-4b22-abeb-afcc72e5290c",
"subject":"/blobServices/default/containers/oc2d2817345i200097container/blobs/oc2d2817345i20002296blob",
"data":{
"api":"PutBlockList",
},
"eventType":"Microsoft.Storage.BlobCreated",
"dataVersion":"2.0",
"metadataVersion":"1",
"eventTime":"2020-08-07T02:28:23.867525Z",
"topic":"/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/topics/eventgridegsub"
}

deserialized_event = consumer.deserialize_eventgrid_events(eg_storage_dict)

# both allow access to raw properties as strings
time_string = deserialized_event.event_time
```

### Consume a Cloud Event

This example demonstrates consuming and deserializing a cloud event.

```Python
import os
from azure.eventgrid import EventGridDeserializer

consumer = EventGridDeserializer()

cloud_storage_dict = {
"id":"a0517898-9fa4-4e70-b4a3-afda1dd68672",
"source":"/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account}",
"data":{
"api":"PutBlockList",
},
"type":"Microsoft.Storage.BlobCreated",
"time":"2020-08-07T01:11:49.765846Z",
"specversion":"1.0"
}

deserialized_event = consumer.deserialize_cloud_events(cloud_storage_dict)

# both allow access to raw properties as strings
time_string = deserialized_event.time
```

## Troubleshooting

- Enable `azure.eventgrid` logger to collect traces from the library.
Expand Down Expand Up @@ -208,9 +149,6 @@ These code samples show common champion scenario operations with the Azure Event

* Publish Custom Events to a topic: [cs1_publish_custom_events_to_a_topic.py][python-eg-sample-customevent]
* Publish Custom events to a domain topic: [cs2_publish_custom_events_to_a_domain_topic.py][python-eg-sample-customevent-to-domain]
* Deserialize a System Event: [cs3_consume_system_events.py][python-eg-sample-consume-systemevent]
* Deserialize a Custom Event: [cs4_consume_custom_events.py][python-eg-sample-consume-customevent]
* Deserialize a Cloud Event: [cs5_consume_events_using_cloud_events_1.0_schema.py][python-eg-sample-consume-cloudevent]
* Publish a Cloud Event: [cs6_publish_events_using_cloud_events_1.0_schema.py][python-eg-sample-send-cloudevent]

More samples can be found [here][python-eg-samples].
Expand Down Expand Up @@ -246,10 +184,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con

[python-eg-sample-customevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs1_publish_custom_events_to_a_topic.py
[python-eg-sample-customevent-to-domain]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs2_publish_custom_events_to_a_domain_topic.py
[python-eg-sample-consume-systemevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs3_consume_system_events.py
[python-eg-sample-consume-customevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs4_consume_custom_events.py
[python-eg-sample-send-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs5_publish_events_using_cloud_events_1.0_schema.py
[python-eg-sample-consume-cloudevent]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/eventgrid/azure-eventgrid/samples/champion_scenarios/cs6_consume_events_using_cloud_events_1.0_schema.py
[publisher-service-doc]: https://docs.microsoft.com/azure/event-grid/concepts

[cla]: https://cla.microsoft.com
Expand Down
10 changes: 4 additions & 6 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@
# --------------------------------------------------------------------------

from ._publisher_client import EventGridPublisherClient
from ._consumer import EventGridDeserializer
from ._event_mappings import SystemEventMappings
from ._event_mappings import SystemEventNames
from ._helpers import generate_sas
from ._models import CloudEvent, CustomEvent, EventGridEvent
from ._models import CloudEvent, EventGridEvent
from ._version import VERSION

__all__ = ['EventGridPublisherClient', 'EventGridDeserializer',
'CloudEvent', 'CustomEvent', 'EventGridEvent', 'generate_sas',
'SystemEventMappings'
__all__ = ['EventGridPublisherClient', 'CloudEvent',
'EventGridEvent', 'generate_sas', 'SystemEventNames'
]
__version__ = VERSION
68 changes: 0 additions & 68 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_consumer.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# --------------------------------------------------------------------------------------------
from enum import Enum

class SystemEventMappings(str, Enum):
class SystemEventNames(str, Enum):
"""
This enum represents the names of the various event types for the system events published to
Azure Event Grid. To check the list of recognizable system topics,
Expand Down
59 changes: 26 additions & 33 deletions sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import six
from msrest.serialization import UTC
from ._generated.models import EventGridEvent as InternalEventGridEvent, CloudEvent as InternalCloudEvent
from ._shared.mixins import DictMixin


class EventMixin(object):
Expand All @@ -36,13 +35,16 @@ class CloudEvent(EventMixin): #pylint:disable=too-many-instance-attributes
"""Properties of an event published to an Event Grid topic using the CloudEvent 1.0 Schema.

All required parameters must be populated in order to send to Azure.
If data is of binary type, data_base64 can be used alternatively. Note that data and data_base64
cannot be present at the same time.
yunhaoling marked this conversation as resolved.
Show resolved Hide resolved

:param source: Required. Identifies the context in which an event happened. The combination of id and source must
be unique for each distinct event. If publishing to a domain topic, source must be the domain name.
be unique for each distinct event. If publishing to a domain topic, source must be the domain name.
:type source: str
:param type: Required. Type of event related to the originating occurrence.
:type type: str
:param data: Required. Event data specific to the event type.
:keyword data: Optional. Event data specific to the event type. Only one of the `data` or `data_base64`
argument must be present. If data is of bytes type, it will be sent as data_base64 in the outgoing request.
:type data: object
:keyword time: Optional. The time (in UTC) the event was generated, in RFC3339 format.
:type time: ~datetime.datetime
Expand All @@ -58,11 +60,17 @@ class CloudEvent(EventMixin): #pylint:disable=too-many-instance-attributes
:keyword id: Optional. An identifier for the event. The combination of id and source must be
unique for each distinct event. If not provided, a random UUID will be generated and used.
:type id: Optional[str]
:keyword data_base64: Optional. Event data specific to the event type if the data is of bytes type.
Only data of bytes type is accepted by `data-base64` and only one of the `data` or `data_base64` argument
must be present.
:type data_base64: bytes
:ivar source: Identifies the context in which an event happened. The combination of id and source must
be unique for each distinct event. If publishing to a domain topic, source must be the domain name.
be unique for each distinct event. If publishing to a domain topic, source must be the domain name.
:vartype source: str
:ivar data: Event data specific to the event type.
:vartype data: object
:ivar data_base64: Event data specific to the event type if the data is of bytes type.
:vartype data_base64: bytes
:ivar type: Type of event related to the originating occurrence.
:vartype type: str
:ivar time: The time (in UTC) the event was generated, in RFC3339 format.
Expand All @@ -80,19 +88,23 @@ class CloudEvent(EventMixin): #pylint:disable=too-many-instance-attributes
unique for each distinct event. If not provided, a random UUID will be generated and used.
:vartype id: Optional[str]
"""
def __init__(self, source, type, data, **kwargs): # pylint: disable=redefined-builtin
# type: (str, str, object, Any) -> None
def __init__(self, source, type, **kwargs): # pylint: disable=redefined-builtin
# type: (str, str, Any) -> None
self.source = source
self.type = type
self.specversion = kwargs.pop("specversion", "1.0")
self.id = kwargs.pop("id", str(uuid.uuid4()))
self.time = kwargs.pop("time", dt.datetime.now(UTC()).isoformat())
self.data = data
self.data = kwargs.pop("data", None)
self.datacontenttype = kwargs.pop("datacontenttype", None)
self.dataschema = kwargs.pop("dataschema", None)
self.subject = kwargs.pop("subject", None)
self.data_base64 = kwargs.pop("data_base64", None)
self.extensions = {}
self.extensions.update(dict(kwargs.pop('extensions', {})))
if self.data is not None and self.data_base64 is not None:
raise ValueError("data and data_base64 cannot be provided at the same time.\
Use data_base64 only if you are sending bytes, and use data otherwise.")
yunhaoling marked this conversation as resolved.
Show resolved Hide resolved

@classmethod
def _from_generated(cls, cloud_event, **kwargs):
Expand All @@ -119,15 +131,15 @@ def _to_generated(self, **kwargs):
data_base64 = self.data
data = None
else:
data_base64 = None
data = self.data
data_base64 = None
return InternalCloudEvent(
id=self.id,
source=self.source,
type=self.type,
specversion=self.specversion,
data=data,
data_base64=data_base64,
data_base64=self.data_base64 or data_base64,
time=self.time,
dataschema=self.dataschema,
datacontenttype=self.datacontenttype,
Expand All @@ -151,17 +163,14 @@ class EventGridEvent(InternalEventGridEvent, EventMixin):
:param data: Required. Event data specific to the event type.
:type data: object
:param data_version: Required. The schema version of the data object.
If not provided, will be stamped with an empty value.
If not provided, will be stamped with an empty value.
:type data_version: str
:keyword topic: Optional. The resource path of the event source. If not provided, Event Grid will
stamp onto the event.
stamp onto the event.
:type topic: str
:keyword metadata_version: Optional. The schema version of the event metadata. If provided,
must match Event Grid Schema exactly. If not provided, EventGrid will stamp onto event.
must match Event Grid Schema exactly. If not provided, EventGrid will stamp onto event.
:type metadata_version: str
:keyword data_version: Optional. The schema version of the data object. If not provided,
will be stamped with an empty value.
:type data_version: str
:keyword id: Optional. An identifier for the event. In not provided, a random UUID will be generated and used.
:type id: Optional[str]
:keyword event_time: Optional.The time (in UTC) of the event. If not provided,
Expand All @@ -181,8 +190,6 @@ class EventGridEvent(InternalEventGridEvent, EventMixin):
:ivar metadata_version: The schema version of the event metadata. If provided, must match Event Grid Schema exactly.
If not provided, EventGrid will stamp onto event.
:vartype metadata_version: str
:ivar data_version: The schema version of the data object. If not provided, will be stamped with an empty value.
:vartype data_version: str
:ivar id: An identifier for the event. In not provided, a random UUID will be generated and used.
:vartype id: Optional[str]
:ivar event_time: The time (in UTC) of the event. If not provided,
Expand Down Expand Up @@ -211,8 +218,8 @@ class EventGridEvent(InternalEventGridEvent, EventMixin):
'data_version': {'key': 'dataVersion', 'type': 'str'},
}

def __init__(self, data, subject, event_type, data_version, **kwargs):
# type: (object, str, str, str, Any) -> None
def __init__(self, subject, event_type, data, data_version, **kwargs):
yunhaoling marked this conversation as resolved.
Show resolved Hide resolved
# type: (str, str, object, str, Any) -> None
kwargs.setdefault('id', uuid.uuid4())
kwargs.setdefault('subject', subject)
kwargs.setdefault("event_type", event_type)
Expand All @@ -221,17 +228,3 @@ def __init__(self, data, subject, event_type, data_version, **kwargs):
kwargs.setdefault('data_version', data_version)

super(EventGridEvent, self).__init__(**kwargs)


class CustomEvent(DictMixin):
"""The wrapper class for a CustomEvent, to be used when publishing events.
:param dict args: dict
"""

def __init__(self, *args, **kwargs):
# type: (Any, Any) -> None
self._update(*args, **kwargs)

def _update(self, *args, **kwargs):
for k, v in dict(*args, **kwargs).items():
self[k] = v
Loading