From 21efe9d6106293210c0bbb469d05600877d2e283 Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Wed, 5 Jan 2022 17:49:27 -0800 Subject: [PATCH 1/9] inital expand kwargs w/o mgmt models --- .../_common/_connection_string_parser.py | 23 +- .../azure/servicebus/_common/message.py | 46 ++-- .../azure/servicebus/_servicebus_client.py | 128 ++++++++-- .../azure/servicebus/_servicebus_receiver.py | 109 ++++++-- .../azure/servicebus/_servicebus_sender.py | 68 +++-- .../azure/servicebus/_servicebus_session.py | 14 +- .../aio/_servicebus_client_async.py | 108 +++++++- .../aio/_servicebus_receiver_async.py | 75 ++++-- .../aio/_servicebus_sender_async.py | 27 +- .../aio/_servicebus_session_async.py | 11 +- .../management/_management_client_async.py | 201 +++++++++------ .../azure/servicebus/amqp/_amqp_message.py | 111 ++++++--- .../management/_management_client.py | 232 +++++++++++------- 13 files changed, 818 insertions(+), 335 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py index 466deaef0a62..302bd5f85e86 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- +from typing import Optional from ..management._models import DictMixin from .._base_handler import _parse_conn_str @@ -12,13 +13,21 @@ class ServiceBusConnectionStringProperties(DictMixin): Properties of a connection string. """ - def __init__(self, **kwargs): - self._fully_qualified_namespace = kwargs.pop("fully_qualified_namespace", None) - self._endpoint = kwargs.pop("endpoint", None) - self._entity_path = kwargs.pop("entity_path", None) - self._shared_access_signature = kwargs.pop("shared_access_signature", None) - self._shared_access_key_name = kwargs.pop("shared_access_key_name", None) - self._shared_access_key = kwargs.pop("shared_access_key", None) + def __init__( + self, + fully_qualified_namespace: Optional[str] = None, + endpoint: Optional[str] = None, + entity_path: Optional[str] = None, + shared_access_signature: Optional[str] = None, + shared_access_key_name: Optional[str] = None, + shared_access_key: Optional[str] = None, + ) -> None: + self._fully_qualified_namespace = fully_qualified_namespace + self._endpoint = endpoint + self._entity_path = entity_path + self._shared_access_signature = shared_access_signature + self._shared_access_key_name = shared_access_key_name + self._shared_access_key = shared_access_key @property def fully_qualified_namespace(self): diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py index eb4644c48ce7..3c664fbf78b2 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py @@ -92,8 +92,24 @@ class ServiceBusMessage( """ - def __init__(self, body, **kwargs): - # type: (Optional[Union[str, bytes]], Any) -> None + def __init__( + self, + body: Optional[Union[str, bytes]], + *, + application_properties: Optional[dict] = None, + session_id: Optional[str] = None, + message_id: Optional[str] = None, + scheduled_enqueue_time_utc: Optional[datetime.datetime] = None, + time_to_live: Optional[datetime.timedelta] = None, + content_type: Optional[str] = None, + correlation_id: Optional[str] = None, + subject: Optional[str] = None, + partition_key: Optional[str] = None, + to: Optional[str] = None, + reply_to: Optional[str] = None, + reply_to_session_id: Optional[str] = None, + **kwargs: Any + ) -> None: # Although we might normally thread through **kwargs this causes # problems as MessageProperties won't absorb spurious args. self._encoding = kwargs.pop("encoding", "UTF-8") @@ -108,20 +124,18 @@ def __init__(self, body, **kwargs): self._raw_amqp_message = AmqpAnnotatedMessage(message=self.message) else: self._build_message(body) - self.application_properties = kwargs.pop("application_properties", None) - self.session_id = kwargs.pop("session_id", None) - self.message_id = kwargs.pop("message_id", None) - self.content_type = kwargs.pop("content_type", None) - self.correlation_id = kwargs.pop("correlation_id", None) - self.to = kwargs.pop("to", None) - self.reply_to = kwargs.pop("reply_to", None) - self.reply_to_session_id = kwargs.pop("reply_to_session_id", None) - self.subject = kwargs.pop("subject", None) - self.scheduled_enqueue_time_utc = kwargs.pop( - "scheduled_enqueue_time_utc", None - ) - self.time_to_live = kwargs.pop("time_to_live", None) - self.partition_key = kwargs.pop("partition_key", None) + self.application_properties = application_properties + self.session_id = session_id + self.message_id = message_id + self.content_type = content_type + self.correlation_id = correlation_id + self.to = to + self.reply_to = reply_to + self.reply_to_session_id = reply_to_session_id + self.subject = subject + self.scheduled_enqueue_time_utc = scheduled_enqueue_time_utc + self.time_to_live = time_to_live + self.partition_key = partition_key def __str__(self): # type: () -> str diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index 1b0f28cc1aa3..38ee765e0ed2 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -2,12 +2,18 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Any, Union, TYPE_CHECKING +from typing import Any, Dict, Union, Optional import logging from weakref import WeakSet import uamqp +from uamqp.constants import TransportType +from azure.core.credentials import ( + TokenCredential, + AzureSasCredential, + AzureNamedKeyCredential, +) from ._base_handler import ( _parse_conn_str, ServiceBusSharedKeyCredential, @@ -15,16 +21,20 @@ ) from ._servicebus_sender import ServiceBusSender from ._servicebus_receiver import ServiceBusReceiver +from ._common.auto_lock_renewer import AutoLockRenewer from ._common._configuration import Configuration from ._common.utils import ( create_authentication, generate_dead_letter_entity_name, strip_protocol_from_uri, ) -from ._common.constants import ServiceBusSubQueue +from ._common.constants import ( + ServiceBusSubQueue, + NEXT_AVAILABLE_SESSION, + ServiceBusReceiveMode, +) +from ._retry import RetryMode -if TYPE_CHECKING: - from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential _LOGGER = logging.getLogger(__name__) @@ -74,15 +84,38 @@ class ServiceBusClient(object): """ - def __init__(self, fully_qualified_namespace, credential, **kwargs): - # type: (str, Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], Any) -> None + def __init__( + self, + fully_qualified_namespace: str, + credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + *, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: Optional[bool] = False, + transport_type: Optional[TransportType] = TransportType.Amqp, + retry_total: int = 3, + retry_backoff_factor: float = 0.8, + retry_backoff_max: int = 120, + retry_mode: RetryMode = RetryMode.EXPONENTIAL, + **kwargs: Any + ) -> None: # If the user provided http:// or sb://, let's be polite and strip that. self.fully_qualified_namespace = strip_protocol_from_uri( fully_qualified_namespace.strip() ) self._credential = credential - self._config = Configuration(**kwargs) + self._config = Configuration( + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + retry_total=retry_total, + retry_backoff_factor=retry_backoff_factor, + retry_backoff_max=retry_backoff_max, + retry_mode=retry_mode, + **kwargs + ) self._connection = None # Optional entity name, can be the name of Queue or Topic. Intentionally not advertised, typically be needed. self._entity_name = kwargs.get("entity_name") @@ -133,8 +166,20 @@ def close(self): self._connection.destroy() @classmethod - def from_connection_string(cls, conn_str, **kwargs): - # type: (str, Any) -> ServiceBusClient + def from_connection_string( + cls, + conn_str: str, + *, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: bool = False, + transport_type: TransportType = TransportType.Amqp, + retry_total: int = 3, + retry_backoff_factor: float = 0.8, + retry_backoff_max: int = 120, + retry_mode: RetryMode = RetryMode.EXPONENTIAL, + **kwargs + ): """ Create a ServiceBusClient from a connection string. @@ -179,6 +224,14 @@ def from_connection_string(cls, conn_str, **kwargs): fully_qualified_namespace=host, entity_name=entity_in_conn_str or kwargs.pop("entity_name", None), credential=credential, # type: ignore + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + retry_total=retry_total, + retry_backoff_factor=retry_backoff_factor, + retry_backoff_max=retry_backoff_max, + retry_mode=retry_mode, **kwargs ) @@ -225,8 +278,20 @@ def get_queue_sender(self, queue_name, **kwargs): self._handlers.add(handler) return handler - def get_queue_receiver(self, queue_name, **kwargs): - # type: (str, Any) -> ServiceBusReceiver + def get_queue_receiver( + self, + queue_name: str, + *, + session_id: Union[str, NEXT_AVAILABLE_SESSION] = None, + sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, + **kwargs: Any + ) -> ServiceBusReceiver: """Get ServiceBusReceiver for the specific queue. :param str queue_name: The path of specific Service Bus Queue the client connects to. @@ -278,8 +343,7 @@ def get_queue_receiver(self, queue_name, **kwargs): "the connection string used to construct the ServiceBusClient." ) - sub_queue = kwargs.get("sub_queue", None) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -312,6 +376,12 @@ def get_queue_receiver(self, queue_name, **kwargs): retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) self._handlers.add(handler) @@ -359,8 +429,21 @@ def get_topic_sender(self, topic_name, **kwargs): self._handlers.add(handler) return handler - def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): - # type: (str, str, Any) -> ServiceBusReceiver + def get_subscription_receiver( + self, + topic_name: str, + subscription_name: str, + *, + session_id: Union[str, NEXT_AVAILABLE_SESSION] = NEXT_AVAILABLE_SESSION, + sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, + **kwargs: Any + ) -> ServiceBusReceiver: """Get ServiceBusReceiver for the specific subscription under the topic. :param str topic_name: The name of specific Service Bus Topic the client connects to. @@ -415,8 +498,7 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): "the connection string used to construct the ServiceBusClient." ) - sub_queue = kwargs.get("sub_queue", None) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -444,6 +526,12 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) except ValueError: @@ -465,6 +553,12 @@ def get_subscription_receiver(self, topic_name, subscription_name, **kwargs): retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) self._handlers.add(handler) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index ead8b2d95949..aadfe1cfcdb3 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -6,17 +6,20 @@ import logging import functools import uuid -from typing import Any, List, TYPE_CHECKING, Optional, Dict, Iterator, Union +import datetime +from typing import Any, List, Optional, Dict, Iterator, Union import six from uamqp import ReceiveClient, types, Message -from uamqp.constants import SenderSettleMode +from uamqp.constants import SenderSettleMode, TransportType from uamqp.authentication.common import AMQPAuth +from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential from .exceptions import ServiceBusError from ._base_handler import BaseHandler from ._common.message import ServiceBusReceivedMessage +from ._common.auto_lock_renewer import AutoLockRenewer from ._common.utils import ( create_authentication, get_receive_links, @@ -53,10 +56,6 @@ from ._servicebus_session import ServiceBusSession -if TYPE_CHECKING: - import datetime - from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential - _LOGGER = logging.getLogger(__name__) @@ -120,19 +119,45 @@ class ServiceBusReceiver( (if provided) within its request to the service. """ - def __init__(self, fully_qualified_namespace, credential, **kwargs): - # type: (str, Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], Any) -> None + def __init__( + self, + fully_qualified_namespace: str, + credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + *, + queue_name: Optional[str] = None, + topic_name: Optional[str] = None, + subscription_name: Optional[str] = None, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: Optional[bool] = False, + transport_type: Optional[TransportType] = TransportType.Amqp, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, + **kwargs: Any + ) -> None: self._message_iter = None # type: Optional[Iterator[ServiceBusReceivedMessage]] if kwargs.get("entity_name"): super(ServiceBusReceiver, self).__init__( fully_qualified_namespace=fully_qualified_namespace, credential=credential, + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) else: - queue_name = kwargs.get("queue_name") # type: Optional[str] - topic_name = kwargs.get("topic_name") # type: Optional[str] - subscription_name = kwargs.get("subscription_name") if queue_name and topic_name: raise ValueError( "Queue/Topic name can not be specified simultaneously." @@ -151,10 +176,34 @@ def __init__(self, fully_qualified_namespace, credential, **kwargs): fully_qualified_namespace=fully_qualified_namespace, credential=credential, entity_name=entity_name, + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) - self._populate_attributes(**kwargs) + self._populate_attributes( + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, + **kwargs + ) self._session = ( None if self._session_id is None else ServiceBusSession(self._session_id, self) ) @@ -558,8 +607,11 @@ def _get_streaming_message_iter(self, max_wait_time=None): raise ValueError("The max_wait_time must be greater than 0.") return self._iter_contextual_wrapper(max_wait_time) - def receive_messages(self, max_message_count=1, max_wait_time=None): - # type: (Optional[int], Optional[float]) -> List[ServiceBusReceivedMessage] + def receive_messages( + self, + max_message_count: Optional[int] = 1, + max_wait_time: Optional[float] = None, + ) -> List[ServiceBusReceivedMessage]: """Receive a batch of messages at once. This approach is optimal if you wish to process multiple messages simultaneously, or @@ -615,8 +667,12 @@ def receive_messages(self, max_message_count=1, max_wait_time=None): self._auto_lock_renewer.register(self, message) return messages - def receive_deferred_messages(self, sequence_numbers, **kwargs): - # type: (Union[int,List[int]], Any) -> List[ServiceBusReceivedMessage] + def receive_deferred_messages( + self, + sequence_numbers: Union[int,List[int]], + *, + timeout: Optional[float] = None + ) -> List[ServiceBusReceivedMessage]: """Receive messages that have previously been deferred. When receiving deferred messages from a partitioned entity, all of the supplied @@ -639,7 +695,6 @@ def receive_deferred_messages(self, sequence_numbers, **kwargs): """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if isinstance(sequence_numbers, six.integer_types): @@ -685,8 +740,13 @@ def receive_deferred_messages(self, sequence_numbers, **kwargs): self._auto_lock_renewer.register(self, message) return messages - def peek_messages(self, max_message_count=1, **kwargs): - # type: (int, Any) -> List[ServiceBusReceivedMessage] + def peek_messages( + self, + max_message_count: int = 1, + *, + sequence_number: int = 0, + timeout: Optional[float] = None + ) -> List[ServiceBusReceivedMessage]: """Browse messages currently pending in the queue. Peeked messages are not removed from queue, nor are they locked. They cannot be completed, @@ -711,8 +771,6 @@ def peek_messages(self, max_message_count=1, **kwargs): """ self._check_live() - sequence_number = kwargs.pop("sequence_number", 0) - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if not sequence_number: @@ -843,8 +901,12 @@ def dead_letter_message(self, message, reason=None, error_description=None): dead_letter_error_description=error_description, ) - def renew_message_lock(self, message, **kwargs): - # type: (ServiceBusReceivedMessage, Any) -> datetime.datetime + def renew_message_lock( + self, + message: ServiceBusReceivedMessage, + *, + timeout: Optional[float] = None + ) -> datetime.datetime: # pylint: disable=protected-access,no-member """Renew the message lock. @@ -892,7 +954,6 @@ def renew_message_lock(self, message, **kwargs): if not token: raise ValueError("Unable to renew lock - no lock token found.") - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py index 110103814a54..fb9d6ad590ea 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py @@ -5,11 +5,15 @@ import logging import time import uuid -from typing import Any, TYPE_CHECKING, Union, List, Optional, Mapping, cast +import datetime +from typing import Any, TYPE_CHECKING, Dict, Union, List, Optional, Mapping, cast import uamqp from uamqp import SendClient, types from uamqp.authentication.common import AMQPAuth +from uamqp.constants import TransportType + +from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential from ._base_handler import BaseHandler from ._common import mgmt_handlers @@ -41,9 +45,6 @@ ) if TYPE_CHECKING: - import datetime - from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential - MessageTypes = Union[ Mapping[str, Any], ServiceBusMessage, @@ -149,8 +150,19 @@ class ServiceBusSender(BaseHandler, SenderMixin): :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. """ - def __init__(self, fully_qualified_namespace, credential, **kwargs): - # type: (str, Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], Any) -> None + def __init__( + self, + fully_qualified_namespace: str, + credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + *, + queue_name: Optional[str] = None, + topic_name: Optional[str] = None, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: bool = False, + transport_type: TransportType = TransportType.Amqp, + **kwargs + ) -> None: if kwargs.get("entity_name"): super(ServiceBusSender, self).__init__( fully_qualified_namespace=fully_qualified_namespace, @@ -158,8 +170,6 @@ def __init__(self, fully_qualified_namespace, credential, **kwargs): **kwargs ) else: - queue_name = kwargs.get("queue_name") - topic_name = kwargs.get("topic_name") if queue_name and topic_name: raise ValueError( "Queue/Topic name can not be specified simultaneously." @@ -172,7 +182,13 @@ def __init__(self, fully_qualified_namespace, credential, **kwargs): super(ServiceBusSender, self).__init__( fully_qualified_namespace=fully_qualified_namespace, credential=credential, - entity_name=entity_name, + entity_name=str(entity_name), + queue_name=queue_name, + topic_name=topic_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, **kwargs ) @@ -263,8 +279,13 @@ def _send(self, message, timeout=None, last_exception=None): finally: # reset the timeout of the handler back to the default value self._set_msg_timeout(default_timeout, None) - def schedule_messages(self, messages, schedule_time_utc, **kwargs): - # type: (MessageTypes, datetime.datetime, Any) -> List[int] + def schedule_messages( + self, + messages: MessageTypes, + schedule_time_utc: datetime.datetime, + *, + timeout: Optional[float] = None + ) -> List[int]: """Send Message or multiple Messages to be enqueued at a specific time. Returns a list of the sequence numbers of the enqueued messages. @@ -290,7 +311,6 @@ def schedule_messages(self, messages, schedule_time_utc, **kwargs): self._check_live() obj_messages = transform_messages_if_needed(messages, ServiceBusMessage) - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") @@ -314,8 +334,12 @@ def schedule_messages(self, messages, schedule_time_utc, **kwargs): timeout=timeout, ) - def cancel_scheduled_messages(self, sequence_numbers, **kwargs): - # type: (Union[int, List[int]], Any) -> None + def cancel_scheduled_messages( + self, + sequence_numbers: Union[int, List[int]], + *, + timeout: Optional[float] = None + ) -> None: """ Cancel one or more messages that have previously been scheduled and are still pending. @@ -337,7 +361,6 @@ def cancel_scheduled_messages(self, sequence_numbers, **kwargs): :caption: Cancelling messages scheduled to be sent in future """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if isinstance(sequence_numbers, int): @@ -354,8 +377,12 @@ def cancel_scheduled_messages(self, sequence_numbers, **kwargs): timeout=timeout, ) - def send_messages(self, message, **kwargs): - # type: (Union[MessageTypes, ServiceBusMessageBatch], Any) -> None + def send_messages( + self, + message: Union[MessageTypes, ServiceBusMessageBatch], + *, + timeout: Optional[float] = None + ) -> None: """Sends message and blocks until acknowledgement is received or operation times out. If a list of messages was provided, attempts to send them as a single batch, throwing a @@ -387,7 +414,6 @@ def send_messages(self, message, **kwargs): """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") @@ -422,8 +448,10 @@ def send_messages(self, message, **kwargs): require_last_exception=True, ) - def create_message_batch(self, max_size_in_bytes=None): - # type: (Optional[int]) -> ServiceBusMessageBatch + def create_message_batch( + self, + max_size_in_bytes: Optional[int] = None + ) -> ServiceBusMessageBatch: """Create a ServiceBusMessageBatch object with the max size of all content being constrained by max_size_in_bytes. The max_size should be no greater than the max allowed message size defined by the service. diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py index 4ea4f06b623e..3f4c4c1bbfc6 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- import logging import datetime -from typing import TYPE_CHECKING, Union, Optional, Any +from typing import TYPE_CHECKING, Union, Optional import six from ._common.utils import utc_from_timestamp, utc_now @@ -88,8 +88,7 @@ class ServiceBusSession(BaseSession): :caption: Get session from a receiver """ - def get_state(self, **kwargs): - # type: (Any) -> bytes + def get_state(self, timeout: Optional[float] = None) -> bytes: # pylint: disable=protected-access """Get the session state. @@ -109,7 +108,6 @@ def get_state(self, **kwargs): :caption: Get the session state """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") response = self._receiver._mgmt_request_response_with_retry( @@ -121,8 +119,7 @@ def get_state(self, **kwargs): session_state = response.get(MGMT_RESPONSE_SESSION_STATE) # type: ignore return session_state - def set_state(self, state, **kwargs): - # type: (Union[str, bytes, bytearray], Any) -> None + def set_state(self, state: Union[str, bytes, bytearray], timeout: Optional[float] = None) -> None: # pylint: disable=protected-access """Set the session state. @@ -141,7 +138,6 @@ def set_state(self, state, **kwargs): :caption: Set the session state """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") state = ( @@ -157,8 +153,7 @@ def set_state(self, state, **kwargs): timeout=timeout, ) - def renew_lock(self, **kwargs): - # type: (Any) -> datetime.datetime + def renew_lock(self, timeout: Optional[float] = None) -> datetime.datetime: # pylint: disable=protected-access """Renew the session lock. @@ -185,7 +180,6 @@ def renew_lock(self, **kwargs): :caption: Renew the session lock before it expires """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") expiry = self._receiver._mgmt_request_response_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 3ba40cdf2e35..2a25f3acab35 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 @@ -2,11 +2,12 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Any, Union, TYPE_CHECKING +from typing import Any, Dict, Union, Optional, TYPE_CHECKING import logging from weakref import WeakSet import uamqp +from uamqp.constants import TransportType from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from .._base_handler import _parse_conn_str @@ -17,9 +18,11 @@ from ._servicebus_sender_async import ServiceBusSender from ._servicebus_receiver_async import ServiceBusReceiver from .._common._configuration import Configuration +from .._common.auto_lock_renewer import AutoLockRenewer from .._common.utils import generate_dead_letter_entity_name, strip_protocol_from_uri -from .._common.constants import ServiceBusSubQueue +from .._common.constants import ServiceBusSubQueue, NEXT_AVAILABLE_SESSION, ServiceBusReceiveMode from ._async_utils import create_authentication +from .._retry import RetryMode if TYPE_CHECKING: from azure.core.credentials_async import AsyncTokenCredential @@ -76,6 +79,15 @@ def __init__( self, fully_qualified_namespace: str, credential: Union["AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential], + *, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: bool = False, + transport_type: TransportType = TransportType.Amqp, + retry_total: int = 3, + retry_backoff_factor: float = 0.8, + retry_backoff_max: int = 120, + retry_mode=RetryMode.EXPONENTIAL, **kwargs: Any ) -> None: # If the user provided http:// or sb://, let's be polite and strip that. @@ -83,7 +95,17 @@ def __init__( fully_qualified_namespace.strip() ) self._credential = credential - self._config = Configuration(**kwargs) + self._config = Configuration( + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + retry_total=retry_total, + retry_backoff_factor=retry_backoff_factor, + retry_backoff_max=retry_backoff_max, + retry_mode=retry_mode, + **kwargs + ) self._connection = None # Optional entity name, can be the name of Queue or Topic. Intentionally not advertised, typically be needed. self._entity_name = kwargs.get("entity_name") @@ -111,7 +133,20 @@ async def _create_uamqp_connection(self): ) @classmethod - def from_connection_string(cls, conn_str: str, **kwargs: Any) -> "ServiceBusClient": + def from_connection_string( + cls, + conn_str: str, + *, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: bool = False, + transport_type: TransportType = TransportType.Amqp, + retry_total: int = 3, + retry_backoff_factor: float = 0.8, + retry_backoff_max: int = 120, + retry_mode=RetryMode.EXPONENTIAL, + **kwargs: Any + ) -> "ServiceBusClient": """ Create a ServiceBusClient from a connection string. @@ -156,6 +191,14 @@ def from_connection_string(cls, conn_str: str, **kwargs: Any) -> "ServiceBusClie fully_qualified_namespace=host, entity_name=entity_in_conn_str or kwargs.pop("entity_name", None), credential=credential, # type: ignore + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + retry_total=retry_total, + retry_backoff_factor=retry_backoff_factor, + retry_backoff_max=retry_backoff_max, + retry_mode=retry_mode, **kwargs ) @@ -180,7 +223,11 @@ async def close(self) -> None: if self._connection_sharing and self._connection: await self._connection.destroy_async() - def get_queue_sender(self, queue_name: str, **kwargs: Any) -> ServiceBusSender: + def get_queue_sender( + self, + queue_name: str, + **kwargs: Any + ) -> ServiceBusSender: """Get ServiceBusSender for the specific queue. :param str queue_name: The path of specific Service Bus Queue the client connects to. @@ -222,7 +269,18 @@ def get_queue_sender(self, queue_name: str, **kwargs: Any) -> ServiceBusSender: self._handlers.add(handler) return handler - def get_queue_receiver(self, queue_name: str, **kwargs: Any) -> ServiceBusReceiver: + def get_queue_receiver( + self, + queue_name: str, + *, + session_id: Union[str, NEXT_AVAILABLE_SESSION] = None, + sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, + receive_mode: Union[ServiceBusReceiveMode, str] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, + **kwargs: Any + ) -> ServiceBusReceiver: """Get ServiceBusReceiver for the specific queue. :param str queue_name: The path of specific Service Bus Queue the client connects to. @@ -274,8 +332,7 @@ def get_queue_receiver(self, queue_name: str, **kwargs: Any) -> ServiceBusReceiv "the connection string used to construct the ServiceBusClient." ) - sub_queue = kwargs.get("sub_queue", None) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -307,6 +364,12 @@ def get_queue_receiver(self, queue_name: str, **kwargs: Any) -> ServiceBusReceiv retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) self._handlers.add(handler) @@ -354,7 +417,19 @@ def get_topic_sender(self, topic_name: str, **kwargs: Any) -> ServiceBusSender: return handler def get_subscription_receiver( - self, topic_name: str, subscription_name: str, **kwargs: Any + self, + topic_name: str, + subscription_name: str, + *, + session_id: Union[str, NEXT_AVAILABLE_SESSION] = NEXT_AVAILABLE_SESSION, + sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, + **kwargs: Any ) -> ServiceBusReceiver: """Get ServiceBusReceiver for the specific subscription under the topic. @@ -410,8 +485,7 @@ def get_subscription_receiver( "the connection string used to construct the ServiceBusClient." ) - sub_queue = kwargs.get("sub_queue", None) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -439,6 +513,12 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) except ValueError: @@ -460,6 +540,12 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, + sub_queue=sub_queue, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) self._handlers.add(handler) 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 a920bd32c44d..3b64a27782c1 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 @@ -7,17 +7,19 @@ import datetime import functools import logging -from typing import Any, TYPE_CHECKING, List, Optional, AsyncIterator, Union, Callable +from typing import Any, List, Dict, Optional, AsyncIterator, Union, Callable import six from uamqp import ReceiveClientAsync, types, Message -from uamqp.constants import SenderSettleMode +from uamqp.constants import SenderSettleMode, TransportType +from azure.core.credentials_async import AsyncTokenCredential from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from ..exceptions import ServiceBusError from ._servicebus_session_async import ServiceBusSession from ._base_handler_async import BaseHandler +from .._common.auto_lock_renewer import AutoLockRenewer from .._common.message import ServiceBusReceivedMessage from .._common.receiver_mixins import ReceiverMixin from .._common.constants import ( @@ -53,8 +55,6 @@ ) from ._async_utils import create_authentication, get_running_loop -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential _LOGGER = logging.getLogger(__name__) @@ -121,6 +121,20 @@ def __init__( self, fully_qualified_namespace: str, credential: Union["AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential], + *, + queue_name: Optional[str] = None, + topic_name: Optional[str] = None, + subscription_name: Optional[str] = None, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: Optional[bool] = False, + transport_type: Optional[TransportType] = TransportType.Amqp, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, + max_wait_time: Optional[float] = None, + auto_lock_renewer: Optional[AutoLockRenewer] = None, + prefetch_count: int = 0, **kwargs: Any ) -> None: self._message_iter = ( @@ -130,12 +144,20 @@ def __init__( super(ServiceBusReceiver, self).__init__( fully_qualified_namespace=fully_qualified_namespace, credential=credential, + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) else: - queue_name = kwargs.get("queue_name") - topic_name = kwargs.get("topic_name") - subscription_name = kwargs.get("subscription_name") if queue_name and topic_name: raise ValueError( "Queue/Topic name can not be specified simultaneously." @@ -155,10 +177,34 @@ def __init__( fully_qualified_namespace=fully_qualified_namespace, credential=credential, entity_name=str(entity_name), + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, **kwargs ) - self._populate_attributes(**kwargs) + self._populate_attributes( + queue_name=queue_name, + topic_name=topic_name, + subscription_name=subscription_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, + receive_mode=receive_mode, + max_wait_time=max_wait_time, + auto_lock_renewer=auto_lock_renewer, + prefetch_count=prefetch_count, + **kwargs + ) self._session = ( None if self._session_id is None else ServiceBusSession(self._session_id, self) ) @@ -616,7 +662,7 @@ async def receive_messages( return messages async def receive_deferred_messages( - self, sequence_numbers: Union[int, List[int]], **kwargs: Any + self, sequence_numbers: Union[int, List[int]], *, timeout: Optional[float] = None ) -> List[ServiceBusReceivedMessage]: """Receive messages that have previously been deferred. @@ -640,7 +686,6 @@ async def receive_deferred_messages( """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if isinstance(sequence_numbers, six.integer_types): @@ -688,7 +733,7 @@ async def receive_deferred_messages( return messages async def peek_messages( - self, max_message_count: int = 1, **kwargs: Any + self, max_message_count: int = 1, *, sequence_number: int = 0, timeout: Optional[float] = None ) -> List[ServiceBusReceivedMessage]: """Browse messages currently pending in the queue. @@ -712,8 +757,6 @@ async def peek_messages( :caption: Peek messages in the queue. """ self._check_live() - sequence_number = kwargs.pop("sequence_number", 0) - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if not sequence_number: @@ -845,8 +888,9 @@ async def dead_letter_message(self, message, reason=None, error_description=None dead_letter_error_description=error_description, ) - async def renew_message_lock(self, message, **kwargs): - # type: (ServiceBusReceivedMessage, Any) -> datetime.datetime + async def renew_message_lock( + self, message: ServiceBusReceivedMessage, *, timeout: Optional[float] = None + ) -> datetime.datetime: # pylint: disable=protected-access,no-member """Renew the message lock. @@ -894,7 +938,6 @@ async def renew_message_lock(self, message, **kwargs): if not token: raise ValueError("Unable to renew lock - no lock token found.") - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") 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 b377f1fae964..5afc7cc6c570 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 @@ -5,10 +5,11 @@ import logging import asyncio import datetime -from typing import Any, TYPE_CHECKING, Union, List, Optional, Mapping, cast +from typing import Any, TYPE_CHECKING, Dict, Union, List, Optional, Mapping, cast import uamqp from uamqp import SendClientAsync, types +from uamqp.constants import TransportType from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from .._common.message import ( @@ -91,6 +92,13 @@ def __init__( self, fully_qualified_namespace: str, credential: Union["AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential], + *, + queue_name: Optional[str] = None, + topic_name: Optional[str] = None, + http_proxy: Optional[Dict[str, Any]] = None, + user_agent: Optional[str] = None, + logging_enable: bool = False, + transport_type: TransportType = TransportType.Amqp, **kwargs: Any ) -> None: if kwargs.get("entity_name"): @@ -100,8 +108,6 @@ def __init__( **kwargs ) else: - queue_name = kwargs.get("queue_name") - topic_name = kwargs.get("topic_name") if queue_name and topic_name: raise ValueError( "Queue/Topic name can not be specified simultaneously." @@ -115,6 +121,12 @@ def __init__( fully_qualified_namespace=fully_qualified_namespace, credential=credential, entity_name=str(entity_name), + queue_name=queue_name, + topic_name=topic_name, + http_proxy=http_proxy, + user_agent=user_agent, + logging_enable=logging_enable, + transport_type=transport_type, **kwargs ) @@ -203,6 +215,8 @@ async def schedule_messages( self, messages: MessageTypes, schedule_time_utc: datetime.datetime, + *, + timeout: Optional[float] = None, **kwargs: Any ) -> List[int]: """Send Message or multiple Messages to be enqueued at a specific time by the service. @@ -230,7 +244,6 @@ async def schedule_messages( self._check_live() obj_messages = transform_messages_if_needed(messages, ServiceBusMessage) - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") with send_trace_context_manager(span_name=SPAN_NAME_SCHEDULE) as send_span: @@ -254,7 +267,7 @@ async def schedule_messages( ) async def cancel_scheduled_messages( - self, sequence_numbers: Union[int, List[int]], **kwargs: Any + self, sequence_numbers: Union[int, List[int]], *, timeout: Optional[float] = None, **kwargs: Any ) -> None: """ Cancel one or more messages that have previously been scheduled and are still pending. @@ -277,7 +290,6 @@ async def cancel_scheduled_messages( :caption: Cancelling messages scheduled to be sent in future """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") if isinstance(sequence_numbers, int): @@ -295,7 +307,7 @@ async def cancel_scheduled_messages( ) async def send_messages( - self, message: Union[MessageTypes, ServiceBusMessageBatch], **kwargs: Any + self, message: Union[MessageTypes, ServiceBusMessageBatch], *, timeout: Optional[float] = None, **kwargs: Any ) -> None: """Sends message and blocks until acknowledgement is received or operation times out. @@ -329,7 +341,6 @@ async def send_messages( """ self._check_live() - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py index 712eebd2c374..6010ab1c5b42 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- import logging import datetime -from typing import Union, Any +from typing import Union, Optional import six from .._servicebus_session import BaseSession @@ -40,7 +40,7 @@ class ServiceBusSession(BaseSession): :caption: Get session from a receiver """ - async def get_state(self, **kwargs: Any) -> bytes: + async def get_state(self, timeout: Optional[float] = None) -> bytes: """Get the session state. Returns None if no state has been set. @@ -59,7 +59,6 @@ async def get_state(self, **kwargs: Any) -> bytes: :caption: Get the session state """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") response = await self._receiver._mgmt_request_response_with_retry( # pylint: disable=protected-access @@ -72,7 +71,7 @@ async def get_state(self, **kwargs: Any) -> bytes: return session_state async def set_state( - self, state: Union[str, bytes, bytearray], **kwargs: Any + self, state: Union[str, bytes, bytearray], timeout: Optional[float] = None ) -> None: """Set the session state. @@ -92,7 +91,6 @@ async def set_state( :caption: Set the session state """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") state = ( @@ -108,7 +106,7 @@ async def set_state( timeout=timeout, ) - async def renew_lock(self, **kwargs: Any) -> datetime.datetime: + async def renew_lock(self, timeout: Optional[float] = None) -> datetime.datetime: """Renew the session lock. This operation must be performed periodically in order to retain a lock on the @@ -134,7 +132,6 @@ async def renew_lock(self, **kwargs: Any) -> datetime.datetime: :caption: Renew the session lock before it expires """ self._receiver._check_live() # pylint: disable=protected-access - timeout = kwargs.pop("timeout", None) if timeout is not None and timeout <= 0: raise ValueError("The timeout must be greater than 0.") expiry = await self._receiver._mgmt_request_response_with_retry( # pylint: disable=protected-access diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py index a30b92cf89c7..1562de056c33 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py @@ -6,8 +6,9 @@ # pylint:disable=specify-parameter-names-in-call # pylint:disable=too-many-lines import functools +import datetime from copy import deepcopy -from typing import TYPE_CHECKING, Any, Union, cast, Mapping +from typing import Any, Union, cast, Mapping, Optional, List from xml.etree.ElementTree import ElementTree from azure.core.async_paging import AsyncItemPaged @@ -21,6 +22,7 @@ AsyncBearerTokenCredentialPolicy, ) from azure.core.pipeline.transport import AioHttpTransport +from azure.core.credentials_async import AsyncTokenCredential from ...management._generated.models import ( QueueDescriptionFeed, @@ -62,6 +64,7 @@ from ...management._api_version import DEFAULT_VERSION from ._shared_key_policy_async import AsyncServiceBusSharedKeyCredentialPolicy from ...management._models import ( + AuthorizationRule, QueueRuntimeProperties, QueueProperties, TopicProperties, @@ -71,6 +74,9 @@ RuleProperties, NamespaceProperties, TrueRuleFilter, + CorrelationRuleFilter, + SqlRuleFilter, + SqlRuleAction, ) from ...management._xml_workaround_policy import ServiceBusXMLWorkaroundPolicy from ...management._handle_response_error import _handle_response_error @@ -85,11 +91,6 @@ _validate_topic_subscription_and_rule_types, ) -if TYPE_CHECKING: - from azure.core.credentials_async import ( - AsyncTokenCredential, - ) # pylint:disable=ungrouped-imports - class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods """Use this client to create, update, list, and delete resources of a ServiceBus namespace. @@ -106,11 +107,13 @@ def __init__( self, fully_qualified_namespace: str, credential: "AsyncTokenCredential", + *, + api_version: str = DEFAULT_VERSION, **kwargs: Any ) -> None: self.fully_qualified_namespace = fully_qualified_namespace - self._api_version = kwargs.pop("api_version", DEFAULT_VERSION) + self._api_version = api_version self._credential = credential self._endpoint = "https://" + fully_qualified_namespace self._config = ServiceBusManagementClientConfiguration(self._endpoint, **kwargs) @@ -237,7 +240,7 @@ async def _populate_header_within_kwargs(uri, header): @classmethod def from_connection_string( - cls, conn_str: str, **kwargs: Any + cls, conn_str: str, *, api_version: str = DEFAULT_VERSION, **kwargs: Any ) -> "ServiceBusAdministrationClient": """Create a client from connection string. @@ -261,7 +264,7 @@ def from_connection_string( credential = ServiceBusSharedKeyCredential(shared_access_key_name, shared_access_key) # type: ignore if "//" in endpoint: endpoint = endpoint[endpoint.index("//") + 2 :] - return cls(endpoint, credential, **kwargs) # type: ignore + return cls(endpoint, credential, api_version=api_version, **kwargs) # type: ignore async def get_queue(self, queue_name: str, **kwargs) -> QueueProperties: """Get the properties of a queue. @@ -295,7 +298,29 @@ async def get_queue_runtime_properties( ) return runtime_properties - async def create_queue(self, queue_name: str, **kwargs) -> QueueProperties: + async def create_queue( + self, + queue_name: str, + *, + authorization_rules: Optional[list[AuthorizationRule]] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + dead_lettering_on_message_expiration: Optional[bool] = None, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + enable_batched_operations: Optional[bool] = None, + enable_express: Optional[bool] = None, + enable_partitioning: Optional[bool] = None, + lock_duration: Optional[Union[datetime.timedelta, str]] = None, + max_delivery_count: Optional[int] = None, + max_size_in_megabytes: Optional[int] = None, + requires_duplicate_detection: Optional[bool] = None, + requires_session: Optional[bool] = None, + forward_to: Optional[str] = None, + user_metadata: Optional[str] = None, + forward_dead_lettered_messages_to: Optional[str] = None, + max_message_size_in_kilobytes: Optional[int] = None, + **kwargs: Any + ) -> QueueProperties: """Create a queue. :param queue_name: Name of the queue. @@ -362,43 +387,35 @@ async def create_queue(self, queue_name: str, **kwargs) -> QueueProperties: :rtype: ~azure.servicebus.management.QueueProperties """ forward_to = _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_to", None), self.fully_qualified_namespace + forward_to, self.fully_qualified_namespace ) forward_dead_lettered_messages_to = ( _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_dead_lettered_messages_to", None), + forward_dead_lettered_messages_to, self.fully_qualified_namespace, ) ) queue = QueueProperties( queue_name, - authorization_rules=kwargs.pop("authorization_rules", None), - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), - dead_lettering_on_message_expiration=kwargs.pop( - "dead_lettering_on_message_expiration", None - ), - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - duplicate_detection_history_time_window=kwargs.pop( - "duplicate_detection_history_time_window", None - ), + authorization_rules=authorization_rules, + auto_delete_on_idle=auto_delete_on_idle, + dead_lettering_on_message_expiration=dead_lettering_on_message_expiration, + default_message_time_to_live=default_message_time_to_live, + duplicate_detection_history_time_window=duplicate_detection_history_time_window, availability_status=None, - enable_batched_operations=kwargs.pop("enable_batched_operations", None), - enable_express=kwargs.pop("enable_express", None), - enable_partitioning=kwargs.pop("enable_partitioning", None), - lock_duration=kwargs.pop("lock_duration", None), - max_delivery_count=kwargs.pop("max_delivery_count", None), - max_size_in_megabytes=kwargs.pop("max_size_in_megabytes", None), - requires_duplicate_detection=kwargs.pop( - "requires_duplicate_detection", None - ), - requires_session=kwargs.pop("requires_session", None), + enable_batched_operations=enable_batched_operations, + enable_express=enable_express, + enable_partitioning=enable_partitioning, + lock_duration=lock_duration, + max_delivery_count=max_delivery_count, + max_size_in_megabytes=max_size_in_megabytes, + requires_duplicate_detection=requires_duplicate_detection, + requires_session=requires_session, status=kwargs.pop("status", None), forward_to=forward_to, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, - user_metadata=kwargs.pop("user_metadata", None), - max_message_size_in_kilobytes=kwargs.pop("max_message_size_in_kilobytes", None) + user_metadata=user_metadata, + max_message_size_in_kilobytes=max_message_size_in_kilobytes ) to_create = queue._to_internal_entity(self.fully_qualified_namespace) create_entity_body = CreateQueueBody( @@ -560,7 +577,26 @@ async def get_topic_runtime_properties( ) return topic_description - async def create_topic(self, topic_name: str, **kwargs) -> TopicProperties: + async def create_topic( + self, + topic_name: str, + *, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + max_size_in_megabytes: Optional[float] = None, # TODO: said long? should it be float + requires_duplicate_detection: Optional[bool] = None, + duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + enable_batched_operations: Optional[bool] = None, + size_in_bytes: Optional[int] = None, + filtering_messages_before_publishing: Optional[bool] = None, + authorization_rules: Optional[List[AuthorizationRule]] = None, + support_ordering: Optional[bool] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + enable_partitioning: Optional[bool] = None, + enable_express: Optional[bool] = None, + user_metadata: Optional[str] = None, + max_message_size_in_kilobytes: Optional[int] = None, + **kwargs: Any + ) -> TopicProperties: """Create a topic. :param topic_name: Name of the topic. @@ -615,27 +651,24 @@ async def create_topic(self, topic_name: str, **kwargs) -> TopicProperties: topic = TopicProperties( topic_name, - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - max_size_in_megabytes=kwargs.pop("max_size_in_megabytes", None), - requires_duplicate_detection=kwargs.pop( - "requires_duplicate_detection", None - ), - duplicate_detection_history_time_window=kwargs.pop( - "duplicate_detection_history_time_window", None - ), - enable_batched_operations=kwargs.pop("enable_batched_operations", None), - size_in_bytes=kwargs.pop("size_in_bytes", None), - authorization_rules=kwargs.pop("authorization_rules", None), + default_message_time_to_live=default_message_time_to_live, + max_size_in_megabytes=max_size_in_megabytes, + requires_duplicate_detection=requires_duplicate_detection, + # TODO: ask why default of 10 mins isn't followed below, + duplicate_detection_history_time_window=duplicate_detection_history_time_window, + enable_batched_operations=enable_batched_operations, + size_in_bytes=size_in_bytes, + authorization_rules=authorization_rules, + filtering_messages_before_publishing=filtering_messages_before_publishing, status=kwargs.pop("status", None), - support_ordering=kwargs.pop("support_ordering", None), - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), - enable_partitioning=kwargs.pop("enable_partitioning", None), + support_ordering=support_ordering, + auto_delete_on_idle=auto_delete_on_idle, + enable_partitioning=enable_partitioning, availability_status=None, - enable_express=kwargs.pop("enable_express", None), - user_metadata=kwargs.pop("user_metadata", None), - max_message_size_in_kilobytes=kwargs.pop("max_message_size_in_kilobytes", None) + enable_express=enable_express, + user_metadata=user_metadata, + max_message_size_in_kilobytes=max_message_size_in_kilobytes, + **kwargs ) to_create = topic._to_internal_entity() @@ -808,7 +841,22 @@ async def get_subscription_runtime_properties( return subscription async def create_subscription( - self, topic_name: str, subscription_name: str, **kwargs + self, + topic_name: str, + subscription_name: str, + *, + lock_duration: Optional[Union[datetime.timedelta, str]] = None, + requires_session: Optional[bool] = None, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + dead_lettering_on_message_expiration: Optional[bool] = None, + dead_lettering_on_filter_evaluation_exceptions: Optional[bool] = None, + max_delivery_count: Optional[int] = None, + enable_batched_operations: Optional[bool] = None, + forward_to: Optional[str] = None, + user_metadata: Optional[str] = None, + forward_dead_lettered_messages_to: Optional[str] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + **kwargs: Any ) -> SubscriptionProperties: """Create a topic subscription. @@ -859,35 +907,29 @@ async def create_subscription( # pylint:disable=protected-access _validate_entity_name_type(topic_name, display_name="topic_name") forward_to = _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_to", None), self.fully_qualified_namespace + forward_to, self.fully_qualified_namespace ) forward_dead_lettered_messages_to = ( _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_dead_lettered_messages_to", None), + forward_dead_lettered_messages_to, self.fully_qualified_namespace, ) ) subscription = SubscriptionProperties( subscription_name, - lock_duration=kwargs.pop("lock_duration", None), - requires_session=kwargs.pop("requires_session", None), - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - dead_lettering_on_message_expiration=kwargs.pop( - "dead_lettering_on_message_expiration", None - ), - dead_lettering_on_filter_evaluation_exceptions=kwargs.pop( - "dead_lettering_on_filter_evaluation_exceptions", None - ), - max_delivery_count=kwargs.pop("max_delivery_count", None), - enable_batched_operations=kwargs.pop("enable_batched_operations", None), + lock_duration=lock_duration, + requires_session=requires_session, + default_message_time_to_live=default_message_time_to_live, + dead_lettering_on_message_expiration=dead_lettering_on_message_expiration, + dead_lettering_on_filter_evaluation_exceptions=dead_lettering_on_filter_evaluation_exceptions, + max_delivery_count=max_delivery_count, + enable_batched_operations=enable_batched_operations, status=kwargs.pop("status", None), forward_to=forward_to, - user_metadata=kwargs.pop("user_metadata", None), + user_metadata=user_metadata, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), + auto_delete_on_idle=auto_delete_on_idle, availability_status=None, ) to_create = subscription._to_internal_entity(self.fully_qualified_namespace) # type: ignore @@ -1062,7 +1104,14 @@ async def get_rule( return rule_description async def create_rule( - self, topic_name: str, subscription_name: str, rule_name: str, **kwargs + self, + topic_name: str, + subscription_name: str, + rule_name: str, + *, + filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), + action: Optional[SqlRuleAction] = None, + **kwargs: Any ) -> RuleProperties: """Create a rule for a topic subscription. @@ -1084,8 +1133,8 @@ async def create_rule( rule = RuleProperties( rule_name, - filter=kwargs.pop("filter", TrueRuleFilter()), - action=kwargs.pop("action", None), + filter=filter, + action=action, created_at_utc=None, ) to_create = rule._to_internal_entity() diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py index ec60df31e3cc..f34e1544cfe1 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py @@ -5,8 +5,9 @@ # ------------------------------------------------------------------------- import time +import uuid from datetime import datetime -from typing import Optional, Any, cast, Mapping +from typing import Optional, Any, cast, Mapping, Union, List from msrest.serialization import TZ_UTC import uamqp @@ -112,8 +113,20 @@ class AmqpAnnotatedMessage(object): :paramtype delivery_annotations: Optional[dict] """ - def __init__(self, **kwargs): - # type: (Any) -> None + def __init__( + self, + *, + data_body: Optional[Union[str, bytes, List[Union[str, bytes]]]] = None, + sequence_body: Optional[List[Any]] = None, + value_body: Any = None, + header: Optional[AmqpMessageHeader] = None, + footer: Optional[dict] = None, + properties: Optional[AmqpMessageProperties] = None, + application_properties: Optional[dict] = None, + annotations: Optional[dict] = None, + delivery_annotations: Optional[dict] = None, + **kwargs: Any + ) -> None: self._message = kwargs.pop("message", None) self._encoding = kwargs.pop("encoding", "UTF-8") @@ -123,7 +136,7 @@ def __init__(self, **kwargs): return # manually constructed AMQPAnnotatedMessage - input_count_validation = len([key for key in ("data_body", "sequence_body", "value_body") if key in kwargs]) + input_count_validation = len([key for key in (data_body, sequence_body, value_body) if key]) if input_count_validation != 1: raise ValueError( "There should be one and only one of either data_body, sequence_body " @@ -132,25 +145,25 @@ def __init__(self, **kwargs): self._body = None self._body_type = None - if "data_body" in kwargs: - self._body = kwargs.get("data_body") + if data_body: + self._body = data_body self._body_type = uamqp.MessageBodyType.Data - elif "sequence_body" in kwargs: - self._body = kwargs.get("sequence_body") + elif sequence_body: + self._body = sequence_body self._body_type = uamqp.MessageBodyType.Sequence - elif "value_body" in kwargs: - self._body = kwargs.get("value_body") + elif value_body: + self._body = value_body self._body_type = uamqp.MessageBodyType.Value self._message = uamqp.message.Message(body=self._body, body_type=self._body_type) - header_dict = cast(Mapping, kwargs.get("header")) - self._header = AmqpMessageHeader(**header_dict) if "header" in kwargs else None - self._footer = kwargs.get("footer") - properties_dict = cast(Mapping, kwargs.get("properties")) - self._properties = AmqpMessageProperties(**properties_dict) if "properties" in kwargs else None - self._application_properties = kwargs.get("application_properties") - self._annotations = kwargs.get("annotations") - self._delivery_annotations = kwargs.get("delivery_annotations") + header_dict = cast(Mapping, header) + self._header = AmqpMessageHeader(**header_dict) if header else None + self._footer = footer + properties_dict = cast(Mapping, properties) + self._properties = AmqpMessageProperties(**properties_dict) if properties else None + self._application_properties = application_properties + self._annotations = annotations + self._delivery_annotations = delivery_annotations def __str__(self): # type: () -> str @@ -483,12 +496,19 @@ class AmqpMessageHeader(DictMixin): priority messages. Messages with higher priorities MAY be delivered before those with lower priorities. :vartype priority: Optional[int] """ - def __init__(self, **kwargs): - self.delivery_count = kwargs.get("delivery_count") - self.time_to_live = kwargs.get("time_to_live") - self.first_acquirer = kwargs.get("first_acquirer") - self.durable = kwargs.get("durable") - self.priority = kwargs.get("priority") + def __init__( + self, + delivery_count: Optional[int] = None, + time_to_live: Optional[int] = None, + durable: Optional[bool] = None, + first_acquirer: Optional[bool] = None, + priority: Optional[int] = None + ): + self.delivery_count = delivery_count + self.time_to_live = time_to_live + self.first_acquirer = first_acquirer + self.durable = durable + self.priority = priority class AmqpMessageProperties(DictMixin): @@ -568,17 +588,32 @@ class AmqpMessageProperties(DictMixin): to this message to a specific group. :vartype reply_to_group_id: Optional[Union[str, bytes]] """ - def __init__(self, **kwargs): - self.message_id = kwargs.get("message_id") - self.user_id = kwargs.get("user_id") - self.to = kwargs.get("to") - self.subject = kwargs.get("subject") - self.reply_to = kwargs.get("reply_to") - self.correlation_id = kwargs.get("correlation_id") - self.content_type = kwargs.get("content_type") - self.content_encoding = kwargs.get("content_encoding") - self.creation_time = kwargs.get("creation_time") - self.absolute_expiry_time = kwargs.get("absolute_expiry_time") - self.group_id = kwargs.get("group_id") - self.group_sequence = kwargs.get("group_sequence") - self.reply_to_group_id = kwargs.get("reply_to_group_id") + def __init__( + self, + message_id: Optional[Union[str, bytes, uuid.UUID]] = None, + user_id: Optional[Union[str, bytes]] = None, + to: Optional[Union[str, bytes]] = None, + subject: Optional[Union[str, bytes]] = None, + reply_to: Optional[Union[str, bytes]] = None, + correlation_id: Optional[Union[str, bytes]] = None, + content_type: Optional[Union[str, bytes]] = None, + content_encoding: Optional[Union[str, bytes]] = None, + creation_time: Optional[int] = None, + absolute_expiry_time: Optional[int] = None, + group_id: Optional[Union[str, bytes]] = None, + group_sequence: Optional[int] = None, + reply_to_group_id: Optional[Union[str, bytes]] = None + ): + self.message_id = message_id + self.user_id = user_id + self.to = to + self.subject = subject + self.reply_to = reply_to + self.correlation_id = correlation_id + self.content_type = content_type + self.content_encoding = content_encoding + self.creation_time = creation_time + self.absolute_expiry_time = absolute_expiry_time + self.group_id = group_id + self.group_sequence = group_sequence + self.reply_to_group_id = reply_to_group_id diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py index f7545396270a..8a32362d4a9f 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py @@ -6,8 +6,9 @@ # pylint:disable=specify-parameter-names-in-call # pylint:disable=too-many-lines import functools +import datetime from copy import deepcopy -from typing import TYPE_CHECKING, Dict, Any, Union, cast, Mapping +from typing import Any, Union, cast, Mapping, Optional, List from xml.etree.ElementTree import ElementTree from azure.core.paging import ItemPaged @@ -21,6 +22,7 @@ BearerTokenCredentialPolicy, ) from azure.core.pipeline.transport import RequestsTransport +from azure.core.credentials import TokenCredential from ._generated.models import ( QueueDescriptionFeed, @@ -73,6 +75,7 @@ from . import _constants as constants from ._api_version import DEFAULT_VERSION from ._models import ( + AuthorizationRule, QueueRuntimeProperties, QueueProperties, TopicProperties, @@ -82,13 +85,12 @@ RuleProperties, NamespaceProperties, TrueRuleFilter, + CorrelationRuleFilter, + SqlRuleFilter, + SqlRuleAction, ) from ._handle_response_error import _handle_response_error -if TYPE_CHECKING: - from azure.core.credentials import ( - TokenCredential, - ) # pylint:disable=ungrouped-imports class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods @@ -102,13 +104,19 @@ class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods in reduced feature compatibility. """ - def __init__(self, fully_qualified_namespace, credential, **kwargs): - # type: (str, TokenCredential, Dict[str, Any]) -> None + def __init__( + self, + fully_qualified_namespace: str, + credential: TokenCredential, + *, + api_version: str = DEFAULT_VERSION, + **kwargs: Any + ) -> None: self.fully_qualified_namespace = fully_qualified_namespace - self._api_version = kwargs.pop("api_version", DEFAULT_VERSION) + self._api_version = api_version self._credential = credential self._endpoint = "https://" + fully_qualified_namespace - self._config = ServiceBusManagementClientConfiguration(self._endpoint, **kwargs) + self._config = ServiceBusManagementClientConfiguration(self._endpoint, api_version=api_version, **kwargs) self._pipeline = self._build_pipeline() self._impl = ServiceBusManagementClientImpl( endpoint=fully_qualified_namespace, pipeline=self._pipeline @@ -228,8 +236,13 @@ def _populate_header_within_kwargs(uri, header): ) @classmethod - def from_connection_string(cls, conn_str, **kwargs): - # type: (str, Any) -> ServiceBusAdministrationClient + def from_connection_string( + cls, + conn_str: str, + *, + api_version: str = DEFAULT_VERSION, + **kwargs: Any + ) -> "ServiceBusAdministrationClient": """Create a client from connection string. :param str conn_str: The connection string of the Service Bus Namespace. @@ -252,10 +265,13 @@ def from_connection_string(cls, conn_str, **kwargs): credential = ServiceBusSharedKeyCredential(shared_access_key_name, shared_access_key) # type: ignore if "//" in endpoint: endpoint = endpoint[endpoint.index("//") + 2 :] - return cls(endpoint, credential, **kwargs) + return cls(endpoint, credential, api_version=api_version, **kwargs) - def get_queue(self, queue_name, **kwargs): - # type: (str, Any) -> QueueProperties + def get_queue( + self, + queue_name: str, + **kwargs: Any + ) -> QueueProperties: """Get the properties of a queue. :param str queue_name: The name of the queue. @@ -286,8 +302,29 @@ def get_queue_runtime_properties(self, queue_name, **kwargs): ) return runtime_properties - def create_queue(self, queue_name, **kwargs): - # type: (str, Any) -> QueueProperties + def create_queue( + self, + queue_name: str, + *, + authorization_rules: Optional[list[AuthorizationRule]] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + dead_lettering_on_message_expiration: Optional[bool] = None, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + enable_batched_operations: Optional[bool] = None, + enable_express: Optional[bool] = None, + enable_partitioning: Optional[bool] = None, + lock_duration: Optional[Union[datetime.timedelta, str]] = None, + max_delivery_count: Optional[int] = None, + max_size_in_megabytes: Optional[int] = None, + requires_duplicate_detection: Optional[bool] = None, + requires_session: Optional[bool] = None, + forward_to: Optional[str] = None, + user_metadata: Optional[str] = None, + forward_dead_lettered_messages_to: Optional[str] = None, + max_message_size_in_kilobytes: Optional[int] = None, + **kwargs: Any + ) -> QueueProperties: """Create a queue. :param queue_name: Name of the queue. @@ -354,43 +391,35 @@ def create_queue(self, queue_name, **kwargs): :rtype: ~azure.servicebus.management.QueueProperties """ forward_to = _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_to", None), self.fully_qualified_namespace + forward_to, self.fully_qualified_namespace ) forward_dead_lettered_messages_to = ( _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_dead_lettered_messages_to", None), + forward_dead_lettered_messages_to, self.fully_qualified_namespace, ) ) queue = QueueProperties( queue_name, - authorization_rules=kwargs.pop("authorization_rules", None), - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), - dead_lettering_on_message_expiration=kwargs.pop( - "dead_lettering_on_message_expiration", None - ), - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - duplicate_detection_history_time_window=kwargs.pop( - "duplicate_detection_history_time_window", None - ), + authorization_rules=authorization_rules, + auto_delete_on_idle=auto_delete_on_idle, + dead_lettering_on_message_expiration=dead_lettering_on_message_expiration, + default_message_time_to_live=default_message_time_to_live, + duplicate_detection_history_time_window=duplicate_detection_history_time_window, availability_status=None, - enable_batched_operations=kwargs.pop("enable_batched_operations", None), - enable_express=kwargs.pop("enable_express", None), - enable_partitioning=kwargs.pop("enable_partitioning", None), - lock_duration=kwargs.pop("lock_duration", None), - max_delivery_count=kwargs.pop("max_delivery_count", None), - max_size_in_megabytes=kwargs.pop("max_size_in_megabytes", None), - requires_duplicate_detection=kwargs.pop( - "requires_duplicate_detection", None - ), - requires_session=kwargs.pop("requires_session", None), + enable_batched_operations=enable_batched_operations, + enable_express=enable_express, + enable_partitioning=enable_partitioning, + lock_duration=lock_duration, + max_delivery_count=max_delivery_count, + max_size_in_megabytes=max_size_in_megabytes, + requires_duplicate_detection=requires_duplicate_detection, + requires_session=requires_session, status=kwargs.pop("status", None), forward_to=forward_to, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, - user_metadata=kwargs.pop("user_metadata", None), - max_message_size_in_kilobytes=kwargs.pop("max_message_size_in_kilobytes", None) + user_metadata=user_metadata, + max_message_size_in_kilobytes=max_message_size_in_kilobytes ) to_create = queue._to_internal_entity(self.fully_qualified_namespace) create_entity_body = CreateQueueBody( @@ -552,8 +581,26 @@ def get_topic_runtime_properties(self, topic_name, **kwargs): ) return topic_description - def create_topic(self, topic_name, **kwargs): - # type: (str, Any) -> TopicProperties + def create_topic( + self, + topic_name: str, + *, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + max_size_in_megabytes: Optional[float] = None, # TODO: said long? should it be float + requires_duplicate_detection: Optional[bool] = None, + duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + enable_batched_operations: Optional[bool] = None, + size_in_bytes: Optional[int] = None, + filtering_messages_before_publishing: Optional[bool] = None, + authorization_rules: Optional[List[AuthorizationRule]] = None, + support_ordering: Optional[bool] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + enable_partitioning: Optional[bool] = None, + enable_express: Optional[bool] = None, + user_metadata: Optional[str] = None, + max_message_size_in_kilobytes: Optional[int] = None, + **kwargs: Any + ) -> TopicProperties: """Create a topic. :param topic_name: Name of the topic. @@ -607,27 +654,24 @@ def create_topic(self, topic_name, **kwargs): """ topic = TopicProperties( topic_name, - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - max_size_in_megabytes=kwargs.pop("max_size_in_megabytes", None), - requires_duplicate_detection=kwargs.pop( - "requires_duplicate_detection", None - ), - duplicate_detection_history_time_window=kwargs.pop( - "duplicate_detection_history_time_window", None - ), - enable_batched_operations=kwargs.pop("enable_batched_operations", None), - size_in_bytes=kwargs.pop("size_in_bytes", None), - authorization_rules=kwargs.pop("authorization_rules", None), + default_message_time_to_live=default_message_time_to_live, + max_size_in_megabytes=max_size_in_megabytes, + requires_duplicate_detection=requires_duplicate_detection, + # TODO: ask why default of 10 mins isn't followed below, + duplicate_detection_history_time_window=duplicate_detection_history_time_window, + enable_batched_operations=enable_batched_operations, + size_in_bytes=size_in_bytes, + authorization_rules=authorization_rules, + filtering_messages_before_publishing=filtering_messages_before_publishing, status=kwargs.pop("status", None), - support_ordering=kwargs.pop("support_ordering", None), - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), - enable_partitioning=kwargs.pop("enable_partitioning", None), + support_ordering=support_ordering, + auto_delete_on_idle=auto_delete_on_idle, + enable_partitioning=enable_partitioning, availability_status=None, - enable_express=kwargs.pop("enable_express", None), - user_metadata=kwargs.pop("user_metadata", None), - max_message_size_in_kilobytes=kwargs.pop("max_message_size_in_kilobytes", None) + enable_express=enable_express, + user_metadata=user_metadata, + max_message_size_in_kilobytes=max_message_size_in_kilobytes, + **kwargs ) to_create = topic._to_internal_entity() @@ -799,8 +843,24 @@ def get_subscription_runtime_properties( ) return subscription - def create_subscription(self, topic_name, subscription_name, **kwargs): - # type: (str, str, Any) -> SubscriptionProperties + def create_subscription( + self, + topic_name: str, + subscription_name: str, + *, + lock_duration: Optional[Union[datetime.timedelta, str]] = None, + requires_session: Optional[bool] = None, + default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, + dead_lettering_on_message_expiration: Optional[bool] = None, + dead_lettering_on_filter_evaluation_exceptions: Optional[bool] = None, + max_delivery_count: Optional[int] = None, + enable_batched_operations: Optional[bool] = None, + forward_to: Optional[str] = None, + user_metadata: Optional[str] = None, + forward_dead_lettered_messages_to: Optional[str] = None, + auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, + **kwargs: Any + ) -> SubscriptionProperties: """Create a topic subscription. :param str topic_name: The topic that will own the @@ -849,35 +909,29 @@ def create_subscription(self, topic_name, subscription_name, **kwargs): """ _validate_entity_name_type(topic_name, display_name="topic_name") forward_to = _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_to", None), self.fully_qualified_namespace + forward_to, self.fully_qualified_namespace ) forward_dead_lettered_messages_to = ( _normalize_entity_path_to_full_path_if_needed( - kwargs.pop("forward_dead_lettered_messages_to", None), + forward_dead_lettered_messages_to, self.fully_qualified_namespace, ) ) subscription = SubscriptionProperties( subscription_name, - lock_duration=kwargs.pop("lock_duration", None), - requires_session=kwargs.pop("requires_session", None), - default_message_time_to_live=kwargs.pop( - "default_message_time_to_live", None - ), - dead_lettering_on_message_expiration=kwargs.pop( - "dead_lettering_on_message_expiration", None - ), - dead_lettering_on_filter_evaluation_exceptions=kwargs.pop( - "dead_lettering_on_filter_evaluation_exceptions", None - ), - max_delivery_count=kwargs.pop("max_delivery_count", None), - enable_batched_operations=kwargs.pop("enable_batched_operations", None), + lock_duration=lock_duration, + requires_session=requires_session, + default_message_time_to_live=default_message_time_to_live, + dead_lettering_on_message_expiration=dead_lettering_on_message_expiration, + dead_lettering_on_filter_evaluation_exceptions=dead_lettering_on_filter_evaluation_exceptions, + max_delivery_count=max_delivery_count, + enable_batched_operations=enable_batched_operations, status=kwargs.pop("status", None), forward_to=forward_to, - user_metadata=kwargs.pop("user_metadata", None), + user_metadata=user_metadata, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, - auto_delete_on_idle=kwargs.pop("auto_delete_on_idle", None), + auto_delete_on_idle=auto_delete_on_idle, availability_status=None, ) to_create = subscription._to_internal_entity(self.fully_qualified_namespace) # type: ignore # pylint:disable=protected-access @@ -1044,8 +1098,16 @@ def get_rule(self, topic_name, subscription_name, rule_name, **kwargs): ) # to remove after #3535 is released. return rule_description - def create_rule(self, topic_name, subscription_name, rule_name, **kwargs): - # type: (str, str, str, Any) -> RuleProperties + def create_rule( + self, + topic_name: str, + subscription_name: str, + rule_name: str, + *, + filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), + action: Optional[SqlRuleAction] = None, + **kwargs: Any + ) -> RuleProperties: """Create a rule for a topic subscription. :param str topic_name: The topic that will own the @@ -1065,8 +1127,8 @@ def create_rule(self, topic_name, subscription_name, rule_name, **kwargs): rule = RuleProperties( rule_name, - filter=kwargs.pop("filter", TrueRuleFilter()), - action=kwargs.pop("action", None), + filter=filter, + action=action, created_at_utc=None, ) to_create = rule._to_internal_entity() From 5be09e805aa61f0a631b14fe14e989a78349b293 Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Thu, 6 Jan 2022 11:33:12 -0800 Subject: [PATCH 2/9] fix mypy/pylint --- .../azure/servicebus/_servicebus_client.py | 32 +++++++++++-------- .../azure/servicebus/_servicebus_receiver.py | 17 ++++++---- .../azure/servicebus/_servicebus_sender.py | 13 +++++--- .../aio/_servicebus_client_async.py | 26 ++++++++------- .../aio/_servicebus_receiver_async.py | 13 ++++---- .../aio/_servicebus_sender_async.py | 7 ++-- .../management/_management_client_async.py | 12 +++---- .../azure/servicebus/amqp/_amqp_message.py | 23 +++++++------ .../management/_management_client.py | 14 ++++---- .../azure/servicebus/management/_utils.py | 4 +-- 10 files changed, 89 insertions(+), 72 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index 38ee765e0ed2..ec67080360bb 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -2,18 +2,13 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Any, Dict, Union, Optional +from typing import Any, Dict, Union, Optional, TYPE_CHECKING import logging from weakref import WeakSet import uamqp from uamqp.constants import TransportType -from azure.core.credentials import ( - TokenCredential, - AzureSasCredential, - AzureNamedKeyCredential, -) from ._base_handler import ( _parse_conn_str, ServiceBusSharedKeyCredential, @@ -30,11 +25,18 @@ ) from ._common.constants import ( ServiceBusSubQueue, - NEXT_AVAILABLE_SESSION, ServiceBusReceiveMode, + ServiceBusSessionFilter ) from ._retry import RetryMode +if TYPE_CHECKING: + from azure.core.credentials import ( + TokenCredential, + AzureSasCredential, + AzureNamedKeyCredential, + ) + _LOGGER = logging.getLogger(__name__) @@ -87,7 +89,9 @@ class ServiceBusClient(object): def __init__( self, fully_qualified_namespace: str, - credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + credential: Union[ + "TokenCredential", "AzureSasCredential", "AzureNamedKeyCredential" + ], *, http_proxy: Optional[Dict[str, Any]] = None, user_agent: Optional[str] = None, @@ -178,8 +182,8 @@ def from_connection_string( retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, retry_mode: RetryMode = RetryMode.EXPONENTIAL, - **kwargs - ): + **kwargs: Any + ) -> "ServiceBusClient": """ Create a ServiceBusClient from a connection string. @@ -282,7 +286,7 @@ def get_queue_receiver( self, queue_name: str, *, - session_id: Union[str, NEXT_AVAILABLE_SESSION] = None, + session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -298,7 +302,7 @@ def get_queue_receiver( :keyword session_id: A specific session from which to receive. This must be specified for a sessionful queue, otherwise it must be None. In order to receive messages from the next available session, set this to ~azure.servicebus.NEXT_AVAILABLE_SESSION. - :paramtype session_id: Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION] + :paramtype session_id: Optional[Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION]] :keyword Optional[Union[ServiceBusSubQueue, str]] sub_queue: If specified, the subqueue this receiver will connect to. This includes the DEAD_LETTER and TRANSFER_DEAD_LETTER queues, holds messages that can't be delivered to any @@ -434,7 +438,7 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, - session_id: Union[str, NEXT_AVAILABLE_SESSION] = NEXT_AVAILABLE_SESSION, + session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -452,7 +456,7 @@ def get_subscription_receiver( :keyword session_id: A specific session from which to receive. This must be specified for a sessionful subscription, otherwise it must be None. In order to receive messages from the next available session, set this to ~azure.servicebus.NEXT_AVAILABLE_SESSION. - :paramtype session_id: Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION] + :paramtype session_id: Optional[Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION]] :keyword Optional[Union[ServiceBusSubQueue, str]] sub_queue: If specified, the subqueue this receiver will connect to. This includes the DEAD_LETTER and TRANSFER_DEAD_LETTER queues, holds messages that can't be delivered to any diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index aadfe1cfcdb3..c539afd6d86c 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -7,19 +7,17 @@ import functools import uuid import datetime -from typing import Any, List, Optional, Dict, Iterator, Union +from typing import Any, List, Optional, Dict, Iterator, Union, TYPE_CHECKING import six from uamqp import ReceiveClient, types, Message from uamqp.constants import SenderSettleMode, TransportType from uamqp.authentication.common import AMQPAuth -from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential from .exceptions import ServiceBusError from ._base_handler import BaseHandler from ._common.message import ServiceBusReceivedMessage -from ._common.auto_lock_renewer import AutoLockRenewer from ._common.utils import ( create_authentication, get_receive_links, @@ -55,6 +53,13 @@ from ._common.utils import utc_from_timestamp from ._servicebus_session import ServiceBusSession +if TYPE_CHECKING: + from ._common.auto_lock_renewer import AutoLockRenewer + from azure.core.credentials import ( + TokenCredential, + AzureSasCredential, + AzureNamedKeyCredential, + ) _LOGGER = logging.getLogger(__name__) @@ -122,7 +127,7 @@ class ServiceBusReceiver( def __init__( self, fully_qualified_namespace: str, - credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + credential: Union["TokenCredential", "AzureSasCredential", "AzureNamedKeyCredential"], *, queue_name: Optional[str] = None, topic_name: Optional[str] = None, @@ -135,7 +140,7 @@ def __init__( ServiceBusReceiveMode, str ] = ServiceBusReceiveMode.PEEK_LOCK, max_wait_time: Optional[float] = None, - auto_lock_renewer: Optional[AutoLockRenewer] = None, + auto_lock_renewer: Optional["AutoLockRenewer"] = None, prefetch_count: int = 0, **kwargs: Any ) -> None: @@ -669,7 +674,7 @@ def receive_messages( def receive_deferred_messages( self, - sequence_numbers: Union[int,List[int]], + sequence_numbers: Union[int, List[int]], *, timeout: Optional[float] = None ) -> List[ServiceBusReceivedMessage]: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py index fb9d6ad590ea..dcf33d86ee77 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py @@ -13,8 +13,6 @@ from uamqp.authentication.common import AMQPAuth from uamqp.constants import TransportType -from azure.core.credentials import TokenCredential, AzureSasCredential, AzureNamedKeyCredential - from ._base_handler import BaseHandler from ._common import mgmt_handlers from ._common.message import ( @@ -45,6 +43,11 @@ ) if TYPE_CHECKING: + from azure.core.credentials import ( + TokenCredential, + AzureSasCredential, + AzureNamedKeyCredential, + ) MessageTypes = Union[ Mapping[str, Any], ServiceBusMessage, @@ -153,7 +156,7 @@ class ServiceBusSender(BaseHandler, SenderMixin): def __init__( self, fully_qualified_namespace: str, - credential: Union[TokenCredential, AzureSasCredential, AzureNamedKeyCredential], + credential: Union["TokenCredential", "AzureSasCredential", "AzureNamedKeyCredential"], *, queue_name: Optional[str] = None, topic_name: Optional[str] = None, @@ -281,7 +284,7 @@ def _send(self, message, timeout=None, last_exception=None): def schedule_messages( self, - messages: MessageTypes, + messages: "MessageTypes", schedule_time_utc: datetime.datetime, *, timeout: Optional[float] = None @@ -379,7 +382,7 @@ def cancel_scheduled_messages( def send_messages( self, - message: Union[MessageTypes, ServiceBusMessageBatch], + message: Union["MessageTypes", ServiceBusMessageBatch], *, timeout: Optional[float] = None ) -> None: 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 2a25f3acab35..802549421be6 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 @@ -20,7 +20,11 @@ from .._common._configuration import Configuration from .._common.auto_lock_renewer import AutoLockRenewer from .._common.utils import generate_dead_letter_entity_name, strip_protocol_from_uri -from .._common.constants import ServiceBusSubQueue, NEXT_AVAILABLE_SESSION, ServiceBusReceiveMode +from .._common.constants import ( + ServiceBusSubQueue, + ServiceBusSessionFilter, + ServiceBusReceiveMode +) from ._async_utils import create_authentication from .._retry import RetryMode @@ -78,7 +82,9 @@ class ServiceBusClient(object): def __init__( self, fully_qualified_namespace: str, - credential: Union["AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential], + credential: Union[ + "AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential + ], *, http_proxy: Optional[Dict[str, Any]] = None, user_agent: Optional[str] = None, @@ -187,7 +193,7 @@ def from_connection_string( credential = ServiceBusSASTokenCredential(token, token_expiry) elif policy and key: credential = ServiceBusSharedKeyCredential(policy, key) # type: ignore - return cls( # type: ignore # for credential + return cls( # type: ignore # for credential fully_qualified_namespace=host, entity_name=entity_in_conn_str or kwargs.pop("entity_name", None), credential=credential, # type: ignore @@ -223,11 +229,7 @@ async def close(self) -> None: if self._connection_sharing and self._connection: await self._connection.destroy_async() - def get_queue_sender( - self, - queue_name: str, - **kwargs: Any - ) -> ServiceBusSender: + def get_queue_sender(self, queue_name: str, **kwargs: Any) -> ServiceBusSender: """Get ServiceBusSender for the specific queue. :param str queue_name: The path of specific Service Bus Queue the client connects to. @@ -273,9 +275,11 @@ def get_queue_receiver( self, queue_name: str, *, - session_id: Union[str, NEXT_AVAILABLE_SESSION] = None, + session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, - receive_mode: Union[ServiceBusReceiveMode, str] = ServiceBusReceiveMode.PEEK_LOCK, + receive_mode: Union[ + ServiceBusReceiveMode, str + ] = ServiceBusReceiveMode.PEEK_LOCK, max_wait_time: Optional[float] = None, auto_lock_renewer: Optional[AutoLockRenewer] = None, prefetch_count: int = 0, @@ -421,7 +425,7 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, - session_id: Union[str, NEXT_AVAILABLE_SESSION] = NEXT_AVAILABLE_SESSION, + session_id: Union[str, ServiceBusSessionFilter] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str 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 3b64a27782c1..043c7be8270b 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 @@ -7,19 +7,16 @@ import datetime import functools import logging -from typing import Any, List, Dict, Optional, AsyncIterator, Union, Callable +from typing import Any, List, Dict, Optional, AsyncIterator, Union, Callable, TYPE_CHECKING import six from uamqp import ReceiveClientAsync, types, Message from uamqp.constants import SenderSettleMode, TransportType -from azure.core.credentials_async import AsyncTokenCredential -from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from ..exceptions import ServiceBusError from ._servicebus_session_async import ServiceBusSession from ._base_handler_async import BaseHandler -from .._common.auto_lock_renewer import AutoLockRenewer from .._common.message import ServiceBusReceivedMessage from .._common.receiver_mixins import ReceiverMixin from .._common.constants import ( @@ -55,6 +52,10 @@ ) from ._async_utils import create_authentication, get_running_loop +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential + from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential + from .._common.auto_lock_renewer import AutoLockRenewer _LOGGER = logging.getLogger(__name__) @@ -120,7 +121,7 @@ class ServiceBusReceiver(collections.abc.AsyncIterator, BaseHandler, ReceiverMix def __init__( self, fully_qualified_namespace: str, - credential: Union["AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential], + credential: Union["AsyncTokenCredential", "AzureSasCredential", "AzureNamedKeyCredential"], *, queue_name: Optional[str] = None, topic_name: Optional[str] = None, @@ -133,7 +134,7 @@ def __init__( ServiceBusReceiveMode, str ] = ServiceBusReceiveMode.PEEK_LOCK, max_wait_time: Optional[float] = None, - auto_lock_renewer: Optional[AutoLockRenewer] = None, + auto_lock_renewer: Optional["AutoLockRenewer"] = None, prefetch_count: int = 0, **kwargs: Any ) -> None: 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 5afc7cc6c570..0d17db635dc2 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 @@ -216,8 +216,7 @@ async def schedule_messages( messages: MessageTypes, schedule_time_utc: datetime.datetime, *, - timeout: Optional[float] = None, - **kwargs: Any + timeout: Optional[float] = None ) -> List[int]: """Send Message or multiple Messages to be enqueued at a specific time by the service. Returns a list of the sequence numbers of the enqueued messages. @@ -267,7 +266,7 @@ async def schedule_messages( ) async def cancel_scheduled_messages( - self, sequence_numbers: Union[int, List[int]], *, timeout: Optional[float] = None, **kwargs: Any + self, sequence_numbers: Union[int, List[int]], *, timeout: Optional[float] = None ) -> None: """ Cancel one or more messages that have previously been scheduled and are still pending. @@ -307,7 +306,7 @@ async def cancel_scheduled_messages( ) async def send_messages( - self, message: Union[MessageTypes, ServiceBusMessageBatch], *, timeout: Optional[float] = None, **kwargs: Any + self, message: Union[MessageTypes, ServiceBusMessageBatch], *, timeout: Optional[float] = None ) -> None: """Sends message and blocks until acknowledgement is received or operation times out. diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py index 1562de056c33..8aa50fd6ca65 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py @@ -8,7 +8,7 @@ import functools import datetime from copy import deepcopy -from typing import Any, Union, cast, Mapping, Optional, List +from typing import Any, Union, cast, Mapping, Optional, List, TYPE_CHECKING from xml.etree.ElementTree import ElementTree from azure.core.async_paging import AsyncItemPaged @@ -22,7 +22,6 @@ AsyncBearerTokenCredentialPolicy, ) from azure.core.pipeline.transport import AioHttpTransport -from azure.core.credentials_async import AsyncTokenCredential from ...management._generated.models import ( QueueDescriptionFeed, @@ -90,7 +89,8 @@ _validate_topic_and_subscription_types, _validate_topic_subscription_and_rule_types, ) - +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods """Use this client to create, update, list, and delete resources of a ServiceBus namespace. @@ -298,11 +298,11 @@ async def get_queue_runtime_properties( ) return runtime_properties - async def create_queue( + async def create_queue( # pylint: disable=too-many-locals self, queue_name: str, *, - authorization_rules: Optional[list[AuthorizationRule]] = None, + authorization_rules: Optional[List[AuthorizationRule]] = None, auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, dead_lettering_on_message_expiration: Optional[bool] = None, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, @@ -1109,7 +1109,7 @@ async def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), + filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), # pylint: disable=redefined-builtin action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py index f34e1544cfe1..431951a71ec7 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py @@ -116,12 +116,9 @@ class AmqpAnnotatedMessage(object): def __init__( self, *, - data_body: Optional[Union[str, bytes, List[Union[str, bytes]]]] = None, - sequence_body: Optional[List[Any]] = None, - value_body: Any = None, - header: Optional[AmqpMessageHeader] = None, + header: Optional["AmqpMessageHeader"] = None, footer: Optional[dict] = None, - properties: Optional[AmqpMessageProperties] = None, + properties: Optional["AmqpMessageProperties"] = None, application_properties: Optional[dict] = None, annotations: Optional[dict] = None, delivery_annotations: Optional[dict] = None, @@ -136,7 +133,7 @@ def __init__( return # manually constructed AMQPAnnotatedMessage - input_count_validation = len([key for key in (data_body, sequence_body, value_body) if key]) + input_count_validation = len([key for key in ("data_body", "sequence_body", "value_body") if key in kwargs]) if input_count_validation != 1: raise ValueError( "There should be one and only one of either data_body, sequence_body " @@ -145,14 +142,14 @@ def __init__( self._body = None self._body_type = None - if data_body: - self._body = data_body + if "data_body" in kwargs: + self._body = kwargs.pop("data_body") self._body_type = uamqp.MessageBodyType.Data - elif sequence_body: - self._body = sequence_body + elif "sequence_body" in kwargs: + self._body = kwargs.pop("sequence_body") self._body_type = uamqp.MessageBodyType.Sequence - elif value_body: - self._body = value_body + elif "value_body" in kwargs: + self._body = kwargs.pop("value_body") self._body_type = uamqp.MessageBodyType.Value self._message = uamqp.message.Message(body=self._body, body_type=self._body_type) @@ -498,6 +495,7 @@ class AmqpMessageHeader(DictMixin): """ def __init__( self, + *, delivery_count: Optional[int] = None, time_to_live: Optional[int] = None, durable: Optional[bool] = None, @@ -590,6 +588,7 @@ class AmqpMessageProperties(DictMixin): """ def __init__( self, + *, message_id: Optional[Union[str, bytes, uuid.UUID]] = None, user_id: Optional[Union[str, bytes]] = None, to: Optional[Union[str, bytes]] = None, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py index 8a32362d4a9f..b981f8580dfb 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py @@ -8,7 +8,7 @@ import functools import datetime from copy import deepcopy -from typing import Any, Union, cast, Mapping, Optional, List +from typing import Any, Union, cast, Mapping, Optional, List, TYPE_CHECKING from xml.etree.ElementTree import ElementTree from azure.core.paging import ItemPaged @@ -22,7 +22,6 @@ BearerTokenCredentialPolicy, ) from azure.core.pipeline.transport import RequestsTransport -from azure.core.credentials import TokenCredential from ._generated.models import ( QueueDescriptionFeed, @@ -91,6 +90,9 @@ ) from ._handle_response_error import _handle_response_error +if TYPE_CHECKING: + from azure.core.credentials import TokenCredential + class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods @@ -107,7 +109,7 @@ class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods def __init__( self, fully_qualified_namespace: str, - credential: TokenCredential, + credential: "TokenCredential", *, api_version: str = DEFAULT_VERSION, **kwargs: Any @@ -302,11 +304,11 @@ def get_queue_runtime_properties(self, queue_name, **kwargs): ) return runtime_properties - def create_queue( + def create_queue( # pylint: disable=too-many-locals self, queue_name: str, *, - authorization_rules: Optional[list[AuthorizationRule]] = None, + authorization_rules: Optional[List[AuthorizationRule]] = None, auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, dead_lettering_on_message_expiration: Optional[bool] = None, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, @@ -1104,7 +1106,7 @@ def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), + filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), # pylint: disable=redefined-builtin action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py index fbf5e8fbd755..62f8d5c63143 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- from datetime import datetime, timedelta -from typing import TYPE_CHECKING, cast, Union, Mapping, Type, Any +from typing import TYPE_CHECKING, cast, Union, Mapping, Type, Any, Optional from xml.etree.ElementTree import ElementTree, SubElement, QName import isodate import six @@ -335,7 +335,7 @@ def _validate_topic_subscription_and_rule_types( def _normalize_entity_path_to_full_path_if_needed( entity_path, fully_qualified_namespace ): - # type: (str, str) -> str + # type: (Optional[str], str) -> str if not entity_path: return entity_path parsed = urlparse.urlparse(entity_path) From 03a93bbc96a895a4733d1b0fceafafd60f923bd9 Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Thu, 6 Jan 2022 14:55:19 -0800 Subject: [PATCH 3/9] mypy --- .../azure-servicebus/azure/servicebus/management/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py index 62f8d5c63143..983465978ef8 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_utils.py @@ -335,7 +335,7 @@ def _validate_topic_subscription_and_rule_types( def _normalize_entity_path_to_full_path_if_needed( entity_path, fully_qualified_namespace ): - # type: (Optional[str], str) -> str + # type: (Optional[str], str) -> Optional[str] if not entity_path: return entity_path parsed = urlparse.urlparse(entity_path) From 9171e4940f10fc88b8366afdb9d884c708ec8c0f Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Thu, 6 Jan 2022 18:07:47 -0800 Subject: [PATCH 4/9] adam + anna comments --- .../_common/_connection_string_parser.py | 1 + .../azure/servicebus/_common/message.py | 4 +- .../azure/servicebus/_servicebus_client.py | 33 +++----------- .../azure/servicebus/_servicebus_receiver.py | 18 +------- .../azure/servicebus/_servicebus_sender.py | 13 +----- .../azure/servicebus/_servicebus_session.py | 6 +-- .../aio/_servicebus_client_async.py | 29 ++----------- .../aio/_servicebus_receiver_async.py | 20 +-------- .../aio/_servicebus_sender_async.py | 11 +---- .../aio/_servicebus_session_async.py | 6 +-- .../management/_management_client_async.py | 37 ++++++++++------ .../azure/servicebus/amqp/_amqp_message.py | 16 +++---- .../management/_management_client.py | 43 ++++++++++--------- 13 files changed, 78 insertions(+), 159 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py index 302bd5f85e86..c714d05994e7 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py @@ -15,6 +15,7 @@ class ServiceBusConnectionStringProperties(DictMixin): def __init__( self, + *, fully_qualified_namespace: Optional[str] = None, endpoint: Optional[str] = None, entity_path: Optional[str] = None, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py index 3c664fbf78b2..73f47c5e2edc 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/message.py @@ -9,7 +9,7 @@ import datetime import uuid import logging -from typing import Optional, List, Union, Iterable, TYPE_CHECKING, Any, Mapping, cast +from typing import Optional, Dict, List, Union, Iterable, TYPE_CHECKING, Any, Mapping, cast import six @@ -96,7 +96,7 @@ def __init__( self, body: Optional[Union[str, bytes]], *, - application_properties: Optional[dict] = None, + application_properties: Optional[Dict[str, Any]] = None, session_id: Optional[str] = None, message_id: Optional[str] = None, scheduled_enqueue_time_utc: Optional[datetime.datetime] = None, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index ec67080360bb..de6f5c87753a 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -2,12 +2,11 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Any, Dict, Union, Optional, TYPE_CHECKING +from typing import Any, Union, Optional, TYPE_CHECKING import logging from weakref import WeakSet import uamqp -from uamqp.constants import TransportType from ._base_handler import ( _parse_conn_str, @@ -26,7 +25,6 @@ from ._common.constants import ( ServiceBusSubQueue, ServiceBusReceiveMode, - ServiceBusSessionFilter ) from ._retry import RetryMode @@ -93,10 +91,6 @@ def __init__( "TokenCredential", "AzureSasCredential", "AzureNamedKeyCredential" ], *, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: Optional[bool] = False, - transport_type: Optional[TransportType] = TransportType.Amqp, retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, @@ -110,10 +104,6 @@ def __init__( self._credential = credential self._config = Configuration( - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, retry_total=retry_total, retry_backoff_factor=retry_backoff_factor, retry_backoff_max=retry_backoff_max, @@ -174,10 +164,6 @@ def from_connection_string( cls, conn_str: str, *, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: bool = False, - transport_type: TransportType = TransportType.Amqp, retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, @@ -228,10 +214,6 @@ def from_connection_string( fully_qualified_namespace=host, entity_name=entity_in_conn_str or kwargs.pop("entity_name", None), credential=credential, # type: ignore - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, retry_total=retry_total, retry_backoff_factor=retry_backoff_factor, retry_backoff_max=retry_backoff_max, @@ -286,7 +268,6 @@ def get_queue_receiver( self, queue_name: str, *, - session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -302,7 +283,7 @@ def get_queue_receiver( :keyword session_id: A specific session from which to receive. This must be specified for a sessionful queue, otherwise it must be None. In order to receive messages from the next available session, set this to ~azure.servicebus.NEXT_AVAILABLE_SESSION. - :paramtype session_id: Optional[Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION]] + :paramtype session_id: Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION] :keyword Optional[Union[ServiceBusSubQueue, str]] sub_queue: If specified, the subqueue this receiver will connect to. This includes the DEAD_LETTER and TRANSFER_DEAD_LETTER queues, holds messages that can't be delivered to any @@ -347,7 +328,7 @@ def get_queue_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and session_id: + if sub_queue and kwargs.get("session_id"): raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -380,7 +361,6 @@ def get_queue_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -438,7 +418,6 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, - session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -456,7 +435,7 @@ def get_subscription_receiver( :keyword session_id: A specific session from which to receive. This must be specified for a sessionful subscription, otherwise it must be None. In order to receive messages from the next available session, set this to ~azure.servicebus.NEXT_AVAILABLE_SESSION. - :paramtype session_id: Optional[Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION]] + :paramtype session_id: Union[str, ~azure.servicebus.NEXT_AVAILABLE_SESSION] :keyword Optional[Union[ServiceBusSubQueue, str]] sub_queue: If specified, the subqueue this receiver will connect to. This includes the DEAD_LETTER and TRANSFER_DEAD_LETTER queues, holds messages that can't be delivered to any @@ -502,7 +481,7 @@ def get_subscription_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and session_id: + if sub_queue and kwargs.get("session_id"): raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -530,7 +509,6 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -557,7 +535,6 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index c539afd6d86c..162cf2a4c653 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -12,7 +12,7 @@ import six from uamqp import ReceiveClient, types, Message -from uamqp.constants import SenderSettleMode, TransportType +from uamqp.constants import SenderSettleMode from uamqp.authentication.common import AMQPAuth from .exceptions import ServiceBusError @@ -132,10 +132,6 @@ def __init__( queue_name: Optional[str] = None, topic_name: Optional[str] = None, subscription_name: Optional[str] = None, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: Optional[bool] = False, - transport_type: Optional[TransportType] = TransportType.Amqp, receive_mode: Union[ ServiceBusReceiveMode, str ] = ServiceBusReceiveMode.PEEK_LOCK, @@ -152,10 +148,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, @@ -184,10 +176,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, @@ -199,10 +187,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py index dcf33d86ee77..45f069e85d7a 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_sender.py @@ -6,12 +6,11 @@ import time import uuid import datetime -from typing import Any, TYPE_CHECKING, Dict, Union, List, Optional, Mapping, cast +from typing import Any, TYPE_CHECKING, Union, List, Optional, Mapping, cast import uamqp from uamqp import SendClient, types from uamqp.authentication.common import AMQPAuth -from uamqp.constants import TransportType from ._base_handler import BaseHandler from ._common import mgmt_handlers @@ -160,11 +159,7 @@ def __init__( *, queue_name: Optional[str] = None, topic_name: Optional[str] = None, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: bool = False, - transport_type: TransportType = TransportType.Amqp, - **kwargs + **kwargs: Any ) -> None: if kwargs.get("entity_name"): super(ServiceBusSender, self).__init__( @@ -188,10 +183,6 @@ def __init__( entity_name=str(entity_name), queue_name=queue_name, topic_name=topic_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, **kwargs ) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py index 3f4c4c1bbfc6..272e580ffc7b 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py @@ -88,7 +88,7 @@ class ServiceBusSession(BaseSession): :caption: Get session from a receiver """ - def get_state(self, timeout: Optional[float] = None) -> bytes: + def get_state(self, *, timeout: Optional[float] = None) -> bytes: # pylint: disable=protected-access """Get the session state. @@ -119,7 +119,7 @@ def get_state(self, timeout: Optional[float] = None) -> bytes: session_state = response.get(MGMT_RESPONSE_SESSION_STATE) # type: ignore return session_state - def set_state(self, state: Union[str, bytes, bytearray], timeout: Optional[float] = None) -> None: + def set_state(self, *, state: Union[str, bytes, bytearray], timeout: Optional[float] = None) -> None: # pylint: disable=protected-access """Set the session state. @@ -153,7 +153,7 @@ def set_state(self, state: Union[str, bytes, bytearray], timeout: Optional[float timeout=timeout, ) - def renew_lock(self, timeout: Optional[float] = None) -> datetime.datetime: + def renew_lock(self, *, timeout: Optional[float] = None) -> datetime.datetime: # pylint: disable=protected-access """Renew the session lock. 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 802549421be6..ac73f821db61 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 @@ -2,12 +2,11 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Any, Dict, Union, Optional, TYPE_CHECKING +from typing import Any, Union, Optional, TYPE_CHECKING import logging from weakref import WeakSet import uamqp -from uamqp.constants import TransportType from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from .._base_handler import _parse_conn_str @@ -22,7 +21,6 @@ from .._common.utils import generate_dead_letter_entity_name, strip_protocol_from_uri from .._common.constants import ( ServiceBusSubQueue, - ServiceBusSessionFilter, ServiceBusReceiveMode ) from ._async_utils import create_authentication @@ -86,10 +84,6 @@ def __init__( "AsyncTokenCredential", AzureSasCredential, AzureNamedKeyCredential ], *, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: bool = False, - transport_type: TransportType = TransportType.Amqp, retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, @@ -102,10 +96,6 @@ def __init__( ) self._credential = credential self._config = Configuration( - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, retry_total=retry_total, retry_backoff_factor=retry_backoff_factor, retry_backoff_max=retry_backoff_max, @@ -143,10 +133,6 @@ def from_connection_string( cls, conn_str: str, *, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: bool = False, - transport_type: TransportType = TransportType.Amqp, retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, @@ -197,10 +183,6 @@ def from_connection_string( fully_qualified_namespace=host, entity_name=entity_in_conn_str or kwargs.pop("entity_name", None), credential=credential, # type: ignore - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, retry_total=retry_total, retry_backoff_factor=retry_backoff_factor, retry_backoff_max=retry_backoff_max, @@ -275,7 +257,6 @@ def get_queue_receiver( self, queue_name: str, *, - session_id: Optional[Union[str, ServiceBusSessionFilter]] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -336,7 +317,7 @@ def get_queue_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and session_id: + if sub_queue and kwargs.get("session_id"): raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -368,7 +349,6 @@ def get_queue_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -425,7 +405,6 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, - session_id: Union[str, ServiceBusSessionFilter] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -489,7 +468,7 @@ def get_subscription_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and session_id: + if sub_queue and kwargs.get("session_id"): raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -517,7 +496,6 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -544,7 +522,6 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, - session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, 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 043c7be8270b..3e5da709a453 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 @@ -7,12 +7,12 @@ import datetime import functools import logging -from typing import Any, List, Dict, Optional, AsyncIterator, Union, Callable, TYPE_CHECKING +from typing import Any, List, Optional, AsyncIterator, Union, Callable, TYPE_CHECKING import six from uamqp import ReceiveClientAsync, types, Message -from uamqp.constants import SenderSettleMode, TransportType +from uamqp.constants import SenderSettleMode from ..exceptions import ServiceBusError from ._servicebus_session_async import ServiceBusSession @@ -126,10 +126,6 @@ def __init__( queue_name: Optional[str] = None, topic_name: Optional[str] = None, subscription_name: Optional[str] = None, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: Optional[bool] = False, - transport_type: Optional[TransportType] = TransportType.Amqp, receive_mode: Union[ ServiceBusReceiveMode, str ] = ServiceBusReceiveMode.PEEK_LOCK, @@ -148,10 +144,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, @@ -181,10 +173,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, @@ -196,10 +184,6 @@ def __init__( queue_name=queue_name, topic_name=topic_name, subscription_name=subscription_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, receive_mode=receive_mode, max_wait_time=max_wait_time, auto_lock_renewer=auto_lock_renewer, 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 0d17db635dc2..92256d6b8d1e 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 @@ -5,11 +5,10 @@ import logging import asyncio import datetime -from typing import Any, TYPE_CHECKING, Dict, Union, List, Optional, Mapping, cast +from typing import Any, TYPE_CHECKING, Union, List, Optional, Mapping, cast import uamqp from uamqp import SendClientAsync, types -from uamqp.constants import TransportType from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential from .._common.message import ( @@ -95,10 +94,6 @@ def __init__( *, queue_name: Optional[str] = None, topic_name: Optional[str] = None, - http_proxy: Optional[Dict[str, Any]] = None, - user_agent: Optional[str] = None, - logging_enable: bool = False, - transport_type: TransportType = TransportType.Amqp, **kwargs: Any ) -> None: if kwargs.get("entity_name"): @@ -123,10 +118,6 @@ def __init__( entity_name=str(entity_name), queue_name=queue_name, topic_name=topic_name, - http_proxy=http_proxy, - user_agent=user_agent, - logging_enable=logging_enable, - transport_type=transport_type, **kwargs ) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py index 6010ab1c5b42..8d10b3231d73 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_session_async.py @@ -40,7 +40,7 @@ class ServiceBusSession(BaseSession): :caption: Get session from a receiver """ - async def get_state(self, timeout: Optional[float] = None) -> bytes: + async def get_state(self, *, timeout: Optional[float] = None) -> bytes: """Get the session state. Returns None if no state has been set. @@ -71,7 +71,7 @@ async def get_state(self, timeout: Optional[float] = None) -> bytes: return session_state async def set_state( - self, state: Union[str, bytes, bytearray], timeout: Optional[float] = None + self, state: Union[str, bytes, bytearray], *, timeout: Optional[float] = None ) -> None: """Set the session state. @@ -106,7 +106,7 @@ async def set_state( timeout=timeout, ) - async def renew_lock(self, timeout: Optional[float] = None) -> datetime.datetime: + async def renew_lock(self, *, timeout: Optional[float] = None) -> datetime.datetime: """Renew the session lock. This operation must be performed periodically in order to retain a lock on the diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py index 8aa50fd6ca65..eed14e9b6a63 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py @@ -89,9 +89,11 @@ _validate_topic_and_subscription_types, _validate_topic_subscription_and_rule_types, ) + if TYPE_CHECKING: from azure.core.credentials_async import AsyncTokenCredential + class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods """Use this client to create, update, list, and delete resources of a ServiceBus namespace. @@ -166,10 +168,7 @@ async def _get_entity_element(self, entity_name, enrich=False, **kwargs): element = cast( ElementTree, await self._impl.entity.get( - entity_name, - enrich=enrich, - api_version=self._api_version, - **kwargs + entity_name, enrich=enrich, api_version=self._api_version, **kwargs ), ) return element @@ -298,7 +297,7 @@ async def get_queue_runtime_properties( ) return runtime_properties - async def create_queue( # pylint: disable=too-many-locals + async def create_queue( # pylint: disable=too-many-locals self, queue_name: str, *, @@ -306,7 +305,9 @@ async def create_queue( # pylint: disable=too-many-locals auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, dead_lettering_on_message_expiration: Optional[bool] = None, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, - duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[ + Union[datetime.timedelta, str] + ] = None, enable_batched_operations: Optional[bool] = None, enable_express: Optional[bool] = None, enable_partitioning: Optional[bool] = None, @@ -415,7 +416,7 @@ async def create_queue( # pylint: disable=too-many-locals forward_to=forward_to, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, user_metadata=user_metadata, - max_message_size_in_kilobytes=max_message_size_in_kilobytes + max_message_size_in_kilobytes=max_message_size_in_kilobytes, ) to_create = queue._to_internal_entity(self.fully_qualified_namespace) create_entity_body = CreateQueueBody( @@ -582,9 +583,13 @@ async def create_topic( topic_name: str, *, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, - max_size_in_megabytes: Optional[float] = None, # TODO: said long? should it be float + max_size_in_megabytes: Optional[ + int + ] = None, requires_duplicate_detection: Optional[bool] = None, - duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[ + Union[datetime.timedelta, str] + ] = None, enable_batched_operations: Optional[bool] = None, size_in_bytes: Optional[int] = None, filtering_messages_before_publishing: Optional[bool] = None, @@ -608,7 +613,7 @@ async def create_topic( :paramtype default_message_time_to_live: Union[~datetime.timedelta, str] :keyword max_size_in_megabytes: The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. - :paramtype max_size_in_megabytes: long + :paramtype max_size_in_megabytes: int :keyword requires_duplicate_detection: A value indicating if this topic requires duplicate detection. :paramtype requires_duplicate_detection: bool @@ -982,8 +987,12 @@ async def update_subscription( _validate_entity_name_type(topic_name, display_name="topic_name") # we should not mutate the input, making a copy first for update - subscription = deepcopy(create_properties_from_dict_if_needed(subscription, SubscriptionProperties)) - to_update = subscription._to_internal_entity(self.fully_qualified_namespace, kwargs) + subscription = deepcopy( + create_properties_from_dict_if_needed(subscription, SubscriptionProperties) + ) + to_update = subscription._to_internal_entity( + self.fully_qualified_namespace, kwargs + ) create_entity_body = CreateSubscriptionBody( content=CreateSubscriptionBodyContent( @@ -1109,7 +1118,9 @@ async def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), # pylint: disable=redefined-builtin + filter: Union[ + CorrelationRuleFilter, SqlRuleFilter + ] = TrueRuleFilter(), # pylint: disable=redefined-builtin action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py index 431951a71ec7..bbf69aec6463 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/amqp/_amqp_message.py @@ -7,7 +7,7 @@ import time import uuid from datetime import datetime -from typing import Optional, Any, cast, Mapping, Union, List +from typing import Optional, Any, cast, Mapping, Union, Dict from msrest.serialization import TZ_UTC import uamqp @@ -117,11 +117,11 @@ def __init__( self, *, header: Optional["AmqpMessageHeader"] = None, - footer: Optional[dict] = None, + footer: Optional[Dict[str, Any]] = None, properties: Optional["AmqpMessageProperties"] = None, - application_properties: Optional[dict] = None, - annotations: Optional[dict] = None, - delivery_annotations: Optional[dict] = None, + application_properties: Optional[Dict[str, Any]] = None, + annotations: Optional[Dict[str, Any]] = None, + delivery_annotations: Optional[Dict[str, Any]] = None, **kwargs: Any ) -> None: self._message = kwargs.pop("message", None) @@ -143,13 +143,13 @@ def __init__( self._body = None self._body_type = None if "data_body" in kwargs: - self._body = kwargs.pop("data_body") + self._body = kwargs.get("data_body") self._body_type = uamqp.MessageBodyType.Data elif "sequence_body" in kwargs: - self._body = kwargs.pop("sequence_body") + self._body = kwargs.get("sequence_body") self._body_type = uamqp.MessageBodyType.Sequence elif "value_body" in kwargs: - self._body = kwargs.pop("value_body") + self._body = kwargs.get("value_body") self._body_type = uamqp.MessageBodyType.Value self._message = uamqp.message.Message(body=self._body, body_type=self._body_type) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py index b981f8580dfb..bb09d6696a6b 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py @@ -94,7 +94,6 @@ from azure.core.credentials import TokenCredential - class ServiceBusAdministrationClient: # pylint:disable=too-many-public-methods """Use this client to create, update, list, and delete resources of a ServiceBus namespace. @@ -118,7 +117,9 @@ def __init__( self._api_version = api_version self._credential = credential self._endpoint = "https://" + fully_qualified_namespace - self._config = ServiceBusManagementClientConfiguration(self._endpoint, api_version=api_version, **kwargs) + self._config = ServiceBusManagementClientConfiguration( + self._endpoint, api_version=api_version, **kwargs + ) self._pipeline = self._build_pipeline() self._impl = ServiceBusManagementClientImpl( endpoint=fully_qualified_namespace, pipeline=self._pipeline @@ -239,11 +240,7 @@ def _populate_header_within_kwargs(uri, header): @classmethod def from_connection_string( - cls, - conn_str: str, - *, - api_version: str = DEFAULT_VERSION, - **kwargs: Any + cls, conn_str: str, *, api_version: str = DEFAULT_VERSION, **kwargs: Any ) -> "ServiceBusAdministrationClient": """Create a client from connection string. @@ -269,11 +266,7 @@ def from_connection_string( endpoint = endpoint[endpoint.index("//") + 2 :] return cls(endpoint, credential, api_version=api_version, **kwargs) - def get_queue( - self, - queue_name: str, - **kwargs: Any - ) -> QueueProperties: + def get_queue(self, queue_name: str, **kwargs: Any) -> QueueProperties: """Get the properties of a queue. :param str queue_name: The name of the queue. @@ -304,7 +297,7 @@ def get_queue_runtime_properties(self, queue_name, **kwargs): ) return runtime_properties - def create_queue( # pylint: disable=too-many-locals + def create_queue( # pylint: disable=too-many-locals self, queue_name: str, *, @@ -312,7 +305,9 @@ def create_queue( # pylint: disable=too-many-locals auto_delete_on_idle: Optional[Union[datetime.timedelta, str]] = None, dead_lettering_on_message_expiration: Optional[bool] = None, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, - duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[ + Union[datetime.timedelta, str] + ] = None, enable_batched_operations: Optional[bool] = None, enable_express: Optional[bool] = None, enable_partitioning: Optional[bool] = None, @@ -421,7 +416,7 @@ def create_queue( # pylint: disable=too-many-locals forward_to=forward_to, forward_dead_lettered_messages_to=forward_dead_lettered_messages_to, user_metadata=user_metadata, - max_message_size_in_kilobytes=max_message_size_in_kilobytes + max_message_size_in_kilobytes=max_message_size_in_kilobytes, ) to_create = queue._to_internal_entity(self.fully_qualified_namespace) create_entity_body = CreateQueueBody( @@ -588,9 +583,13 @@ def create_topic( topic_name: str, *, default_message_time_to_live: Optional[Union[datetime.timedelta, str]] = None, - max_size_in_megabytes: Optional[float] = None, # TODO: said long? should it be float + max_size_in_megabytes: Optional[ + int + ] = None, requires_duplicate_detection: Optional[bool] = None, - duplicate_detection_history_time_window: Optional[Union[datetime.timedelta, str]] = None, + duplicate_detection_history_time_window: Optional[ + Union[datetime.timedelta, str] + ] = None, enable_batched_operations: Optional[bool] = None, size_in_bytes: Optional[int] = None, filtering_messages_before_publishing: Optional[bool] = None, @@ -614,7 +613,7 @@ def create_topic( :paramtype default_message_time_to_live: Union[~datetime.timedelta, str] :keyword max_size_in_megabytes: The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. - :paramtype max_size_in_megabytes: long + :paramtype max_size_in_megabytes: int :keyword requires_duplicate_detection: A value indicating if this topic requires duplicate detection. :paramtype requires_duplicate_detection: bool @@ -984,7 +983,9 @@ def update_subscription(self, topic_name, subscription, **kwargs): subscription = deepcopy( create_properties_from_dict_if_needed(subscription, SubscriptionProperties) # type: ignore ) - to_update = subscription._to_internal_entity(self.fully_qualified_namespace, kwargs) + to_update = subscription._to_internal_entity( + self.fully_qualified_namespace, kwargs + ) create_entity_body = CreateSubscriptionBody( content=CreateSubscriptionBodyContent( @@ -1106,7 +1107,9 @@ def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[CorrelationRuleFilter, SqlRuleFilter] = TrueRuleFilter(), # pylint: disable=redefined-builtin + filter: Union[ + CorrelationRuleFilter, SqlRuleFilter + ] = TrueRuleFilter(), # pylint: disable=redefined-builtin action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: From ef19350bcf6f85a7cc94722137f3dbe0b960a7db Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Thu, 6 Jan 2022 19:01:21 -0800 Subject: [PATCH 5/9] lint --- .../servicebus/aio/management/_management_client_async.py | 4 ++-- .../azure/servicebus/management/_management_client.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py index eed14e9b6a63..3adf4164aa28 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py @@ -1118,9 +1118,9 @@ async def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[ + filter: Union[ # pylint: disable=redefined-builtin CorrelationRuleFilter, SqlRuleFilter - ] = TrueRuleFilter(), # pylint: disable=redefined-builtin + ] = TrueRuleFilter(), action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py index bb09d6696a6b..73c76193fe52 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py @@ -1107,9 +1107,9 @@ def create_rule( subscription_name: str, rule_name: str, *, - filter: Union[ + filter: Union[ # pylint: disable=redefined-builtin CorrelationRuleFilter, SqlRuleFilter - ] = TrueRuleFilter(), # pylint: disable=redefined-builtin + ] = TrueRuleFilter(), action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: From c9e0c95493751c734ea9a4f24cddb8c076bec4bf Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Thu, 6 Jan 2022 19:25:10 -0800 Subject: [PATCH 6/9] lint bad whitespace --- .../azure/servicebus/aio/management/_management_client_async.py | 2 +- .../azure/servicebus/management/_management_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py index 3adf4164aa28..531fc71f6afc 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/management/_management_client_async.py @@ -1120,7 +1120,7 @@ async def create_rule( *, filter: Union[ # pylint: disable=redefined-builtin CorrelationRuleFilter, SqlRuleFilter - ] = TrueRuleFilter(), + ]=TrueRuleFilter(), action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py index 73c76193fe52..64d20f1ceab4 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/management/_management_client.py @@ -1109,7 +1109,7 @@ def create_rule( *, filter: Union[ # pylint: disable=redefined-builtin CorrelationRuleFilter, SqlRuleFilter - ] = TrueRuleFilter(), + ]=TrueRuleFilter(), action: Optional[SqlRuleAction] = None, **kwargs: Any ) -> RuleProperties: From dc554cceb3e9b45b8e334f8437ed361d65fb70b8 Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Fri, 7 Jan 2022 09:21:25 -0800 Subject: [PATCH 7/9] remove retry --- .../azure-servicebus/azure/servicebus/_servicebus_client.py | 5 ++--- .../azure/servicebus/aio/_servicebus_client_async.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index b3f8c4a642f1..553dbdd2d48a 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -26,7 +26,6 @@ ServiceBusSubQueue, ServiceBusReceiveMode, ) -from ._retry import RetryMode if TYPE_CHECKING: from azure.core.credentials import ( @@ -95,7 +94,7 @@ def __init__( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode: RetryMode = RetryMode.EXPONENTIAL, + retry_mode: str = 'exponential', **kwargs: Any ) -> None: # If the user provided http:// or sb://, let's be polite and strip that. @@ -168,7 +167,7 @@ def from_connection_string( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode: RetryMode = RetryMode.EXPONENTIAL, + retry_mode: str = 'exponential', **kwargs: Any ) -> "ServiceBusClient": """ 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 464e93fa6b84..72efaeedbf79 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 @@ -24,7 +24,6 @@ ServiceBusReceiveMode ) from ._async_utils import create_authentication -from .._retry import RetryMode if TYPE_CHECKING: from azure.core.credentials_async import AsyncTokenCredential @@ -88,7 +87,7 @@ def __init__( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode=RetryMode.EXPONENTIAL, + retry_mode: str = 'exponential', **kwargs: Any ) -> None: # If the user provided http:// or sb://, let's be polite and strip that. @@ -137,7 +136,7 @@ def from_connection_string( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode=RetryMode.EXPONENTIAL, + retry_mode: str = 'exponential', **kwargs: Any ) -> "ServiceBusClient": """ From 6bc5129a98b200d270865cb7bd0ce15c0f1a896b Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Fri, 7 Jan 2022 12:54:07 -0800 Subject: [PATCH 8/9] adams comments --- .../_common/_connection_string_parser.py | 24 ++++++------------- .../azure/servicebus/_servicebus_client.py | 13 ++++++---- .../azure/servicebus/_servicebus_receiver.py | 13 ++++++---- .../azure/servicebus/_servicebus_session.py | 2 +- .../aio/_servicebus_client_async.py | 9 +++++-- .../aio/_servicebus_receiver_async.py | 13 ++++++---- 6 files changed, 42 insertions(+), 32 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py index c714d05994e7..466deaef0a62 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_common/_connection_string_parser.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from typing import Optional from ..management._models import DictMixin from .._base_handler import _parse_conn_str @@ -13,22 +12,13 @@ class ServiceBusConnectionStringProperties(DictMixin): Properties of a connection string. """ - def __init__( - self, - *, - fully_qualified_namespace: Optional[str] = None, - endpoint: Optional[str] = None, - entity_path: Optional[str] = None, - shared_access_signature: Optional[str] = None, - shared_access_key_name: Optional[str] = None, - shared_access_key: Optional[str] = None, - ) -> None: - self._fully_qualified_namespace = fully_qualified_namespace - self._endpoint = endpoint - self._entity_path = entity_path - self._shared_access_signature = shared_access_signature - self._shared_access_key_name = shared_access_key_name - self._shared_access_key = shared_access_key + def __init__(self, **kwargs): + self._fully_qualified_namespace = kwargs.pop("fully_qualified_namespace", None) + self._endpoint = kwargs.pop("endpoint", None) + self._entity_path = kwargs.pop("entity_path", None) + self._shared_access_signature = kwargs.pop("shared_access_signature", None) + self._shared_access_key_name = kwargs.pop("shared_access_key_name", None) + self._shared_access_key = kwargs.pop("shared_access_key", None) @property def fully_qualified_namespace(self): diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index 553dbdd2d48a..8edb65699fff 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -94,7 +94,7 @@ def __init__( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode: str = 'exponential', + retry_mode: str = "exponential", **kwargs: Any ) -> None: # If the user provided http:// or sb://, let's be polite and strip that. @@ -167,7 +167,7 @@ def from_connection_string( retry_total: int = 3, retry_backoff_factor: float = 0.8, retry_backoff_max: int = 120, - retry_mode: str = 'exponential', + retry_mode: str = "exponential", **kwargs: Any ) -> "ServiceBusClient": """ @@ -269,6 +269,7 @@ def get_queue_receiver( self, queue_name: str, *, + session_id: Optional[str] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -329,7 +330,7 @@ def get_queue_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -362,6 +363,7 @@ def get_queue_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -419,6 +421,7 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, + session_id: Optional[str] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -482,7 +485,7 @@ def get_subscription_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -510,6 +513,7 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -536,6 +540,7 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index 162cf2a4c653..9c9b33550e86 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -784,7 +784,7 @@ def peek_messages( ): return messages - def complete_message(self, message): + def complete_message(self, message: ServiceBusReceivedMessage) -> None: """Complete the message. This removes the message from the queue. @@ -808,7 +808,7 @@ def complete_message(self, message): """ self._settle_message_with_retry(message, MESSAGE_COMPLETE) - def abandon_message(self, message): + def abandon_message(self, message: ServiceBusReceivedMessage) -> None: """Abandon the message. This message will be returned to the queue and made available to be received again. @@ -832,7 +832,7 @@ def abandon_message(self, message): """ self._settle_message_with_retry(message, MESSAGE_ABANDON) - def defer_message(self, message): + def defer_message(self, message: ServiceBusReceivedMessage) -> None: """Defers the message. This message will remain in the queue but must be requested @@ -857,7 +857,12 @@ def defer_message(self, message): """ self._settle_message_with_retry(message, MESSAGE_DEFER) - def dead_letter_message(self, message, reason=None, error_description=None): + def dead_letter_message( + self, + message: ServiceBusReceivedMessage, + reason: Optional[str]=None, + error_description: Optional[str]=None + ) -> None: """Move the message to the Dead Letter queue. The Dead Letter queue is a sub-queue that can be diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py index 272e580ffc7b..3e0d9657b26b 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_session.py @@ -119,7 +119,7 @@ def get_state(self, *, timeout: Optional[float] = None) -> bytes: session_state = response.get(MGMT_RESPONSE_SESSION_STATE) # type: ignore return session_state - def set_state(self, *, state: Union[str, bytes, bytearray], timeout: Optional[float] = None) -> None: + def set_state(self, state: Union[str, bytes, bytearray], *, timeout: Optional[float] = None) -> None: # pylint: disable=protected-access """Set the session state. 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 72efaeedbf79..9b32c03d600a 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 @@ -258,6 +258,7 @@ def get_queue_receiver( self, queue_name: str, *, + session_id: Optional[str] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -318,7 +319,7 @@ def get_queue_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful queue, " @@ -350,6 +351,7 @@ def get_queue_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -406,6 +408,7 @@ def get_subscription_receiver( topic_name: str, subscription_name: str, *, + session_id: Optional[str] = None, sub_queue: Optional[Union[ServiceBusSubQueue, str]] = None, receive_mode: Union[ ServiceBusReceiveMode, str @@ -469,7 +472,7 @@ def get_subscription_receiver( "the connection string used to construct the ServiceBusClient." ) - if sub_queue and kwargs.get("session_id"): + if sub_queue and session_id: raise ValueError( "session_id and sub_queue can not be specified simultaneously. " "To connect to the sub queue of a sessionful subscription, " @@ -497,6 +500,7 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, @@ -523,6 +527,7 @@ def get_subscription_receiver( retry_total=self._config.retry_total, retry_backoff_factor=self._config.retry_backoff_factor, retry_backoff_max=self._config.retry_backoff_max, + session_id=session_id, sub_queue=sub_queue, receive_mode=receive_mode, max_wait_time=max_wait_time, 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 3e5da709a453..053c45a6407b 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 @@ -767,7 +767,7 @@ async def peek_messages( ): return messages - async def complete_message(self, message): + async def complete_message(self, message: ServiceBusReceivedMessage) -> None: """Complete the message. This removes the message from the queue. @@ -791,7 +791,7 @@ async def complete_message(self, message): """ await self._settle_message_with_retry(message, MESSAGE_COMPLETE) - async def abandon_message(self, message): + async def abandon_message(self, message: ServiceBusReceivedMessage) -> None: """Abandon the message. This message will be returned to the queue and made available to be received again. @@ -815,7 +815,7 @@ async def abandon_message(self, message): """ await self._settle_message_with_retry(message, MESSAGE_ABANDON) - async def defer_message(self, message): + async def defer_message(self, message: ServiceBusReceivedMessage) -> None: """Defers the message. This message will remain in the queue but must be requested @@ -840,7 +840,12 @@ async def defer_message(self, message): """ await self._settle_message_with_retry(message, MESSAGE_DEFER) - async def dead_letter_message(self, message, reason=None, error_description=None): + async def dead_letter_message( + self, + message: ServiceBusReceivedMessage, + reason: Optional[str]=None, + error_description: Optional[str]=None + ) -> None: """Move the message to the Dead Letter queue. The Dead Letter queue is a sub-queue that can be From b1a646ea99556a18158b28456ae2551b04301d64 Mon Sep 17 00:00:00 2001 From: Swathi Pillalamarri Date: Fri, 7 Jan 2022 13:17:48 -0800 Subject: [PATCH 9/9] lint --- .../azure-servicebus/azure/servicebus/_servicebus_receiver.py | 4 ++-- .../azure/servicebus/aio/_servicebus_receiver_async.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index 9c9b33550e86..1b4c0157b769 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -860,8 +860,8 @@ def defer_message(self, message: ServiceBusReceivedMessage) -> None: def dead_letter_message( self, message: ServiceBusReceivedMessage, - reason: Optional[str]=None, - error_description: Optional[str]=None + reason: Optional[str] = None, + error_description: Optional[str] = None ) -> None: """Move the message to the Dead Letter queue. 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 053c45a6407b..975c72352a68 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 @@ -843,8 +843,8 @@ async def defer_message(self, message: ServiceBusReceivedMessage) -> None: async def dead_letter_message( self, message: ServiceBusReceivedMessage, - reason: Optional[str]=None, - error_description: Optional[str]=None + reason: Optional[str] = None, + error_description: Optional[str] = None ) -> None: """Move the message to the Dead Letter queue.