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 22 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
61 changes: 1 addition & 60 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.
Either a list or a single instance of CloudEvent/EventGridEvent can be sent. Alternatively, a list or a single instance of the dict representation of CloudEvent/EventGridEvent or a Custom Schema can also be published.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording is a little confusing. Might be more clear to separate the idea that CloudEvent/EGEvents can be sent as dicts and that events in a custom schema can be sent as a dict or list of dicts. Would be useful to add links for either the samples of sending all these different formats or from the champion_scenarios.md . Something like?

Suggested change
Either a list or a single instance of CloudEvent/EventGridEvent can be sent. Alternatively, a list or a single instance of the dict representation of CloudEvent/EventGridEvent or a Custom Schema can also be published.
The following formats of events are allowed to be sent:
- a [list of strongly-typed EventGridEvents](add link to list of strongly typed EGE from champion_scenarios.md)
- a [list of strongly-typed CloudEvents](add link to scenario from champion_scenarios.md)
- a [single strongly-typed EventGridEvent instance](add link to single strongly typed EGE from champion_scenarios.md)
- a [single strongly-typed CloudEvent instance](add link to scenario from champion_scenarios.md)
- a list of the [dict representation of EventGridEvents](add link)
- a list of the [dict representation of CloudEvents](add link)
- a single instance of the [dict representation of EventGridEvent](url)
- a single instance of the [dict representation of CloudEvent](url)
- a list of [dicts in a custom schema](link)
- a single [dict in a custom schema](url)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be worth it - i'll tackle it in the samples issue though since i fell this is a non blocker. changing the wording a bit for now

rakshith91 marked this conversation as resolved.
Show resolved Hide resolved

## 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
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
48 changes: 20 additions & 28 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.
: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.
yunhaoling marked this conversation as resolved.
Show resolved Hide resolved
If data is of bytes type, we'll send it 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,16 @@ 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.
: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 +87,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 +130,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 Down Expand Up @@ -159,9 +170,6 @@ class EventGridEvent(InternalEventGridEvent, EventMixin):
: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.
: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 +189,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 +217,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 +227,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
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
UserAgentPolicy
)

from ._models import CloudEvent, EventGridEvent, CustomEvent
from ._models import CloudEvent, EventGridEvent
from ._helpers import (
_get_endpoint_only_fqdn,
_get_authentication_policy,
Expand All @@ -41,18 +41,15 @@
SendType = Union[
CloudEvent,
EventGridEvent,
CustomEvent,
Dict,
List[CloudEvent],
List[EventGridEvent],
List[CustomEvent],
List[Dict]
]

ListEventType = Union[
List[CloudEvent],
List[EventGridEvent],
List[CustomEvent],
List[Dict]
]

Expand Down Expand Up @@ -106,7 +103,7 @@ def send(self, events, **kwargs):
inefficient to loop the send method for each event instead of just using a list
and we highly recommend against it.

:param events: A list of CloudEvent/EventGridEvent/CustomEvent to be sent.
:param events: A list of CloudEvent/EventGridEvent to be sent.
:type events: SendType
: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,
Expand All @@ -132,8 +129,6 @@ def send(self, events, **kwargs):
if isinstance(events[0], EventGridEvent) or _is_eventgrid_event(events[0]):
for event in events:
_eventgrid_data_typecheck(event)
elif isinstance(events[0], CustomEvent):
events = [dict(e) for e in events] # type: ignore
return self._client.publish_custom_event_events(self._endpoint, cast(List, events), **kwargs)

def close(self):
Expand Down

This file was deleted.

Loading