From 3f154bbc3d813cea87bd5f57eb91c66308cec1d7 Mon Sep 17 00:00:00 2001 From: "Adam Ling (MSFT)" <47871814+yunhaoling@users.noreply.github.com> Date: Tue, 21 Jul 2020 16:46:17 -0700 Subject: [PATCH] [ServiceBus] Adjust user-agent following the guideline (#12596) * enable user agent * switch user agent string posititon, add check, update comment * fix typo * remove validation part --- .../azure/servicebus/_base_handler.py | 2 +- .../azure/servicebus/_common/utils.py | 40 +++++++++++++++---- .../azure/servicebus/_servicebus_client.py | 10 +++++ .../azure/servicebus/_servicebus_receiver.py | 2 + .../azure/servicebus/_servicebus_sender.py | 2 + .../_servicebus_session_receiver.py | 24 +++++++---- .../servicebus/aio/_base_handler_async.py | 2 +- .../aio/_servicebus_client_async.py | 10 +++++ .../aio/_servicebus_receiver_async.py | 2 + .../aio/_servicebus_sender_async.py | 2 + .../aio/_servicebus_session_receiver_async.py | 24 +++++++---- .../azure-servicebus/tests/test_sb_client.py | 2 +- 12 files changed, 95 insertions(+), 27 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_base_handler.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_base_handler.py index 7ff53c728df8..223180d1bf11 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_base_handler.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_base_handler.py @@ -156,7 +156,7 @@ def __init__( self._running = False self._handler = None # type: uamqp.AMQPClient self._auth_uri = None - self._properties = create_properties() + self._properties = create_properties(self._config.user_agent) def __enter__(self): self._open_with_retry() diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/utils.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/utils.py index e6d047e8ad37..38f6db331483 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/utils.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/utils.py @@ -10,22 +10,25 @@ import threading import time import functools +import platform +from typing import Optional, Dict try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse from concurrent.futures import ThreadPoolExecutor -from uamqp import authentication +from uamqp import authentication, types from ..exceptions import AutoLockRenewFailed, AutoLockRenewTimeout, ServiceBusError -from .._version import VERSION as sdk_version +from .._version import VERSION from .constants import ( JWT_TOKEN_SCOPE, TOKEN_TYPE_JWT, TOKEN_TYPE_SASTOKEN, DEAD_LETTER_QUEUE_SUFFIX, - TRANSFER_DEAD_LETTER_QUEUE_SUFFIX + TRANSFER_DEAD_LETTER_QUEUE_SUFFIX, + USER_AGENT_PREFIX ) _log = logging.getLogger(__name__) @@ -93,12 +96,33 @@ def build_uri(address, entity): return address -def create_properties(): +def create_properties(user_agent=None): + # type: (Optional[str]) -> Dict[types.AMQPSymbol, str] + """ + Format the properties with which to instantiate the connection. + This acts like a user agent over HTTP. + + :param str user_agent: If specified, this will be added in front of the built-in user agent string. + + :rtype: dict + """ properties = {} - properties["product"] = "servicebus.python" - properties["version"] = sdk_version - properties["framework"] = "Python {}.{}.{}".format(*sys.version_info[0:3]) - properties["platform"] = sys.platform + properties[types.AMQPSymbol("product")] = USER_AGENT_PREFIX + properties[types.AMQPSymbol("version")] = VERSION + framework = "Python/{}.{}.{}".format( + sys.version_info[0], sys.version_info[1], sys.version_info[2] + ) + properties[types.AMQPSymbol("framework")] = framework + platform_str = platform.platform() + properties[types.AMQPSymbol("platform")] = platform_str + + final_user_agent = "{}/{} {} ({})".format( + USER_AGENT_PREFIX, VERSION, framework, platform_str + ) + if user_agent: + final_user_agent = "{} {}".format(user_agent, final_user_agent) + + properties[types.AMQPSymbol("user-agent")] = final_user_agent return properties diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index d57f51e8b04f..b0e8d1fc67c7 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -40,6 +40,7 @@ class ServiceBusClient(object): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. .. admonition:: Example: @@ -115,6 +116,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :rtype: ~azure.servicebus.ServiceBusClient .. admonition:: Example: @@ -163,6 +165,7 @@ def get_queue_sender(self, queue_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -210,6 +213,7 @@ def get_queue_receiver(self, queue_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -270,6 +274,7 @@ def get_queue_deadletter_receiver(self, queue_name, **kwargs): http_proxy=self._config.http_proxy, connection=self._connection, is_dead_letter_receiver=True, + user_agent=self._config.user_agent, **kwargs ) @@ -303,6 +308,7 @@ def get_topic_sender(self, topic_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -356,6 +362,7 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -418,6 +425,7 @@ def get_subscription_deadletter_receiver(self, topic_name, subscription_name, ** http_proxy=self._config.http_proxy, connection=self._connection, is_dead_letter_receiver=True, + user_agent=self._config.user_agent, **kwargs ) @@ -475,6 +483,7 @@ def get_subscription_session_receiver(self, topic_name, subscription_name, sessi http_proxy=self._config.http_proxy, connection=self._connection, session_id=session_id, + user_agent=self._config.user_agent, **kwargs ) @@ -526,5 +535,6 @@ def get_queue_session_receiver(self, queue_name, session_id=None, **kwargs): session_id=session_id, transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, + user_agent=self._config.user_agent, **kwargs ) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index b3b85e6aff1e..b498eb4fbfcd 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -79,6 +79,7 @@ class ServiceBusReceiver(BaseHandler, ReceiverMixin): # pylint: disable=too-man :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :keyword int prefetch: The maximum number of messages to cache with each request to the service. This setting is only for advanced performance tuning. Increasing this value will improve message throughput performance but increase the chance that messages will expire while they are cached if they're not @@ -290,6 +291,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :keyword int prefetch: The maximum number of messages to cache with each request to the service. This setting is only for advanced performance tuning. Increasing this value will improve message throughput performance but increase the chance that messages will expire while they are cached if they're not diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py index f5714bd8a1ae..4a10d18d74db 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py @@ -109,6 +109,7 @@ class ServiceBusSender(BaseHandler, SenderMixin): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. .. admonition:: Example: @@ -276,6 +277,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :rtype: ~azure.servicebus.ServiceBusSenderClient .. admonition:: Example: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session_receiver.py index dca10d3176fe..3120a9dbe463 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session_receiver.py @@ -40,10 +40,6 @@ class ServiceBusSessionReceiver(ServiceBusReceiver, SessionReceiverMixin): the client connects to. :keyword str subscription_name: The path of specific Service Bus Subscription under the specified Topic the client connects to. - :keyword int prefetch: The maximum number of messages to cache with each request to the service. - The default value is 0, meaning messages will be received from the service and processed - one at a time. Increasing this value will improve message throughput performance but increase - the change that messages will expire while they are cached if they're not processed fast enough. :keyword float idle_timeout: The timeout in seconds between received messages after which the receiver will automatically shutdown. The default value is 0, meaning no timeout. :keyword mode: The mode with which messages will be retrieved from the entity. The two options @@ -66,6 +62,14 @@ class ServiceBusSessionReceiver(ServiceBusReceiver, SessionReceiverMixin): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. + :keyword int prefetch: The maximum number of messages to cache with each request to the service. + This setting is only for advanced performance tuning. Increasing this value will improve message throughput + performance but increase the chance that messages will expire while they are cached if they're not + processed fast enough. + The default value is 0, meaning messages will be received from the service and processed one at a time. + In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided) + within its request to the service. .. admonition:: Example: @@ -128,10 +132,6 @@ def from_connection_string( sessionful entity, otherwise it must be None. In order to receive messages from the next available session, set this to None. The default is None. :paramtype session_id: str - :keyword int prefetch: The maximum number of messages to cache with each request to the service. - The default value is 0, meaning messages will be received from the service and processed - one at a time. Increasing this value will improve message throughput performance but increase - the change that messages will expire while they are cached if they're not processed fast enough. :keyword float idle_timeout: The timeout in seconds between received messages after which the receiver will automatically shutdown. The default value is 0, meaning no timeout. :keyword bool logging_enable: Whether to output network trace logs to the logger. Default is `False`. @@ -143,6 +143,14 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. + :keyword int prefetch: The maximum number of messages to cache with each request to the service. + This setting is only for advanced performance tuning. Increasing this value will improve message throughput + performance but increase the chance that messages will expire while they are cached if they're not + processed fast enough. + The default value is 0, meaning messages will be received from the service and processed one at a time. + In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided) + within its request to the service. :rtype: ~azure.servicebus.ServiceBusSessionReceiver .. admonition:: Example: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_base_handler_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_base_handler_async.py index 2ad4335e1333..f22ed2b058b1 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_base_handler_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_base_handler_async.py @@ -67,7 +67,7 @@ def __init__( self._running = False self._handler = None # type: uamqp.AMQPClient self._auth_uri = None - self._properties = create_properties() + self._properties = create_properties(self._config.user_agent) async def __aenter__(self): await self._open_with_retry() diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py index 3ff676ed7b07..85c7e4868d8f 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py @@ -42,6 +42,7 @@ class ServiceBusClient(object): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. .. admonition:: Example: @@ -107,6 +108,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :rtype: ~azure.servicebus.aio.ServiceBusClient .. admonition:: Example: @@ -165,6 +167,7 @@ def get_queue_sender(self, queue_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -211,6 +214,7 @@ def get_queue_receiver(self, queue_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -271,6 +275,7 @@ def get_queue_deadletter_receiver(self, queue_name, **kwargs): http_proxy=self._config.http_proxy, connection=self._connection, is_dead_letter_receiver=True, + user_agent=self._config.user_agent, **kwargs ) @@ -304,6 +309,7 @@ def get_topic_sender(self, topic_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -357,6 +363,7 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, connection=self._connection, + user_agent=self._config.user_agent, **kwargs ) @@ -419,6 +426,7 @@ def get_subscription_deadletter_receiver(self, topic_name, subscription_name, ** http_proxy=self._config.http_proxy, connection=self._connection, is_dead_letter_receiver=True, + user_agent=self._config.user_agent, **kwargs ) @@ -476,6 +484,7 @@ def get_subscription_session_receiver(self, topic_name, subscription_name, sessi http_proxy=self._config.http_proxy, connection=self._connection, session_id=session_id, + user_agent=self._config.user_agent, **kwargs ) @@ -526,5 +535,6 @@ def get_queue_session_receiver(self, queue_name, session_id=None, **kwargs): session_id=session_id, transport_type=self._config.transport_type, http_proxy=self._config.http_proxy, + user_agent=self._config.user_agent, **kwargs ) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py index 9363f7670b54..86498c2137d8 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py @@ -79,6 +79,7 @@ class ServiceBusReceiver(collections.abc.AsyncIterator, BaseHandler, ReceiverMix :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :keyword int prefetch: The maximum number of messages to cache with each request to the service. This setting is only for advanced performance tuning. Increasing this value will improve message throughput performance but increase the chance that messages will expire while they are cached if they're not @@ -279,6 +280,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :keyword int prefetch: The maximum number of messages to cache with each request to the service. This setting is only for advanced performance tuning. Increasing this value will improve message throughput performance but increase the chance that messages will expire while they are cached if they're not diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_sender_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_sender_async.py index c59bc36a5037..0ad3a4f7c558 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_sender_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_sender_async.py @@ -57,6 +57,7 @@ class ServiceBusSender(BaseHandler, SenderMixin): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. .. admonition:: Example: @@ -217,6 +218,7 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. :rtype: ~azure.servicebus.aio.ServiceBusSender .. admonition:: Example: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_receiver_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_receiver_async.py index 96a5ecf2a92b..b162ee273d22 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_receiver_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_receiver_async.py @@ -51,10 +51,6 @@ class ServiceBusSessionReceiver(ServiceBusReceiver, SessionReceiverMixin): sessionful entity, otherwise it must be None. In order to receive messages from the next available session, set this to None. The default is None. :paramtype session_id: str - :keyword int prefetch: The maximum number of messages to cache with each request to the service. - The default value is 0 meaning messages will be received from the service and processed - one at a time. Increasing this value will improve message throughput performance but increase - the change that messages will expire while they are cached if they're not processed fast enough. :keyword float idle_timeout: The timeout in seconds between received messages after which the receiver will automatically shutdown. The default value is 0, meaning no timeout. :keyword bool logging_enable: Whether to output network trace logs to the logger. Default is `False`. @@ -66,6 +62,14 @@ class ServiceBusSessionReceiver(ServiceBusReceiver, SessionReceiverMixin): :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. + :keyword int prefetch: The maximum number of messages to cache with each request to the service. + This setting is only for advanced performance tuning. Increasing this value will improve message throughput + performance but increase the chance that messages will expire while they are cached if they're not + processed fast enough. + The default value is 0, meaning messages will be received from the service and processed one at a time. + In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided) + within its request to the service. .. admonition:: Example: @@ -112,10 +116,6 @@ def from_connection_string( sessionful entity, otherwise it must be None. In order to receive messages from the next available session, set this to None. The default is None. :paramtype session_id: str - :keyword int prefetch: The maximum number of messages to cache with each request to the service. - The default value is 0, meaning messages will be received from the service and processed - one at a time. Increasing this value will improve message throughput performance but increase - the change that messages will expire while they are cached if they're not processed fast enough. :keyword float idle_timeout: The timeout in seconds between received messages after which the receiver will automatically shutdown. The default value is 0, meaning no timeout. :keyword bool logging_enable: Whether to output network trace logs to the logger. Default is `False`. @@ -127,6 +127,14 @@ def from_connection_string( :keyword dict http_proxy: HTTP proxy settings. This must be a dictionary with the following keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. + :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. + :keyword int prefetch: The maximum number of messages to cache with each request to the service. + This setting is only for advanced performance tuning. Increasing this value will improve message throughput + performance but increase the chance that messages will expire while they are cached if they're not + processed fast enough. + The default value is 0, meaning messages will be received from the service and processed one at a time. + In the case of prefetch being 0, `ServiceBusReceiver.receive` would try to cache `max_batch_size` (if provided) + within its request to the service. :rtype: ~azure.servicebus.aio.ServiceBusSessionReceiver .. admonition:: Example: diff --git a/sdk/servicebus/azure-servicebus/tests/test_sb_client.py b/sdk/servicebus/azure-servicebus/tests/test_sb_client.py index b2b958543ec7..22ff1a910036 100644 --- a/sdk/servicebus/azure-servicebus/tests/test_sb_client.py +++ b/sdk/servicebus/azure-servicebus/tests/test_sb_client.py @@ -125,4 +125,4 @@ def test_sb_client_incorrect_queue_conn_str(self, servicebus_queue_authorization with client: with pytest.raises(ServiceBusError): with client.get_queue_sender(wrong_queue.name) as sender: - sender.send_messages(Message("test")) \ No newline at end of file + sender.send_messages(Message("test"))