From 1596b03bf7b43b8d39a25e4f8d287d72260f37c0 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Tue, 9 Feb 2021 17:59:39 -0800 Subject: [PATCH 01/28] Updated SMS clients with new swagger --- .../azure/communication/sms/__init__.py | 11 +- .../_azure_communication_sms_service.py | 1 + .../sms/_generated/_configuration.py | 2 +- .../aio/_azure_communication_sms_service.py | 1 + .../sms/_generated/aio/_configuration.py | 2 +- .../aio/operations/_sms_operations.py | 129 ++++++++++++------ .../sms/_generated/models/__init__.py | 15 +- .../_azure_communication_sms_service_enums.py | 35 +++++ .../sms/_generated/models/_models.py | 85 ++++++++++-- .../sms/_generated/models/_models_py3.py | 95 +++++++++++-- .../_generated/operations/_sms_operations.py | 127 +++++++++++------ .../azure/communication/sms/_sms_client.py | 48 ++++--- .../sms/aio/_sms_client_async.py | 54 +++++--- .../swagger/SWAGGER.md | 10 +- 14 files changed, 442 insertions(+), 173 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py index c44b589aa2ac..d4d8b5669c6d 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py @@ -1,17 +1,10 @@ from ._sms_client import SmsClient -from ._shared.models import ( - PhoneNumberIdentifier, -) - from ._generated.models import ( - SendSmsOptions, - SendSmsResponse, + SmsSendResult, ) __all__ = [ 'SmsClient', - 'PhoneNumberIdentifier', - 'SendSmsOptions', - 'SendSmsResponse', + 'SmsSendResult', ] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py index cf3c05b03286..739d3568a0db 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py @@ -41,6 +41,7 @@ def __init__( client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False self._deserialize = Deserializer(client_models) self.sms = SmsOperations( diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py index 4278d2bdd48a..def4a7c79be9 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py @@ -38,7 +38,7 @@ def __init__( super(AzureCommunicationSMSServiceConfiguration, self).__init__(**kwargs) self.endpoint = endpoint - self.api_version = "2020-07-20-preview1" + self.api_version = "2021-03-07" kwargs.setdefault('sdk_moniker', 'azurecommunicationsmsservice/{}'.format(VERSION)) self._configure(**kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py index 81e188e2282b..b32eb2f7151d 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py @@ -36,6 +36,7 @@ def __init__( client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False self._deserialize = Deserializer(client_models) self.sms = SmsOperations( diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py index 4200ab88d62c..19ba0e93c716 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py @@ -33,7 +33,7 @@ def __init__( super(AzureCommunicationSMSServiceConfiguration, self).__init__(**kwargs) self.endpoint = endpoint - self.api_version = "2020-07-20-preview1" + self.api_version = "2021-03-07" kwargs.setdefault('sdk_moniker', 'azurecommunicationsmsservice/{}'.format(VERSION)) self._configure(**kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py index e291a219e3ee..341269700b32 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py @@ -5,14 +5,15 @@ # Code generated by Microsoft (R) AutoRest Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, Callable, Dict, Generic, Optional, TypeVar +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar import warnings +from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest -from ... import models +from ... import models as _models T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] @@ -31,7 +32,7 @@ class SmsOperations: :param deserializer: An object model deserializer. """ - models = models + models = _models def __init__(self, client, config, serializer, deserializer) -> None: self._client = client @@ -39,62 +40,102 @@ def __init__(self, client, config, serializer, deserializer) -> None: self._deserialize = deserializer self._config = config - async def send( + def send( self, - send_message_request: "models.SendMessageRequest", + send_message_request: "_models.SendMessageRequest", + repeatability_request_id: Optional[str] = None, + repeatability_first_sent: Optional[str] = None, **kwargs - ) -> "models.SendSmsResponse": + ) -> AsyncIterable["_models.SmsSendResponse"]: """Sends a SMS message from a phone number that belongs to the authenticated account. Sends a SMS message from a phone number that belongs to the authenticated account. :param send_message_request: Represents the body of the send message request. :type send_message_request: ~azure.communication.sms.models.SendMessageRequest + :param repeatability_request_id: If specified, the client directs that the request is + repeatable; that is, the client can make the request multiple times with the same + Repeatability-Request-ID and get back an appropriate response without the server executing the + request multiple times. The value of the Repeatability-Request-ID is an opaque string + representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID + (GUID), identifier for the request. + :type repeatability_request_id: str + :param repeatability_first_sent: MUST be sent by clients to specify that a request is + repeatable. Repeatability-First-Sent is used to specify the date and time at which the request + was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. + :type repeatability_first_sent: str :keyword callable cls: A custom type or function that will be passed the direct response - :return: SendSmsResponse, or the result of cls(response) - :rtype: ~azure.communication.sms.models.SendSmsResponse + :return: An iterator like instance of either SmsSendResponse or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.communication.sms.models.SmsSendResponse] :raises: ~azure.core.exceptions.HttpResponseError """ - cls = kwargs.pop('cls', None) # type: ClsType["models.SendSmsResponse"] + cls = kwargs.pop('cls', None) # type: ClsType["_models.SmsSendResponse"] error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2020-07-20-preview1" - content_type = kwargs.pop("content_type", "application/json") + api_version = "2021-03-07" + content_type = "application/json" accept = "application/json" - # Construct URL - url = self.send.metadata['url'] # type: ignore - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - - # Construct parameters - query_parameters = {} # type: Dict[str, Any] - query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = {} # type: Dict[str, Any] - header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') - header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') - - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) - pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - deserialized = self._deserialize('SendSmsResponse', pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) - - return deserialized + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if repeatability_request_id is not None: + header_parameters['repeatability-request-id'] = self._serialize.header("repeatability_request_id", repeatability_request_id, 'str') + if repeatability_first_sent is not None: + header_parameters['repeatability-first-sent'] = self._serialize.header("repeatability_first_sent", repeatability_first_sent, 'str') + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.send.metadata['url'] # type: ignore + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.get(url, query_parameters, header_parameters, **body_content_kwargs) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('SmsSendResponse', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) send.metadata = {'url': '/sms'} # type: ignore diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py index e2aafb5fe3ea..8869534805dd 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py @@ -8,15 +8,18 @@ try: from ._models_py3 import SendMessageRequest - from ._models_py3 import SendSmsOptions - from ._models_py3 import SendSmsResponse + from ._models_py3 import SmsSendOptions + from ._models_py3 import SmsSendResponse + from ._models_py3 import SmsSendResult except (SyntaxError, ImportError): from ._models import SendMessageRequest # type: ignore - from ._models import SendSmsOptions # type: ignore - from ._models import SendSmsResponse # type: ignore + from ._models import SmsSendOptions # type: ignore + from ._models import SmsSendResponse # type: ignore + from ._models import SmsSendResult # type: ignore __all__ = [ 'SendMessageRequest', - 'SendSmsOptions', - 'SendSmsResponse', + 'SmsSendOptions', + 'SmsSendResponse', + 'SmsSendResult', ] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py new file mode 100644 index 000000000000..3fa3ec4ac067 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py @@ -0,0 +1,35 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum, EnumMeta +from six import with_metaclass + +class _CaseInsensitiveEnumMeta(EnumMeta): + def __getitem__(self, name): + return super().__getitem__(name.upper()) + + def __getattr__(cls, name): + """Return the enum member matching `name` + We use __getattr__ instead of descriptors or inserting into the enum + class' __dict__ in order to support `name` and `value` being both + properties for enum members (which live in the class' __dict__) and + enum members themselves. + """ + try: + return cls._member_map_[name.upper()] + except KeyError: + raise AttributeError(name) + + +class SmsSendResultRepeatabilityResult(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The result of a repeatable request with one of the case-insensitive values accepted or + rejected. + """ + + ACCEPTED = "accepted" + REJECTED = "rejected" diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py index 7cb1120b4b3f..da21c0802beb 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py @@ -17,14 +17,14 @@ class SendMessageRequest(msrest.serialization.Model): :param from_property: Required. The sender's phone number in E.164 format that is owned by the authenticated account. :type from_property: str - :param to: Required. The recipients' phone number in E.164 format. In this version, only one - recipient in the list is supported. + :param to: Required. The recipient's phone number in E.164 format. In this version, a minimum + of 1 and upto 100 recipients in the list are supported. :type to: list[str] :param message: Required. The contents of the message that will be sent to the recipient. The allowable content is defined by RFC 5724. :type message: str - :param send_sms_options: Optional configuration for sending SMS messages. - :type send_sms_options: ~azure.communication.sms.models.SendSmsOptions + :param sms_send_options: Optional configuration for sending SMS messages. + :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions """ _validation = { @@ -37,7 +37,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'to': {'key': 'to', 'type': '[str]'}, 'message': {'key': 'message', 'type': 'str'}, - 'send_sms_options': {'key': 'sendSmsOptions', 'type': 'SendSmsOptions'}, + 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } def __init__( @@ -48,43 +48,102 @@ def __init__( self.from_property = kwargs['from_property'] self.to = kwargs['to'] self.message = kwargs['message'] - self.send_sms_options = kwargs.get('send_sms_options', None) + self.sms_send_options = kwargs.get('sms_send_options', None) -class SendSmsOptions(msrest.serialization.Model): +class SmsSendOptions(msrest.serialization.Model): """Optional configuration for sending SMS messages. :param enable_delivery_report: Enable this flag to receive a delivery report for this message on the Azure Resource EventGrid. :type enable_delivery_report: bool + :param tag: Use this field to provide metadata that will then be sent back in the corresponding + Delivery Report. + :type tag: str """ _attribute_map = { 'enable_delivery_report': {'key': 'enableDeliveryReport', 'type': 'bool'}, + 'tag': {'key': 'tag', 'type': 'str'}, } def __init__( self, **kwargs ): - super(SendSmsOptions, self).__init__(**kwargs) - self.enable_delivery_report = kwargs.get('enable_delivery_report', None) + super(SmsSendOptions, self).__init__(**kwargs) + self.enable_delivery_report = kwargs.get('enable_delivery_report', False) + self.tag = kwargs.get('tag', None) -class SendSmsResponse(msrest.serialization.Model): - """Response for a successful send Sms request. +class SmsSendResponse(msrest.serialization.Model): + """Response for a successful or multi status send Sms request. - :param message_id: The identifier of the outgoing SMS message. + All required parameters must be populated in order to send to Azure. + + :param value: Required. + :type value: list[~azure.communication.sms.models.SmsSendResult] + :param next_link: + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[SmsSendResult]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(SmsSendResponse, self).__init__(**kwargs) + self.value = kwargs['value'] + self.next_link = kwargs.get('next_link', None) + + +class SmsSendResult(msrest.serialization.Model): + """Response for a single recipient. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipients's phone number in E.164 format. + :type to: str + :param message_id: The identifier of the outgoing SMS message. Only present if message + processed. :type message_id: str + :param http_status_code: Required. HTTP Status code. + :type http_status_code: int + :param succeeded: Required. Flag to check if message processing succeeded or not. + :type succeeded: bool + :param error_message: Optional error message in case of 4xx or 5xx errors. + :type error_message: str """ + _validation = { + 'to': {'required': True}, + 'http_status_code': {'required': True}, + 'succeeded': {'required': True}, + } + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, 'message_id': {'key': 'messageId', 'type': 'str'}, + 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, + 'succeeded': {'key': 'succeeded', 'type': 'bool'}, + 'error_message': {'key': 'errorMessage', 'type': 'str'}, } def __init__( self, **kwargs ): - super(SendSmsResponse, self).__init__(**kwargs) + super(SmsSendResult, self).__init__(**kwargs) + self.to = kwargs['to'] self.message_id = kwargs.get('message_id', None) + self.http_status_code = kwargs['http_status_code'] + self.succeeded = kwargs['succeeded'] + self.error_message = kwargs.get('error_message', None) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py index 03f686209337..afca499d44aa 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py @@ -19,14 +19,14 @@ class SendMessageRequest(msrest.serialization.Model): :param from_property: Required. The sender's phone number in E.164 format that is owned by the authenticated account. :type from_property: str - :param to: Required. The recipients' phone number in E.164 format. In this version, only one - recipient in the list is supported. + :param to: Required. The recipient's phone number in E.164 format. In this version, a minimum + of 1 and upto 100 recipients in the list are supported. :type to: list[str] :param message: Required. The contents of the message that will be sent to the recipient. The allowable content is defined by RFC 5724. :type message: str - :param send_sms_options: Optional configuration for sending SMS messages. - :type send_sms_options: ~azure.communication.sms.models.SendSmsOptions + :param sms_send_options: Optional configuration for sending SMS messages. + :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions """ _validation = { @@ -39,7 +39,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'to': {'key': 'to', 'type': '[str]'}, 'message': {'key': 'message', 'type': 'str'}, - 'send_sms_options': {'key': 'sendSmsOptions', 'type': 'SendSmsOptions'}, + 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } def __init__( @@ -48,54 +48,121 @@ def __init__( from_property: str, to: List[str], message: str, - send_sms_options: Optional["SendSmsOptions"] = None, + sms_send_options: Optional["SmsSendOptions"] = None, **kwargs ): super(SendMessageRequest, self).__init__(**kwargs) self.from_property = from_property self.to = to self.message = message - self.send_sms_options = send_sms_options + self.sms_send_options = sms_send_options -class SendSmsOptions(msrest.serialization.Model): +class SmsSendOptions(msrest.serialization.Model): """Optional configuration for sending SMS messages. :param enable_delivery_report: Enable this flag to receive a delivery report for this message on the Azure Resource EventGrid. :type enable_delivery_report: bool + :param tag: Use this field to provide metadata that will then be sent back in the corresponding + Delivery Report. + :type tag: str """ _attribute_map = { 'enable_delivery_report': {'key': 'enableDeliveryReport', 'type': 'bool'}, + 'tag': {'key': 'tag', 'type': 'str'}, } def __init__( self, *, - enable_delivery_report: Optional[bool] = None, + enable_delivery_report: Optional[bool] = False, + tag: Optional[str] = None, **kwargs ): - super(SendSmsOptions, self).__init__(**kwargs) + super(SmsSendOptions, self).__init__(**kwargs) self.enable_delivery_report = enable_delivery_report + self.tag = tag -class SendSmsResponse(msrest.serialization.Model): - """Response for a successful send Sms request. +class SmsSendResponse(msrest.serialization.Model): + """Response for a successful or multi status send Sms request. - :param message_id: The identifier of the outgoing SMS message. + All required parameters must be populated in order to send to Azure. + + :param value: Required. + :type value: list[~azure.communication.sms.models.SmsSendResult] + :param next_link: + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[SmsSendResult]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: List["SmsSendResult"], + next_link: Optional[str] = None, + **kwargs + ): + super(SmsSendResponse, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class SmsSendResult(msrest.serialization.Model): + """Response for a single recipient. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipients's phone number in E.164 format. + :type to: str + :param message_id: The identifier of the outgoing SMS message. Only present if message + processed. :type message_id: str + :param http_status_code: Required. HTTP Status code. + :type http_status_code: int + :param succeeded: Required. Flag to check if message processing succeeded or not. + :type succeeded: bool + :param error_message: Optional error message in case of 4xx or 5xx errors. + :type error_message: str """ + _validation = { + 'to': {'required': True}, + 'http_status_code': {'required': True}, + 'succeeded': {'required': True}, + } + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, 'message_id': {'key': 'messageId', 'type': 'str'}, + 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, + 'succeeded': {'key': 'succeeded', 'type': 'bool'}, + 'error_message': {'key': 'errorMessage', 'type': 'str'}, } def __init__( self, *, + to: str, + http_status_code: int, + succeeded: bool, message_id: Optional[str] = None, + error_message: Optional[str] = None, **kwargs ): - super(SendSmsResponse, self).__init__(**kwargs) + super(SmsSendResult, self).__init__(**kwargs) + self.to = to self.message_id = message_id + self.http_status_code = http_status_code + self.succeeded = succeeded + self.error_message = error_message diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py index 162fa238b22c..0f8129a136fa 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py @@ -9,14 +9,15 @@ import warnings from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged from azure.core.pipeline import PipelineResponse from azure.core.pipeline.transport import HttpRequest, HttpResponse -from .. import models +from .. import models as _models if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Callable, Dict, Generic, Optional, TypeVar + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -35,7 +36,7 @@ class SmsOperations(object): :param deserializer: An object model deserializer. """ - models = models + models = _models def __init__(self, client, config, serializer, deserializer): self._client = client @@ -45,61 +46,101 @@ def __init__(self, client, config, serializer, deserializer): def send( self, - send_message_request, # type: "models.SendMessageRequest" + send_message_request, # type: "_models.SendMessageRequest" + repeatability_request_id=None, # type: Optional[str] + repeatability_first_sent=None, # type: Optional[str] **kwargs # type: Any ): - # type: (...) -> "models.SendSmsResponse" + # type: (...) -> Iterable["_models.SmsSendResponse"] """Sends a SMS message from a phone number that belongs to the authenticated account. Sends a SMS message from a phone number that belongs to the authenticated account. :param send_message_request: Represents the body of the send message request. :type send_message_request: ~azure.communication.sms.models.SendMessageRequest + :param repeatability_request_id: If specified, the client directs that the request is + repeatable; that is, the client can make the request multiple times with the same + Repeatability-Request-ID and get back an appropriate response without the server executing the + request multiple times. The value of the Repeatability-Request-ID is an opaque string + representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID + (GUID), identifier for the request. + :type repeatability_request_id: str + :param repeatability_first_sent: MUST be sent by clients to specify that a request is + repeatable. Repeatability-First-Sent is used to specify the date and time at which the request + was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. + :type repeatability_first_sent: str :keyword callable cls: A custom type or function that will be passed the direct response - :return: SendSmsResponse, or the result of cls(response) - :rtype: ~azure.communication.sms.models.SendSmsResponse + :return: An iterator like instance of either SmsSendResponse or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResponse] :raises: ~azure.core.exceptions.HttpResponseError """ - cls = kwargs.pop('cls', None) # type: ClsType["models.SendSmsResponse"] + cls = kwargs.pop('cls', None) # type: ClsType["_models.SmsSendResponse"] error_map = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2020-07-20-preview1" - content_type = kwargs.pop("content_type", "application/json") + api_version = "2021-03-07" + content_type = "application/json" accept = "application/json" - # Construct URL - url = self.send.metadata['url'] # type: ignore - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - - # Construct parameters - query_parameters = {} # type: Dict[str, Any] - query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = {} # type: Dict[str, Any] - header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') - header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') - - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) - pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - deserialized = self._deserialize('SendSmsResponse', pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) - - return deserialized + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if repeatability_request_id is not None: + header_parameters['repeatability-request-id'] = self._serialize.header("repeatability_request_id", repeatability_request_id, 'str') + if repeatability_first_sent is not None: + header_parameters['repeatability-first-sent'] = self._serialize.header("repeatability_first_sent", repeatability_first_sent, 'str') + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.send.metadata['url'] # type: ignore + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.get(url, query_parameters, header_parameters, **body_content_kwargs) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('SmsSendResponse', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) send.metadata = {'url': '/sms'} # type: ignore diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 15f06ad9da1c..b32236bef6d4 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -5,8 +5,11 @@ # -------------------------------------------------------------------------- from azure.core.tracing.decorator import distributed_trace -from azure.communication.sms._generated.models import SendMessageRequest -from azure.communication.sms._generated.models import SendSmsResponse +from azure.communication.sms._generated.models import ( + SendMessageRequest, + SmsSendResult, + SmsSendOptions, +) from ._generated._azure_communication_sms_service import AzureCommunicationSMSService from ._shared.utils import parse_connection_str, get_authentication_policy @@ -72,31 +75,38 @@ def from_connection_string(cls, conn_str, # type: str return cls(endpoint, access_key, **kwargs) @distributed_trace - def send(self, from_phone_number, # type: ~azure.communication.sms.PhoneNumberIdentifier - to_phone_numbers, # type: list[~azure.communication.sms.PhoneNumberIdentifier] + def send(self, from_, # type: str + to, # type: Union[str, List[str]] message, # type: str - **kwargs #type: Any - ): # type: (...) -> SendSmsResponse + **kwargs #type: Any + ): # type: (...) -> ItemPaged[SmsSendResult] """Sends SMSs to phone numbers. - :param from_phone_number: the sender of the SMS. - :type from_phone_number: ~azure.communication.sms.PhoneNumberIdentifier - :param to_phone_numbers: the list of recipients of the SMS. - :type to_phone_numbers: list[~azure.communication.sms.PhoneNumberIdentifier] + :param str from_: The sender of the SMS. + :param to: The single recipient or the list of recipients of the SMS. + :type to: Union[str, List[str]] :param str message: The message in the SMS - :keyword send_sms_options: the options object to configure delivery reporting. - :type send_sms_options: ~azure.communication.sms.models.SendSmsOptions - :return: The response object with the message_id - :rtype: SendMessageResponse: ~azure.communication.sms.models.SendMessageResponse + :keyword bool enable_delivery_report: Enable this flag to receive a delivery report for this + message on the Azure Resource EventGrid. + :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding + Delivery Report. + :return: An iterator like instance of SmsSendResult + :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResult] """ - send_sms_options = kwargs.pop('send_sms_options', None) + enable_delivery_report = kwargs.pop('enable_delivery_report', False) + tag = kwargs.pop('tag', None) + + sms_send_options = SmsSendOptions( + enable_delivery_report=enable_delivery_report, + tag=tag + ) request = SendMessageRequest( - from_property=from_phone_number.phone_number, - to=[p.phone_number for p in to_phone_numbers], + from_property=from_, + to=[p for p in to], message=message, - send_sms_options=send_sms_options, + sms_send_options=sms_send_options, **kwargs) - + return self._sms_service_client.sms.send(request, **kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 19f59f7dd40e..4b7e73e75c76 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -4,9 +4,12 @@ # license information. # -------------------------------------------------------------------------- -from azure.core.tracing.decorator_async import distributed_trace_async -from azure.communication.sms._generated.models import SendMessageRequest -from azure.communication.sms._generated.models import SendSmsResponse +from azure.core.tracing.decorator import distributed_trace +from azure.communication.sms._generated.models import ( + SendMessageRequest, + SmsSendResult, + SmsSendOptions, +) from .._generated.aio._azure_communication_sms_service import AzureCommunicationSMSService from .._shared.utils import parse_connection_str, get_authentication_policy @@ -72,35 +75,42 @@ def from_connection_string(cls, conn_str, # type: str return cls(endpoint, access_key, **kwargs) - @distributed_trace_async() - async def send(self, from_phone_number, # type: ~azure.communication.sms.PhoneNumberIdentifier - to_phone_numbers, # type: list[~azure.communication.sms.PhoneNumberIdentifier] - message, # type: str - **kwargs # type: Any - ): # type: (...) -> SendSmsResponse + @distributed_trace() + def send(self, from_, # type: str + to, # type: Union[str, List[str]] + message, # type: str + **kwargs # type: Any + ): # type: (...) -> ItemPaged[SmsSendResult] """Sends SMSs to phone numbers. - :param from_phone_number: the sender of the SMS. - :type from_phone_number: ~azure.communication.sms.PhoneNumberIdentifier - :param to_phone_numbers: the list of recipients of the SMS. - :type to_phone_numbers: list[~azure.communication.sms.PhoneNumberIdentifier] + :param str from_: The sender of the SMS. + :param to: The single recipient or the list of recipients of the SMS. + :type to: Union[str, List[str]] :param str message: The message in the SMS - :keyword send_sms_options: the options object to configure delivery reporting. - :type send_sms_options: ~azure.communication.sms.models.SendSmsOptions - :return: The response object with the message_id - :rtype: SendMessageResponse: ~azure.communication.sms.models.SendMessageResponse + :keyword bool enable_delivery_report: Enable this flag to receive a delivery report for this + message on the Azure Resource EventGrid. + :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding + Delivery Report. + :return: An iterator like instance of SmsSendResult + :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResult] """ - send_sms_options = kwargs.pop('send_sms_options', None) + enable_delivery_report = kwargs.pop('enable_delivery_report', False) + tag = kwargs.pop('tag', None) + + sms_send_options = SmsSendOptions( + enable_delivery_report=enable_delivery_report, + tag=tag + ) request = SendMessageRequest( - from_property=from_phone_number.phone_number, - to=[p.phone_number for p in to_phone_numbers], + from_property=from_, + to=[p for p in to], message=message, - send_sms_options=send_sms_options, + sms_send_options=sms_send_options, **kwargs) - return await self._sms_service_client.sms.send(request, **kwargs) + return self._sms_service_client.sms.send(request, **kwargs) async def __aenter__(self) -> "SMSClient": await self._sms_service_client.__aenter__() diff --git a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md index 188eb3161203..3d534536aa2d 100644 --- a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md +++ b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md @@ -13,9 +13,17 @@ cd autorest SWAGGER.md ``` +### Rename SmsSendResponseItem to SmsSendResult +``` yaml +directive: + - rename-model: + from: SmsSendResponseItem + to: SmsSendResult +``` + ### Settings ``` yaml -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/8818a603b78a1355ba1647ab9cd4e3354cdc4b69/specification/communication/data-plane/Microsoft.CommunicationServicesSms/preview/2020-07-20-preview1/communicationservicessms.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/dc652c9308ddcb19a73dbbb37498e63081dfde6e/specification/communication/data-plane/Microsoft.CommunicationServicesSms/stable/2021-03-07/communicationservicessms.json output-folder: ../azure/communication/sms/_generated namespace: azure.communication.sms no-namespace-folders: true From 214605ade1e4fc84d173f804e5431f7df1a7b663 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Tue, 9 Feb 2021 18:00:51 -0800 Subject: [PATCH 02/28] Updated SMS client tests --- .../tests/test_sms_client_e2e.py | 39 +++++++++--- .../tests/test_sms_client_e2e_async.py | 61 ++++++++++++++----- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index 2c4e3d3cc322..f76b38981124 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -6,9 +6,7 @@ import os import pytest -from azure.communication.sms import ( - PhoneNumberIdentifier, SendSmsOptions, SmsClient -) +from azure.communication.sms import SmsClient from _shared.testcase import ( CommunicationTestCase, BodyReplacerProcessor, @@ -34,13 +32,36 @@ def setUp(self): self.sms_client = SmsClient.from_connection_string(self.connection_str) @pytest.mark.live_test_only - def test_send_sms(self): + def test_send_sms_single(self): # calling send() with sms values - sms_response = self.sms_client.send( - from_phone_number=PhoneNumberIdentifier(self.phone_number), - to_phone_numbers=[PhoneNumberIdentifier(self.phone_number)], + sms_responses = self.sms_client.send( + from_=self.phone_number, + to=[self.phone_number], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property + enable_delivery_report=True) # optional property + + count = 0 + for sms_response in sms_responses: + count += 1 + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert count is 1 + + @pytest.mark.live_test_only + def test_send_sms_multiple(self): - assert sms_response.message_id is not None + # calling send() with sms values + sms_responses = self.sms_client.send( + from_=self.phone_number, + to=[self.phone_number, self.phone_number], + message="Hello World via SMS", + enable_delivery_report=True) # optional property + + count = 0 + for sms_response in sms_responses: + count += 1 + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert count is 2 + \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index 4543ccc909fe..6d7932d06c10 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -8,9 +8,6 @@ import pytest from azure.core.credentials import AccessToken from azure.communication.sms.aio import SmsClient -from azure.communication.sms import ( - PhoneNumberIdentifier, SendSmsOptions -) from azure.communication.sms._shared.utils import parse_connection_str from _shared.asynctestcase import AsyncCommunicationTestCase from _shared.testcase import ( @@ -18,13 +15,13 @@ ) from azure.identity import DefaultAzureCredential - class FakeTokenCredential(object): def __init__(self): self.token = AccessToken("Fake Token", 0) def get_token(self, *args): return self.token + class SMSClientTestAsync(AsyncCommunicationTestCase): def __init__(self, method_name): super(SMSClientTestAsync, self).__init__(method_name) @@ -49,13 +46,39 @@ async def test_send_sms_async(self): async with sms_client: # calling send() with sms values - sms_response = await sms_client.send( - from_phone_number=PhoneNumberIdentifier(self.phone_number), - to_phone_numbers=[PhoneNumberIdentifier(self.phone_number)], + sms_responses = sms_client.send( + from_=self.phone_number, + to=[self.phone_number], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property + enable_delivery_report=True) # optional property + + count = 0 + async for sms_response in sms_responses: + count += 1 + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert count is 1 - assert sms_response.message_id is not None + @AsyncCommunicationTestCase.await_prepared_test + @pytest.mark.live_test_only + async def test_send_sms_multiple_async(self): + + sms_client = SmsClient.from_connection_string(self.connection_str) + + async with sms_client: + # calling send() with sms values + sms_responses = sms_client.send( + from_=self.phone_number, + to=[self.phone_number, self.phone_number], + message="Hello World via SMS", + enable_delivery_report=True) # optional property + + count = 0 + async for sms_response in sms_responses: + count += 1 + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert count is 2 @AsyncCommunicationTestCase.await_prepared_test @pytest.mark.live_test_only @@ -67,13 +90,19 @@ async def test_send_sms_async_from_managed_identity(self): else: credential = DefaultAzureCredential() sms_client = SmsClient(endpoint, credential) - print(sms_client) + async with sms_client: # calling send() with sms values - sms_response = await sms_client.send( - from_phone_number=PhoneNumberIdentifier(self.phone_number), - to_phone_numbers=[PhoneNumberIdentifier(self.phone_number)], + sms_responses = sms_client.send( + from_=self.phone_number, + to=[self.phone_number], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property - - assert sms_response.message_id is not None + enable_delivery_report=True) # optional property + + count = 0 + async for sms_response in sms_responses: + count += 1 + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert count is 1 + \ No newline at end of file From ea773b2c6248ddb439830a0b1aa856476a0c738f Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Tue, 9 Feb 2021 18:02:03 -0800 Subject: [PATCH 03/28] Updated SMS samples --- .../samples/sms_sample.py | 25 +++++++++------- .../samples/sms_sample_async.py | 30 +++++++++++-------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample.py b/sdk/communication/azure-communication-sms/samples/sms_sample.py index a6a649ca793b..f30713e7f475 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample.py @@ -17,9 +17,7 @@ """ import sys -from azure.communication.sms import ( - SendSmsOptions, PhoneNumberIdentifier, SmsClient -) +from azure.communication.sms import SmsClient sys.path.append("..") @@ -31,14 +29,21 @@ def send_sms(self): sms_client = SmsClient.from_connection_string(connection_string) # calling send() with sms values - smsresponse = sms_client.send( - from_phone_number=PhoneNumberIdentifier(""), - to_phone_numbers=[PhoneNumberIdentifier("")], + sms_responses = sms_client.send( + from_phone_number="", + to_phone_numbers=["", "", ""], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property - - print(smsresponse) - + enable_delivery_report=True, # optional property + tag="custom-tag") # optional property + + for sms_response in sms_responses: + if (sms_response.succeeded): + print("Message with message id {} was successful sent to {}" + .format(sms_response.message_id , sms_response.to)) + else: + print("Message with message id {} failed to send to {}" + .format(sms_response.message_id , sms_response.to)) + if __name__ == '__main__': sample = SmsSamples() sample.send_sms() diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py index 29d958c01a7e..77b32cef2f40 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py @@ -6,14 +6,6 @@ # license information. # -------------------------------------------------------------------------- -import sys -import asyncio -from azure.communication.sms import ( - SendSmsOptions, PhoneNumberIdentifier -) -from azure.communication.sms.aio import SmsClient -sys.path.append("..") - """ FILE: sms_sample_async.py DESCRIPTION: @@ -24,6 +16,11 @@ python sms_sample_async.py """ +import sys +import asyncio +from azure.communication.sms.aio import SmsClient +sys.path.append("..") + class SmsSamples(object): async def send_sms_async(self): @@ -33,16 +30,23 @@ async def send_sms_async(self): async with sms_client: try: # calling send() with constructed request object - smsresponse = await sms_client.send( - from_phone_number=PhoneNumberIdentifier(""), - to_phone_numbers=[PhoneNumberIdentifier("")], + sms_responses = await sms_client.send( + from_phone_number="", + to_phone_numbers=["", "", ""], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property + enable_delivery_report=True, + tag="custom-tag") # optional property except Exception: print(Exception) pass - print(smsresponse) + async for sms_response in sms_responses: + if (sms_response.succeeded): + print("Message with message id {} was successful sent to {}" + .format(sms_response.message_id , sms_response.to)) + else: + print("Message with message id {} failed to send to {}" + .format(sms_response.message_id , sms_response.to)) if __name__ == '__main__': sample = SmsSamples() From 57cc156a68b419d1c9b734166cea8aed434195c1 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 10 Feb 2021 11:35:11 -0800 Subject: [PATCH 04/28] Added resending failed messages to SMS samples --- .../samples/sms_sample.py | 19 ++++++++++--- .../samples/sms_sample_async.py | 28 +++++++++++++++---- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample.py b/sdk/communication/azure-communication-sms/samples/sms_sample.py index f30713e7f475..d3fa2f13fc59 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample.py @@ -9,7 +9,8 @@ """ FILE: sms_sample.py DESCRIPTION: - These samples demonstrate sending an sms. + These samples demonstrate sending mutiple sms messages and resending + any failed messages. ///authenticating a client via a connection string USAGE: @@ -30,12 +31,13 @@ def send_sms(self): # calling send() with sms values sms_responses = sms_client.send( - from_phone_number="", - to_phone_numbers=["", "", ""], + from_="", + to=["", "", ""], message="Hello World via SMS", enable_delivery_report=True, # optional property tag="custom-tag") # optional property + failed_recipients = [] for sms_response in sms_responses: if (sms_response.succeeded): print("Message with message id {} was successful sent to {}" @@ -43,7 +45,16 @@ def send_sms(self): else: print("Message with message id {} failed to send to {}" .format(sms_response.message_id , sms_response.to)) - + failed_recipients.append(sms_response.to) + + # calling send() with failed recipients + sms_responses = sms_client.send( + from_="", + to=failed_recipients, + message="Hello World via SMS", + enable_delivery_report=True, # optional property + tag="custom-tag") # optional property + if __name__ == '__main__': sample = SmsSamples() sample.send_sms() diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py index 77b32cef2f40..ef4a0f56afb2 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py @@ -9,7 +9,8 @@ """ FILE: sms_sample_async.py DESCRIPTION: - These samples demonstrate sending an sms asynchronously. + These samples demonstrate sending mutiple sms messages and resending + any failed messages. ///authenticating a client via a connection string USAGE: @@ -19,6 +20,7 @@ import sys import asyncio from azure.communication.sms.aio import SmsClient + sys.path.append("..") class SmsSamples(object): @@ -29,17 +31,18 @@ async def send_sms_async(self): async with sms_client: try: - # calling send() with constructed request object - sms_responses = await sms_client.send( - from_phone_number="", - to_phone_numbers=["", "", ""], + # calling send() with sms values + sms_responses = sms_client.send( + from_="", + to=["", "", ""], message="Hello World via SMS", - enable_delivery_report=True, + enable_delivery_report=True, # optional property tag="custom-tag") # optional property except Exception: print(Exception) pass + failed_recipients = [] async for sms_response in sms_responses: if (sms_response.succeeded): print("Message with message id {} was successful sent to {}" @@ -47,6 +50,19 @@ async def send_sms_async(self): else: print("Message with message id {} failed to send to {}" .format(sms_response.message_id , sms_response.to)) + failed_recipients.append(sms_response.to) + + try: + # calling send() with failed recipients + sms_responses = sms_client.send( + from_="", + to=failed_recipients, + message="Hello World via SMS", + enable_delivery_report=True, # optional property + tag="custom-tag") # optional property + except Exception: + print(Exception) + pass if __name__ == '__main__': sample = SmsSamples() From ba3c2afd2881e0c19e62a6a30a36e56c652eaf7d Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 10:36:56 -0800 Subject: [PATCH 05/28] Updated SMS clients to latest swagger --- .../_azure_communication_sms_service.py | 2 +- .../sms/_generated/_configuration.py | 2 +- .../aio/_azure_communication_sms_service.py | 2 +- .../sms/_generated/aio/_configuration.py | 2 +- .../aio/operations/_sms_operations.py | 119 ++++++------------ .../sms/_generated/models/__init__.py | 8 ++ .../sms/_generated/models/_models.py | 90 +++++++++---- .../sms/_generated/models/_models_py3.py | 104 +++++++++++---- .../_generated/operations/_sms_operations.py | 117 ++++++----------- .../azure/communication/sms/_sms_client.py | 14 ++- .../sms/aio/_sms_client_async.py | 18 +-- .../swagger/SWAGGER.md | 2 +- 12 files changed, 258 insertions(+), 222 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py index 739d3568a0db..5782b9f7d32a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_azure_communication_sms_service.py @@ -25,7 +25,7 @@ class AzureCommunicationSMSService(object): :ivar sms: SmsOperations operations :vartype sms: azure.communication.sms.operations.SmsOperations - :param endpoint: The endpoint of the Azure Communication resource. + :param endpoint: The communication resource, for example https://my-resource.communication.azure.com. :type endpoint: str """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py index def4a7c79be9..9d3154a1fa3b 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/_configuration.py @@ -23,7 +23,7 @@ class AzureCommunicationSMSServiceConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. - :param endpoint: The endpoint of the Azure Communication resource. + :param endpoint: The communication resource, for example https://my-resource.communication.azure.com. :type endpoint: str """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py index b32eb2f7151d..1a50cb2f24f5 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_azure_communication_sms_service.py @@ -21,7 +21,7 @@ class AzureCommunicationSMSService(object): :ivar sms: SmsOperations operations :vartype sms: azure.communication.sms.aio.operations.SmsOperations - :param endpoint: The endpoint of the Azure Communication resource. + :param endpoint: The communication resource, for example https://my-resource.communication.azure.com. :type endpoint: str """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py index 19ba0e93c716..77033099353f 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/_configuration.py @@ -19,7 +19,7 @@ class AzureCommunicationSMSServiceConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. - :param endpoint: The endpoint of the Azure Communication resource. + :param endpoint: The communication resource, for example https://my-resource.communication.azure.com. :type endpoint: str """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py index 341269700b32..500c4fa9d9e5 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/aio/operations/_sms_operations.py @@ -5,10 +5,9 @@ # Code generated by Microsoft (R) AutoRest Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +from typing import Any, Callable, Dict, Generic, Optional, TypeVar import warnings -from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest @@ -40,33 +39,20 @@ def __init__(self, client, config, serializer, deserializer) -> None: self._deserialize = deserializer self._config = config - def send( + async def send( self, send_message_request: "_models.SendMessageRequest", - repeatability_request_id: Optional[str] = None, - repeatability_first_sent: Optional[str] = None, **kwargs - ) -> AsyncIterable["_models.SmsSendResponse"]: + ) -> "_models.SmsSendResponse": """Sends a SMS message from a phone number that belongs to the authenticated account. Sends a SMS message from a phone number that belongs to the authenticated account. :param send_message_request: Represents the body of the send message request. :type send_message_request: ~azure.communication.sms.models.SendMessageRequest - :param repeatability_request_id: If specified, the client directs that the request is - repeatable; that is, the client can make the request multiple times with the same - Repeatability-Request-ID and get back an appropriate response without the server executing the - request multiple times. The value of the Repeatability-Request-ID is an opaque string - representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID - (GUID), identifier for the request. - :type repeatability_request_id: str - :param repeatability_first_sent: MUST be sent by clients to specify that a request is - repeatable. Repeatability-First-Sent is used to specify the date and time at which the request - was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. - :type repeatability_first_sent: str :keyword callable cls: A custom type or function that will be passed the direct response - :return: An iterator like instance of either SmsSendResponse or the result of cls(response) - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.communication.sms.models.SmsSendResponse] + :return: SmsSendResponse, or the result of cls(response) + :rtype: ~azure.communication.sms.models.SmsSendResponse :raises: ~azure.core.exceptions.HttpResponseError """ cls = kwargs.pop('cls', None) # type: ClsType["_models.SmsSendResponse"] @@ -75,67 +61,40 @@ def send( } error_map.update(kwargs.pop('error_map', {})) api_version = "2021-03-07" - content_type = "application/json" + content_type = kwargs.pop("content_type", "application/json") accept = "application/json" - def prepare_request(next_link=None): - # Construct headers - header_parameters = {} # type: Dict[str, Any] - if repeatability_request_id is not None: - header_parameters['repeatability-request-id'] = self._serialize.header("repeatability_request_id", repeatability_request_id, 'str') - if repeatability_first_sent is not None: - header_parameters['repeatability-first-sent'] = self._serialize.header("repeatability_first_sent", repeatability_first_sent, 'str') - header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') - header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') - - if not next_link: - # Construct URL - url = self.send.metadata['url'] # type: ignore - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - # Construct parameters - query_parameters = {} # type: Dict[str, Any] - query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') - - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) - else: - url = next_link - query_parameters = {} # type: Dict[str, Any] - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.get(url, query_parameters, header_parameters, **body_content_kwargs) - return request - - async def extract_data(pipeline_response): - deserialized = self._deserialize('SmsSendResponse', pipeline_response) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) - return deserialized.next_link or None, AsyncList(list_of_elem) - - async def get_next(next_link=None): - request = prepare_request(next_link) - - pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [202]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return AsyncItemPaged( - get_next, extract_data - ) + # Construct URL + url = self.send.metadata['url'] # type: ignore + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('SmsSendResponse', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized send.metadata = {'url': '/sms'} # type: ignore diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py index 8869534805dd..cfede64e32fb 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py @@ -8,18 +8,26 @@ try: from ._models_py3 import SendMessageRequest + from ._models_py3 import SmsRecipient from ._models_py3 import SmsSendOptions from ._models_py3 import SmsSendResponse from ._models_py3 import SmsSendResult except (SyntaxError, ImportError): from ._models import SendMessageRequest # type: ignore + from ._models import SmsRecipient # type: ignore from ._models import SmsSendOptions # type: ignore from ._models import SmsSendResponse # type: ignore from ._models import SmsSendResult # type: ignore +from ._azure_communication_sms_service_enums import ( + SmsSendResultRepeatabilityResult, +) + __all__ = [ 'SendMessageRequest', + 'SmsRecipient', 'SmsSendOptions', 'SmsSendResponse', 'SmsSendResult', + 'SmsSendResultRepeatabilityResult', ] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py index da21c0802beb..8940997d8640 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py @@ -17,9 +17,9 @@ class SendMessageRequest(msrest.serialization.Model): :param from_property: Required. The sender's phone number in E.164 format that is owned by the authenticated account. :type from_property: str - :param to: Required. The recipient's phone number in E.164 format. In this version, a minimum - of 1 and upto 100 recipients in the list are supported. - :type to: list[str] + :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, + a minimum of 1 and upto 100 recipients in the list are supported. + :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] :param message: Required. The contents of the message that will be sent to the recipient. The allowable content is defined by RFC 5724. :type message: str @@ -29,13 +29,13 @@ class SendMessageRequest(msrest.serialization.Model): _validation = { 'from_property': {'required': True}, - 'to': {'required': True}, + 'sms_recipients': {'required': True}, 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, } _attribute_map = { 'from_property': {'key': 'from', 'type': 'str'}, - 'to': {'key': 'to', 'type': '[str]'}, + 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } @@ -46,22 +46,68 @@ def __init__( ): super(SendMessageRequest, self).__init__(**kwargs) self.from_property = kwargs['from_property'] - self.to = kwargs['to'] + self.sms_recipients = kwargs['sms_recipients'] self.message = kwargs['message'] self.sms_send_options = kwargs.get('sms_send_options', None) +class SmsRecipient(msrest.serialization.Model): + """Recipient details for sending SMS messages. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipient's phone number in E.164 format. + :type to: str + :param repeatability_request_id: If specified, the client directs that the request is + repeatable; that is, the client can make the request multiple times with the same + Repeatability-Request-ID and get back an appropriate response without the server executing the + request multiple times. The value of the Repeatability-Request-ID is an opaque string + representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID + (GUID), identifier for the request. + :type repeatability_request_id: str + :param repeatability_first_sent: MUST be sent by clients to specify that a request is + repeatable. Repeatability-First-Sent is used to specify the date and time at which the request + was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. + :type repeatability_first_sent: str + """ + + _validation = { + 'to': {'required': True}, + } + + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, + 'repeatability_request_id': {'key': 'repeatabilityRequestId', 'type': 'str'}, + 'repeatability_first_sent': {'key': 'repeatabilityFirstSent', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(SmsRecipient, self).__init__(**kwargs) + self.to = kwargs['to'] + self.repeatability_request_id = kwargs.get('repeatability_request_id', None) + self.repeatability_first_sent = kwargs.get('repeatability_first_sent', None) + + class SmsSendOptions(msrest.serialization.Model): """Optional configuration for sending SMS messages. - :param enable_delivery_report: Enable this flag to receive a delivery report for this message - on the Azure Resource EventGrid. + All required parameters must be populated in order to send to Azure. + + :param enable_delivery_report: Required. Enable this flag to receive a delivery report for this + message on the Azure Resource EventGrid. :type enable_delivery_report: bool :param tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. :type tag: str """ + _validation = { + 'enable_delivery_report': {'required': True}, + } + _attribute_map = { 'enable_delivery_report': {'key': 'enableDeliveryReport', 'type': 'bool'}, 'tag': {'key': 'tag', 'type': 'str'}, @@ -72,7 +118,7 @@ def __init__( **kwargs ): super(SmsSendOptions, self).__init__(**kwargs) - self.enable_delivery_report = kwargs.get('enable_delivery_report', False) + self.enable_delivery_report = kwargs['enable_delivery_report'] self.tag = kwargs.get('tag', None) @@ -83,8 +129,6 @@ class SmsSendResponse(msrest.serialization.Model): :param value: Required. :type value: list[~azure.communication.sms.models.SmsSendResult] - :param next_link: - :type next_link: str """ _validation = { @@ -93,7 +137,6 @@ class SmsSendResponse(msrest.serialization.Model): _attribute_map = { 'value': {'key': 'value', 'type': '[SmsSendResult]'}, - 'next_link': {'key': 'nextLink', 'type': 'str'}, } def __init__( @@ -102,7 +145,6 @@ def __init__( ): super(SmsSendResponse, self).__init__(**kwargs) self.value = kwargs['value'] - self.next_link = kwargs.get('next_link', None) class SmsSendResult(msrest.serialization.Model): @@ -110,30 +152,35 @@ class SmsSendResult(msrest.serialization.Model): All required parameters must be populated in order to send to Azure. - :param to: Required. The recipients's phone number in E.164 format. + :param to: Required. The recipient's phone number in E.164 format. :type to: str - :param message_id: The identifier of the outgoing SMS message. Only present if message + :param message_id: The identifier of the outgoing Sms message. Only present if message processed. :type message_id: str :param http_status_code: Required. HTTP Status code. :type http_status_code: int - :param succeeded: Required. Flag to check if message processing succeeded or not. - :type succeeded: bool - :param error_message: Optional error message in case of 4xx or 5xx errors. + :param repeatability_result: The result of a repeatable request with one of the case- + insensitive values accepted or rejected. Possible values include: "accepted", "rejected". + :type repeatability_result: str or + ~azure.communication.sms.models.SmsSendResultRepeatabilityResult + :param successful: Required. Indicates if the message is processed successfully or not. + :type successful: bool + :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. :type error_message: str """ _validation = { 'to': {'required': True}, 'http_status_code': {'required': True}, - 'succeeded': {'required': True}, + 'successful': {'required': True}, } _attribute_map = { 'to': {'key': 'to', 'type': 'str'}, 'message_id': {'key': 'messageId', 'type': 'str'}, 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, - 'succeeded': {'key': 'succeeded', 'type': 'bool'}, + 'repeatability_result': {'key': 'repeatabilityResult', 'type': 'str'}, + 'successful': {'key': 'successful', 'type': 'bool'}, 'error_message': {'key': 'errorMessage', 'type': 'str'}, } @@ -145,5 +192,6 @@ def __init__( self.to = kwargs['to'] self.message_id = kwargs.get('message_id', None) self.http_status_code = kwargs['http_status_code'] - self.succeeded = kwargs['succeeded'] + self.repeatability_result = kwargs.get('repeatability_result', None) + self.successful = kwargs['successful'] self.error_message = kwargs.get('error_message', None) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py index afca499d44aa..593047cd2346 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py @@ -6,10 +6,12 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import List, Optional +from typing import List, Optional, Union import msrest.serialization +from ._azure_communication_sms_service_enums import * + class SendMessageRequest(msrest.serialization.Model): """Represents the properties of a send message request. @@ -19,9 +21,9 @@ class SendMessageRequest(msrest.serialization.Model): :param from_property: Required. The sender's phone number in E.164 format that is owned by the authenticated account. :type from_property: str - :param to: Required. The recipient's phone number in E.164 format. In this version, a minimum - of 1 and upto 100 recipients in the list are supported. - :type to: list[str] + :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, + a minimum of 1 and upto 100 recipients in the list are supported. + :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] :param message: Required. The contents of the message that will be sent to the recipient. The allowable content is defined by RFC 5724. :type message: str @@ -31,13 +33,13 @@ class SendMessageRequest(msrest.serialization.Model): _validation = { 'from_property': {'required': True}, - 'to': {'required': True}, + 'sms_recipients': {'required': True}, 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, } _attribute_map = { 'from_property': {'key': 'from', 'type': 'str'}, - 'to': {'key': 'to', 'type': '[str]'}, + 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } @@ -46,29 +48,79 @@ def __init__( self, *, from_property: str, - to: List[str], + sms_recipients: List["SmsRecipient"], message: str, sms_send_options: Optional["SmsSendOptions"] = None, **kwargs ): super(SendMessageRequest, self).__init__(**kwargs) self.from_property = from_property - self.to = to + self.sms_recipients = sms_recipients self.message = message self.sms_send_options = sms_send_options +class SmsRecipient(msrest.serialization.Model): + """Recipient details for sending SMS messages. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipient's phone number in E.164 format. + :type to: str + :param repeatability_request_id: If specified, the client directs that the request is + repeatable; that is, the client can make the request multiple times with the same + Repeatability-Request-ID and get back an appropriate response without the server executing the + request multiple times. The value of the Repeatability-Request-ID is an opaque string + representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID + (GUID), identifier for the request. + :type repeatability_request_id: str + :param repeatability_first_sent: MUST be sent by clients to specify that a request is + repeatable. Repeatability-First-Sent is used to specify the date and time at which the request + was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. + :type repeatability_first_sent: str + """ + + _validation = { + 'to': {'required': True}, + } + + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, + 'repeatability_request_id': {'key': 'repeatabilityRequestId', 'type': 'str'}, + 'repeatability_first_sent': {'key': 'repeatabilityFirstSent', 'type': 'str'}, + } + + def __init__( + self, + *, + to: str, + repeatability_request_id: Optional[str] = None, + repeatability_first_sent: Optional[str] = None, + **kwargs + ): + super(SmsRecipient, self).__init__(**kwargs) + self.to = to + self.repeatability_request_id = repeatability_request_id + self.repeatability_first_sent = repeatability_first_sent + + class SmsSendOptions(msrest.serialization.Model): """Optional configuration for sending SMS messages. - :param enable_delivery_report: Enable this flag to receive a delivery report for this message - on the Azure Resource EventGrid. + All required parameters must be populated in order to send to Azure. + + :param enable_delivery_report: Required. Enable this flag to receive a delivery report for this + message on the Azure Resource EventGrid. :type enable_delivery_report: bool :param tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. :type tag: str """ + _validation = { + 'enable_delivery_report': {'required': True}, + } + _attribute_map = { 'enable_delivery_report': {'key': 'enableDeliveryReport', 'type': 'bool'}, 'tag': {'key': 'tag', 'type': 'str'}, @@ -77,7 +129,7 @@ class SmsSendOptions(msrest.serialization.Model): def __init__( self, *, - enable_delivery_report: Optional[bool] = False, + enable_delivery_report: bool, tag: Optional[str] = None, **kwargs ): @@ -93,8 +145,6 @@ class SmsSendResponse(msrest.serialization.Model): :param value: Required. :type value: list[~azure.communication.sms.models.SmsSendResult] - :param next_link: - :type next_link: str """ _validation = { @@ -103,19 +153,16 @@ class SmsSendResponse(msrest.serialization.Model): _attribute_map = { 'value': {'key': 'value', 'type': '[SmsSendResult]'}, - 'next_link': {'key': 'nextLink', 'type': 'str'}, } def __init__( self, *, value: List["SmsSendResult"], - next_link: Optional[str] = None, **kwargs ): super(SmsSendResponse, self).__init__(**kwargs) self.value = value - self.next_link = next_link class SmsSendResult(msrest.serialization.Model): @@ -123,30 +170,35 @@ class SmsSendResult(msrest.serialization.Model): All required parameters must be populated in order to send to Azure. - :param to: Required. The recipients's phone number in E.164 format. + :param to: Required. The recipient's phone number in E.164 format. :type to: str - :param message_id: The identifier of the outgoing SMS message. Only present if message + :param message_id: The identifier of the outgoing Sms message. Only present if message processed. :type message_id: str :param http_status_code: Required. HTTP Status code. :type http_status_code: int - :param succeeded: Required. Flag to check if message processing succeeded or not. - :type succeeded: bool - :param error_message: Optional error message in case of 4xx or 5xx errors. + :param repeatability_result: The result of a repeatable request with one of the case- + insensitive values accepted or rejected. Possible values include: "accepted", "rejected". + :type repeatability_result: str or + ~azure.communication.sms.models.SmsSendResultRepeatabilityResult + :param successful: Required. Indicates if the message is processed successfully or not. + :type successful: bool + :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. :type error_message: str """ _validation = { 'to': {'required': True}, 'http_status_code': {'required': True}, - 'succeeded': {'required': True}, + 'successful': {'required': True}, } _attribute_map = { 'to': {'key': 'to', 'type': 'str'}, 'message_id': {'key': 'messageId', 'type': 'str'}, 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, - 'succeeded': {'key': 'succeeded', 'type': 'bool'}, + 'repeatability_result': {'key': 'repeatabilityResult', 'type': 'str'}, + 'successful': {'key': 'successful', 'type': 'bool'}, 'error_message': {'key': 'errorMessage', 'type': 'str'}, } @@ -155,8 +207,9 @@ def __init__( *, to: str, http_status_code: int, - succeeded: bool, + successful: bool, message_id: Optional[str] = None, + repeatability_result: Optional[Union[str, "SmsSendResultRepeatabilityResult"]] = None, error_message: Optional[str] = None, **kwargs ): @@ -164,5 +217,6 @@ def __init__( self.to = to self.message_id = message_id self.http_status_code = http_status_code - self.succeeded = succeeded + self.repeatability_result = repeatability_result + self.successful = successful self.error_message = error_message diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py index 0f8129a136fa..1f0d0640e125 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/operations/_sms_operations.py @@ -9,7 +9,6 @@ import warnings from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error -from azure.core.paging import ItemPaged from azure.core.pipeline import PipelineResponse from azure.core.pipeline.transport import HttpRequest, HttpResponse @@ -17,7 +16,7 @@ if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + from typing import Any, Callable, Dict, Generic, Optional, TypeVar T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -47,31 +46,18 @@ def __init__(self, client, config, serializer, deserializer): def send( self, send_message_request, # type: "_models.SendMessageRequest" - repeatability_request_id=None, # type: Optional[str] - repeatability_first_sent=None, # type: Optional[str] **kwargs # type: Any ): - # type: (...) -> Iterable["_models.SmsSendResponse"] + # type: (...) -> "_models.SmsSendResponse" """Sends a SMS message from a phone number that belongs to the authenticated account. Sends a SMS message from a phone number that belongs to the authenticated account. :param send_message_request: Represents the body of the send message request. :type send_message_request: ~azure.communication.sms.models.SendMessageRequest - :param repeatability_request_id: If specified, the client directs that the request is - repeatable; that is, the client can make the request multiple times with the same - Repeatability-Request-ID and get back an appropriate response without the server executing the - request multiple times. The value of the Repeatability-Request-ID is an opaque string - representing a client-generated, 36-character hexadecimal case-insensitive encoding of a UUID - (GUID), identifier for the request. - :type repeatability_request_id: str - :param repeatability_first_sent: MUST be sent by clients to specify that a request is - repeatable. Repeatability-First-Sent is used to specify the date and time at which the request - was first created.eg- Tue, 26 Mar 2019 16:06:51 GMT. - :type repeatability_first_sent: str :keyword callable cls: A custom type or function that will be passed the direct response - :return: An iterator like instance of either SmsSendResponse or the result of cls(response) - :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResponse] + :return: SmsSendResponse, or the result of cls(response) + :rtype: ~azure.communication.sms.models.SmsSendResponse :raises: ~azure.core.exceptions.HttpResponseError """ cls = kwargs.pop('cls', None) # type: ClsType["_models.SmsSendResponse"] @@ -80,67 +66,40 @@ def send( } error_map.update(kwargs.pop('error_map', {})) api_version = "2021-03-07" - content_type = "application/json" + content_type = kwargs.pop("content_type", "application/json") accept = "application/json" - def prepare_request(next_link=None): - # Construct headers - header_parameters = {} # type: Dict[str, Any] - if repeatability_request_id is not None: - header_parameters['repeatability-request-id'] = self._serialize.header("repeatability_request_id", repeatability_request_id, 'str') - if repeatability_first_sent is not None: - header_parameters['repeatability-first-sent'] = self._serialize.header("repeatability_first_sent", repeatability_first_sent, 'str') - header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') - header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') - - if not next_link: - # Construct URL - url = self.send.metadata['url'] # type: ignore - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - # Construct parameters - query_parameters = {} # type: Dict[str, Any] - query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') - - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) - else: - url = next_link - query_parameters = {} # type: Dict[str, Any] - path_format_arguments = { - 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - url = self._client.format_url(url, **path_format_arguments) - body_content_kwargs = {} # type: Dict[str, Any] - body_content = self._serialize.body(send_message_request, 'SendMessageRequest') - body_content_kwargs['content'] = body_content - request = self._client.get(url, query_parameters, header_parameters, **body_content_kwargs) - return request - - def extract_data(pipeline_response): - deserialized = self._deserialize('SmsSendResponse', pipeline_response) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) - return deserialized.next_link or None, iter(list_of_elem) - - def get_next(next_link=None): - request = prepare_request(next_link) - - pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [202]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged( - get_next, extract_data - ) + # Construct URL + url = self.send.metadata['url'] # type: ignore + path_format_arguments = { + 'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(send_message_request, 'SendMessageRequest') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('SmsSendResponse', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized send.metadata = {'url': '/sms'} # type: ignore diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index b32236bef6d4..98f65d327bd9 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -7,6 +7,7 @@ from azure.core.tracing.decorator import distributed_trace from azure.communication.sms._generated.models import ( SendMessageRequest, + SmsRecipient, SmsSendResult, SmsSendOptions, ) @@ -79,7 +80,7 @@ def send(self, from_, # type: str to, # type: Union[str, List[str]] message, # type: str **kwargs #type: Any - ): # type: (...) -> ItemPaged[SmsSendResult] + ): # type: (...) -> [SmsSendResult] """Sends SMSs to phone numbers. :param str from_: The sender of the SMS. @@ -90,8 +91,8 @@ def send(self, from_, # type: str message on the Azure Resource EventGrid. :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. - :return: An iterator like instance of SmsSendResult - :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResult] + :return: A list of SmsSendResults. + :rtype: [~azure.communication.sms.models.SmsSendResult] """ enable_delivery_report = kwargs.pop('enable_delivery_report', False) @@ -104,9 +105,12 @@ def send(self, from_, # type: str request = SendMessageRequest( from_property=from_, - to=[p for p in to], + sms_recipients=[SmsRecipient(to=p) for p in to], message=message, sms_send_options=sms_send_options, **kwargs) - return self._sms_service_client.sms.send(request, **kwargs) + return self._sms_service_client.sms.send( + request, + cls=lambda pr, r, e: r.value, + **kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 4b7e73e75c76..a1eb3fa03b01 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -4,9 +4,10 @@ # license information. # -------------------------------------------------------------------------- -from azure.core.tracing.decorator import distributed_trace +from azure.core.tracing.decorator_async import distributed_trace_async from azure.communication.sms._generated.models import ( SendMessageRequest, + SmsRecipient, SmsSendResult, SmsSendOptions, ) @@ -75,8 +76,8 @@ def from_connection_string(cls, conn_str, # type: str return cls(endpoint, access_key, **kwargs) - @distributed_trace() - def send(self, from_, # type: str + @distributed_trace_async() + async def send(self, from_, # type: str to, # type: Union[str, List[str]] message, # type: str **kwargs # type: Any @@ -91,8 +92,8 @@ def send(self, from_, # type: str message on the Azure Resource EventGrid. :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. - :return: An iterator like instance of SmsSendResult - :rtype: ~azure.core.paging.ItemPaged[~azure.communication.sms.models.SmsSendResult] + :return: A list of SmsSendResults. + :rtype: [~azure.communication.sms.models.SmsSendResult] """ enable_delivery_report = kwargs.pop('enable_delivery_report', False) @@ -105,12 +106,15 @@ def send(self, from_, # type: str request = SendMessageRequest( from_property=from_, - to=[p for p in to], + sms_recipients=[SmsRecipient(to=p) for p in to], message=message, sms_send_options=sms_send_options, **kwargs) - return self._sms_service_client.sms.send(request, **kwargs) + return await self._sms_service_client.sms.send( + request, + cls=lambda pr, r, e: r.value, + **kwargs) async def __aenter__(self) -> "SMSClient": await self._sms_service_client.__aenter__() diff --git a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md index 3d534536aa2d..5420dfc7af2a 100644 --- a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md +++ b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md @@ -23,7 +23,7 @@ directive: ### Settings ``` yaml -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/dc652c9308ddcb19a73dbbb37498e63081dfde6e/specification/communication/data-plane/Microsoft.CommunicationServicesSms/stable/2021-03-07/communicationservicessms.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/83d782b99cb85a9b2f5ef22774584541dd0ff997/specification/communication/data-plane/Microsoft.CommunicationServicesSms/stable/2021-03-07/communicationservicessms.json output-folder: ../azure/communication/sms/_generated namespace: azure.communication.sms no-namespace-folders: true From 850d194b3d0b332ced45bb610a151efade04d4bd Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 12:33:58 -0800 Subject: [PATCH 06/28] Updated SMS client tests and recordings --- .../tests/_shared/testcase.py | 15 ++++-- ...sms_client_e2e.test_send_sms_multiple.yaml | 48 +++++++++++++++++ ...t_sms_client_e2e.test_send_sms_single.yaml | 47 +++++++++++++++++ ..._client_e2e_async.test_send_sms_async.yaml | 30 ++++++----- ..._send_sms_async_from_managed_identity.yaml | 28 +++++----- ...2e_async.test_send_sms_multiple_async.yaml | 38 ++++++++++++++ .../tests/test_sms_client_e2e.py | 29 ++++++----- .../tests/test_sms_client_e2e_async.py | 52 ++++++++++--------- 8 files changed, 223 insertions(+), 64 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml diff --git a/sdk/communication/azure-communication-sms/tests/_shared/testcase.py b/sdk/communication/azure-communication-sms/tests/_shared/testcase.py index 287b1d789c29..a45462eee0d7 100644 --- a/sdk/communication/azure-communication-sms/tests/_shared/testcase.py +++ b/sdk/communication/azure-communication-sms/tests/_shared/testcase.py @@ -52,12 +52,21 @@ def process_response(self, response): return response def _replace_keys(self, body): + def _replace_recursively(obj): + if isinstance(obj, dict): + for key in obj: + if key in self._keys: + obj[key] = self._replacement + else: + _replace_recursively(obj[key]) + elif isinstance(obj, list): + for i in obj: + _replace_recursively(i) + import json try: body = json.loads(body) - for key in self._keys: - if key in body: - body[key] = self._replacement + _replace_recursively(body) except (KeyError, ValueError): return body diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml new file mode 100644 index 000000000000..ba9b51374036 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}, {"to": "sanitized"}], + "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": + true, "tag": "test-tag"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '194' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 20:32:31 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}, {"to": "sanitized", "messageId": "sanitized", "httpStatusCode": 202, + "errorMessage": null, "repeatabilityResult": "accepted", "successful": true}]}' + headers: + api-supported-versions: + - 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 19 Feb 2021 20:32:30 GMT + ms-cv: + - Me4qe0hj+0S3ms9aJlQ9IA.0 + request-context: + - appId= + transfer-encoding: + - chunked + x-processing-time: + - 688ms + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml new file mode 100644 index 000000000000..63711ef20c43 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml @@ -0,0 +1,47 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "test-tag"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '170' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 20:32:32 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}]}' + headers: + api-supported-versions: + - 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 19 Feb 2021 20:32:31 GMT + ms-cv: + - x4Yv/8e4lUuw4Vk7+37JWQ.0 + request-context: + - appId= + transfer-encoding: + - chunked + x-processing-time: + - 529ms + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml index 51b14df7e423..9e1ea963f777 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml @@ -1,33 +1,37 @@ interactions: - request: - body: '{"from": "sanitized", "to": "sanitized", "message": "Hello World via SMS", - "sendSmsOptions": {"enableDeliveryReport": true}}' + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "test-tag"}}' headers: Accept: - application/json Content-Length: - - '132' + - '170' Content-Type: - application/json Date: - - Wed, 20 Jan 2021 18:11:24 GMT + - Fri, 19 Feb 2021 20:32:33 GMT User-Agent: - - azsdk-python-communication-sms/1.0.0b5 Python/3.8.5 (Windows-10-10.0.19041-SP0) + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) x-ms-return-client-request-id: - 'true' method: POST - uri: https://sanitized.communication.azure.com/sms?api-version=2020-07-20-preview1 + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 response: - body: '{"messageId": "sanitized"}' + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}]}' headers: + api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 content-type: application/json; charset=utf-8 - date: Wed, 20 Jan 2021 18:11:24 GMT - ms-cv: x7uY4q7a+EmmyTMUW8my+A.0 + date: Fri, 19 Feb 2021 20:32:32 GMT + ms-cv: PrVehffsBkKjxNAFVfuKhw.0 request-context: appId= transfer-encoding: chunked - x-processing-time: 468ms + x-processing-time: 759ms status: - code: 200 - message: OK - url: https://sanitized.communication.azure.com/sms?api-version=2020-07-20-preview1 + code: 202 + message: Accepted + url: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml index d425853c779b..fc2d2997451e 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml @@ -1,29 +1,33 @@ interactions: - request: - body: '{"from": "sanitized", "to": "sanitized", "message": "Hello World via SMS", - "sendSmsOptions": {"enableDeliveryReport": true}}' + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "test-tag"}}' headers: Accept: - application/json Content-Length: - - '132' + - '170' Content-Type: - application/json User-Agent: - - azsdk-python-communication-sms/1.0.0b5 Python/3.8.5 (Windows-10-10.0.19041-SP0) + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) method: POST - uri: https://sanitized.communication.azure.com/sms?api-version=2020-07-20-preview1 + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 response: - body: '{"messageId": "sanitized"}' + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}]}' headers: + api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 content-type: application/json; charset=utf-8 - date: Wed, 20 Jan 2021 18:11:27 GMT - ms-cv: 2alAVqPXy0O98kSmG+jzFA.0 + date: Fri, 19 Feb 2021 20:32:34 GMT + ms-cv: wKagbFg+REufGIeqX4sk5w.0 request-context: appId= transfer-encoding: chunked - x-processing-time: 827ms + x-processing-time: 561ms status: - code: 200 - message: OK - url: https://sanitized.communication.azure.com/sms?api-version=2020-07-20-preview1 + code: 202 + message: Accepted + url: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml new file mode 100644 index 000000000000..ba6c4cc5a3da --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml @@ -0,0 +1,38 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}, {"to": "sanitized"}], + "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": + true, "tag": "test-tag"}}' + headers: + Accept: + - application/json + Content-Length: + - '194' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 20:32:35 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}, {"to": "sanitized", "messageId": "sanitized", "httpStatusCode": 202, + "errorMessage": null, "repeatabilityResult": "accepted", "successful": true}]}' + headers: + api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: application/json; charset=utf-8 + date: Fri, 19 Feb 2021 20:32:35 GMT + ms-cv: Yf4grqyJZkSyYxFZZF/DLA.0 + request-context: appId= + transfer-encoding: chunked + x-processing-time: 752ms + status: + code: 202 + message: Accepted + url: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index f76b38981124..cf997d9ae71a 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -39,14 +39,13 @@ def test_send_sms_single(self): from_=self.phone_number, to=[self.phone_number], message="Hello World via SMS", - enable_delivery_report=True) # optional property + enable_delivery_report=True, # optional property + tag="test-tag") # optional property - count = 0 + assert len(sms_responses) is 1 + for sms_response in sms_responses: - count += 1 - assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 - assert count is 1 + self.verify_sms_response(sms_response) @pytest.mark.live_test_only def test_send_sms_multiple(self): @@ -56,12 +55,18 @@ def test_send_sms_multiple(self): from_=self.phone_number, to=[self.phone_number, self.phone_number], message="Hello World via SMS", - enable_delivery_report=True) # optional property + enable_delivery_report=True, # optional property + tag="test-tag") # optional property - count = 0 + assert len(sms_responses) is 2 + for sms_response in sms_responses: - count += 1 - assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 - assert count is 2 + self.verify_sms_response(sms_response) + + def verify_sms_response(self, sms_response): + assert sms_response.to == self.phone_number + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert sms_response.error_message is None + assert sms_response.successful \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index 6d7932d06c10..29caf538e53b 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -46,19 +46,18 @@ async def test_send_sms_async(self): async with sms_client: # calling send() with sms values - sms_responses = sms_client.send( + sms_responses = await sms_client.send( from_=self.phone_number, to=[self.phone_number], message="Hello World via SMS", - enable_delivery_report=True) # optional property + enable_delivery_report=True, # optional property + tag="test-tag") # optional property - count = 0 - async for sms_response in sms_responses: - count += 1 - assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 - assert count is 1 + assert len(sms_responses) is 1 + for sms_response in sms_responses: + self.verify_sms_response(sms_response) + @AsyncCommunicationTestCase.await_prepared_test @pytest.mark.live_test_only async def test_send_sms_multiple_async(self): @@ -67,18 +66,17 @@ async def test_send_sms_multiple_async(self): async with sms_client: # calling send() with sms values - sms_responses = sms_client.send( + sms_responses = await sms_client.send( from_=self.phone_number, to=[self.phone_number, self.phone_number], message="Hello World via SMS", - enable_delivery_report=True) # optional property + enable_delivery_report=True, # optional property + tag="test-tag") # optional propert - count = 0 - async for sms_response in sms_responses: - count += 1 - assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 - assert count is 2 + assert len(sms_responses) is 2 + + for sms_response in sms_responses: + self.verify_sms_response(sms_response) @AsyncCommunicationTestCase.await_prepared_test @pytest.mark.live_test_only @@ -93,16 +91,22 @@ async def test_send_sms_async_from_managed_identity(self): async with sms_client: # calling send() with sms values - sms_responses = sms_client.send( + sms_responses = await sms_client.send( from_=self.phone_number, to=[self.phone_number], message="Hello World via SMS", - enable_delivery_report=True) # optional property + enable_delivery_report=True, # optional property + tag="test-tag") # optional propert - count = 0 - async for sms_response in sms_responses: - count += 1 - assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 - assert count is 1 + assert len(sms_responses) is 1 + + for sms_response in sms_responses: + self.verify_sms_response(sms_response) + + def verify_sms_response(self, sms_response): + assert sms_response.to == self.phone_number + assert sms_response.message_id is not None + assert sms_response.http_status_code is 202 + assert sms_response.error_message is None + assert sms_response.successful \ No newline at end of file From b2b87f6a35f1e2965626c2db48a9b645d9c2d0be Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 15:21:16 -0800 Subject: [PATCH 07/28] Updated SMS samples with changes from new swagger --- .../azure-communication-sms/samples/sms_sample.py | 4 ++-- .../azure-communication-sms/samples/sms_sample_async.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample.py b/sdk/communication/azure-communication-sms/samples/sms_sample.py index d3fa2f13fc59..77c736c38ebe 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample.py @@ -39,14 +39,14 @@ def send_sms(self): failed_recipients = [] for sms_response in sms_responses: - if (sms_response.succeeded): + if (sms_response.successful): print("Message with message id {} was successful sent to {}" .format(sms_response.message_id , sms_response.to)) else: print("Message with message id {} failed to send to {}" .format(sms_response.message_id , sms_response.to)) failed_recipients.append(sms_response.to) - + # calling send() with failed recipients sms_responses = sms_client.send( from_="", diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py index ef4a0f56afb2..75c2ffb92d5a 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py @@ -32,7 +32,7 @@ async def send_sms_async(self): async with sms_client: try: # calling send() with sms values - sms_responses = sms_client.send( + sms_responses = await sms_client.send( from_="", to=["", "", ""], message="Hello World via SMS", @@ -43,8 +43,8 @@ async def send_sms_async(self): pass failed_recipients = [] - async for sms_response in sms_responses: - if (sms_response.succeeded): + for sms_response in sms_responses: + if (sms_response.successful): print("Message with message id {} was successful sent to {}" .format(sms_response.message_id , sms_response.to)) else: @@ -54,7 +54,7 @@ async def send_sms_async(self): try: # calling send() with failed recipients - sms_responses = sms_client.send( + sms_responses = await sms_client.send( from_="", to=failed_recipients, message="Hello World via SMS", From 527ac62908bc9d74fd39e7dc2f6863fa444969ba Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 15:54:17 -0800 Subject: [PATCH 08/28] Added more test cases --- ...st_send_sms_invalid_from_phone_number.yaml | 47 ++++++++++++++++++ ...test_send_sms_invalid_to_phone_number.yaml | 47 ++++++++++++++++++ ...sms_client_e2e.test_send_sms_multiple.yaml | 12 ++--- ....test_send_sms_phone_number_not_owned.yaml | 48 +++++++++++++++++++ ...t_sms_client_e2e.test_send_sms_single.yaml | 12 ++--- ..._client_e2e_async.test_send_sms_async.yaml | 12 ++--- ..._send_sms_async_from_managed_identity.yaml | 10 ++-- ...d_sms_invalid_from_phone_number_async.yaml | 37 ++++++++++++++ ...end_sms_invalid_to_phone_number_async.yaml | 37 ++++++++++++++ ...2e_async.test_send_sms_multiple_async.yaml | 12 ++--- .../tests/test_sms_client_e2e.py | 23 +++++++-- .../tests/test_sms_client_e2e_async.py | 29 +++++++++-- 12 files changed, 290 insertions(+), 36 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_from_phone_number.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_to_phone_number.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_phone_number_not_owned.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_from_phone_number_async.yaml create mode 100644 sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_to_phone_number_async.yaml diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_from_phone_number.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_from_phone_number.yaml new file mode 100644 index 000000000000..26e81794ba98 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_from_phone_number.yaml @@ -0,0 +1,47 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "custom-tag"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '174' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 23:46:23 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 400, "errorMessage": "Invalid To phone number format.", "repeatabilityResult": + "notavailable", "successful": false}]}' + headers: + api-supported-versions: + - 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 19 Feb 2021 23:46:22 GMT + ms-cv: + - KrZPD8ayDkeofuM5VxUYRA.0 + request-context: + - appId= + transfer-encoding: + - chunked + x-processing-time: + - 442ms + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_to_phone_number.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_to_phone_number.yaml new file mode 100644 index 000000000000..30f949cf9cd4 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_invalid_to_phone_number.yaml @@ -0,0 +1,47 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "custom-tag"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '174' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 23:53:30 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 400, "errorMessage": "Invalid To phone number format.", "repeatabilityResult": + "notavailable", "successful": false}]}' + headers: + api-supported-versions: + - 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 19 Feb 2021 23:53:29 GMT + ms-cv: + - ZSmIhRXZ/ku095wAm8oL0Q.0 + request-context: + - appId= + transfer-encoding: + - chunked + x-processing-time: + - 449ms + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml index ba9b51374036..3963a2963ef7 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_multiple.yaml @@ -2,7 +2,7 @@ interactions: - request: body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}, {"to": "sanitized"}], "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": - true, "tag": "test-tag"}}' + true, "tag": "custom-tag"}}' headers: Accept: - application/json @@ -11,11 +11,11 @@ interactions: Connection: - keep-alive Content-Length: - - '194' + - '196' Content-Type: - application/json Date: - - Fri, 19 Feb 2021 20:32:31 GMT + - Fri, 19 Feb 2021 23:53:31 GMT User-Agent: - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) x-ms-return-client-request-id: @@ -33,15 +33,15 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Fri, 19 Feb 2021 20:32:30 GMT + - Fri, 19 Feb 2021 23:53:31 GMT ms-cv: - - Me4qe0hj+0S3ms9aJlQ9IA.0 + - zGP+zoxEzEWfEoCv9nxZUg.0 request-context: - appId= transfer-encoding: - chunked x-processing-time: - - 688ms + - 864ms status: code: 202 message: Accepted diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_phone_number_not_owned.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_phone_number_not_owned.yaml new file mode 100644 index 000000000000..cd85b3577267 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_phone_number_not_owned.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}, {"to": "sanitized"}], + "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": + true, "tag": "custom-tag"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '196' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 23:46:25 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 202, "errorMessage": null, "repeatabilityResult": "accepted", "successful": + true}, {"to": "sanitized", "messageId": "sanitized", "httpStatusCode": 202, + "errorMessage": null, "repeatabilityResult": "accepted", "successful": true}]}' + headers: + api-supported-versions: + - 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 19 Feb 2021 23:46:24 GMT + ms-cv: + - QRn5iC0ChkehszEjsw0lPA.0 + request-context: + - appId= + transfer-encoding: + - chunked + x-processing-time: + - 966ms + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml index 63711ef20c43..42a254f4252f 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e.test_send_sms_single.yaml @@ -2,7 +2,7 @@ interactions: - request: body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": - "test-tag"}}' + "custom-tag"}}' headers: Accept: - application/json @@ -11,11 +11,11 @@ interactions: Connection: - keep-alive Content-Length: - - '170' + - '172' Content-Type: - application/json Date: - - Fri, 19 Feb 2021 20:32:32 GMT + - Fri, 19 Feb 2021 23:53:32 GMT User-Agent: - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) x-ms-return-client-request-id: @@ -32,15 +32,15 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Fri, 19 Feb 2021 20:32:31 GMT + - Fri, 19 Feb 2021 23:53:32 GMT ms-cv: - - x4Yv/8e4lUuw4Vk7+37JWQ.0 + - HHBTrB+/bkCxJVnBfHRdcA.0 request-context: - appId= transfer-encoding: - chunked x-processing-time: - - 529ms + - 510ms status: code: 202 message: Accepted diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml index 9e1ea963f777..13d7ef48afb4 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async.yaml @@ -2,16 +2,16 @@ interactions: - request: body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": - "test-tag"}}' + "custom-tag"}}' headers: Accept: - application/json Content-Length: - - '170' + - '172' Content-Type: - application/json Date: - - Fri, 19 Feb 2021 20:32:33 GMT + - Fri, 19 Feb 2021 23:53:33 GMT User-Agent: - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) x-ms-return-client-request-id: @@ -25,11 +25,11 @@ interactions: headers: api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 content-type: application/json; charset=utf-8 - date: Fri, 19 Feb 2021 20:32:32 GMT - ms-cv: PrVehffsBkKjxNAFVfuKhw.0 + date: Fri, 19 Feb 2021 23:53:32 GMT + ms-cv: aukatTugoECOYdRfE0uZrA.0 request-context: appId= transfer-encoding: chunked - x-processing-time: 759ms + x-processing-time: 559ms status: code: 202 message: Accepted diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml index fc2d2997451e..0891c2c7ee95 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_async_from_managed_identity.yaml @@ -2,12 +2,12 @@ interactions: - request: body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": - "test-tag"}}' + "custom-tag"}}' headers: Accept: - application/json Content-Length: - - '170' + - '172' Content-Type: - application/json User-Agent: @@ -21,11 +21,11 @@ interactions: headers: api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 content-type: application/json; charset=utf-8 - date: Fri, 19 Feb 2021 20:32:34 GMT - ms-cv: wKagbFg+REufGIeqX4sk5w.0 + date: Fri, 19 Feb 2021 23:53:34 GMT + ms-cv: YVbyy8ilhUCYHPz1CtyXCg.0 request-context: appId= transfer-encoding: chunked - x-processing-time: 561ms + x-processing-time: 984ms status: code: 202 message: Accepted diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_from_phone_number_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_from_phone_number_async.yaml new file mode 100644 index 000000000000..342164912d90 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_from_phone_number_async.yaml @@ -0,0 +1,37 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "custom-tag"}}' + headers: + Accept: + - application/json + Content-Length: + - '174' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 23:46:29 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 400, "errorMessage": "Invalid To phone number format.", "repeatabilityResult": + "notavailable", "successful": false}]}' + headers: + api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: application/json; charset=utf-8 + date: Fri, 19 Feb 2021 23:46:28 GMT + ms-cv: XLQdnhCtfU2LhQparOIUmw.0 + request-context: appId= + transfer-encoding: chunked + x-processing-time: 448ms + status: + code: 202 + message: Accepted + url: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_to_phone_number_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_to_phone_number_async.yaml new file mode 100644 index 000000000000..7a9c3848e1a9 --- /dev/null +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_invalid_to_phone_number_async.yaml @@ -0,0 +1,37 @@ +interactions: +- request: + body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}], "message": + "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": true, "tag": + "custom-tag"}}' + headers: + Accept: + - application/json + Content-Length: + - '174' + Content-Type: + - application/json + Date: + - Fri, 19 Feb 2021 23:53:35 GMT + User-Agent: + - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) + x-ms-return-client-request-id: + - 'true' + method: POST + uri: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 + response: + body: '{"value": [{"to": "sanitized", "messageId": "sanitized", "httpStatusCode": + 400, "errorMessage": "Invalid To phone number format.", "repeatabilityResult": + "notavailable", "successful": false}]}' + headers: + api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 + content-type: application/json; charset=utf-8 + date: Fri, 19 Feb 2021 23:53:34 GMT + ms-cv: GdUCMRXUhU2Ugu0aFWmg2g.0 + request-context: appId= + transfer-encoding: chunked + x-processing-time: 370ms + status: + code: 202 + message: Accepted + url: https://sanitized.communication.azure.com/sms?api-version=2021-03-07 +version: 1 diff --git a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml index ba6c4cc5a3da..2df9bcfe0415 100644 --- a/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml +++ b/sdk/communication/azure-communication-sms/tests/recordings/test_sms_client_e2e_async.test_send_sms_multiple_async.yaml @@ -2,16 +2,16 @@ interactions: - request: body: '{"from": "sanitized", "smsRecipients": [{"to": "sanitized"}, {"to": "sanitized"}], "message": "Hello World via SMS", "smsSendOptions": {"enableDeliveryReport": - true, "tag": "test-tag"}}' + true, "tag": "custom-tag"}}' headers: Accept: - application/json Content-Length: - - '194' + - '196' Content-Type: - application/json Date: - - Fri, 19 Feb 2021 20:32:35 GMT + - Fri, 19 Feb 2021 23:53:36 GMT User-Agent: - azsdk-python-communication-sms/1.0.0b5 Python/3.9.0 (Windows-10-10.0.19041-SP0) x-ms-return-client-request-id: @@ -26,11 +26,11 @@ interactions: headers: api-supported-versions: 2020-07-20-preview1, 2020-08-20-preview, 2021-03-07 content-type: application/json; charset=utf-8 - date: Fri, 19 Feb 2021 20:32:35 GMT - ms-cv: Yf4grqyJZkSyYxFZZF/DLA.0 + date: Fri, 19 Feb 2021 23:53:35 GMT + ms-cv: 4aZ8xJa3pU+My8OuXJTm2g.0 request-context: appId= transfer-encoding: chunked - x-processing-time: 752ms + x-processing-time: 622ms status: code: 202 message: Accepted diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index cf997d9ae71a..8010f1ab1413 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -40,7 +40,7 @@ def test_send_sms_single(self): to=[self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="test-tag") # optional property + tag="custom-tag") # optional property assert len(sms_responses) is 1 @@ -56,17 +56,34 @@ def test_send_sms_multiple(self): to=[self.phone_number, self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="test-tag") # optional property + tag="custom-tag") # optional property assert len(sms_responses) is 2 for sms_response in sms_responses: self.verify_sms_response(sms_response) + @pytest.mark.live_test_only + def test_send_sms_invalid_to_phone_number(self): + + # calling send() with sms values + sms_responses = self.sms_client.send( + from_=self.phone_number, + to=["+1234567891011"], + message="Hello World via SMS", + enable_delivery_report=True, # optional property + tag="custom-tag") # optional property + + assert len(sms_responses) is 1 + + for sms_response in sms_responses: + assert sms_response.http_status_code == 400 + assert not sms_response.successful + def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 + assert sms_response.http_status_code == 202 assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index 29caf538e53b..bbe4caaeed78 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -51,7 +51,7 @@ async def test_send_sms_async(self): to=[self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="test-tag") # optional property + tag="custom-tag") # optional property assert len(sms_responses) is 1 @@ -71,7 +71,7 @@ async def test_send_sms_multiple_async(self): to=[self.phone_number, self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="test-tag") # optional propert + tag="custom-tag") # optional propert assert len(sms_responses) is 2 @@ -96,17 +96,38 @@ async def test_send_sms_async_from_managed_identity(self): to=[self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="test-tag") # optional propert + tag="custom-tag") # optional propert assert len(sms_responses) is 1 for sms_response in sms_responses: self.verify_sms_response(sms_response) + + @AsyncCommunicationTestCase.await_prepared_test + @pytest.mark.live_test_only + async def test_send_sms_invalid_to_phone_number_async(self): + + sms_client = SmsClient.from_connection_string(self.connection_str) + + async with sms_client: + # calling send() with sms values + sms_responses = await sms_client.send( + from_=self.phone_number, + to=["+1234567891011"], + message="Hello World via SMS", + enable_delivery_report=True, # optional property + tag="custom-tag") # optional propert + + assert len(sms_responses) is 1 + + for sms_response in sms_responses: + assert sms_response.http_status_code == 400 + assert not sms_response.successful def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None - assert sms_response.http_status_code is 202 + assert sms_response.http_status_code == 202 assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file From 0c6cad9c62059cdc308ef7ece20bd0eefdbb299f Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 17:22:13 -0800 Subject: [PATCH 09/28] Rebased README file --- .../azure-communication-sms/README.md | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/sdk/communication/azure-communication-sms/README.md b/sdk/communication/azure-communication-sms/README.md index 88d93b0579b6..7a8046408d64 100644 --- a/sdk/communication/azure-communication-sms/README.md +++ b/sdk/communication/azure-communication-sms/README.md @@ -28,14 +28,14 @@ pip install azure-communication-sms ## Key concepts Azure Communication SMS package is used to do following: -- Send an SMS +- Send SMS Messages ## Examples The following section provides several code snippets covering some of the most common Azure Communication Services tasks, including: - [Client Initialization](#client-initialization) -- [Sending an SMS](#sending-an-sms) +- [Sending SMS Messages](#sending--zsms) ### Client Initialization @@ -54,23 +54,27 @@ endpoint = os.getenv('AZURE_COMMUNICATION_SERVICE_ENDPOINT') sms_client = SmsClient(endpoint, DefaultAzureCredential()) ``` -### Sending an SMS +### Sending SMS Messages Once the client is initialized, the `.send()` method can be invoked: ```Python -from azure.communication.sms import SendSmsOptions, PhoneNumberIdentifier +from azure.communication.sms import SendSmsOptions -smsresponse = sms_client.send( +sms_responses = sms_client.send( from_phone_number=PhoneNumberIdentifier(""), - to_phone_number=[PhoneNumberIdentifier("")], + to_phone_numbers=["", "", ""], message="Hello World via SMS", - send_sms_options=SendSmsOptions(enable_delivery_report=True)) # optional property + enable_delivery_report=True, # optional property + tag="custom-tag") # optional property ``` -- `from-phone-number`: an SMS enabled phone number associated with your communication service -- `to-phone-number`: the phone number you wish to send a message to -- `send_sms_options`: an optional parameter that you can use to configure Delivery Reporting. This is useful for scenarios where you want to emit events when SMS messages are delivered. +- `from_phone_number`: An SMS enabled phone number associated with your communication service. +- `to_phone_numbers`: The phone numbers you wish to send a message to. +- `message`: The message that you want to send. +- `enable_delivery_report`: An optional parameter that you can use to configure delivery reporting. This is useful for scenarios where you want to emit events when SMS messages are delivered. +- `tag`: An optional parameter that you can use to configure custom tagging. + ## Troubleshooting The Azure Communication Service Identity client will raise exceptions defined in [Azure Core](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/core/azure-core/README.md). @@ -93,4 +97,7 @@ When you submit a pull request, a CLA-bot will automatically determine whether y PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. \ No newline at end of file +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + + +[azure_core]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/core/azure-core/README.md \ No newline at end of file From 52eb2224af762867e820778c039bd2dedffe03ce Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 19 Feb 2021 17:04:03 -0800 Subject: [PATCH 10/28] Fixed pylint issues --- .../azure/communication/sms/_sms_client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 98f65d327bd9..6db2684e7287 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -8,7 +8,6 @@ from azure.communication.sms._generated.models import ( SendMessageRequest, SmsRecipient, - SmsSendResult, SmsSendOptions, ) @@ -109,7 +108,7 @@ def send(self, from_, # type: str message=message, sms_send_options=sms_send_options, **kwargs) - + return self._sms_service_client.sms.send( request, cls=lambda pr, r, e: r.value, From cfdd168b53055b5b483d0cca64d2554ff5f61e03 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Mon, 22 Feb 2021 14:51:15 -0800 Subject: [PATCH 11/28] Added Idempotence Parameters --- .../azure/communication/sms/_sms_client.py | 14 +++++++++++--- .../communication/sms/aio/_sms_client_async.py | 12 ++++++++++-- .../tests/test_sms_client_e2e.py | 1 + .../tests/test_sms_client_e2e_async.py | 1 + 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 6db2684e7287..ef370607dc4a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -4,6 +4,8 @@ # license information. # -------------------------------------------------------------------------- +from uuid import uuid4 +from datetime import datetime from azure.core.tracing.decorator import distributed_trace from azure.communication.sms._generated.models import ( SendMessageRequest, @@ -104,11 +106,17 @@ def send(self, from_, # type: str request = SendMessageRequest( from_property=from_, - sms_recipients=[SmsRecipient(to=p) for p in to], + sms_recipients=[ + SmsRecipient( + to=p, + repeatability_request_id=str(uuid4()), + repeatability_first_sent=datetime.now() + ) for p in to + ], message=message, - sms_send_options=sms_send_options, + send_sms_options=sms_send_options, **kwargs) - + return self._sms_service_client.sms.send( request, cls=lambda pr, r, e: r.value, diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index a1eb3fa03b01..c84db30565b9 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -4,6 +4,8 @@ # license information. # -------------------------------------------------------------------------- +from uuid import uuid4 +from datetime import datetime from azure.core.tracing.decorator_async import distributed_trace_async from azure.communication.sms._generated.models import ( SendMessageRequest, @@ -106,9 +108,15 @@ async def send(self, from_, # type: str request = SendMessageRequest( from_property=from_, - sms_recipients=[SmsRecipient(to=p) for p in to], + sms_recipients=[ + SmsRecipient( + to=p, + repeatability_request_id=str(uuid4()), + repeatability_first_sent=datetime.now() + ) for p in to + ], message=message, - sms_send_options=sms_send_options, + send_sms_options=sms_send_options, **kwargs) return await self._sms_service_client.sms.send( diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index 8010f1ab1413..e92adc2a99d6 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -84,6 +84,7 @@ def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None assert sms_response.http_status_code == 202 + assert sms_response.repeatability_result == "accepted" assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index bbe4caaeed78..1a0ba7a84ef0 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -128,6 +128,7 @@ def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None assert sms_response.http_status_code == 202 + assert sms_response.repeatability_result == "accepted" assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file From b2a6d6f381683da22dc827fb38c80aa318727db0 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Mon, 22 Feb 2021 16:24:28 -0800 Subject: [PATCH 12/28] Updated SWAGGER formatting --- .../azure-communication-sms/swagger/SWAGGER.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md index 5420dfc7af2a..74700087abd9 100644 --- a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md +++ b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md @@ -16,9 +16,9 @@ autorest SWAGGER.md ### Rename SmsSendResponseItem to SmsSendResult ``` yaml directive: - - rename-model: - from: SmsSendResponseItem - to: SmsSendResult + - rename-model: + from: SmsSendResponseItem + to: SmsSendResult ``` ### Settings From 34eb9268e19bd259e591491e70d877d714ad291b Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Mon, 22 Feb 2021 17:25:46 -0800 Subject: [PATCH 13/28] Added custom SendMessageRequest model to rename the smsSendOptions field to sendSmsOptions --- .../communication/sms/_models/__init__.py | 16 +++++ .../communication/sms/_models/_models.py | 51 ++++++++++++++++ .../communication/sms/_models/_models_py3.py | 60 +++++++++++++++++++ .../azure/communication/sms/_sms_client.py | 6 +- .../sms/aio/_sms_client_async.py | 7 +-- 5 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py new file mode 100644 index 000000000000..748885609d75 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +try: + from ._models_py3 import SendMessageRequest +except (SyntaxError, ImportError): + from ._models import SendMessageRequest # type: ignore + +__all__ = [ + 'SendMessageRequest' +] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py new file mode 100644 index 000000000000..150502f93d77 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py @@ -0,0 +1,51 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import msrest.serialization + + +class SendMessageRequest(msrest.serialization.Model): + """Represents the properties of a send message request. + + All required parameters must be populated in order to send to Azure. + + :param from_property: Required. The sender's phone number in E.164 format that is owned by the + authenticated account. + :type from_property: str + :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, + a minimum of 1 and upto 100 recipients in the list are supported. + :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] + :param message: Required. The contents of the message that will be sent to the recipient. The + allowable content is defined by RFC 5724. + :type message: str + :param sms_send_options: Optional configuration for sending SMS messages. + :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions + """ + + _validation = { + 'from_property': {'required': True}, + 'sms_recipients': {'required': True}, + 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, + } + + _attribute_map = { + 'from_property': {'key': 'from', 'type': 'str'}, + 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, + 'message': {'key': 'message', 'type': 'str'}, + 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, + } + + def __init__( + self, + **kwargs + ): + super(SendMessageRequest, self).__init__(**kwargs) + self.from_property = kwargs['from_property'] + self.sms_recipients = kwargs['sms_recipients'] + self.message = kwargs['message'] + self.sms_send_options = kwargs.get('sms_send_options', None) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py new file mode 100644 index 000000000000..0b4ca2759e60 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py @@ -0,0 +1,60 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import List, Optional, Union + +import msrest.serialization + +from ._azure_communication_sms_service_enums import * + + +class SendMessageRequest(msrest.serialization.Model): + """Represents the properties of a send message request. + + All required parameters must be populated in order to send to Azure. + + :param from_property: Required. The sender's phone number in E.164 format that is owned by the + authenticated account. + :type from_property: str + :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, + a minimum of 1 and upto 100 recipients in the list are supported. + :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] + :param message: Required. The contents of the message that will be sent to the recipient. The + allowable content is defined by RFC 5724. + :type message: str + :param sms_send_options: Optional configuration for sending SMS messages. + :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions + """ + + _validation = { + 'from_property': {'required': True}, + 'sms_recipients': {'required': True}, + 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, + } + + _attribute_map = { + 'from_property': {'key': 'from', 'type': 'str'}, + 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, + 'message': {'key': 'message', 'type': 'str'}, + 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, + } + + def __init__( + self, + *, + from_property: str, + sms_recipients: List["SmsRecipient"], + message: str, + sms_send_options: Optional["SmsSendOptions"] = None, + **kwargs + ): + super(SendMessageRequest, self).__init__(**kwargs) + self.from_property = from_property + self.sms_recipients = sms_recipients + self.message = message + self.sms_send_options = sms_send_options diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index ef370607dc4a..eb60aee5e71e 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -8,10 +8,10 @@ from datetime import datetime from azure.core.tracing.decorator import distributed_trace from azure.communication.sms._generated.models import ( - SendMessageRequest, SmsRecipient, SmsSendOptions, ) +from azure.communication.sms._models import SendMessageRequest from ._generated._azure_communication_sms_service import AzureCommunicationSMSService from ._shared.utils import parse_connection_str, get_authentication_policy @@ -114,9 +114,9 @@ def send(self, from_, # type: str ) for p in to ], message=message, - send_sms_options=sms_send_options, + sms_send_options=sms_send_options, **kwargs) - + return self._sms_service_client.sms.send( request, cls=lambda pr, r, e: r.value, diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index c84db30565b9..2c5e869a8729 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -8,11 +8,10 @@ from datetime import datetime from azure.core.tracing.decorator_async import distributed_trace_async from azure.communication.sms._generated.models import ( - SendMessageRequest, SmsRecipient, - SmsSendResult, SmsSendOptions, ) +from azure.communication.sms._models import SendMessageRequest from .._generated.aio._azure_communication_sms_service import AzureCommunicationSMSService from .._shared.utils import parse_connection_str, get_authentication_policy @@ -83,7 +82,7 @@ async def send(self, from_, # type: str to, # type: Union[str, List[str]] message, # type: str **kwargs # type: Any - ): # type: (...) -> ItemPaged[SmsSendResult] + ): # type: (...) -> [SmsSendResult] """Sends SMSs to phone numbers. :param str from_: The sender of the SMS. @@ -116,7 +115,7 @@ async def send(self, from_, # type: str ) for p in to ], message=message, - send_sms_options=sms_send_options, + sms_send_options=sms_send_options, **kwargs) return await self._sms_service_client.sms.send( From 6576d90cf1af41de217ca6ad8c052dae70fa20ad Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Tue, 23 Feb 2021 10:52:52 -0800 Subject: [PATCH 14/28] Updated SMS options parameter --- .../sms/_generated/models/_models.py | 2 +- .../sms/_generated/models/_models_py3.py | 2 +- .../communication/sms/_models/__init__.py | 16 ----- .../communication/sms/_models/_models.py | 51 ---------------- .../communication/sms/_models/_models_py3.py | 60 ------------------- .../azure/communication/sms/_sms_client.py | 2 +- .../sms/aio/_sms_client_async.py | 2 +- 7 files changed, 4 insertions(+), 131 deletions(-) delete mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py delete mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py delete mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py index 8940997d8640..7b4a260a4236 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py @@ -37,7 +37,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, + 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, } def __init__( diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py index 593047cd2346..d98ef7453199 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py @@ -41,7 +41,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, + 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, } def __init__( diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py deleted file mode 100644 index 748885609d75..000000000000 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -try: - from ._models_py3 import SendMessageRequest -except (SyntaxError, ImportError): - from ._models import SendMessageRequest # type: ignore - -__all__ = [ - 'SendMessageRequest' -] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py deleted file mode 100644 index 150502f93d77..000000000000 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py +++ /dev/null @@ -1,51 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -import msrest.serialization - - -class SendMessageRequest(msrest.serialization.Model): - """Represents the properties of a send message request. - - All required parameters must be populated in order to send to Azure. - - :param from_property: Required. The sender's phone number in E.164 format that is owned by the - authenticated account. - :type from_property: str - :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, - a minimum of 1 and upto 100 recipients in the list are supported. - :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] - :param message: Required. The contents of the message that will be sent to the recipient. The - allowable content is defined by RFC 5724. - :type message: str - :param sms_send_options: Optional configuration for sending SMS messages. - :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions - """ - - _validation = { - 'from_property': {'required': True}, - 'sms_recipients': {'required': True}, - 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, - } - - _attribute_map = { - 'from_property': {'key': 'from', 'type': 'str'}, - 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, - 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, - } - - def __init__( - self, - **kwargs - ): - super(SendMessageRequest, self).__init__(**kwargs) - self.from_property = kwargs['from_property'] - self.sms_recipients = kwargs['sms_recipients'] - self.message = kwargs['message'] - self.sms_send_options = kwargs.get('sms_send_options', None) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py deleted file mode 100644 index 0b4ca2759e60..000000000000 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py +++ /dev/null @@ -1,60 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from typing import List, Optional, Union - -import msrest.serialization - -from ._azure_communication_sms_service_enums import * - - -class SendMessageRequest(msrest.serialization.Model): - """Represents the properties of a send message request. - - All required parameters must be populated in order to send to Azure. - - :param from_property: Required. The sender's phone number in E.164 format that is owned by the - authenticated account. - :type from_property: str - :param sms_recipients: Required. The recipient's phone number in E.164 format. In this version, - a minimum of 1 and upto 100 recipients in the list are supported. - :type sms_recipients: list[~azure.communication.sms.models.SmsRecipient] - :param message: Required. The contents of the message that will be sent to the recipient. The - allowable content is defined by RFC 5724. - :type message: str - :param sms_send_options: Optional configuration for sending SMS messages. - :type sms_send_options: ~azure.communication.sms.models.SmsSendOptions - """ - - _validation = { - 'from_property': {'required': True}, - 'sms_recipients': {'required': True}, - 'message': {'required': True, 'max_length': 2048, 'min_length': 0}, - } - - _attribute_map = { - 'from_property': {'key': 'from', 'type': 'str'}, - 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, - 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, - } - - def __init__( - self, - *, - from_property: str, - sms_recipients: List["SmsRecipient"], - message: str, - sms_send_options: Optional["SmsSendOptions"] = None, - **kwargs - ): - super(SendMessageRequest, self).__init__(**kwargs) - self.from_property = from_property - self.sms_recipients = sms_recipients - self.message = message - self.sms_send_options = sms_send_options diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index eb60aee5e71e..2d46a91f65eb 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -8,10 +8,10 @@ from datetime import datetime from azure.core.tracing.decorator import distributed_trace from azure.communication.sms._generated.models import ( + SendMessageRequest, SmsRecipient, SmsSendOptions, ) -from azure.communication.sms._models import SendMessageRequest from ._generated._azure_communication_sms_service import AzureCommunicationSMSService from ._shared.utils import parse_connection_str, get_authentication_policy diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 2c5e869a8729..e4582f6747e6 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -8,10 +8,10 @@ from datetime import datetime from azure.core.tracing.decorator_async import distributed_trace_async from azure.communication.sms._generated.models import ( + SendMessageRequest, SmsRecipient, SmsSendOptions, ) -from azure.communication.sms._models import SendMessageRequest from .._generated.aio._azure_communication_sms_service import AzureCommunicationSMSService from .._shared.utils import parse_connection_str, get_authentication_policy From 9590bb713a1c6c653a91452dc18de6fb25e8d026 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Tue, 23 Feb 2021 18:31:01 -0800 Subject: [PATCH 15/28] Hide repeatability_result from SmsSendResult --- .../azure/communication/sms/__init__.py | 4 +- .../sms/_generated/models/__init__.py | 10 ++-- .../_azure_communication_sms_service_enums.py | 2 +- .../sms/_generated/models/_models.py | 10 ++-- .../sms/_generated/models/_models_py3.py | 14 +++--- .../azure/communication/sms/_models.py | 48 +++++++++++++++++++ .../azure/communication/sms/_sms_client.py | 3 +- .../sms/aio/_sms_client_async.py | 3 +- .../swagger/SWAGGER.md | 8 ---- .../tests/test_sms_client_e2e.py | 1 - .../tests/test_sms_client_e2e_async.py | 1 - 11 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models.py diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py index d4d8b5669c6d..f1e383aa3376 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/__init__.py @@ -1,8 +1,6 @@ from ._sms_client import SmsClient -from ._generated.models import ( - SmsSendResult, -) +from ._models import SmsSendResult __all__ = [ 'SmsClient', diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py index cfede64e32fb..74b2447dbed0 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/__init__.py @@ -11,16 +11,16 @@ from ._models_py3 import SmsRecipient from ._models_py3 import SmsSendOptions from ._models_py3 import SmsSendResponse - from ._models_py3 import SmsSendResult + from ._models_py3 import SmsSendResponseItem except (SyntaxError, ImportError): from ._models import SendMessageRequest # type: ignore from ._models import SmsRecipient # type: ignore from ._models import SmsSendOptions # type: ignore from ._models import SmsSendResponse # type: ignore - from ._models import SmsSendResult # type: ignore + from ._models import SmsSendResponseItem # type: ignore from ._azure_communication_sms_service_enums import ( - SmsSendResultRepeatabilityResult, + SmsSendResponseItemRepeatabilityResult, ) __all__ = [ @@ -28,6 +28,6 @@ 'SmsRecipient', 'SmsSendOptions', 'SmsSendResponse', - 'SmsSendResult', - 'SmsSendResultRepeatabilityResult', + 'SmsSendResponseItem', + 'SmsSendResponseItemRepeatabilityResult', ] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py index 3fa3ec4ac067..635ce86194d5 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_azure_communication_sms_service_enums.py @@ -26,7 +26,7 @@ def __getattr__(cls, name): raise AttributeError(name) -class SmsSendResultRepeatabilityResult(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): +class SmsSendResponseItemRepeatabilityResult(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): """The result of a repeatable request with one of the case-insensitive values accepted or rejected. """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py index 7b4a260a4236..5a7d85540e00 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py @@ -128,7 +128,7 @@ class SmsSendResponse(msrest.serialization.Model): All required parameters must be populated in order to send to Azure. :param value: Required. - :type value: list[~azure.communication.sms.models.SmsSendResult] + :type value: list[~azure.communication.sms.models.SmsSendResponseItem] """ _validation = { @@ -136,7 +136,7 @@ class SmsSendResponse(msrest.serialization.Model): } _attribute_map = { - 'value': {'key': 'value', 'type': '[SmsSendResult]'}, + 'value': {'key': 'value', 'type': '[SmsSendResponseItem]'}, } def __init__( @@ -147,7 +147,7 @@ def __init__( self.value = kwargs['value'] -class SmsSendResult(msrest.serialization.Model): +class SmsSendResponseItem(msrest.serialization.Model): """Response for a single recipient. All required parameters must be populated in order to send to Azure. @@ -162,7 +162,7 @@ class SmsSendResult(msrest.serialization.Model): :param repeatability_result: The result of a repeatable request with one of the case- insensitive values accepted or rejected. Possible values include: "accepted", "rejected". :type repeatability_result: str or - ~azure.communication.sms.models.SmsSendResultRepeatabilityResult + ~azure.communication.sms.models.SmsSendResponseItemRepeatabilityResult :param successful: Required. Indicates if the message is processed successfully or not. :type successful: bool :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. @@ -188,7 +188,7 @@ def __init__( self, **kwargs ): - super(SmsSendResult, self).__init__(**kwargs) + super(SmsSendResponseItem, self).__init__(**kwargs) self.to = kwargs['to'] self.message_id = kwargs.get('message_id', None) self.http_status_code = kwargs['http_status_code'] diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py index d98ef7453199..860a45526ffd 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py @@ -144,7 +144,7 @@ class SmsSendResponse(msrest.serialization.Model): All required parameters must be populated in order to send to Azure. :param value: Required. - :type value: list[~azure.communication.sms.models.SmsSendResult] + :type value: list[~azure.communication.sms.models.SmsSendResponseItem] """ _validation = { @@ -152,20 +152,20 @@ class SmsSendResponse(msrest.serialization.Model): } _attribute_map = { - 'value': {'key': 'value', 'type': '[SmsSendResult]'}, + 'value': {'key': 'value', 'type': '[SmsSendResponseItem]'}, } def __init__( self, *, - value: List["SmsSendResult"], + value: List["SmsSendResponseItem"], **kwargs ): super(SmsSendResponse, self).__init__(**kwargs) self.value = value -class SmsSendResult(msrest.serialization.Model): +class SmsSendResponseItem(msrest.serialization.Model): """Response for a single recipient. All required parameters must be populated in order to send to Azure. @@ -180,7 +180,7 @@ class SmsSendResult(msrest.serialization.Model): :param repeatability_result: The result of a repeatable request with one of the case- insensitive values accepted or rejected. Possible values include: "accepted", "rejected". :type repeatability_result: str or - ~azure.communication.sms.models.SmsSendResultRepeatabilityResult + ~azure.communication.sms.models.SmsSendResponseItemRepeatabilityResult :param successful: Required. Indicates if the message is processed successfully or not. :type successful: bool :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. @@ -209,11 +209,11 @@ def __init__( http_status_code: int, successful: bool, message_id: Optional[str] = None, - repeatability_result: Optional[Union[str, "SmsSendResultRepeatabilityResult"]] = None, + repeatability_result: Optional[Union[str, "SmsSendResponseItemRepeatabilityResult"]] = None, error_message: Optional[str] = None, **kwargs ): - super(SmsSendResult, self).__init__(**kwargs) + super(SmsSendResponseItem, self).__init__(**kwargs) self.to = to self.message_id = message_id self.http_status_code = http_status_code diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py new file mode 100644 index 000000000000..f27dfcef4050 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py @@ -0,0 +1,48 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +class SmsSendResult(object): + """Response for a single recipient. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipient's phone number in E.164 format. + :type to: str + :param message_id: The identifier of the outgoing Sms message. Only present if message + processed. + :type message_id: str + :param http_status_code: Required. HTTP Status code. + :type http_status_code: int + :param successful: Required. Indicates if the message is processed successfully or not. + :type successful: bool + :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. + :type error_message: str + """ + + def __init__( + self, + **kwargs # type: Any + ): + # type: (...) -> None + + self.to = kwargs['to'] + self.message_id = kwargs.get('message_id', None) + self.http_status_code = kwargs['http_status_code'] + self.successful = kwargs['successful'] + self.error_message = kwargs.get('error_message', None) + + @classmethod + def _from_generated(cls, sms_send_response_item): + return cls( + to=sms_send_response_item.to, + message_id=sms_send_response_item.message_id, + http_status_code=sms_send_response_item.http_status_code, + successful = sms_send_response_item.successful, + error_message = sms_send_response_item.error_message + ) + \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 2d46a91f65eb..8474c69919da 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -12,6 +12,7 @@ SmsRecipient, SmsSendOptions, ) +from azure.communication.sms._models import SmsSendResult from ._generated._azure_communication_sms_service import AzureCommunicationSMSService from ._shared.utils import parse_connection_str, get_authentication_policy @@ -119,5 +120,5 @@ def send(self, from_, # type: str return self._sms_service_client.sms.send( request, - cls=lambda pr, r, e: r.value, + cls=lambda pr, r, e: [SmsSendResult._from_generated(x) for x in r.value], **kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index e4582f6747e6..3117ec842208 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -12,6 +12,7 @@ SmsRecipient, SmsSendOptions, ) +from azure.communication.sms._models import SmsSendResult from .._generated.aio._azure_communication_sms_service import AzureCommunicationSMSService from .._shared.utils import parse_connection_str, get_authentication_policy @@ -120,7 +121,7 @@ async def send(self, from_, # type: str return await self._sms_service_client.sms.send( request, - cls=lambda pr, r, e: r.value, + cls=lambda pr, r, e: [SmsSendResult._from_generated(x) for x in r.value], **kwargs) async def __aenter__(self) -> "SMSClient": diff --git a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md index 74700087abd9..efbd87cb9a62 100644 --- a/sdk/communication/azure-communication-sms/swagger/SWAGGER.md +++ b/sdk/communication/azure-communication-sms/swagger/SWAGGER.md @@ -13,14 +13,6 @@ cd autorest SWAGGER.md ``` -### Rename SmsSendResponseItem to SmsSendResult -``` yaml -directive: - - rename-model: - from: SmsSendResponseItem - to: SmsSendResult -``` - ### Settings ``` yaml input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/83d782b99cb85a9b2f5ef22774584541dd0ff997/specification/communication/data-plane/Microsoft.CommunicationServicesSms/stable/2021-03-07/communicationservicessms.json diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index e92adc2a99d6..8010f1ab1413 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -84,7 +84,6 @@ def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None assert sms_response.http_status_code == 202 - assert sms_response.repeatability_result == "accepted" assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index 1a0ba7a84ef0..bbe4caaeed78 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -128,7 +128,6 @@ def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None assert sms_response.http_status_code == 202 - assert sms_response.repeatability_result == "accepted" assert sms_response.error_message is None assert sms_response.successful \ No newline at end of file From 87a23018ee986318cc6bade74f7f48e216238f18 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 24 Feb 2021 10:18:10 -0800 Subject: [PATCH 16/28] Updated failure message in SMS samples --- .../azure-communication-sms/samples/sms_sample.py | 4 ++-- .../azure-communication-sms/samples/sms_sample_async.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample.py b/sdk/communication/azure-communication-sms/samples/sms_sample.py index 77c736c38ebe..93f5af062eb1 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample.py @@ -43,8 +43,8 @@ def send_sms(self): print("Message with message id {} was successful sent to {}" .format(sms_response.message_id , sms_response.to)) else: - print("Message with message id {} failed to send to {}" - .format(sms_response.message_id , sms_response.to)) + print("Message failed to send to {}" + .format(sms_response.to)) failed_recipients.append(sms_response.to) # calling send() with failed recipients diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py index 75c2ffb92d5a..9d4169a71b59 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py @@ -48,8 +48,8 @@ async def send_sms_async(self): print("Message with message id {} was successful sent to {}" .format(sms_response.message_id , sms_response.to)) else: - print("Message with message id {} failed to send to {}" - .format(sms_response.message_id , sms_response.to)) + print("Message failed to send to {}" + .format(sms_response.to)) failed_recipients.append(sms_response.to) try: From 1577572445417759faf755b3a11f80e735c2016a Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 24 Feb 2021 11:15:55 -0800 Subject: [PATCH 17/28] Updated formatting in models file --- .../azure/communication/sms/_models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py index f27dfcef4050..f74bb6c8a8a6 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py @@ -42,7 +42,7 @@ def _from_generated(cls, sms_send_response_item): to=sms_send_response_item.to, message_id=sms_send_response_item.message_id, http_status_code=sms_send_response_item.http_status_code, - successful = sms_send_response_item.successful, - error_message = sms_send_response_item.error_message + successful=sms_send_response_item.successful, + error_message=sms_send_response_item.error_message ) \ No newline at end of file From 3383cd8b391294ad4b83a0fb2aec8c4c57b32d8f Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 24 Feb 2021 11:51:33 -0800 Subject: [PATCH 18/28] Updated SmsSendResult --- .../azure/communication/sms/_models.py | 10 ---------- .../azure/communication/sms/_sms_client.py | 10 +++++++++- .../azure/communication/sms/aio/_sms_client_async.py | 10 +++++++++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py index f74bb6c8a8a6..7baff6ff7e65 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py @@ -35,14 +35,4 @@ def __init__( self.http_status_code = kwargs['http_status_code'] self.successful = kwargs['successful'] self.error_message = kwargs.get('error_message', None) - - @classmethod - def _from_generated(cls, sms_send_response_item): - return cls( - to=sms_send_response_item.to, - message_id=sms_send_response_item.message_id, - http_status_code=sms_send_response_item.http_status_code, - successful=sms_send_response_item.successful, - error_message=sms_send_response_item.error_message - ) \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 8474c69919da..ac5780b2b798 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -120,5 +120,13 @@ def send(self, from_, # type: str return self._sms_service_client.sms.send( request, - cls=lambda pr, r, e: [SmsSendResult._from_generated(x) for x in r.value], + cls=lambda pr, r, e: [ + SmsSendResult( + to=item.to, + message_id=item.message_id, + http_status_code=item.http_status_code, + successful=item.successful, + error_message=item.error_message + ) for item in r.value + ], **kwargs) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 3117ec842208..951723ad92bf 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -121,7 +121,15 @@ async def send(self, from_, # type: str return await self._sms_service_client.sms.send( request, - cls=lambda pr, r, e: [SmsSendResult._from_generated(x) for x in r.value], + cls=lambda pr, r, e: [ + SmsSendResult( + to=item.to, + message_id=item.message_id, + http_status_code=item.http_status_code, + successful=item.successful, + error_message=item.error_message + ) for item in r.value + ], **kwargs) async def __aenter__(self) -> "SMSClient": From b64d5678ec3fdfc6d9f123f678fb67cb7792a92c Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 24 Feb 2021 14:08:00 -0800 Subject: [PATCH 19/28] Refactored SmsSendResult --- .../communication/sms/_models/__init__.py | 16 +++++ .../sms/{ => _models}/_models.py | 25 ++++++-- .../communication/sms/_models/_models_py3.py | 61 +++++++++++++++++++ 3 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py rename sdk/communication/azure-communication-sms/azure/communication/sms/{ => _models}/_models.py (69%) create mode 100644 sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py new file mode 100644 index 000000000000..e54b888774ef --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +try: + from ._models_py3 import SmsSendResult +except (SyntaxError, ImportError): + from ._models import SmsSendResult # type: ignore + +__all__ = [ + 'SmsSendResult' +] \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py similarity index 69% rename from sdk/communication/azure-communication-sms/azure/communication/sms/_models.py rename to sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py index 7baff6ff7e65..c6b703966efe 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models.py @@ -6,7 +6,10 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -class SmsSendResult(object): +import msrest.serialization + + +class SmsSendResult(msrest.serialization.Model): """Response for a single recipient. All required parameters must be populated in order to send to Azure. @@ -24,15 +27,27 @@ class SmsSendResult(object): :type error_message: str """ + _validation = { + 'to': {'required': True}, + 'http_status_code': {'required': True}, + 'successful': {'required': True}, + } + + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, + 'message_id': {'key': 'messageId', 'type': 'str'}, + 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, + 'successful': {'key': 'successful', 'type': 'bool'}, + 'error_message': {'key': 'errorMessage', 'type': 'str'}, + } + def __init__( self, - **kwargs # type: Any + **kwargs ): - # type: (...) -> None - + super(SmsSendResult, self).__init__(**kwargs) self.to = kwargs['to'] self.message_id = kwargs.get('message_id', None) self.http_status_code = kwargs['http_status_code'] self.successful = kwargs['successful'] self.error_message = kwargs.get('error_message', None) - \ No newline at end of file diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py new file mode 100644 index 000000000000..cd3d27e53547 --- /dev/null +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/_models_py3.py @@ -0,0 +1,61 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Optional + +import msrest.serialization + + +class SmsSendResult(msrest.serialization.Model): + """Response for a single recipient. + + All required parameters must be populated in order to send to Azure. + + :param to: Required. The recipient's phone number in E.164 format. + :type to: str + :param message_id: The identifier of the outgoing Sms message. Only present if message + processed. + :type message_id: str + :param http_status_code: Required. HTTP Status code. + :type http_status_code: int + :param successful: Required. Indicates if the message is processed successfully or not. + :type successful: bool + :param error_message: Optional error message in case of 4xx/5xx/repeatable errors. + :type error_message: str + """ + + _validation = { + 'to': {'required': True}, + 'http_status_code': {'required': True}, + 'successful': {'required': True}, + } + + _attribute_map = { + 'to': {'key': 'to', 'type': 'str'}, + 'message_id': {'key': 'messageId', 'type': 'str'}, + 'http_status_code': {'key': 'httpStatusCode', 'type': 'int'}, + 'successful': {'key': 'successful', 'type': 'bool'}, + 'error_message': {'key': 'errorMessage', 'type': 'str'}, + } + + def __init__( + self, + *, + to: str, + http_status_code: int, + successful: bool, + message_id: Optional[str] = None, + error_message: Optional[str] = None, + **kwargs + ): + super(SmsSendResult, self).__init__(**kwargs) + self.to = to + self.message_id = message_id + self.http_status_code = http_status_code + self.successful = successful + self.error_message = error_message From 63e9dac708096bab00b04b75e29b59199da4511f Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Wed, 24 Feb 2021 14:33:53 -0800 Subject: [PATCH 20/28] Fixed pylint issue --- .../azure/communication/sms/_models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py index e54b888774ef..96cd579bc6e1 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_models/__init__.py @@ -13,4 +13,4 @@ __all__ = [ 'SmsSendResult' -] \ No newline at end of file +] From 521ef56e3d7ebf3581a0cf4a7a0f3d4c8c7f4632 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 15:21:58 -0800 Subject: [PATCH 21/28] Updated CHANGELOG --- .../azure-communication-sms/CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sdk/communication/azure-communication-sms/CHANGELOG.md b/sdk/communication/azure-communication-sms/CHANGELOG.md index 0af08f9be347..ef70c9d37293 100644 --- a/sdk/communication/azure-communication-sms/CHANGELOG.md +++ b/sdk/communication/azure-communication-sms/CHANGELOG.md @@ -1,5 +1,17 @@ # Release History +## 1.0.0b6 (Unreleased) +### Added +- Added support for 1:N SMS messaging. +- Added support for SMS idempotency. +- Send method series in SmsClient are idempotent under retry policy. +- Added support for tagging SMS messages. + +### Breaking +- Send method takes in strings for phone numbers instead of `PhoneNumberIdentifier`. +to `Task> SendAsync(string from, string to, string message, Models.SmsSendOptions options = default)` +- Send method returns a list of `SmsSendResult`s instead of a `SendSmsResponse`. + ## 1.0.0b5 (2021-02-09) ### Added - Added support for Azure Active Directory authentication. From 51b6396d3acb6a09bf0dba41c0be0c1f9f9d3876 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 15:52:31 -0800 Subject: [PATCH 22/28] Use UTC time zone for repeatability_first_sent --- .../azure/communication/sms/_sms_client.py | 2 +- .../azure/communication/sms/aio/_sms_client_async.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index ac5780b2b798..6f927e0c4c8a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -111,7 +111,7 @@ def send(self, from_, # type: str SmsRecipient( to=p, repeatability_request_id=str(uuid4()), - repeatability_first_sent=datetime.now() + repeatability_first_sent=datetime.utcnow() ) for p in to ], message=message, diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 951723ad92bf..5e8a128b9022 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -112,7 +112,7 @@ async def send(self, from_, # type: str SmsRecipient( to=p, repeatability_request_id=str(uuid4()), - repeatability_first_sent=datetime.now() + repeatability_first_sent=datetime.utcnow() ) for p in to ], message=message, From 763fe6cc233524ff4c746ab181c8dd1c4fadaa0c Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 16:02:01 -0800 Subject: [PATCH 23/28] Cleaned up CHANGELOG --- sdk/communication/azure-communication-sms/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/communication/azure-communication-sms/CHANGELOG.md b/sdk/communication/azure-communication-sms/CHANGELOG.md index ef70c9d37293..01806b00a435 100644 --- a/sdk/communication/azure-communication-sms/CHANGELOG.md +++ b/sdk/communication/azure-communication-sms/CHANGELOG.md @@ -9,7 +9,6 @@ ### Breaking - Send method takes in strings for phone numbers instead of `PhoneNumberIdentifier`. -to `Task> SendAsync(string from, string to, string message, Models.SmsSendOptions options = default)` - Send method returns a list of `SmsSendResult`s instead of a `SendSmsResponse`. ## 1.0.0b5 (2021-02-09) From c763cdc08f22438ca38767815100f6179c65e6e4 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 16:31:27 -0800 Subject: [PATCH 24/28] Updated SMS samples --- .../azure-communication-sms/samples/sms_sample.py | 9 +++++---- .../azure-communication-sms/samples/sms_sample_async.py | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample.py b/sdk/communication/azure-communication-sms/samples/sms_sample.py index 93f5af062eb1..69597b1799b7 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample.py @@ -41,11 +41,12 @@ def send_sms(self): for sms_response in sms_responses: if (sms_response.successful): print("Message with message id {} was successful sent to {}" - .format(sms_response.message_id , sms_response.to)) + .format(sms_response.message_id, sms_response.to)) else: - print("Message failed to send to {}" - .format(sms_response.to)) - failed_recipients.append(sms_response.to) + print("Message failed to send to {} with the status code {} and error: {}" + .format(sms_response.to, sms_response.http_status_code, sms_response.error_message)) + if (sms_response.http_status_code != 400): + failed_recipients.append(sms_response.to) # calling send() with failed recipients sms_responses = sms_client.send( diff --git a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py index 9d4169a71b59..2dcf17c7e7f2 100644 --- a/sdk/communication/azure-communication-sms/samples/sms_sample_async.py +++ b/sdk/communication/azure-communication-sms/samples/sms_sample_async.py @@ -46,11 +46,12 @@ async def send_sms_async(self): for sms_response in sms_responses: if (sms_response.successful): print("Message with message id {} was successful sent to {}" - .format(sms_response.message_id , sms_response.to)) + .format(sms_response.message_id, sms_response.to)) else: - print("Message failed to send to {}" - .format(sms_response.to)) - failed_recipients.append(sms_response.to) + print("Message failed to send to {} with the status code {} and error: {}" + .format(sms_response.to, sms_response.http_status_code, sms_response.error_message)) + if (sms_response.http_status_code != 400): + failed_recipients.append(sms_response.to) try: # calling send() with failed recipients From 9c1a87ecea46f39f7dfbc44d0bbfb990cfa6a32a Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 16:44:48 -0800 Subject: [PATCH 25/28] Updated SmsSendOptions --- .../azure/communication/sms/_generated/models/_models.py | 2 +- .../azure/communication/sms/_generated/models/_models_py3.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py index 5a7d85540e00..5e173280184a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models.py @@ -37,7 +37,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, + 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } def __init__( diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py index 860a45526ffd..e6ad9d3aba20 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_generated/models/_models_py3.py @@ -41,7 +41,7 @@ class SendMessageRequest(msrest.serialization.Model): 'from_property': {'key': 'from', 'type': 'str'}, 'sms_recipients': {'key': 'smsRecipients', 'type': '[SmsRecipient]'}, 'message': {'key': 'message', 'type': 'str'}, - 'sms_send_options': {'key': 'sendSmsOptions', 'type': 'SmsSendOptions'}, + 'sms_send_options': {'key': 'smsSendOptions', 'type': 'SmsSendOptions'}, } def __init__( From b4866237506c85569da57711e028424c008b3ca1 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Fri, 26 Feb 2021 18:02:03 -0800 Subject: [PATCH 26/28] Add test for idempotency --- .../tests/test_sms_client_e2e.py | 18 +++++++++++++ .../tests/test_sms_client_e2e_async.py | 27 ++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index 8010f1ab1413..f4b067fe6967 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -79,6 +79,24 @@ def test_send_sms_invalid_to_phone_number(self): for sms_response in sms_responses: assert sms_response.http_status_code == 400 assert not sms_response.successful + + @pytest.mark.live_test_only + def test_send_sms_unique_message_ids(self): + + # calling send() with sms values + sms_responses_1 = self.sms_client.send( + from_=self.phone_number, + to=[self.phone_number], + message="Hello World via SMS") + + # calling send() again with the same sms values + sms_responses_2 = self.sms_client.send( + from_=self.phone_number, + to=[self.phone_number], + message="Hello World via SMS") + + # message ids should be unique due to having a different idempotency key + assert sms_responses_1[0].message_id != sms_responses_2[0].message_id def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index bbe4caaeed78..a11e8a87b107 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -71,7 +71,7 @@ async def test_send_sms_multiple_async(self): to=[self.phone_number, self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="custom-tag") # optional propert + tag="custom-tag") # optional property assert len(sms_responses) is 2 @@ -96,7 +96,7 @@ async def test_send_sms_async_from_managed_identity(self): to=[self.phone_number], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="custom-tag") # optional propert + tag="custom-tag") # optional property assert len(sms_responses) is 1 @@ -116,14 +116,35 @@ async def test_send_sms_invalid_to_phone_number_async(self): to=["+1234567891011"], message="Hello World via SMS", enable_delivery_report=True, # optional property - tag="custom-tag") # optional propert + tag="custom-tag") # optional property assert len(sms_responses) is 1 for sms_response in sms_responses: assert sms_response.http_status_code == 400 assert not sms_response.successful + + @AsyncCommunicationTestCase.await_prepared_test + @pytest.mark.live_test_only + async def test_send_sms_unique_message_ids_async(self): + + sms_client = SmsClient.from_connection_string(self.connection_str) + async with sms_client: + # calling send() with sms values + sms_responses_1 = await sms_client.send( + from_=self.phone_number, + to=[self.phone_number], + message="Hello World via SMS") + + # calling send() again with the same sms values + sms_responses_2 = await sms_client.send( + from_=self.phone_number, + to=[self.phone_number], + message="Hello World via SMS") + + assert sms_responses_1[0].message_id != sms_responses_2[0].message_id + def verify_sms_response(self, sms_response): assert sms_response.to == self.phone_number assert sms_response.message_id is not None From 494827a67fcc0e68d3978c0b6b27fbefbd8a7170 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Mon, 1 Mar 2021 11:41:48 -0800 Subject: [PATCH 27/28] Added case when single recipient phone number is a string --- .../azure/communication/sms/_sms_client.py | 3 +++ .../azure/communication/sms/aio/_sms_client_async.py | 3 +++ .../azure-communication-sms/tests/test_sms_client_e2e.py | 2 +- .../tests/test_sms_client_e2e_async.py | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index 6f927e0c4c8a..a2e88cedbf12 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -97,6 +97,9 @@ def send(self, from_, # type: str :rtype: [~azure.communication.sms.models.SmsSendResult] """ + if isinstance(to, str): + to = [to] + enable_delivery_report = kwargs.pop('enable_delivery_report', False) tag = kwargs.pop('tag', None) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 5e8a128b9022..6a850200aa94 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -98,6 +98,9 @@ async def send(self, from_, # type: str :rtype: [~azure.communication.sms.models.SmsSendResult] """ + if isinstance(to, str): + to = [to] + enable_delivery_report = kwargs.pop('enable_delivery_report', False) tag = kwargs.pop('tag', None) diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py index f4b067fe6967..3b8020bccdf1 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e.py @@ -37,7 +37,7 @@ def test_send_sms_single(self): # calling send() with sms values sms_responses = self.sms_client.send( from_=self.phone_number, - to=[self.phone_number], + to=self.phone_number, message="Hello World via SMS", enable_delivery_report=True, # optional property tag="custom-tag") # optional property diff --git a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py index a11e8a87b107..31a77793bb2a 100644 --- a/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py +++ b/sdk/communication/azure-communication-sms/tests/test_sms_client_e2e_async.py @@ -40,7 +40,7 @@ def setUp(self): @AsyncCommunicationTestCase.await_prepared_test @pytest.mark.live_test_only - async def test_send_sms_async(self): + async def test_send_sms_single_async(self): sms_client = SmsClient.from_connection_string(self.connection_str) @@ -48,7 +48,7 @@ async def test_send_sms_async(self): # calling send() with sms values sms_responses = await sms_client.send( from_=self.phone_number, - to=[self.phone_number], + to=self.phone_number, message="Hello World via SMS", enable_delivery_report=True, # optional property tag="custom-tag") # optional property From 837fb305ad914a9673e32f550ecf085a705f74b4 Mon Sep 17 00:00:00 2001 From: Lakshman Sundaralingam Date: Mon, 1 Mar 2021 15:05:00 -0800 Subject: [PATCH 28/28] Updated method documentation in SMS clients --- .../azure/communication/sms/_sms_client.py | 2 +- .../azure/communication/sms/aio/_sms_client_async.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py index a2e88cedbf12..be0956fc1853 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_sms_client.py @@ -93,7 +93,7 @@ def send(self, from_, # type: str message on the Azure Resource EventGrid. :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. - :return: A list of SmsSendResults. + :return: A list of SmsSendResult. :rtype: [~azure.communication.sms.models.SmsSendResult] """ diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py index 6a850200aa94..bdf820701f50 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/aio/_sms_client_async.py @@ -94,7 +94,7 @@ async def send(self, from_, # type: str message on the Azure Resource EventGrid. :keyword str tag: Use this field to provide metadata that will then be sent back in the corresponding Delivery Report. - :return: A list of SmsSendResults. + :return: A list of SmsSendResult. :rtype: [~azure.communication.sms.models.SmsSendResult] """