-
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
[ServiceBus] AMQPAnnotatedMessage API Review Feedback #18432
[ServiceBus] AMQPAnnotatedMessage API Review Feedback #18432
Conversation
@@ -37,8 +35,6 @@ | |||
"ServiceBusMessage", | |||
"ServiceBusMessageBatch", | |||
"ServiceBusReceivedMessage", | |||
"AMQPAnnotatedMessage", |
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.
this would be breaking - i thought we never exposed this to customer?
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.
this would be a breaking change for b1, and we never exposed this to customer in GA
if self.message._body.type != uamqp.MessageBodyType.Data: | ||
return None # TODO: TBD, raise TypeError vs return None |
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.
thoughts:
if message.body == None:
message.raw_amqp_message.body
# vs
try:
message.body
except TypeError:
message.raw_amqp_message.body
although raising error on property seems not common in python, but it seems be a stronger indicator to me in this dedicated scenario..
there're some discussions:
https://stackoverflow.com/questions/48778945/by-design-should-a-property-getter-ever-throw-an-exception-in-python
https://softwareengineering.stackexchange.com/questions/16646/is-throwing-an-exception-from-a-property-bad-form
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.
I wasn't there during the original discussion, but looking through these questions, it seems that raising an error is not preferred. Is there a specific scenario you have in mind where the try/except would work and the ==
wouldn't?
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.
Having a case in mind which is pushing me to the return None
approach:
corner case for sending None:
sb_msg = ServiceBusMessage(body=None, application_properties={"key": "value"})
amqp_msg = AMQPAnnotatedMessage(value_body=None, application_properties={"key": "value"})
- if we want to adopt the raise error approach
- our current sbmessage supports passing None (although it's not documented)
- there is a reason, normal users might just want to send some app prop without a body
- if users sending amqpannotatedmessage with None value body, and on the receiving side we didn't raise TypeError (because we can't differentiate)
- then this feels like we're breaking the consistency with sequence, and non-None value body
- our current sbmessage supports passing None (although it's not documented)
(well, actually I have a way to convince myself that ServiceBusMessage.body is always trying to extract the data body, so in the sequence/value body case, data body is None which returns None is fair enough)
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.
find one raising error property sample from requests content:
similar in httpx lib:
""" | ||
Properties to add to the message. | ||
|
||
:rtype: Optional[~azure.servicebus.amqp.AMQPMessageProperties] |
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.
in GAed it's returning uamqp.message.MessageProperties
. This would be a breaking change to stuff like type hint / isinstance check. but we don't know how many existing users reply on the type check (as far as I understand, raw_amqp_message should be a rare use case).
way to hack isinstance:
@property
def __class__(self):
return uamqp.message.MessagePropreties # bad idea?
or
class AMQPMessageProperties(DicMixin, uamqp.message.MessageProperties)
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.
is the first way (with setting class property to return uamqp.message.MessageProperties
) the one that would be a breaking change?
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.
@yunhaoling @annatisch I'd like to get rid of everything that shows uamqp
, in case we replace that transport by something else. As long as the duck typing is consistent, I think I'm happy enough.
if self.message._body.type != uamqp.MessageBodyType.Data: | ||
return None # TODO: TBD, raise TypeError vs return None |
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.
I wasn't there during the original discussion, but looking through these questions, it seems that raising an error is not preferred. Is there a specific scenario you have in mind where the try/except would work and the ==
wouldn't?
message_header = None | ||
message_properties = None | ||
if header: | ||
message_header = uamqp.message.MessageHeader() |
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.
will this need to be replaced/wrapped by AMQPMessageHeader()
?
message_header.priority = header.get("priority") | ||
|
||
if properties: | ||
message_properties = uamqp.message.MessageProperties(**properties) |
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.
same comment as above: replaced/wrapped by AMQPMessageProperties()
?
""" | ||
Properties to add to the message. | ||
|
||
:rtype: Optional[~azure.servicebus.amqp.AMQPMessageProperties] |
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.
is the first way (with setting class property to return uamqp.message.MessageProperties
) the one that would be a breaking change?
Update resource association swagger (Azure#18432) * update access mode values * update examples * Add 202 in delete spec * Add provisioning issues changes * update schema * review changs * update * typo in model fix * make provisioning issues readonly * Add one example in list association, provisioning state enum update * Add logggin categories in profile * examples update * update * update examples * reformat code * Add x-msidentifier for logger * update * provisioning state fix * Fix provisioning state * Add location header in delete nsp association * update location header * update location header * location header update Co-authored-by: Kaushal Kumar <kumarkaushal@microsoft.com>
The change is based upon the gist and the discussion:
https://gist.github.com/yunhaoling/4bf19d56fcb9c21c3944eba41d272433
Decision:
ServiceBusReceivedMessage.raw_amqp_message
body_type
property onServiceBusReceivedMessage
- (TBD) body return None vs raise Error
- (TBD) whether to inherit from uamqp classes as well for backward-compatibility
API View is available here:
https://apiview.dev/Assemblies/Review/c4c7244a8c1d4968827e0163db9187c5