-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Implement from_dict #16509
Implement from_dict #16509
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
import json | ||
import six | ||
from msrest.serialization import UTC | ||
from ._helpers import _decode | ||
from ._generated.models import EventGridEvent as InternalEventGridEvent, CloudEvent as InternalCloudEvent | ||
|
||
|
||
|
@@ -106,6 +107,31 @@ def __init__(self, source, type, **kwargs): # pylint: disable=redefined-builtin | |
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.") | ||
|
||
@classmethod | ||
def from_dict(cls, event, **kwargs): | ||
# type: (Dict, Any) -> CloudEvent | ||
""" | ||
Returns the deserialized CloudEvent object when a dict is provided. | ||
|
||
:param event: The dict representation of the event which needs to be deserialized. | ||
:type event: dict | ||
Comment on lines
+114
to
+117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be helpful if we could add description on the key-value items we accepts -- but it's a doc stuff There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, the payload normally comes directly from a storage queue - i can put a link to the relevant spec There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If not all the key-value pairs, at least mentioning that |
||
|
||
:rtype: CloudEvent | ||
""" | ||
return cls( | ||
id=event.pop("id", None), | ||
source=event.pop("source", None), | ||
type=event.pop("type", None), | ||
specversion=event.pop("specversion", None), | ||
data=event.pop("data", None) or _decode(event.pop("data_base64", None)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my understanding, to use the dict = {
data_base64 = b'<base64 bytes>'
}
# or
dict = {
data = data
} which means internally we do:
is setting input There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is by design, and mirrors this. Similar to sending There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking of the following two creation case which makes me feel the inconsistency, from intuition I would expect two cases to return the "same" event_created_from_class = CloudEvent(data_base64=b'bytes_data')
event_created_from_class.data is None
event_created_from_class.data_base64 is not None
event_created_from_dict = CloudEvent.from_dict({'data_base64':b'bytes_data'})
event_created_from_dict.data is not None
event_created_from_dict.data_base64 is None apart from that, I notice that # I think this should be an invalid input?
event_created_from_dict = CloudEvent.from_dict({'data': 'somedata', 'data_base64':b'bytes_data'}) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I could also be wrong, might be missing some context here, just thinking out loud) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That two ways that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could also do a cross-language check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update: we decided not to expose data_base64 |
||
time=event.pop("time", None), | ||
dataschema=event.pop("dataschema", None), | ||
datacontenttype=event.pop("datacontenttype", None), | ||
subject=event.pop("subject", None), | ||
extensions=event, | ||
**kwargs | ||
) | ||
|
||
@classmethod | ||
def _from_generated(cls, cloud_event, **kwargs): | ||
# type: (Union[str, Dict, bytes], Any) -> CloudEvent | ||
|
@@ -228,3 +254,26 @@ def __init__(self, subject, event_type, data, data_version, **kwargs): | |
kwargs.setdefault('data_version', data_version) | ||
|
||
super(EventGridEvent, self).__init__(**kwargs) | ||
|
||
@classmethod | ||
def from_dict(cls, event, **kwargs): | ||
# type: (Dict, Any) -> EventGridEvent | ||
""" | ||
Returns the deserialized EventGridEvent object when a dict is provided. | ||
|
||
:param event: The dict representation of the event which needs to be deserialized. | ||
:type event: dict | ||
|
||
:rtype: EventGridEvent | ||
Comment on lines
+262
to
+267
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as above regarding to the description of the dict accepted key-value items. |
||
""" | ||
return cls( | ||
id=event.get("id", None), | ||
subject=event.get("subject", None), | ||
topic=event.get("topic", None), | ||
data_version=event.get("dataVersion", None), | ||
data=event.get("data", None), | ||
event_time=event.get("eventTime", None), | ||
event_type=event.get("eventType", None), | ||
metadata_version=event.get("metadataVersion", None), | ||
**kwargs | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import logging | ||
import sys | ||
import os | ||
import pytest | ||
import json | ||
|
||
from azure.eventgrid import CloudEvent, EventGridEvent | ||
from devtools_testutils import AzureMgmtTestCase | ||
from _mocks import ( | ||
cloud_storage_dict, | ||
cloud_custom_dict_base64, | ||
cloud_custom_dict_with_extensions, | ||
eg_storage_dict | ||
) | ||
|
||
class EventGridDeserializerTests(AzureMgmtTestCase): | ||
|
||
# Cloud Event tests | ||
def test_eg_consumer_cloud_storage_dict(self, **kwargs): | ||
event = CloudEvent.from_dict(cloud_storage_dict) | ||
assert event.data == { | ||
"api":"PutBlockList", | ||
"client_request_id":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", | ||
"request_id":"831e1650-001e-001b-66ab-eeb76e000000", | ||
"e_tag":"0x8D4BCC2E4835CD0", | ||
"content_type":"application/octet-stream", | ||
"content_length":524288, | ||
"blob_type":"BlockBlob", | ||
"url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", | ||
"sequencer":"00000000000004420000000000028963", | ||
"storage_diagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} | ||
} | ||
assert event.specversion == "1.0" | ||
assert event.__class__ == CloudEvent | ||
|
||
|
||
def test_cloud_custom_dict_with_extensions(self, **kwargs): | ||
event = CloudEvent.from_dict(cloud_custom_dict_with_extensions) | ||
assert event.data == {"team": "event grid squad"} | ||
assert event.__class__ == CloudEvent | ||
assert event.extensions == {"ext1": "example", "ext2": "example2"} | ||
|
||
def test_cloud_custom_dict_base64(self, **kwargs): | ||
event = CloudEvent.from_dict(cloud_custom_dict_base64) | ||
assert event.data == b'cloudevent' | ||
assert event.data_base64 == None | ||
Comment on lines
+45
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as I mentioned in the |
||
assert event.specversion == "1.0" | ||
assert event.__class__ == CloudEvent | ||
|
||
# EG Event tests | ||
|
||
def test_eg_storage_from_dict(self, **kwargs): | ||
event = EventGridEvent.from_dict(eg_storage_dict) | ||
assert event.__class__ == EventGridEvent | ||
assert event.event_time == "2020-08-07T02:28:23.867525Z" | ||
assert event.event_type == "Microsoft.Storage.BlobCreated" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dumb question: what does the
content
look like, utf-8 base64 string?also probably worth a better method name
_decode_base64_string
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"data_base64":'Y2xvdWRldmVudA==',
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so we decided not to expose data_base64 to users at all
see #16661