From 56aa4eee322560273e809e2079c0b05cb3e9d09d Mon Sep 17 00:00:00 2001 From: Jorge Beauregard Date: Mon, 12 Apr 2021 15:24:00 -0500 Subject: [PATCH 1/3] Sync SMS and PNM shared folders --- .../phonenumbers/_shared/models.py | 297 +++++++----------- .../azure/communication/sms/_shared/models.py | 297 +++++++----------- 2 files changed, 238 insertions(+), 356 deletions(-) diff --git a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/models.py b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/models.py index 734e074cc27c..7820b25a7d1a 100644 --- a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/models.py +++ b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/models.py @@ -6,210 +6,151 @@ from enum import Enum, EnumMeta from six import with_metaclass +from typing import Mapping, Optional, Union, Any +try: + from typing import Protocol, TypedDict +except ImportError: + from typing_extensions import Protocol, TypedDict -import msrest +from azure.core import CaseInsensitiveEnumMeta -class CommunicationError(msrest.serialization.Model): - """The Communication Services error. - Variables are only populated by the server, and will be ignored when sending a request. +class CommunicationIdentifierKind(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)): + """Communication Identifier Kind.""" - All required parameters must be populated in order to send to Azure. + UNKNOWN = "unknown" + COMMUNICATION_USER = "communication_user" + PHONE_NUMBER = "phone_number" + MICROSOFT_TEAMS_USER = "microsoft_teams_user" + + +class CommunicationCloudEnvironment(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)): + """The cloud enviornment that the identifier belongs to""" + + PUBLIC = "PUBLIC" + DOD = "DOD" + GCCH = "GCCH" - :param code: Required. The error code. - :type code: str - :param message: Required. The error message. - :type message: str - :ivar target: The error target. - :vartype target: str - :ivar details: Further details about specific errors that led to this error. - :vartype details: list[~communication.models.CommunicationError] - :ivar inner_error: The inner error if any. - :vartype inner_error: ~communication.models.CommunicationError - """ - _validation = { - 'code': {'required': True}, - 'message': {'required': True}, - 'target': {'readonly': True}, - 'details': {'readonly': True}, - 'inner_error': {'readonly': True}, - } - - _attribute_map = { - 'code': {'key': 'code', 'type': 'str'}, - 'message': {'key': 'message', 'type': 'str'}, - 'target': {'key': 'target', 'type': 'str'}, - 'details': {'key': 'details', 'type': '[CommunicationError]'}, - 'inner_error': {'key': 'innererror', 'type': 'CommunicationError'}, - } - - def __init__( - self, - **kwargs - ): - super(CommunicationError, self).__init__(**kwargs) - self.code = kwargs['code'] - self.message = kwargs['message'] - self.target = None - self.details = None - self.inner_error = None - - -class CommunicationErrorResponse(msrest.serialization.Model): - """The Communication Services error. - - All required parameters must be populated in order to send to Azure. - - :param error: Required. The Communication Services error. - :type error: ~communication.models.CommunicationError +class CommunicationIdentifier(Protocol): + """Communication Identifier. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping[str, Any] properties: The properties of the identifier. """ + raw_id = None # type: Optional[str] + kind = None # type: Optional[Union[CommunicationIdentifierKind, str]] + properties = {} # type: Mapping[str, Any] - _validation = { - 'error': {'required': True}, - } - _attribute_map = { - 'error': {'key': 'error', 'type': 'CommunicationError'}, - } +CommunicationUserProperties = TypedDict( + 'CommunicationUserProperties', + id=str +) - def __init__( - self, - **kwargs - ): - super(CommunicationErrorResponse, self).__init__(**kwargs) - self.error = kwargs['error'] class CommunicationUserIdentifier(object): + """Represents a user in Azure Communication Service. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping[str, Any] properties: The properties of the identifier. + The keys in this mapping include: + - `id`(str): ID of the Communication user as returned from Azure Communication Identity. + + :param str id: ID of the Communication user as returned from Azure Communication Identity. """ - Represents a user in Azure Communication Service. - :ivar identifier: Communication user identifier. - :vartype identifier: str - :param identifier: Identifier to initialize CommunicationUserIdentifier. - :type identifier: str - """ - def __init__(self, identifier): - self.identifier = identifier + kind = CommunicationIdentifierKind.COMMUNICATION_USER + + def __init__(self, id, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = CommunicationUserProperties(id=id) + + +PhoneNumberProperties = TypedDict( + 'PhoneNumberProperties', + value=str +) + class PhoneNumberIdentifier(object): + """Represents a phone number. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + The keys in this mapping include: + - `value`(str): The phone number in E.164 format. + + :param str value: The phone number. """ - Represents a phone number. - :param phone_number: The phone number in E.164 format. - :type phone_number: str - :param raw_id: The full id of the phone number. - :type raw_id: str - """ - def __init__(self, phone_number, raw_id=None): - self.phone_number = phone_number - self.raw_id = raw_id + kind = CommunicationIdentifierKind.PHONE_NUMBER + + def __init__(self, value, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = PhoneNumberProperties(value=value) + class UnknownIdentifier(object): - """ - Represents an identifier of an unknown type. + """Represents an identifier of an unknown type. + It will be encountered in communications with endpoints that are not identifiable by this version of the SDK. - :ivar raw_id: Unknown communication identifier. - :vartype raw_id: str - :param identifier: Value to initialize UnknownIdentifier. - :type identifier: str + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + :param str identifier: The ID of the identifier. """ + kind = CommunicationIdentifierKind.UNKNOWN + def __init__(self, identifier): + # type: (str) -> None self.raw_id = identifier + self.properties = {} -class CommunicationIdentifierModel(msrest.serialization.Model): - """Communication Identifier Model. - All required parameters must be populated in order to send to Azure. - :param kind: Required. Kind of Communication Identifier. - :type kind: CommunicationIdentifierKind - :param id: Full id of the identifier. - :type id: str - :param phone_number: phone number in case the identifier is a phone number. - :type phone_number: str - :param is_anonymous: True if the identifier is anonymous. - :type is_anonymous: bool - :param microsoft_teams_user_id: Microsoft Teams user id. - :type microsoft_teams_user_id: str - :param communication_cloud_environment: Cloud environment that the user belongs to. - :type communication_cloud_environment: CommunicationCloudEnvironment - """ - _validation = { - 'kind': {'required': True}, - } - - _attribute_map = { - 'kind': {'key': 'kind', 'type': 'str'}, - 'id': {'key': 'id', 'type': 'str'}, - 'phone_number': {'key': 'phoneNumber', 'type': 'str'}, - 'is_anonymous': {'key': 'isAnonymous', 'type': 'bool'}, - 'microsoft_teams_user_id': {'key': 'microsoftTeamsUserId', 'type': 'str'}, - 'communication_cloud_environment': {'key': 'communicationCloudEnvironment', 'type': 'str'}, - } - - def __init__( - self, - **kwargs - ): - super(CommunicationIdentifierModel, self).__init__(**kwargs) - self.kind = kwargs['kind'] - self.id = kwargs.get('id', None) - self.phone_number = kwargs.get('phone_number', None) - self.is_anonymous = kwargs.get('is_anonymous', None) - self.microsoft_teams_user_id = kwargs.get('microsoft_teams_user_id', None) - self.communication_cloud_environment = kwargs.get('communication_cloud_environment', None) - -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 CommunicationIdentifierKind(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): - """Communication Identifier Kind. - """ - Unknown = "UNKNOWN" - CommunicationUser = "COMMUNICATIONUSER" - PhoneNumber = "PHONENUMBER" - CallingApplication = "CALLINGAPPLICATION" - MicrosoftTeamsUser = "MICROSOFTTEAMSUSER" +MicrosoftTeamsUserProperties = TypedDict( + 'MicrosoftTeamsUserProperties', + user_id=str, + is_anonymous=bool, + cloud=Union[CommunicationCloudEnvironment, str] +) -class CommunicationCloudEnvironment(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): - """ - The cloud enviornment that the identifier belongs to - """ - - Public = "PUBLIC" - Dod = "DOD" - Gcch = "GCCH" class MicrosoftTeamsUserIdentifier(object): + """Represents an identifier for a Microsoft Teams user. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + The keys in this mapping include: + - `user_id`(str): The id of the Microsoft Teams user. If the user isn't anonymous, + the id is the AAD object id of the user. + - `is_anonymous` (bool): Set this to true if the user is anonymous for example when joining + a meeting with a share link. + - `cloud` (str): Cloud environment that this identifier belongs to. + + :param str user_id: Microsoft Teams user id. + :keyword bool is_anonymous: `True` if the identifier is anonymous. Default value is `False`. + :keyword cloud: Cloud environment that the user belongs to. Default value is `PUBLIC`. + :paramtype cloud: str or ~azure.communication.chat.CommunicationCloudEnvironment """ - Represents an identifier for a Microsoft Teams user. - :ivar user_id: The id of the Microsoft Teams user. If the user isn't anonymous, the id is the AAD object id of the user. - :vartype user_id: str - :param user_id: Value to initialize MicrosoftTeamsUserIdentifier. - :type user_id: str - :ivar raw_id: Raw id of the Microsoft Teams user. - :vartype raw_id: str - :ivar cloud: Cloud environment that this identifier belongs to - :vartype cloud: CommunicationCloudEnvironment - :ivar is_anonymous: set this to true if the user is anonymous for example when joining a meeting with a share link - :vartype is_anonymous: bool - :param is_anonymous: Value to initialize MicrosoftTeamsUserIdentifier. - :type is_anonymous: bool - """ - def __init__(self, user_id, raw_id=None, cloud=CommunicationCloudEnvironment.Public, is_anonymous=False): - self.raw_id = raw_id - self.user_id = user_id - self.is_anonymous = is_anonymous - self.cloud = cloud + kind = CommunicationIdentifierKind.MICROSOFT_TEAMS_USER + + def __init__(self, user_id, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = MicrosoftTeamsUserProperties( + user_id=user_id, + is_anonymous=kwargs.get('is_anonymous', False), + cloud=kwargs.get('cloud') or CommunicationCloudEnvironment.PUBLIC + ) diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/models.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/models.py index 734e074cc27c..7820b25a7d1a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/models.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/models.py @@ -6,210 +6,151 @@ from enum import Enum, EnumMeta from six import with_metaclass +from typing import Mapping, Optional, Union, Any +try: + from typing import Protocol, TypedDict +except ImportError: + from typing_extensions import Protocol, TypedDict -import msrest +from azure.core import CaseInsensitiveEnumMeta -class CommunicationError(msrest.serialization.Model): - """The Communication Services error. - Variables are only populated by the server, and will be ignored when sending a request. +class CommunicationIdentifierKind(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)): + """Communication Identifier Kind.""" - All required parameters must be populated in order to send to Azure. + UNKNOWN = "unknown" + COMMUNICATION_USER = "communication_user" + PHONE_NUMBER = "phone_number" + MICROSOFT_TEAMS_USER = "microsoft_teams_user" + + +class CommunicationCloudEnvironment(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)): + """The cloud enviornment that the identifier belongs to""" + + PUBLIC = "PUBLIC" + DOD = "DOD" + GCCH = "GCCH" - :param code: Required. The error code. - :type code: str - :param message: Required. The error message. - :type message: str - :ivar target: The error target. - :vartype target: str - :ivar details: Further details about specific errors that led to this error. - :vartype details: list[~communication.models.CommunicationError] - :ivar inner_error: The inner error if any. - :vartype inner_error: ~communication.models.CommunicationError - """ - _validation = { - 'code': {'required': True}, - 'message': {'required': True}, - 'target': {'readonly': True}, - 'details': {'readonly': True}, - 'inner_error': {'readonly': True}, - } - - _attribute_map = { - 'code': {'key': 'code', 'type': 'str'}, - 'message': {'key': 'message', 'type': 'str'}, - 'target': {'key': 'target', 'type': 'str'}, - 'details': {'key': 'details', 'type': '[CommunicationError]'}, - 'inner_error': {'key': 'innererror', 'type': 'CommunicationError'}, - } - - def __init__( - self, - **kwargs - ): - super(CommunicationError, self).__init__(**kwargs) - self.code = kwargs['code'] - self.message = kwargs['message'] - self.target = None - self.details = None - self.inner_error = None - - -class CommunicationErrorResponse(msrest.serialization.Model): - """The Communication Services error. - - All required parameters must be populated in order to send to Azure. - - :param error: Required. The Communication Services error. - :type error: ~communication.models.CommunicationError +class CommunicationIdentifier(Protocol): + """Communication Identifier. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping[str, Any] properties: The properties of the identifier. """ + raw_id = None # type: Optional[str] + kind = None # type: Optional[Union[CommunicationIdentifierKind, str]] + properties = {} # type: Mapping[str, Any] - _validation = { - 'error': {'required': True}, - } - _attribute_map = { - 'error': {'key': 'error', 'type': 'CommunicationError'}, - } +CommunicationUserProperties = TypedDict( + 'CommunicationUserProperties', + id=str +) - def __init__( - self, - **kwargs - ): - super(CommunicationErrorResponse, self).__init__(**kwargs) - self.error = kwargs['error'] class CommunicationUserIdentifier(object): + """Represents a user in Azure Communication Service. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping[str, Any] properties: The properties of the identifier. + The keys in this mapping include: + - `id`(str): ID of the Communication user as returned from Azure Communication Identity. + + :param str id: ID of the Communication user as returned from Azure Communication Identity. """ - Represents a user in Azure Communication Service. - :ivar identifier: Communication user identifier. - :vartype identifier: str - :param identifier: Identifier to initialize CommunicationUserIdentifier. - :type identifier: str - """ - def __init__(self, identifier): - self.identifier = identifier + kind = CommunicationIdentifierKind.COMMUNICATION_USER + + def __init__(self, id, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = CommunicationUserProperties(id=id) + + +PhoneNumberProperties = TypedDict( + 'PhoneNumberProperties', + value=str +) + class PhoneNumberIdentifier(object): + """Represents a phone number. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + The keys in this mapping include: + - `value`(str): The phone number in E.164 format. + + :param str value: The phone number. """ - Represents a phone number. - :param phone_number: The phone number in E.164 format. - :type phone_number: str - :param raw_id: The full id of the phone number. - :type raw_id: str - """ - def __init__(self, phone_number, raw_id=None): - self.phone_number = phone_number - self.raw_id = raw_id + kind = CommunicationIdentifierKind.PHONE_NUMBER + + def __init__(self, value, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = PhoneNumberProperties(value=value) + class UnknownIdentifier(object): - """ - Represents an identifier of an unknown type. + """Represents an identifier of an unknown type. + It will be encountered in communications with endpoints that are not identifiable by this version of the SDK. - :ivar raw_id: Unknown communication identifier. - :vartype raw_id: str - :param identifier: Value to initialize UnknownIdentifier. - :type identifier: str + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + :param str identifier: The ID of the identifier. """ + kind = CommunicationIdentifierKind.UNKNOWN + def __init__(self, identifier): + # type: (str) -> None self.raw_id = identifier + self.properties = {} -class CommunicationIdentifierModel(msrest.serialization.Model): - """Communication Identifier Model. - All required parameters must be populated in order to send to Azure. - :param kind: Required. Kind of Communication Identifier. - :type kind: CommunicationIdentifierKind - :param id: Full id of the identifier. - :type id: str - :param phone_number: phone number in case the identifier is a phone number. - :type phone_number: str - :param is_anonymous: True if the identifier is anonymous. - :type is_anonymous: bool - :param microsoft_teams_user_id: Microsoft Teams user id. - :type microsoft_teams_user_id: str - :param communication_cloud_environment: Cloud environment that the user belongs to. - :type communication_cloud_environment: CommunicationCloudEnvironment - """ - _validation = { - 'kind': {'required': True}, - } - - _attribute_map = { - 'kind': {'key': 'kind', 'type': 'str'}, - 'id': {'key': 'id', 'type': 'str'}, - 'phone_number': {'key': 'phoneNumber', 'type': 'str'}, - 'is_anonymous': {'key': 'isAnonymous', 'type': 'bool'}, - 'microsoft_teams_user_id': {'key': 'microsoftTeamsUserId', 'type': 'str'}, - 'communication_cloud_environment': {'key': 'communicationCloudEnvironment', 'type': 'str'}, - } - - def __init__( - self, - **kwargs - ): - super(CommunicationIdentifierModel, self).__init__(**kwargs) - self.kind = kwargs['kind'] - self.id = kwargs.get('id', None) - self.phone_number = kwargs.get('phone_number', None) - self.is_anonymous = kwargs.get('is_anonymous', None) - self.microsoft_teams_user_id = kwargs.get('microsoft_teams_user_id', None) - self.communication_cloud_environment = kwargs.get('communication_cloud_environment', None) - -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 CommunicationIdentifierKind(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): - """Communication Identifier Kind. - """ - Unknown = "UNKNOWN" - CommunicationUser = "COMMUNICATIONUSER" - PhoneNumber = "PHONENUMBER" - CallingApplication = "CALLINGAPPLICATION" - MicrosoftTeamsUser = "MICROSOFTTEAMSUSER" +MicrosoftTeamsUserProperties = TypedDict( + 'MicrosoftTeamsUserProperties', + user_id=str, + is_anonymous=bool, + cloud=Union[CommunicationCloudEnvironment, str] +) -class CommunicationCloudEnvironment(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): - """ - The cloud enviornment that the identifier belongs to - """ - - Public = "PUBLIC" - Dod = "DOD" - Gcch = "GCCH" class MicrosoftTeamsUserIdentifier(object): + """Represents an identifier for a Microsoft Teams user. + + :ivar str raw_id: Optional raw ID of the identifier. + :ivar kind: The type of identifier. + :vartype kind: str or CommunicationIdentifierKind + :ivar Mapping properties: The properties of the identifier. + The keys in this mapping include: + - `user_id`(str): The id of the Microsoft Teams user. If the user isn't anonymous, + the id is the AAD object id of the user. + - `is_anonymous` (bool): Set this to true if the user is anonymous for example when joining + a meeting with a share link. + - `cloud` (str): Cloud environment that this identifier belongs to. + + :param str user_id: Microsoft Teams user id. + :keyword bool is_anonymous: `True` if the identifier is anonymous. Default value is `False`. + :keyword cloud: Cloud environment that the user belongs to. Default value is `PUBLIC`. + :paramtype cloud: str or ~azure.communication.chat.CommunicationCloudEnvironment """ - Represents an identifier for a Microsoft Teams user. - :ivar user_id: The id of the Microsoft Teams user. If the user isn't anonymous, the id is the AAD object id of the user. - :vartype user_id: str - :param user_id: Value to initialize MicrosoftTeamsUserIdentifier. - :type user_id: str - :ivar raw_id: Raw id of the Microsoft Teams user. - :vartype raw_id: str - :ivar cloud: Cloud environment that this identifier belongs to - :vartype cloud: CommunicationCloudEnvironment - :ivar is_anonymous: set this to true if the user is anonymous for example when joining a meeting with a share link - :vartype is_anonymous: bool - :param is_anonymous: Value to initialize MicrosoftTeamsUserIdentifier. - :type is_anonymous: bool - """ - def __init__(self, user_id, raw_id=None, cloud=CommunicationCloudEnvironment.Public, is_anonymous=False): - self.raw_id = raw_id - self.user_id = user_id - self.is_anonymous = is_anonymous - self.cloud = cloud + kind = CommunicationIdentifierKind.MICROSOFT_TEAMS_USER + + def __init__(self, user_id, **kwargs): + # type: (str, Any) -> None + self.raw_id = kwargs.get('raw_id') + self.properties = MicrosoftTeamsUserProperties( + user_id=user_id, + is_anonymous=kwargs.get('is_anonymous', False), + cloud=kwargs.get('cloud') or CommunicationCloudEnvironment.PUBLIC + ) From ecc71ee100fe6092313bd33e87a85f79db497f4f Mon Sep 17 00:00:00 2001 From: Jorge Beauregard Date: Mon, 12 Apr 2021 16:20:59 -0500 Subject: [PATCH 2/3] Added typing extensions --- sdk/communication/azure-communication-phonenumbers/setup.py | 1 + sdk/communication/azure-communication-sms/setup.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/communication/azure-communication-phonenumbers/setup.py b/sdk/communication/azure-communication-phonenumbers/setup.py index e80ec7470ce3..ade6f9a35403 100644 --- a/sdk/communication/azure-communication-phonenumbers/setup.py +++ b/sdk/communication/azure-communication-phonenumbers/setup.py @@ -66,6 +66,7 @@ ], extras_require={ ":python_version<'3.0'": ['azure-communication-nspkg'], + ":python_version<'3.8'": ["typing-extensions"] }, project_urls={ 'Bug Reports': 'https://github.com/Azure/azure-sdk-for-python/issues', diff --git a/sdk/communication/azure-communication-sms/setup.py b/sdk/communication/azure-communication-sms/setup.py index 56c70a8de195..90d7f75bda76 100644 --- a/sdk/communication/azure-communication-sms/setup.py +++ b/sdk/communication/azure-communication-sms/setup.py @@ -67,6 +67,7 @@ ], extras_require={ ":python_version<'3.0'": ['azure-communication-nspkg'], - ":python_version<'3.5'": ["typing"] + ":python_version<'3.5'": ["typing"], + ":python_version<'3.8'": ["typing-extensions"] } ) \ No newline at end of file From f793e30e4dc3c02b4df402161220efbe76f2b06c Mon Sep 17 00:00:00 2001 From: Jorge Beauregard Date: Mon, 12 Apr 2021 16:30:47 -0500 Subject: [PATCH 3/3] Sync other shared folder files --- .../phonenumbers/_shared/user_credential.py | 37 ++++++------ .../_shared/user_credential_async.py | 56 +++++++++++-------- .../phonenumbers/_shared/utils.py | 6 +- .../azure-communication-phonenumbers/setup.py | 2 +- .../sms/_shared/user_credential.py | 37 ++++++------ .../sms/_shared/user_credential_async.py | 56 +++++++++++-------- .../azure/communication/sms/_shared/utils.py | 2 + .../azure-communication-sms/setup.py | 2 +- shared_requirements.txt | 4 +- 9 files changed, 112 insertions(+), 90 deletions(-) diff --git a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential.py b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential.py index e920d356a518..9b5f17dcc95d 100644 --- a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential.py +++ b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential.py @@ -4,32 +4,39 @@ # license information. # -------------------------------------------------------------------------- from threading import Lock, Condition -from datetime import datetime, timedelta +from datetime import timedelta from typing import ( # pylint: disable=unused-import cast, Tuple, ) -from msrest.serialization import TZ_UTC +from .utils import get_current_utc_as_int +from .user_token_refresh_options import CommunicationTokenRefreshOptions + class CommunicationTokenCredential(object): """Credential type used for authenticating to an Azure Communication service. - :param communication_token_refresh_options: The token used to authenticate to an Azure Communication service - :type communication_token_refresh_options: ~azure.communication.chat.CommunicationTokenRefreshOptions + :param str token: The token used to authenticate to an Azure Communication service + :keyword token_refresher: The token refresher to provide capacity to fetch fresh token + :raises: TypeError """ - ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 + _ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 def __init__(self, - communication_token_refresh_options - ): + token, # type: str + **kwargs + ): + token_refresher = kwargs.pop('token_refresher', None) + communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token, + token_refresher=token_refresher) self._token = communication_token_refresh_options.get_token() self._token_refresher = communication_token_refresh_options.get_token_refresher() self._lock = Condition(Lock()) self._some_thread_refreshing = False - def get_token(self): - # type () -> ~azure.core.credentials.AccessToken + def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument + # type (*str, **Any) -> AccessToken """The value of the configured token. :rtype: ~azure.core.credentials.AccessToken """ @@ -53,7 +60,7 @@ def get_token(self): if should_this_thread_refresh: try: - newtoken = self._token_refresher() + newtoken = self._token_refresher() # pylint:disable=not-callable with self._lock: self._token = newtoken @@ -72,12 +79,8 @@ def _wait_till_inprogress_thread_finish_refreshing(self): self._lock.acquire() def _token_expiring(self): - return self._token.expires_on - self._get_utc_now() <\ - timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES) + return self._token.expires_on - get_current_utc_as_int() <\ + timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds() def _is_currenttoken_valid(self): - return self._get_utc_now() < self._token.expires_on - - @classmethod - def _get_utc_now(cls): - return datetime.now().replace(tzinfo=TZ_UTC) + return get_current_utc_as_int() < self._token.expires_on diff --git a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential_async.py b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential_async.py index 0918074eb04a..52a99e7a4b6a 100644 --- a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential_async.py +++ b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/user_credential_async.py @@ -4,50 +4,53 @@ # license information. # -------------------------------------------------------------------------- from asyncio import Condition, Lock -from datetime import datetime, timedelta +from datetime import timedelta from typing import ( # pylint: disable=unused-import cast, Tuple, + Any ) -from msrest.serialization import TZ_UTC +from .utils import get_current_utc_as_int +from .user_token_refresh_options import CommunicationTokenRefreshOptions + class CommunicationTokenCredential(object): """Credential type used for authenticating to an Azure Communication service. - :param communication_token_refresh_options: The token used to authenticate to an Azure Communication service - :type communication_token_refresh_options: ~azure.communication.chat.aio.CommunicationTokenRefreshOptions + :param str token: The token used to authenticate to an Azure Communication service + :keyword token_refresher: The async token refresher to provide capacity to fetch fresh token :raises: TypeError """ - ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 + _ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 - def __init__(self, - communication_token_refresh_options - ): + def __init__(self, token: str, **kwargs: Any): + token_refresher = kwargs.pop('token_refresher', None) + communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token, + token_refresher=token_refresher) self._token = communication_token_refresh_options.get_token() self._token_refresher = communication_token_refresh_options.get_token_refresher() self._lock = Condition(Lock()) self._some_thread_refreshing = False - def get_token(self): - # type () -> ~azure.core.credentials.AccessToken + async def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument + # type (*str, **Any) -> AccessToken """The value of the configured token. :rtype: ~azure.core.credentials.AccessToken """ - if not self._token_refresher or not self._token_expiring(): return self._token should_this_thread_refresh = False - with self._lock: + async with self._lock: while self._token_expiring(): if self._some_thread_refreshing: if self._is_currenttoken_valid(): return self._token - self._wait_till_inprogress_thread_finish_refreshing() + await self._wait_till_inprogress_thread_finish_refreshing() else: should_this_thread_refresh = True self._some_thread_refreshing = True @@ -56,14 +59,14 @@ def get_token(self): if should_this_thread_refresh: try: - newtoken = self._token_refresher() + newtoken = await self._token_refresher() # pylint:disable=not-callable - with self._lock: + async with self._lock: self._token = newtoken self._some_thread_refreshing = False self._lock.notify_all() except: - with self._lock: + async with self._lock: self._some_thread_refreshing = False self._lock.notify_all() @@ -71,17 +74,22 @@ def get_token(self): return self._token - def _wait_till_inprogress_thread_finish_refreshing(self): + async def _wait_till_inprogress_thread_finish_refreshing(self): self._lock.release() - self._lock.acquire() + await self._lock.acquire() def _token_expiring(self): - return self._token.expires_on - self._get_utc_now() <\ - timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES) + return self._token.expires_on - get_current_utc_as_int() <\ + timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds() def _is_currenttoken_valid(self): - return self._get_utc_now() < self._token.expires_on + return get_current_utc_as_int() < self._token.expires_on + + async def close(self) -> None: + pass + + async def __aenter__(self): + return self - @classmethod - def _get_utc_now(cls): - return datetime.now().replace(tzinfo=TZ_UTC) + async def __aexit__(self, *args): + await self.close() diff --git a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/utils.py b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/utils.py index b38aaafc6194..722565f2e0d1 100644 --- a/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/utils.py +++ b/sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_shared/utils.py @@ -15,6 +15,7 @@ from msrest.serialization import TZ_UTC from azure.core.credentials import AccessToken + def _convert_datetime_to_utc_int(expires_on): epoch = time.mktime(datetime(1970, 1, 1).timetuple()) return epoch-time.mktime(expires_on.timetuple()) @@ -50,6 +51,7 @@ def get_current_utc_time(): # type: () -> str return str(datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S ")) + "GMT" + def get_current_utc_as_int(): # type: () -> int current_utc_datetime = datetime.utcnow().replace(tzinfo=TZ_UTC) @@ -113,7 +115,3 @@ def get_authentication_policy( raise TypeError("Unsupported credential: {}. Use an access token string to use HMACCredentialsPolicy" "or a token credential from azure.identity".format(type(credential))) - -def _convert_expires_on_datetime_to_utc_int(expires_on): - epoch = time.mktime(datetime(1970, 1, 1).timetuple()) - return epoch-time.mktime(expires_on.timetuple()) diff --git a/sdk/communication/azure-communication-phonenumbers/setup.py b/sdk/communication/azure-communication-phonenumbers/setup.py index ade6f9a35403..a030d3da7ead 100644 --- a/sdk/communication/azure-communication-phonenumbers/setup.py +++ b/sdk/communication/azure-communication-phonenumbers/setup.py @@ -62,7 +62,7 @@ ]), install_requires=[ "msrest>=0.6.0", - "azure-core<2.0.0,>=1.9.0", + 'azure-core<2.0.0,>=1.11.0', ], extras_require={ ":python_version<'3.0'": ['azure-communication-nspkg'], diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential.py index e920d356a518..9b5f17dcc95d 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential.py @@ -4,32 +4,39 @@ # license information. # -------------------------------------------------------------------------- from threading import Lock, Condition -from datetime import datetime, timedelta +from datetime import timedelta from typing import ( # pylint: disable=unused-import cast, Tuple, ) -from msrest.serialization import TZ_UTC +from .utils import get_current_utc_as_int +from .user_token_refresh_options import CommunicationTokenRefreshOptions + class CommunicationTokenCredential(object): """Credential type used for authenticating to an Azure Communication service. - :param communication_token_refresh_options: The token used to authenticate to an Azure Communication service - :type communication_token_refresh_options: ~azure.communication.chat.CommunicationTokenRefreshOptions + :param str token: The token used to authenticate to an Azure Communication service + :keyword token_refresher: The token refresher to provide capacity to fetch fresh token + :raises: TypeError """ - ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 + _ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 def __init__(self, - communication_token_refresh_options - ): + token, # type: str + **kwargs + ): + token_refresher = kwargs.pop('token_refresher', None) + communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token, + token_refresher=token_refresher) self._token = communication_token_refresh_options.get_token() self._token_refresher = communication_token_refresh_options.get_token_refresher() self._lock = Condition(Lock()) self._some_thread_refreshing = False - def get_token(self): - # type () -> ~azure.core.credentials.AccessToken + def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument + # type (*str, **Any) -> AccessToken """The value of the configured token. :rtype: ~azure.core.credentials.AccessToken """ @@ -53,7 +60,7 @@ def get_token(self): if should_this_thread_refresh: try: - newtoken = self._token_refresher() + newtoken = self._token_refresher() # pylint:disable=not-callable with self._lock: self._token = newtoken @@ -72,12 +79,8 @@ def _wait_till_inprogress_thread_finish_refreshing(self): self._lock.acquire() def _token_expiring(self): - return self._token.expires_on - self._get_utc_now() <\ - timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES) + return self._token.expires_on - get_current_utc_as_int() <\ + timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds() def _is_currenttoken_valid(self): - return self._get_utc_now() < self._token.expires_on - - @classmethod - def _get_utc_now(cls): - return datetime.now().replace(tzinfo=TZ_UTC) + return get_current_utc_as_int() < self._token.expires_on diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential_async.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential_async.py index 0918074eb04a..52a99e7a4b6a 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential_async.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/user_credential_async.py @@ -4,50 +4,53 @@ # license information. # -------------------------------------------------------------------------- from asyncio import Condition, Lock -from datetime import datetime, timedelta +from datetime import timedelta from typing import ( # pylint: disable=unused-import cast, Tuple, + Any ) -from msrest.serialization import TZ_UTC +from .utils import get_current_utc_as_int +from .user_token_refresh_options import CommunicationTokenRefreshOptions + class CommunicationTokenCredential(object): """Credential type used for authenticating to an Azure Communication service. - :param communication_token_refresh_options: The token used to authenticate to an Azure Communication service - :type communication_token_refresh_options: ~azure.communication.chat.aio.CommunicationTokenRefreshOptions + :param str token: The token used to authenticate to an Azure Communication service + :keyword token_refresher: The async token refresher to provide capacity to fetch fresh token :raises: TypeError """ - ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 + _ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2 - def __init__(self, - communication_token_refresh_options - ): + def __init__(self, token: str, **kwargs: Any): + token_refresher = kwargs.pop('token_refresher', None) + communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token, + token_refresher=token_refresher) self._token = communication_token_refresh_options.get_token() self._token_refresher = communication_token_refresh_options.get_token_refresher() self._lock = Condition(Lock()) self._some_thread_refreshing = False - def get_token(self): - # type () -> ~azure.core.credentials.AccessToken + async def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument + # type (*str, **Any) -> AccessToken """The value of the configured token. :rtype: ~azure.core.credentials.AccessToken """ - if not self._token_refresher or not self._token_expiring(): return self._token should_this_thread_refresh = False - with self._lock: + async with self._lock: while self._token_expiring(): if self._some_thread_refreshing: if self._is_currenttoken_valid(): return self._token - self._wait_till_inprogress_thread_finish_refreshing() + await self._wait_till_inprogress_thread_finish_refreshing() else: should_this_thread_refresh = True self._some_thread_refreshing = True @@ -56,14 +59,14 @@ def get_token(self): if should_this_thread_refresh: try: - newtoken = self._token_refresher() + newtoken = await self._token_refresher() # pylint:disable=not-callable - with self._lock: + async with self._lock: self._token = newtoken self._some_thread_refreshing = False self._lock.notify_all() except: - with self._lock: + async with self._lock: self._some_thread_refreshing = False self._lock.notify_all() @@ -71,17 +74,22 @@ def get_token(self): return self._token - def _wait_till_inprogress_thread_finish_refreshing(self): + async def _wait_till_inprogress_thread_finish_refreshing(self): self._lock.release() - self._lock.acquire() + await self._lock.acquire() def _token_expiring(self): - return self._token.expires_on - self._get_utc_now() <\ - timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES) + return self._token.expires_on - get_current_utc_as_int() <\ + timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds() def _is_currenttoken_valid(self): - return self._get_utc_now() < self._token.expires_on + return get_current_utc_as_int() < self._token.expires_on + + async def close(self) -> None: + pass + + async def __aenter__(self): + return self - @classmethod - def _get_utc_now(cls): - return datetime.now().replace(tzinfo=TZ_UTC) + async def __aexit__(self, *args): + await self.close() diff --git a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/utils.py b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/utils.py index 8cfaa8f7e67d..722565f2e0d1 100644 --- a/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/utils.py +++ b/sdk/communication/azure-communication-sms/azure/communication/sms/_shared/utils.py @@ -15,6 +15,7 @@ from msrest.serialization import TZ_UTC from azure.core.credentials import AccessToken + def _convert_datetime_to_utc_int(expires_on): epoch = time.mktime(datetime(1970, 1, 1).timetuple()) return epoch-time.mktime(expires_on.timetuple()) @@ -50,6 +51,7 @@ def get_current_utc_time(): # type: () -> str return str(datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S ")) + "GMT" + def get_current_utc_as_int(): # type: () -> int current_utc_datetime = datetime.utcnow().replace(tzinfo=TZ_UTC) diff --git a/sdk/communication/azure-communication-sms/setup.py b/sdk/communication/azure-communication-sms/setup.py index 90d7f75bda76..8da2d012064a 100644 --- a/sdk/communication/azure-communication-sms/setup.py +++ b/sdk/communication/azure-communication-sms/setup.py @@ -61,7 +61,7 @@ 'azure.communication' ]), install_requires=[ - 'azure-core<2.0.0,>=1.9.0', + 'azure-core<2.0.0,>=1.11.0', 'msrest>=0.6.0', 'six>=1.11.0' ], diff --git a/shared_requirements.txt b/shared_requirements.txt index 4251c007d8a5..ab33da094da1 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -185,8 +185,8 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-communication-sms msrest>=0.6.0 #override azure-communication-phonenumbers msrest>=0.6.0 #override azure-communication-chat azure-core<2.0.0,>=1.11.0 -#override azure-communication-sms azure-core<2.0.0,>=1.9.0 -#override azure-communication-phonenumbers azure-core<2.0.0,>=1.9.0 +#override azure-communication-sms azure-core<2.0.0,>=1.11.0 +#override azure-communication-phonenumbers azure-core<2.0.0,>=1.11.0 #override azure-communication-identity azure-core<2.0.0,>=1.11.0 #override azure-mgmt-communication azure-core<2.0.0,>=1.9.0 #override azure-ai-metricsadvisor azure-core<2.0.0,>=1.6.0