diff --git a/sdk/communication/azure-communication-chat/azure/__init__.py b/sdk/communication/azure-communication-chat/azure/__init__.py index 69e3be50dac4..8db66d3d0f0f 100644 --- a/sdk/communication/azure-communication-chat/azure/__init__.py +++ b/sdk/communication/azure-communication-chat/azure/__init__.py @@ -1 +1 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) +__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/sdk/communication/azure-communication-chat/azure/communication/__init__.py b/sdk/communication/azure-communication-chat/azure/communication/__init__.py index 69e3be50dac4..8db66d3d0f0f 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/__init__.py +++ b/sdk/communication/azure-communication-chat/azure/communication/__init__.py @@ -1 +1 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) +__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/__init__.py b/sdk/communication/azure-communication-chat/azure/communication/chat/__init__.py index b9136cb894d9..13a4160bf9c2 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/__init__.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/__init__.py @@ -1,13 +1,7 @@ from ._version import VERSION from ._chat_client import ChatClient from ._chat_thread_client import ChatThreadClient -from ._generated.models import ( - ChatAttachmentType, - SendChatMessageResult, - ChatThreadItem, - ChatMessageType, - ChatError -) +from ._generated.models import ChatAttachmentType, SendChatMessageResult, ChatThreadItem, ChatMessageType, ChatError from ._models import ( ChatAttachment, @@ -16,7 +10,7 @@ ChatThreadProperties, ChatMessageReadReceipt, ChatMessageContent, - CreateChatThreadResult + CreateChatThreadResult, ) from ._shared.user_credential import CommunicationTokenCredential @@ -32,36 +26,36 @@ MicrosoftTeamsAppProperties, MicrosoftTeamsUserIdentifier, MicrosoftTeamsUserProperties, - UnknownIdentifier + UnknownIdentifier, ) __all__ = [ - 'ChatClient', - 'ChatThreadClient', - 'ChatMessage', - 'ChatMessageContent', - 'ChatMessageReadReceipt', - 'SendChatMessageResult', - 'ChatThreadProperties', - 'ChatThreadItem', - 'ChatParticipant', - 'ChatMessageType', - 'ChatAttachment', - 'ChatAttachmentType', - 'CreateChatThreadResult', - 'ChatError', - 'CommunicationTokenCredential', - 'CommunicationIdentifier', - 'CommunicationIdentifierKind', - 'CommunicationUserIdentifier', - 'CommunicationUserProperties', - 'MicrosoftTeamsAppIdentifier', - 'MicrosoftTeamsAppProperties', - 'MicrosoftTeamsUserIdentifier', - 'MicrosoftTeamsUserProperties', - 'identifier_from_raw_id', - 'PhoneNumberIdentifier', - 'PhoneNumberProperties', - 'UnknownIdentifier' + "ChatClient", + "ChatThreadClient", + "ChatMessage", + "ChatMessageContent", + "ChatMessageReadReceipt", + "SendChatMessageResult", + "ChatThreadProperties", + "ChatThreadItem", + "ChatParticipant", + "ChatMessageType", + "ChatAttachment", + "ChatAttachmentType", + "CreateChatThreadResult", + "ChatError", + "CommunicationTokenCredential", + "CommunicationIdentifier", + "CommunicationIdentifierKind", + "CommunicationUserIdentifier", + "CommunicationUserProperties", + "MicrosoftTeamsAppIdentifier", + "MicrosoftTeamsAppProperties", + "MicrosoftTeamsUserIdentifier", + "MicrosoftTeamsUserProperties", + "identifier_from_raw_id", + "PhoneNumberIdentifier", + "PhoneNumberProperties", + "UnknownIdentifier", ] __version__ = VERSION diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_client.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_client.py index 48260cc8261f..10e533135443 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_client.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_client.py @@ -14,14 +14,11 @@ from ._shared.user_credential import CommunicationTokenCredential from ._generated import AzureCommunicationChatService from ._generated.models import CreateChatThreadRequest -from ._models import ( - ChatThreadProperties, - CreateChatThreadResult -) -from ._utils import ( # pylint: disable=unused-import +from ._models import ChatThreadProperties, CreateChatThreadResult +from ._utils import ( # pylint: disable=unused-import _to_utc_datetime, return_response, - CommunicationErrorResponseConverter + CommunicationErrorResponseConverter, ) from ._version import SDK_MONIKER @@ -31,7 +28,7 @@ from azure.core.paging import ItemPaged -class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword +class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword """A client to interact with the AzureCommunicationService Chat gateway. This client provides operations to create chat thread, delete chat thread, @@ -53,22 +50,22 @@ class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword """ def __init__( - self, - endpoint, # type: str - credential, # type: CommunicationTokenCredential - **kwargs # type: Any + self, + endpoint, # type: str + credential, # type: CommunicationTokenCredential + **kwargs # type: Any ): # type: (...) -> None if not credential: raise ValueError("credential can not be None") try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from + raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from - parsed_url = urlparse(endpoint.rstrip('/')) + parsed_url = urlparse(endpoint.rstrip("/")) if not parsed_url.netloc: raise ValueError("Invalid URL: {}".format(endpoint)) @@ -84,7 +81,8 @@ def __init__( @distributed_trace def get_chat_thread_client( - self, thread_id, # type: str + self, + thread_id, # type: str **kwargs # type: Any ): # type: (...) -> ChatThreadClient @@ -109,16 +107,12 @@ def get_chat_thread_client( if not thread_id: raise ValueError("thread_id cannot be None.") - return ChatThreadClient( - endpoint=self._endpoint, - credential=self._credential, - thread_id=thread_id, - **kwargs - ) + return ChatThreadClient(endpoint=self._endpoint, credential=self._credential, thread_id=thread_id, **kwargs) @distributed_trace def create_chat_thread( - self, topic, # type: str + self, + topic, # type: str **kwargs # type: Any ): # type: (...) -> CreateChatThreadResult @@ -151,11 +145,11 @@ def create_chat_thread( if not topic: raise ValueError("topic cannot be None.") - idempotency_token = kwargs.pop('idempotency_token', None) + idempotency_token = kwargs.pop("idempotency_token", None) if idempotency_token is None: idempotency_token = str(uuid4()) - thread_participants = kwargs.pop('thread_participants', None) + thread_participants = kwargs.pop("thread_participants", None) participants = [] if thread_participants is not None: participants = [m._to_generated() for m in thread_participants] # pylint:disable=protected-access @@ -163,33 +157,25 @@ def create_chat_thread( create_thread_request = CreateChatThreadRequest(topic=topic, participants=participants) create_chat_thread_result = self._client.chat.create_chat_thread( - create_chat_thread_request=create_thread_request, - repeatability_request_id=idempotency_token, - **kwargs) + create_chat_thread_request=create_thread_request, repeatability_request_id=idempotency_token, **kwargs + ) errors = None - if hasattr(create_chat_thread_result, 'invalid_participants'): + if hasattr(create_chat_thread_result, "invalid_participants"): errors = CommunicationErrorResponseConverter.convert( - participants=thread_participants or [], - chat_errors=create_chat_thread_result.invalid_participants + participants=thread_participants or [], chat_errors=create_chat_thread_result.invalid_participants ) - chat_thread_properties = ChatThreadProperties._from_generated( # pylint:disable=protected-access - create_chat_thread_result.chat_thread) - - create_chat_thread_result = CreateChatThreadResult( - chat_thread=chat_thread_properties, - errors=errors + chat_thread_properties = ChatThreadProperties._from_generated( # pylint:disable=protected-access + create_chat_thread_result.chat_thread ) - return create_chat_thread_result + create_chat_thread_result = CreateChatThreadResult(chat_thread=chat_thread_properties, errors=errors) + return create_chat_thread_result @distributed_trace - def list_chat_threads( - self, - **kwargs - ): + def list_chat_threads(self, **kwargs): # type: (...) -> ItemPaged[ChatThreadItem] """Gets the list of chat threads of a user. @@ -211,10 +197,7 @@ def list_chat_threads( results_per_page = kwargs.pop("results_per_page", None) start_time = kwargs.pop("start_time", None) - return self._client.chat.list_chat_threads( - max_page_size=results_per_page, - start_time=start_time, - **kwargs) + return self._client.chat.list_chat_threads(max_page_size=results_per_page, start_time=start_time, **kwargs) @distributed_trace def delete_chat_thread( diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_thread_client.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_thread_client.py index ad8f60088298..8d63a6d35b0a 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_thread_client.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_chat_thread_client.py @@ -21,14 +21,9 @@ UpdateChatMessageRequest, UpdateChatThreadRequest, ChatMessageType, - SendChatMessageResult -) -from ._models import ( - ChatParticipant, - ChatMessage, - ChatMessageReadReceipt, - ChatThreadProperties + SendChatMessageResult, ) +from ._models import ChatParticipant, ChatMessage, ChatMessageReadReceipt, ChatThreadProperties from ._communication_identifier_serializer import serialize_identifier from ._utils import CommunicationErrorResponseConverter @@ -40,7 +35,7 @@ from azure.core.paging import ItemPaged -class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-keyword +class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-keyword """A client to interact with the AzureCommunicationService Chat gateway. Instances of this class is normally retrieved by ChatClient.get_chat_thread_client() @@ -70,11 +65,11 @@ class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-key """ def __init__( - self, - endpoint, # type: str - credential, # type: CommunicationTokenCredential - thread_id, # type: str - **kwargs # type: Any + self, + endpoint, # type: str + credential, # type: CommunicationTokenCredential + thread_id, # type: str + **kwargs # type: Any ): # type: (...) -> None if not thread_id: @@ -84,12 +79,12 @@ def __init__( raise ValueError("credential can not be None") try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Host URL must be a string") # pylint: disable=raise-missing-from + raise ValueError("Host URL must be a string") # pylint: disable=raise-missing-from - parsed_url = urlparse(endpoint.rstrip('/')) + parsed_url = urlparse(endpoint.rstrip("/")) if not parsed_url.netloc: raise ValueError("Invalid URL: {}".format(endpoint)) @@ -116,8 +111,7 @@ def thread_id(self): @distributed_trace def get_properties( - self, - **kwargs # type: Any + self, **kwargs # type: Any ): # type: (...) -> ChatThreadProperties """Gets the properties of the chat thread. @@ -139,7 +133,6 @@ def get_properties( chat_thread = self._client.chat_thread.get_chat_thread_properties(self._thread_id, **kwargs) return ChatThreadProperties._from_generated(chat_thread) # pylint:disable=protected-access - @distributed_trace def update_topic( self, @@ -168,9 +161,8 @@ def update_topic( update_topic_request = UpdateChatThreadRequest(topic=topic) return self._client.chat_thread.update_chat_thread_properties( - chat_thread_id=self._thread_id, - update_chat_thread_request=update_topic_request, - **kwargs) + chat_thread_id=self._thread_id, update_chat_thread_request=update_topic_request, **kwargs + ) @distributed_trace def send_read_receipt( @@ -201,14 +193,12 @@ def send_read_receipt( post_read_receipt_request = SendReadReceiptRequest(chat_message_id=message_id) return self._client.chat_thread.send_chat_read_receipt( - self._thread_id, - send_read_receipt_request=post_read_receipt_request, - **kwargs) + self._thread_id, send_read_receipt_request=post_read_receipt_request, **kwargs + ) @distributed_trace def list_read_receipts( - self, - **kwargs # type: Any + self, **kwargs # type: Any ): # type: (...) -> ItemPaged[ChatMessageReadReceipt] """Gets read receipts for a thread. @@ -235,13 +225,15 @@ def list_read_receipts( self._thread_id, max_page_size=results_per_page, skip=skip, - cls=lambda objs: [ChatMessageReadReceipt._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) + cls=lambda objs: [ + ChatMessageReadReceipt._from_generated(x) for x in objs # pylint:disable=protected-access + ], + **kwargs + ) @distributed_trace def send_typing_notification( - self, - **kwargs # type: Any + self, **kwargs # type: Any ): # type: (...) -> None """Posts a typing event to a thread, on behalf of a user. @@ -265,9 +257,8 @@ def send_typing_notification( sender_display_name = kwargs.pop("sender_display_name", None) send_typing_notification_request = SendTypingNotificationRequest(sender_display_name=sender_display_name) return self._client.chat_thread.send_typing_notification( - chat_thread_id=self._thread_id, - send_typing_notification_request=send_typing_notification_request, - **kwargs) + chat_thread_id=self._thread_id, send_typing_notification_request=send_typing_notification_request, **kwargs + ) @distributed_trace def send_message( @@ -307,29 +298,27 @@ def send_message( chat_message_type = ChatMessageType.TEXT elif not isinstance(chat_message_type, ChatMessageType): try: - chat_message_type = ChatMessageType.__getattr__(chat_message_type) # pylint:disable=protected-access + chat_message_type = ChatMessageType.__getattr__(chat_message_type) # pylint:disable=protected-access except Exception: - raise ValueError( # pylint:disable=raise-missing-from - "chat_message_type: {message_type} is not acceptable".format(message_type=chat_message_type)) + raise ValueError( # pylint:disable=raise-missing-from + "chat_message_type: {message_type} is not acceptable".format(message_type=chat_message_type) + ) if chat_message_type not in [ChatMessageType.TEXT, ChatMessageType.HTML]: raise ValueError( - "chat_message_type: {message_type} can be only 'text' or 'html'".format(message_type=chat_message_type)) + "chat_message_type: {message_type} can be only 'text' or 'html'".format(message_type=chat_message_type) + ) sender_display_name = kwargs.pop("sender_display_name", None) metadata = kwargs.pop("metadata", None) create_message_request = SendChatMessageRequest( - content=content, - type=chat_message_type, - sender_display_name=sender_display_name, - metadata=metadata + content=content, type=chat_message_type, sender_display_name=sender_display_name, metadata=metadata ) send_chat_message_result = self._client.chat_thread.send_chat_message( - chat_thread_id=self._thread_id, - send_chat_message_request=create_message_request, - **kwargs) + chat_thread_id=self._thread_id, send_chat_message_request=create_message_request, **kwargs + ) return send_chat_message_result @distributed_trace @@ -364,8 +353,7 @@ def get_message( @distributed_trace def list_messages( - self, - **kwargs # type: Any + self, **kwargs # type: Any ): # type: (...) -> ItemPaged[ChatMessage] """Gets a list of messages from a thread. @@ -394,7 +382,8 @@ def list_messages( max_page_size=results_per_page, start_time=start_time, cls=lambda objs: [ChatMessage._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) + **kwargs + ) return a @distributed_trace @@ -435,7 +424,8 @@ def update_message( chat_thread_id=self._thread_id, chat_message_id=message_id, update_chat_message_request=update_message_request, - **kwargs) + **kwargs + ) @distributed_trace def delete_message( @@ -465,14 +455,12 @@ def delete_message( raise ValueError("message_id cannot be None.") return self._client.chat_thread.delete_chat_message( - chat_thread_id=self._thread_id, - chat_message_id=message_id, - **kwargs) + chat_thread_id=self._thread_id, chat_message_id=message_id, **kwargs + ) @distributed_trace def list_participants( - self, - **kwargs # type: Any + self, **kwargs # type: Any ): # type: (...) -> ItemPaged[ChatParticipant] """Gets the participants of a thread. @@ -501,8 +489,8 @@ def list_participants( max_page_size=results_per_page, skip=skip, cls=lambda objs: [ChatParticipant._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) - + **kwargs + ) @distributed_trace def add_participants( @@ -538,14 +526,12 @@ def add_participants( add_thread_participants_request = AddChatParticipantsRequest(participants=participants) add_chat_participants_result = self._client.chat_thread.add_chat_participants( - chat_thread_id=self._thread_id, - add_chat_participants_request=add_thread_participants_request, - **kwargs) + chat_thread_id=self._thread_id, add_chat_participants_request=add_thread_participants_request, **kwargs + ) - if hasattr(add_chat_participants_result, 'invalid_participants'): + if hasattr(add_chat_participants_result, "invalid_participants"): response = CommunicationErrorResponseConverter.convert( - participants=thread_participants, - chat_errors=add_chat_participants_result.invalid_participants + participants=thread_participants, chat_errors=add_chat_participants_result.invalid_participants ) return response @@ -579,7 +565,8 @@ def remove_participant( return self._client.chat_thread.remove_chat_participant( chat_thread_id=self._thread_id, participant_communication_identifier=serialize_identifier(identifier), - **kwargs) + **kwargs + ) def close(self): # type: () -> None diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_communication_identifier_serializer.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_communication_identifier_serializer.py index 26dc8a19eaea..6b08da1d07ea 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_communication_identifier_serializer.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_communication_identifier_serializer.py @@ -11,7 +11,7 @@ PhoneNumberIdentifier, MicrosoftTeamsUserIdentifier, UnknownIdentifier, - CommunicationIdentifierKind + CommunicationIdentifierKind, ) if TYPE_CHECKING: @@ -28,13 +28,15 @@ def serialize_identifier(identifier): :rtype: ~azure.communication.chat._generated.models.CommunicationIdentifierModel """ try: - request_model = {'raw_id': identifier.raw_id} + request_model = {"raw_id": identifier.raw_id} if identifier.kind and identifier.kind != CommunicationIdentifierKind.UNKNOWN: request_model[identifier.kind] = dict(identifier.properties) return request_model except AttributeError: - raise TypeError("Unsupported identifier type " + identifier.__class__.__name__) # pylint: disable=raise-missing-from + raise TypeError( # pylint: disable=raise-missing-from + "Unsupported identifier type " + identifier.__class__.__name__ + ) def deserialize_identifier(identifier_model): @@ -58,6 +60,6 @@ def deserialize_identifier(identifier_model): raw_id=raw_id, user_id=identifier_model.microsoft_teams_user.user_id, is_anonymous=identifier_model.microsoft_teams_user.is_anonymous, - cloud=identifier_model.microsoft_teams_user.cloud + cloud=identifier_model.microsoft_teams_user.cloud, ) return UnknownIdentifier(raw_id) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_models.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_models.py index 7d5313d6b37d..c4bcf2d8d77a 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_models.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_models.py @@ -54,16 +54,17 @@ def _from_generated(cls, chat_thread_participant): return cls( identifier=deserialize_identifier(chat_thread_participant.communication_identifier), display_name=chat_thread_participant.display_name, - share_history_time=chat_thread_participant.share_history_time + share_history_time=chat_thread_participant.share_history_time, ) def _to_generated(self): return ChatParticipantAutorest( communication_identifier=serialize_identifier(self.identifier), display_name=self.display_name, - share_history_time=self.share_history_time + share_history_time=self.share_history_time, ) + class ChatAttachment: """An attachment in a chat message. @@ -81,15 +82,12 @@ class ChatAttachment: :vartype preview_url: str or None """ - def __init__( - self, - **kwargs: Any - ) -> None: - self.id = kwargs['id'] - self.attachment_type = kwargs['attachment_type'] - self.name = kwargs.get('name', None) - self.url = kwargs.get('url', None) - self.preview_url = kwargs.get('preview_url', None) + def __init__(self, **kwargs: Any) -> None: + self.id = kwargs["id"] + self.attachment_type = kwargs["attachment_type"] + self.name = kwargs.get("name", None) + self.url = kwargs.get("url", None) + self.preview_url = kwargs.get("preview_url", None) @classmethod def _from_generated(cls, chat_attachment): @@ -98,11 +96,11 @@ def _from_generated(cls, chat_attachment): attachment_type=chat_attachment.attachment_type, name=chat_attachment.name, url=chat_attachment.url, - preview_url=chat_attachment.preview_url + preview_url=chat_attachment.preview_url, ) -class ChatMessage: # pylint: disable=too-many-instance-attributes +class ChatMessage: # pylint: disable=too-many-instance-attributes """Chat message. Variables are only populated by the server, and will be ignored when sending a request. @@ -133,21 +131,18 @@ class ChatMessage: # pylint: disable=too-many-instance-attributes :vartype metadata: dict[str, str] or None """ - def __init__( - self, - **kwargs: Any - ) -> None: - self.id = kwargs['id'] - self.type = kwargs['type'] - self.sequence_id = kwargs['sequence_id'] - self.version = kwargs['version'] - self.content = kwargs['content'] - self.sender_display_name = kwargs['sender_display_name'] - self.created_on = kwargs['created_on'] - self.sender = kwargs['sender'] - self.deleted_on = kwargs['deleted_on'] - self.edited_on = kwargs['edited_on'] - self.metadata = kwargs.get('metadata') + def __init__(self, **kwargs: Any) -> None: + self.id = kwargs["id"] + self.type = kwargs["type"] + self.sequence_id = kwargs["sequence_id"] + self.version = kwargs["version"] + self.content = kwargs["content"] + self.sender_display_name = kwargs["sender_display_name"] + self.created_on = kwargs["created_on"] + self.sender = kwargs["sender"] + self.deleted_on = kwargs["deleted_on"] + self.edited_on = kwargs["edited_on"] + self.metadata = kwargs.get("metadata") @classmethod def _from_generated(cls, chat_message): @@ -159,7 +154,11 @@ def _from_generated(cls, chat_message): message_type = ChatMessageType(chat_message.type) except ValueError: message_type = chat_message.type - content = ChatMessageContent._from_generated(chat_message.content) if chat_message.content else None # pylint:disable=protected-access + content = ( + ChatMessageContent._from_generated(chat_message.content) # pylint:disable=protected-access + if chat_message.content + else None + ) return cls( id=chat_message.id, type=message_type, @@ -171,7 +170,7 @@ def _from_generated(cls, chat_message): sender=sender_communication_identifier, deleted_on=chat_message.deleted_on, edited_on=chat_message.edited_on, - metadata=chat_message.metadata + metadata=chat_message.metadata, ) @@ -192,23 +191,20 @@ class ChatMessageContent: :vartype attachments: List[~azure.communication.chat.ChatAttachment] """ - def __init__( - self, - **kwargs: Any - ) -> None: - self.message = kwargs.get('message', None) - self.topic = kwargs.get('topic', None) - self.participants = kwargs.get('participants', None) - self.initiator = kwargs.get('initiator', None) - self.attachments = kwargs.get('attachments', None) + def __init__(self, **kwargs: Any) -> None: + self.message = kwargs.get("message", None) + self.topic = kwargs.get("topic", None) + self.participants = kwargs.get("participants", None) + self.initiator = kwargs.get("initiator", None) + self.attachments = kwargs.get("attachments", None) @classmethod def _from_generated(cls, chat_message_content): participants_list = chat_message_content.participants if participants_list: participants = [ - ChatParticipant._from_generated(participant) for participant in # pylint:disable=protected-access - participants_list + ChatParticipant._from_generated(participant) # pylint:disable=protected-access + for participant in participants_list ] else: participants = [] @@ -216,8 +212,8 @@ def _from_generated(cls, chat_message_content): attachments_list = chat_message_content.attachments if attachments_list: attachments = [ - ChatAttachment._from_generated(attachment) for attachment in # pylint:disable=protected-access - attachments_list + ChatAttachment._from_generated(attachment) # pylint:disable=protected-access + for attachment in attachments_list ] else: attachments = [] @@ -232,7 +228,7 @@ def _from_generated(cls, chat_message_content): topic=chat_message_content.topic, participants=participants, initiator=initiator, - attachments=attachments + attachments=attachments, ) @@ -253,14 +249,11 @@ class ChatThreadProperties: # pylint:disable=protected-access - def __init__( - self, - **kwargs: Any - ) -> None: - self.id = kwargs['id'] - self.topic = kwargs.get('topic', None) - self.created_on = kwargs['created_on'] - self.created_by = kwargs['created_by'] + def __init__(self, **kwargs: Any) -> None: + self.id = kwargs["id"] + self.topic = kwargs.get("topic", None) + self.created_on = kwargs["created_on"] + self.created_by = kwargs["created_by"] @classmethod def _from_generated(cls, chat_thread): @@ -269,12 +262,7 @@ def _from_generated(cls, chat_thread): if created_by is not None: created_by = deserialize_identifier(chat_thread.created_by_communication_identifier) - return cls( - id=chat_thread.id, - topic=chat_thread.topic, - created_on=chat_thread.created_on, - created_by=created_by - ) + return cls(id=chat_thread.id, topic=chat_thread.topic, created_on=chat_thread.created_on, created_by=created_by) class ChatMessageReadReceipt: @@ -291,13 +279,10 @@ class ChatMessageReadReceipt: :vartype read_on: ~datetime.datetime """ - def __init__( - self, - **kwargs: Any - ) -> None: - self.sender = kwargs['sender'] - self.chat_message_id = kwargs['chat_message_id'] - self.read_on = kwargs['read_on'] + def __init__(self, **kwargs: Any) -> None: + self.sender = kwargs["sender"] + self.chat_message_id = kwargs["chat_message_id"] + self.read_on = kwargs["read_on"] @classmethod def _from_generated(cls, read_receipt): @@ -305,11 +290,8 @@ def _from_generated(cls, read_receipt): if sender is not None: sender = deserialize_identifier(read_receipt.sender_communication_identifier) - return cls( - sender=sender, - chat_message_id=read_receipt.chat_message_id, - read_on=read_receipt.read_on - ) + return cls(sender=sender, chat_message_id=read_receipt.chat_message_id, read_on=read_receipt.read_on) + class CreateChatThreadResult: """Result of the create chat thread operation. @@ -320,9 +302,6 @@ class CreateChatThreadResult: :vartype errors: List[Tuple[~azure.communication.chat.ChatParticipant, ~azure.communication.chat.ChatError]] or None """ - def __init__( - self, - **kwargs: Any - ) -> None: - self.chat_thread = kwargs['chat_thread'] - self.errors = kwargs.get('errors', None) + def __init__(self, **kwargs: Any) -> None: + self.chat_thread = kwargs["chat_thread"] + self.errors = kwargs.get("errors", None) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/auth_policy_utils.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/auth_policy_utils.py index 3b0520c68412..76ee393bc94f 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/auth_policy_utils.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/auth_policy_utils.py @@ -43,9 +43,7 @@ def get_authentication_policy( return AsyncBearerTokenCredentialPolicy( credential, "https://communication.azure.com//.default" # type: ignore ) - return BearerTokenCredentialPolicy( - credential, "https://communication.azure.com//.default" # type: ignore - ) + return BearerTokenCredentialPolicy(credential, "https://communication.azure.com//.default") # type: ignore if isinstance(credential, (AzureKeyCredential, str)): return HMACCredentialsPolicy(endpoint, credential, decode_url=decode_url) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/models.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/models.py index 7b646472045c..43875e1197e5 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/models.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/models.py @@ -14,8 +14,11 @@ class DeprecatedEnumMeta(CaseInsensitiveEnumMeta): def __getattribute__(cls, item): if item.upper() == "MICROSOFT_BOT": - warnings.warn("MICROSOFT_BOT is deprecated and has been replaced by \ - MICROSOFT_TEAMS_APP identifier.", DeprecationWarning) + warnings.warn( + "MICROSOFT_BOT is deprecated and has been replaced by \ + MICROSOFT_TEAMS_APP identifier.", + DeprecationWarning, + ) item = "MICROSOFT_TEAMS_APP" return super().__getattribute__(item) @@ -47,14 +50,17 @@ class CommunicationCloudEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta @runtime_checkable class CommunicationIdentifier(Protocol): """Communication Identifier.""" + @property def raw_id(self) -> str: """The raw ID of the identifier.""" ... + @property def kind(self) -> CommunicationIdentifierKind: """The type of identifier.""" ... + @property def properties(self) -> Mapping[str, Any]: """The properties of the identifier.""" @@ -83,12 +89,14 @@ def properties(self) -> Mapping[str, Any]: class CommunicationUserProperties(TypedDict): """Dictionary of properties for a CommunicationUserIdentifier.""" + id: str """ID of the Communication user as returned from Azure Communication Identity.""" class CommunicationUserIdentifier: """Represents a user in Azure Communication Service.""" + kind: Literal[CommunicationIdentifierKind.COMMUNICATION_USER] = CommunicationIdentifierKind.COMMUNICATION_USER """The type of identifier.""" properties: CommunicationUserProperties @@ -116,12 +124,14 @@ def __eq__(self, other): class PhoneNumberProperties(TypedDict): """Dictionary of properties for a PhoneNumberIdentifier.""" + value: str """The phone number in E.164 format.""" class PhoneNumberIdentifier: """Represents a phone number.""" + kind: Literal[CommunicationIdentifierKind.PHONE_NUMBER] = CommunicationIdentifierKind.PHONE_NUMBER """The type of identifier.""" properties: PhoneNumberProperties @@ -165,6 +175,7 @@ class UnknownIdentifier: It is not advisable to rely on the `kind` property with a value `unknown`, as it could become a new or existing distinct type in the future. """ + kind: Literal[CommunicationIdentifierKind.UNKNOWN] = CommunicationIdentifierKind.UNKNOWN """The type of identifier.""" properties: Mapping[str, Any] @@ -188,6 +199,7 @@ def __eq__(self, other): class MicrosoftTeamsUserProperties(TypedDict): """Dictionary of properties for a MicrosoftTeamsUserIdentifier.""" + 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 @@ -198,6 +210,7 @@ class MicrosoftTeamsUserProperties(TypedDict): class MicrosoftTeamsUserIdentifier: """Represents an identifier for a Microsoft Teams user.""" + kind: Literal[CommunicationIdentifierKind.MICROSOFT_TEAMS_USER] = CommunicationIdentifierKind.MICROSOFT_TEAMS_USER """The type of identifier.""" properties: MicrosoftTeamsUserProperties @@ -246,6 +259,7 @@ def _format_raw_id(self, properties: MicrosoftTeamsUserProperties) -> str: class MicrosoftTeamsAppProperties(TypedDict): """Dictionary of properties for a MicrosoftTeamsAppIdentifier.""" + app_id: str """The id of the Microsoft Teams application.""" cloud: Union[CommunicationCloudEnvironment, str] @@ -254,6 +268,7 @@ class MicrosoftTeamsAppProperties(TypedDict): class _botbackcompatdict(dict): """Backwards compatible properties.""" + def __getitem__(self, __key: Any) -> Any: try: return super().__getitem__(__key) @@ -267,6 +282,7 @@ def __getitem__(self, __key: Any) -> Any: class MicrosoftTeamsAppIdentifier: """Represents an identifier for a Microsoft Teams application.""" + kind: Literal[CommunicationIdentifierKind.MICROSOFT_TEAMS_APP] = CommunicationIdentifierKind.MICROSOFT_TEAMS_APP """The type of identifier.""" properties: MicrosoftTeamsAppProperties @@ -282,10 +298,13 @@ def __init__(self, app_id: str, **kwargs: Any) -> None: :keyword str raw_id: The raw ID of the identifier. If not specified, this value will be constructed from the other properties. """ - self.properties = cast(MicrosoftTeamsAppProperties, _botbackcompatdict( - app_id=app_id, - cloud=kwargs.get("cloud") or CommunicationCloudEnvironment.PUBLIC, - )) + self.properties = cast( + MicrosoftTeamsAppProperties, + _botbackcompatdict( + app_id=app_id, + cloud=kwargs.get("cloud") or CommunicationCloudEnvironment.PUBLIC, + ), + ) raw_id: Optional[str] = kwargs.get("raw_id") self.raw_id = raw_id if raw_id is not None else self._format_raw_id(self.properties) @@ -323,7 +342,7 @@ def __init__(self, bot_id, **kwargs): """ warnings.warn( "The MicrosoftBotIdentifier is deprecated and has been replaced by MicrosoftTeamsAppIdentifier.", - DeprecationWarning + DeprecationWarning, ) super().__init__(bot_id, **kwargs) @@ -339,9 +358,7 @@ def identifier_from_raw_id(raw_id: str) -> CommunicationIdentifier: # pylint: d :rtype: CommunicationIdentifier """ if raw_id.startswith(PHONE_NUMBER_PREFIX): - return PhoneNumberIdentifier( - value=raw_id[len(PHONE_NUMBER_PREFIX) :], raw_id=raw_id - ) + return PhoneNumberIdentifier(value=raw_id[len(PHONE_NUMBER_PREFIX) :], raw_id=raw_id) segments = raw_id.split(":", maxsplit=2) if len(segments) < 3: @@ -350,9 +367,7 @@ def identifier_from_raw_id(raw_id: str) -> CommunicationIdentifier: # pylint: d prefix = f"{segments[0]}:{segments[1]}:" suffix = segments[2] if prefix == TEAMS_USER_ANONYMOUS_PREFIX: - return MicrosoftTeamsUserIdentifier( - user_id=suffix, is_anonymous=True, raw_id=raw_id - ) + return MicrosoftTeamsUserIdentifier(user_id=suffix, is_anonymous=True, raw_id=raw_id) if prefix == TEAMS_USER_PUBLIC_CLOUD_PREFIX: return MicrosoftTeamsUserIdentifier( user_id=suffix, diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/policy.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/policy.py index 2fd2e7426c73..79aa48136fd3 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/policy.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/policy.py @@ -50,9 +50,7 @@ def _compute_hmac( else: decoded_secret = base64.b64decode(self._access_key) - digest = hmac.new( - decoded_secret, value.encode("utf-8"), hashlib.sha256 - ).digest() + digest = hmac.new(decoded_secret, value.encode("utf-8"), hashlib.sha256).digest() return base64.b64encode(digest).decode("utf-8") @@ -101,22 +99,10 @@ def _sign_request(self, request): utc_now = get_current_utc_time() if request.http_request.body is None: request.http_request.body = "" - content_digest = hashlib.sha256( - (request.http_request.body.encode("utf-8")) - ).digest() + content_digest = hashlib.sha256((request.http_request.body.encode("utf-8"))).digest() content_hash = base64.b64encode(content_digest).decode("utf-8") - string_to_sign = ( - verb - + "\n" - + query_url - + "\n" - + utc_now - + ";" - + self._host - + ";" - + content_hash - ) + string_to_sign = verb + "\n" + query_url + "\n" + utc_now + ";" + self._host + ";" + content_hash signature = self._compute_hmac(string_to_sign) @@ -124,10 +110,7 @@ def _sign_request(self, request): "x-ms-date": utc_now, "x-ms-content-sha256": content_hash, "x-ms-return-client-request-id": "true", - "Authorization": "HMAC-SHA256 SignedHeaders=" - + signed_headers - + "&Signature=" - + signature, + "Authorization": "HMAC-SHA256 SignedHeaders=" + signed_headers + "&Signature=" + signature, } request.http_request.headers.update(signature_header) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential.py index 4ca8378f6247..b6feb869d944 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential.py @@ -39,9 +39,7 @@ def __init__(self, token: str, **kwargs: Any): self._token_refresher = kwargs.pop("token_refresher", None) self._proactive_refresh = kwargs.pop("proactive_refresh", False) if self._proactive_refresh and self._token_refresher is None: - raise ValueError( - "When 'proactive_refresh' is True, 'token_refresher' must not be None." - ) + raise ValueError("When 'proactive_refresh' is True, 'token_refresher' must not be None.") self._timer = None self._lock = Condition(Lock()) self._some_thread_refreshing = False @@ -55,9 +53,7 @@ def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument :rtype: ~azure.core.credentials.AccessToken """ if self._proactive_refresh and self._is_closed.is_set(): - raise RuntimeError( - "An instance of CommunicationTokenCredential cannot be reused once it has been closed." - ) + raise RuntimeError("An instance of CommunicationTokenCredential cannot be reused once it has been closed.") if not self._token_refresher or not self._is_token_expiring_soon(self._token): return self._token @@ -81,9 +77,7 @@ def _update_token_and_reschedule(self): try: new_token = self._token_refresher() if not self._is_token_valid(new_token): - raise ValueError( - "The token returned from the token_refresher is expired." - ) + raise ValueError("The token returned from the token_refresher is expired.") with self._lock: self._token = new_token self._some_thread_refreshing = False @@ -110,12 +104,7 @@ def _schedule_refresh(self): timespan = token_ttl // 2 else: # Schedule the next refresh for when it gets in to the soon-to-expire window. - timespan = ( - token_ttl - - timedelta( - minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES - ).total_seconds() - ) + timespan = token_ttl - timedelta(minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES).total_seconds() if timespan <= TIMEOUT_MAX: self._timer = Timer(timespan, self._update_token_and_reschedule) self._timer.daemon = True diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential_async.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential_async.py index 2abd1a063d7a..2537ab7d5532 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential_async.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/user_credential_async.py @@ -41,9 +41,7 @@ def __init__(self, token: str, **kwargs: Any): self._token_refresher = kwargs.pop("token_refresher", None) self._proactive_refresh = kwargs.pop("proactive_refresh", False) if self._proactive_refresh and self._token_refresher is None: - raise ValueError( - "When 'proactive_refresh' is True, 'token_refresher' must not be None." - ) + raise ValueError("When 'proactive_refresh' is True, 'token_refresher' must not be None.") self._timer = None self._async_mutex = Lock() if sys.version_info[:3] == (3, 10, 0): @@ -62,9 +60,7 @@ async def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument :rtype: ~azure.core.credentials.AccessToken """ if self._proactive_refresh and self._is_closed.is_set(): - raise RuntimeError( - "An instance of CommunicationTokenCredential cannot be reused once it has been closed." - ) + raise RuntimeError("An instance of CommunicationTokenCredential cannot be reused once it has been closed.") if not self._token_refresher or not self._is_token_expiring_soon(self._token): return self._token @@ -88,9 +84,7 @@ async def _update_token_and_reschedule(self): try: new_token = await self._token_refresher() if not self._is_token_valid(new_token): - raise ValueError( - "The token returned from the token_refresher is expired." - ) + raise ValueError("The token returned from the token_refresher is expired.") async with self._lock: self._token = new_token self._some_thread_refreshing = False @@ -117,12 +111,7 @@ def _schedule_refresh(self): timespan = token_ttl // 2 else: # Schedule the next refresh for when it gets in to the soon-to-expire window. - timespan = ( - token_ttl - - timedelta( - minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES - ).total_seconds() - ) + timespan = token_ttl - timedelta(minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES).total_seconds() self._timer = AsyncTimer(timespan, self._update_token_and_reschedule) self._timer.start() diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/utils.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/utils.py index 47da8a283e5f..8576c31ddc56 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/utils.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_shared/utils.py @@ -87,9 +87,7 @@ def create_access_token(token): payload = json.loads(padded_base64_payload) return AccessToken( token, - _convert_datetime_to_utc_int( - datetime.fromtimestamp(payload["exp"], TZ_UTC) - ), + _convert_datetime_to_utc_int(datetime.fromtimestamp(payload["exp"], TZ_UTC)), ) except ValueError as val_error: raise ValueError(token_parse_err_msg) from val_error diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/_utils.py b/sdk/communication/azure-communication-chat/azure/communication/chat/_utils.py index 611404fcfabb..c4dc8b52b098 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/_utils.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/_utils.py @@ -6,7 +6,7 @@ def _to_utc_datetime(value): - return value.strftime('%Y-%m-%dT%H:%M:%SZ') + return value.strftime("%Y-%m-%dT%H:%M:%SZ") def return_response(response, deserialized, _): # pylint: disable=unused-argument @@ -39,6 +39,7 @@ def convert(cls, participants, chat_errors): :return: A list of (ChatParticipant, ChatError) :rtype: list[(~azure.communication.chat.ChatParticipant, ~azure.communication.chat.ChatError)] """ + def create_dict(participants): # type: (...) -> Dict(str, ChatThreadParticipant) """ @@ -50,7 +51,7 @@ def create_dict(participants): """ result = {} for participant in participants: - result[participant.identifier.properties['id']] = participant + result[participant.identifier.properties["id"]] = participant return result _thread_participants_dict = create_dict(participants=participants) diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/__init__.py b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/__init__.py index ebda8b1a392f..7d42815d42e6 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/__init__.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/__init__.py @@ -5,8 +5,5 @@ from ._chat_client_async import ChatClient from ._chat_thread_client_async import ChatThreadClient from .._shared.user_credential_async import CommunicationTokenCredential -__all__ = [ - "ChatClient", - "ChatThreadClient", - "CommunicationTokenCredential" -] + +__all__ = ["ChatClient", "ChatThreadClient", "CommunicationTokenCredential"] diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_client_async.py b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_client_async.py index b2e59da2496b..8761951a38da 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_client_async.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_client_async.py @@ -19,24 +19,17 @@ from ._chat_thread_client_async import ChatThreadClient from .._shared.user_credential_async import CommunicationTokenCredential from .._generated.aio import AzureCommunicationChatService -from .._generated.models import ( - CreateChatThreadRequest, - ChatThreadItem -) -from .._models import ( - ChatThreadProperties, - ChatParticipant, - CreateChatThreadResult -) -from .._utils import ( # pylint: disable=unused-import +from .._generated.models import CreateChatThreadRequest, ChatThreadItem +from .._models import ChatThreadProperties, ChatParticipant, CreateChatThreadResult +from .._utils import ( # pylint: disable=unused-import _to_utc_datetime, return_response, - CommunicationErrorResponseConverter + CommunicationErrorResponseConverter, ) from .._version import SDK_MONIKER -class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword +class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword """A client to interact with the AzureCommunicationService Chat gateway. This client provides operations to create chat thread, delete chat thread, @@ -57,21 +50,17 @@ class ChatClient(object): # pylint: disable=client-accepts-api-version-keyword :caption: Creating the ChatClient from a URL and token. """ - def __init__( - self, endpoint: str, - credential: CommunicationTokenCredential, - **kwargs: Any - ) -> None: + def __init__(self, endpoint: str, credential: CommunicationTokenCredential, **kwargs: Any) -> None: if not credential: raise ValueError("credential can not be None") try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from + raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from - parsed_url = urlparse(endpoint.rstrip('/')) + parsed_url = urlparse(endpoint.rstrip("/")) if not parsed_url.netloc: raise ValueError("Invalid URL: {}".format(endpoint)) @@ -82,13 +71,11 @@ def __init__( endpoint=self._endpoint, authentication_policy=AsyncBearerTokenCredentialPolicy(self._credential), sdk_moniker=SDK_MONIKER, - **kwargs) + **kwargs + ) @distributed_trace - def get_chat_thread_client( - self, thread_id: str, - **kwargs: Any - ) -> ChatThreadClient: + def get_chat_thread_client(self, thread_id: str, **kwargs: Any) -> ChatThreadClient: """ Get ChatThreadClient by providing a thread_id. @@ -110,18 +97,10 @@ def get_chat_thread_client( if not thread_id: raise ValueError("thread_id cannot be None.") - return ChatThreadClient( - endpoint=self._endpoint, - credential=self._credential, - thread_id=thread_id, - **kwargs - ) + return ChatThreadClient(endpoint=self._endpoint, credential=self._credential, thread_id=thread_id, **kwargs) @distributed_trace_async - async def create_chat_thread( - self, topic: str, - **kwargs - ) -> CreateChatThreadResult: + async def create_chat_thread(self, topic: str, **kwargs) -> CreateChatThreadResult: """Creates a chat thread. :param topic: Required. The thread topic. @@ -151,46 +130,37 @@ async def create_chat_thread( if not topic: raise ValueError("topic cannot be None.") - idempotency_token = kwargs.pop('idempotency_token', None) + idempotency_token = kwargs.pop("idempotency_token", None) if idempotency_token is None: idempotency_token = str(uuid4()) - thread_participants = kwargs.pop('thread_participants', None) + thread_participants = kwargs.pop("thread_participants", None) participants = [] if thread_participants is not None: participants = [m._to_generated() for m in thread_participants] # pylint:disable=protected-access - create_thread_request = \ - CreateChatThreadRequest(topic=topic, participants=participants) + create_thread_request = CreateChatThreadRequest(topic=topic, participants=participants) create_chat_thread_result = await self._client.chat.create_chat_thread( - create_chat_thread_request=create_thread_request, - repeatability_request_id=idempotency_token, - **kwargs) + create_chat_thread_request=create_thread_request, repeatability_request_id=idempotency_token, **kwargs + ) errors = None - if hasattr(create_chat_thread_result, 'invalid_participants'): + if hasattr(create_chat_thread_result, "invalid_participants"): errors = CommunicationErrorResponseConverter.convert( - participants=thread_participants or [], - chat_errors=create_chat_thread_result.invalid_participants + participants=thread_participants or [], chat_errors=create_chat_thread_result.invalid_participants ) - chat_thread = ChatThreadProperties._from_generated( # pylint:disable=protected-access - create_chat_thread_result.chat_thread) - - create_chat_thread_result = CreateChatThreadResult( - chat_thread=chat_thread, - errors=errors + chat_thread = ChatThreadProperties._from_generated( # pylint:disable=protected-access + create_chat_thread_result.chat_thread ) - return create_chat_thread_result + create_chat_thread_result = CreateChatThreadResult(chat_thread=chat_thread, errors=errors) + return create_chat_thread_result @distributed_trace - def list_chat_threads( - self, - **kwargs: Any - ) -> AsyncItemPaged[ChatThreadItem]: + def list_chat_threads(self, **kwargs: Any) -> AsyncItemPaged[ChatThreadItem]: """Gets the list of chat threads of a user. :keyword int results_per_page: The maximum number of chat threads to be returned per page. @@ -211,17 +181,10 @@ def list_chat_threads( results_per_page = kwargs.pop("results_per_page", None) start_time = kwargs.pop("start_time", None) - return self._client.chat.list_chat_threads( - max_page_size=results_per_page, - start_time=start_time, - **kwargs) + return self._client.chat.list_chat_threads(max_page_size=results_per_page, start_time=start_time, **kwargs) @distributed_trace_async - async def delete_chat_thread( - self, - thread_id: str, - **kwargs - ) -> None: + async def delete_chat_thread(self, thread_id: str, **kwargs) -> None: """Deletes a chat thread. :param thread_id: Required. Thread id to delete. diff --git a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_thread_client_async.py b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_thread_client_async.py index 5fb0ffa4b523..a4ac904ba28a 100644 --- a/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_thread_client_async.py +++ b/sdk/communication/azure-communication-chat/azure/communication/chat/aio/_chat_thread_client_async.py @@ -25,21 +25,16 @@ UpdateChatThreadRequest, SendChatMessageResult, ChatMessageType, - ChatError -) -from .._models import ( - ChatParticipant, - ChatMessage, - ChatMessageReadReceipt, - ChatThreadProperties + ChatError, ) +from .._models import ChatParticipant, ChatMessage, ChatMessageReadReceipt, ChatThreadProperties from .._shared.models import CommunicationIdentifier from .._communication_identifier_serializer import serialize_identifier from .._utils import CommunicationErrorResponseConverter from .._version import SDK_MONIKER -class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-keyword +class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-keyword """A client to interact with the AzureCommunicationService Chat gateway. Instances of this class is normally retrieved by ChatClient.get_chat_thread_client() @@ -68,13 +63,7 @@ class ChatThreadClient(object): # pylint: disable=client-accepts-api-version-key :caption: Creating the ChatThreadClient. """ - def __init__( - self, - endpoint: str, - credential: CommunicationTokenCredential, - thread_id: str, - **kwargs: Any - ) -> None: + def __init__(self, endpoint: str, credential: CommunicationTokenCredential, thread_id: str, **kwargs: Any) -> None: if not thread_id: raise ValueError("thread_id can not be None or empty") @@ -82,12 +71,12 @@ def __init__( raise ValueError("credential can not be None") try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from + raise ValueError("Host URL must be a string") # pylint:disable=raise-missing-from - parsed_url = urlparse(endpoint.rstrip('/')) + parsed_url = urlparse(endpoint.rstrip("/")) if not parsed_url.netloc: raise ValueError("Invalid URL: {}".format(endpoint)) @@ -99,7 +88,8 @@ def __init__( endpoint=self._endpoint, authentication_policy=AsyncBearerTokenCredentialPolicy(self._credential), sdk_moniker=SDK_MONIKER, - **kwargs) + **kwargs + ) @property def thread_id(self) -> str: @@ -111,11 +101,7 @@ def thread_id(self) -> str: return self._thread_id @distributed_trace_async - async def get_properties( - self, - **kwargs - ) -> ChatThreadProperties: - + async def get_properties(self, **kwargs) -> ChatThreadProperties: """Gets the properties of the chat thread. :return: ChatThreadProperties @@ -135,13 +121,8 @@ async def get_properties( chat_thread = await self._client.chat_thread.get_chat_thread_properties(self._thread_id, **kwargs) return ChatThreadProperties._from_generated(chat_thread) # pylint:disable=protected-access - @distributed_trace_async - async def update_topic( - self, - topic: str = None, - **kwargs - ) -> None: + async def update_topic(self, topic: str = None, **kwargs) -> None: """Updates a thread's properties. :param topic: Thread topic. If topic is not specified, the update will succeed but @@ -163,16 +144,11 @@ async def update_topic( update_topic_request = UpdateChatThreadRequest(topic=topic) return await self._client.chat_thread.update_chat_thread_properties( - chat_thread_id=self._thread_id, - update_chat_thread_request=update_topic_request, - **kwargs) + chat_thread_id=self._thread_id, update_chat_thread_request=update_topic_request, **kwargs + ) @distributed_trace_async - async def send_read_receipt( - self, - message_id: str, - **kwargs - ) -> None: + async def send_read_receipt(self, message_id: str, **kwargs) -> None: """Posts a read receipt event to a chat thread, on behalf of a user. :param message_id: Required. Id of the latest message read by current user. @@ -195,15 +171,11 @@ async def send_read_receipt( post_read_receipt_request = SendReadReceiptRequest(chat_message_id=message_id) return await self._client.chat_thread.send_chat_read_receipt( - self._thread_id, - send_read_receipt_request=post_read_receipt_request, - **kwargs) + self._thread_id, send_read_receipt_request=post_read_receipt_request, **kwargs + ) @distributed_trace - def list_read_receipts( - self, - **kwargs: Any - ) -> AsyncItemPaged[ChatMessageReadReceipt]: + def list_read_receipts(self, **kwargs: Any) -> AsyncItemPaged[ChatMessageReadReceipt]: """Gets read receipts for a thread. :keyword int results_per_page: The maximum number of chat message read receipts to be returned per page. @@ -228,16 +200,14 @@ def list_read_receipts( self._thread_id, max_page_size=results_per_page, skip=skip, - cls=lambda objs: [ChatMessageReadReceipt._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) + cls=lambda objs: [ + ChatMessageReadReceipt._from_generated(x) for x in objs # pylint:disable=protected-access + ], + **kwargs + ) @distributed_trace_async - async def send_typing_notification( - self, - *, - sender_display_name: Optional[str] = None, - **kwargs - ) -> None: + async def send_typing_notification(self, *, sender_display_name: Optional[str] = None, **kwargs) -> None: """Posts a typing event to a thread, on behalf of a user. :keyword str sender_display_name: The display name of the typing notification sender. This property @@ -259,18 +229,11 @@ async def send_typing_notification( send_typing_notification_request = SendTypingNotificationRequest(sender_display_name=sender_display_name) return await self._client.chat_thread.send_typing_notification( - chat_thread_id=self._thread_id, - send_typing_notification_request=send_typing_notification_request, - **kwargs) + chat_thread_id=self._thread_id, send_typing_notification_request=send_typing_notification_request, **kwargs + ) @distributed_trace_async - async def send_message( - self, - content: str, - *, - metadata: Dict[str, str] = None, - **kwargs - ) -> SendChatMessageResult: + async def send_message(self, content: str, *, metadata: Dict[str, str] = None, **kwargs) -> SendChatMessageResult: """Sends a message to a thread. :param content: Required. Chat message content. @@ -304,34 +267,28 @@ async def send_message( try: chat_message_type = ChatMessageType.__getattr__(chat_message_type) # pylint:disable=protected-access except Exception: - raise ValueError( # pylint:disable=raise-missing-from - "chat_message_type: {message_type} is not acceptable".format(message_type=chat_message_type)) + raise ValueError( # pylint:disable=raise-missing-from + "chat_message_type: {message_type} is not acceptable".format(message_type=chat_message_type) + ) if chat_message_type not in [ChatMessageType.TEXT, ChatMessageType.HTML]: raise ValueError( - "chat_message_type: {message_type} can be only 'text' or 'html'".format(message_type=chat_message_type)) + "chat_message_type: {message_type} can be only 'text' or 'html'".format(message_type=chat_message_type) + ) sender_display_name = kwargs.pop("sender_display_name", None) create_message_request = SendChatMessageRequest( - content=content, - type=chat_message_type, - sender_display_name=sender_display_name, - metadata=metadata + content=content, type=chat_message_type, sender_display_name=sender_display_name, metadata=metadata ) send_chat_message_result = await self._client.chat_thread.send_chat_message( - chat_thread_id=self._thread_id, - send_chat_message_request=create_message_request, - **kwargs) + chat_thread_id=self._thread_id, send_chat_message_request=create_message_request, **kwargs + ) return send_chat_message_result @distributed_trace_async - async def get_message( - self, - message_id: str, - **kwargs - ) -> ChatMessage: + async def get_message(self, message_id: str, **kwargs) -> ChatMessage: """Gets a message by id. :param message_id: Required. The message id. @@ -356,10 +313,7 @@ async def get_message( return ChatMessage._from_generated(chat_message) # pylint:disable=protected-access @distributed_trace - def list_messages( - self, - **kwargs: Any - ) -> AsyncItemPaged[ChatMessage]: + def list_messages(self, **kwargs: Any) -> AsyncItemPaged[ChatMessage]: """Gets a list of messages from a thread. :keyword int results_per_page: The maximum number of messages to be returned per page. @@ -385,16 +339,12 @@ def list_messages( max_page_size=results_per_page, start_time=start_time, cls=lambda objs: [ChatMessage._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) + **kwargs + ) @distributed_trace_async async def update_message( - self, - message_id: str, - content: str = None, - *, - metadata: Dict[str, str] = None, - **kwargs + self, message_id: str, content: str = None, *, metadata: Dict[str, str] = None, **kwargs ) -> None: """Updates a message. @@ -424,14 +374,11 @@ async def update_message( chat_thread_id=self._thread_id, chat_message_id=message_id, update_chat_message_request=update_message_request, - **kwargs) + **kwargs + ) @distributed_trace_async - async def delete_message( - self, - message_id: str, - **kwargs - ) -> None: + async def delete_message(self, message_id: str, **kwargs) -> None: """Deletes a message. :param message_id: Required. The message id. @@ -453,15 +400,11 @@ async def delete_message( raise ValueError("message_id cannot be None.") return await self._client.chat_thread.delete_chat_message( - chat_thread_id=self._thread_id, - chat_message_id=message_id, - **kwargs) + chat_thread_id=self._thread_id, chat_message_id=message_id, **kwargs + ) @distributed_trace - def list_participants( - self, - **kwargs: Any - ) -> AsyncItemPaged[ChatParticipant]: + def list_participants(self, **kwargs: Any) -> AsyncItemPaged[ChatParticipant]: """Gets the participants of a thread. :keyword int results_per_page: The maximum number of participants to be returned per page. @@ -488,14 +431,12 @@ def list_participants( max_page_size=results_per_page, skip=skip, cls=lambda objs: [ChatParticipant._from_generated(x) for x in objs], # pylint:disable=protected-access - **kwargs) - + **kwargs + ) @distributed_trace_async async def add_participants( - self, - thread_participants: List[ChatParticipant], - **kwargs + self, thread_participants: List[ChatParticipant], **kwargs ) -> List[Tuple[ChatParticipant, ChatError]]: """Adds thread participants to a thread. If participants already exist, no change occurs. @@ -524,23 +465,17 @@ async def add_participants( add_thread_participants_request = AddChatParticipantsRequest(participants=participants) add_chat_participants_result = await self._client.chat_thread.add_chat_participants( - chat_thread_id=self._thread_id, - add_chat_participants_request=add_thread_participants_request, - **kwargs) + chat_thread_id=self._thread_id, add_chat_participants_request=add_thread_participants_request, **kwargs + ) - if hasattr(add_chat_participants_result, 'invalid_participants'): + if hasattr(add_chat_participants_result, "invalid_participants"): response = CommunicationErrorResponseConverter.convert( - participants=thread_participants, - chat_errors=add_chat_participants_result.invalid_participants + participants=thread_participants, chat_errors=add_chat_participants_result.invalid_participants ) return response @distributed_trace_async - async def remove_participant( - self, - identifier: CommunicationIdentifier, - **kwargs - ) -> None: + async def remove_participant(self, identifier: CommunicationIdentifier, **kwargs) -> None: """Remove a participant from a thread. :param identifier: Required. Identifier of the thread participant to remove from the thread. @@ -564,7 +499,8 @@ async def remove_participant( return await self._client.chat_thread.remove_chat_participant( chat_thread_id=self._thread_id, participant_communication_identifier=serialize_identifier(identifier), - **kwargs) + **kwargs + ) async def close(self) -> None: await self._client.close() diff --git a/sdk/communication/azure-communication-chat/samples/chat_client_sample.py b/sdk/communication/azure-communication-chat/samples/chat_client_sample.py index 050e12f8a8c5..ac7b43b698e9 100644 --- a/sdk/communication/azure-communication-chat/samples/chat_client_sample.py +++ b/sdk/communication/azure-communication-chat/samples/chat_client_sample.py @@ -1,4 +1,3 @@ - # ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for @@ -28,6 +27,7 @@ class ChatClientSamples(object): from azure.communication.identity import CommunicationIdentityClient + connection_string = os.environ.get("COMMUNICATION_SAMPLES_CONNECTION_STRING", None) if not connection_string: raise ValueError("Set COMMUNICATION_SAMPLES_CONNECTION_STRING env before run this sample.") @@ -60,32 +60,26 @@ def create_thread(self): # [START create_thread] from datetime import datetime - from azure.communication.chat import( + from azure.communication.chat import ( ChatClient, ChatParticipant, CommunicationUserIdentifier, - CommunicationTokenCredential + CommunicationTokenCredential, ) # set `endpoint` to an existing ACS endpoint chat_client = ChatClient(endpoint, CommunicationTokenCredential(token)) topic = "test topic" - participants = [ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] # creates a new chat_thread everytime create_chat_thread_result = chat_client.create_chat_thread(topic, thread_participants=participants) # creates a new chat_thread if not exists - idempotency_token = 'b66d6031-fdcc-41df-8306-e524c9f226b8' # unique identifier + idempotency_token = "b66d6031-fdcc-41df-8306-e524c9f226b8" # unique identifier create_chat_thread_result_w_repeatability_id = chat_client.create_chat_thread( - topic, - thread_participants=participants, - idempotency_token=idempotency_token + topic, thread_participants=participants, idempotency_token=idempotency_token ) # [END create_thread] @@ -109,7 +103,6 @@ def get_chat_thread_client(self): print("get_chat_thread_client succeeded with thread id: ", chat_thread_client.thread_id) - def list_threads(self): token = self.token endpoint = self.endpoint @@ -150,7 +143,7 @@ def clean_up(self): self.identity_client.delete_user(self.user) -if __name__ == '__main__': +if __name__ == "__main__": sample = ChatClientSamples() sample.create_chat_client() sample.create_thread() diff --git a/sdk/communication/azure-communication-chat/samples/chat_client_sample_async.py b/sdk/communication/azure-communication-chat/samples/chat_client_sample_async.py index 3ff971aa1e46..329e0f40a82a 100644 --- a/sdk/communication/azure-communication-chat/samples/chat_client_sample_async.py +++ b/sdk/communication/azure-communication-chat/samples/chat_client_sample_async.py @@ -1,4 +1,3 @@ - # ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for @@ -28,6 +27,7 @@ class ChatClientSamplesAsync(object): from azure.communication.identity import CommunicationIdentityClient + connection_string = os.environ.get("COMMUNICATION_SAMPLES_CONNECTION_STRING", None) if not connection_string: raise ValueError("Set COMMUNICATION_SAMPLES_CONNECTION_STRING env before run this sample.") @@ -71,20 +71,17 @@ async def create_thread_async(self): async with chat_client: topic = "test topic" - participants = [ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ + ChatParticipant(identifier=self.user, display_name="name", share_history_time=datetime.utcnow()) + ] # creates a new chat_thread everytime create_chat_thread_result = await chat_client.create_chat_thread(topic, thread_participants=participants) # creates a new chat_thread if not exists - idempotency_token = 'b66d6031-fdcc-41df-8306-e524c9f226b8' # unique identifier + idempotency_token = "b66d6031-fdcc-41df-8306-e524c9f226b8" # unique identifier create_chat_thread_result_w_repeatability_id = await chat_client.create_chat_thread( - topic, - thread_participants=participants, - idempotency_token=idempotency_token) + topic, thread_participants=participants, idempotency_token=idempotency_token + ) # [END create_thread] self._thread_id = create_chat_thread_result.chat_thread.id @@ -107,7 +104,6 @@ def get_chat_thread_client(self): print("chat_thread_client created with thread id: ", chat_thread_client.thread_id) - async def list_threads_async(self): token = self.token endpoint = self.endpoint @@ -121,6 +117,7 @@ async def list_threads_async(self): async with chat_client: from datetime import datetime, timedelta + start_time = datetime.utcnow() - timedelta(days=2) chat_threads = chat_client.list_chat_threads(results_per_page=5, start_time=start_time) print("list_threads succeeded with results_per_page is 5, and were created since 2 days ago.") @@ -142,7 +139,7 @@ async def delete_thread_async(self): async with chat_client: # set `thread_id` to an existing chat thread id await chat_client.delete_chat_thread(thread_id) - # [END delete_thread] + # [END delete_thread] print("delete_thread succeeded") def clean_up(self): @@ -159,5 +156,6 @@ async def main(): await sample.delete_thread_async() sample.clean_up() -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample.py b/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample.py index 158bc0539799..f4b816606145 100644 --- a/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample.py +++ b/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample.py @@ -28,10 +28,8 @@ class ChatThreadClientSamples(object): from azure.communication.identity import CommunicationIdentityClient - from azure.communication.chat import ( - ChatClient, - CommunicationTokenCredential - ) + from azure.communication.chat import ChatClient, CommunicationTokenCredential + connection_string = os.environ.get("COMMUNICATION_SAMPLES_CONNECTION_STRING", None) if not connection_string: raise ValueError("Set COMMUNICATION_SAMPLES_CONNECTION_STRING env before run this sample.") @@ -61,19 +59,16 @@ def create_chat_thread_client(self): ChatClient, ChatParticipant, CommunicationUserIdentifier, - CommunicationTokenCredential + CommunicationTokenCredential, ) + # retrieve `token` using CommunicationIdentityClient.get_token method # set `endpoint` to ACS service endpoint # create `user` using CommunicationIdentityClient.create_user method for new users; # else for existing users set `user` = CommunicationUserIdentifier(some_user_id) chat_client = ChatClient(endpoint, CommunicationTokenCredential(token)) topic = "test topic" - participants = [ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] create_chat_thread_result = chat_client.create_chat_thread(topic, thread_participants=participants) chat_thread_client = chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) # [END create_chat_thread_client] @@ -91,11 +86,15 @@ def get_chat_thread_properties(self): chat_client = ChatClient(endpoint, CommunicationTokenCredential(token)) chat_thread_client = chat_client.get_chat_thread_client(thread_id) chat_thread_properties = chat_thread_client.get_properties() - print('Expected Thread Id: ', thread_id, ' Actual Value: ', chat_thread_properties.id) + print("Expected Thread Id: ", thread_id, " Actual Value: ", chat_thread_properties.id) # [END get_thread] - print("get_chat_thread_properties succeeded, thread id: " + chat_thread.id + ", thread topic: " + chat_thread.topic) - + print( + "get_chat_thread_properties succeeded, thread id: " + + chat_thread.id + + ", thread topic: " + + chat_thread.topic + ) def update_topic(self): thread_id = self._thread_id @@ -127,15 +126,16 @@ def send_message(self): # Scenario 1: Send message without specifying chat_message_type send_message_result = chat_thread_client.send_message( - "Hello! My name is Fred Flinstone", - sender_display_name="Fred Flinstone") + "Hello! My name is Fred Flinstone", sender_display_name="Fred Flinstone" + ) send_message_result_id = send_message_result.id # Scenario 2: Send message specifying chat_message_type send_message_result_w_type = chat_thread_client.send_message( "Hello! My name is Wilma Flinstone", sender_display_name="Wilma Flinstone", - chat_message_type=ChatMessageType.TEXT) # equivalent to setting chat_message_type='text' + chat_message_type=ChatMessageType.TEXT, + ) # equivalent to setting chat_message_type='text' send_message_result_w_type_id = send_message_result_w_type.id # Verify message content print("First Message:", chat_thread_client.get_message(send_message_result_id).content.message) @@ -160,8 +160,7 @@ def get_message(self): print("Message received: ChatMessage: content=", chat_message.content.message, ", id=", chat_message.id) # [END get_message] - print("get_message succeeded, message id:", chat_message.id, \ - "content: ", chat_message.content.message) + print("get_message succeeded, message id:", chat_message.id, "content: ", chat_message.content.message) def list_messages(self): thread_id = self._thread_id @@ -272,7 +271,6 @@ def list_participants(self): # [END list_participants] print("list_participants succeeded") - def add_participants_w_check(self): # initially remove already added user thread_id = self._thread_id @@ -297,10 +295,7 @@ def decide_to_retry(error): # create `user` using CommunicationIdentityClient.create_user method for new users; # else for existing users set `user` = CommunicationUserIdentifier(some_user_id) - new_participant = ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow()) + new_participant = ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow()) # create list containing one or more participants thread_participants = [new_participant] @@ -313,8 +308,6 @@ def decide_to_retry(error): # [END add_participants] print("add_participants_w_check succeeded") - - def remove_participant(self): thread_id = self._thread_id chat_client = self._chat_client @@ -332,14 +325,12 @@ def remove_participant(self): # add user1 and user2 to chat thread participant1 = ChatParticipant( - identifier=user1, - display_name='Fred Flinstone', - share_history_time=datetime.utcnow()) + identifier=user1, display_name="Fred Flinstone", share_history_time=datetime.utcnow() + ) participant2 = ChatParticipant( - identifier=user2, - display_name='Wilma Flinstone', - share_history_time=datetime.utcnow()) + identifier=user2, display_name="Wilma Flinstone", share_history_time=datetime.utcnow() + ) thread_participants = [participant1, participant2] chat_thread_client.add_participants(thread_participants) @@ -351,14 +342,16 @@ def remove_participant(self): for chat_thread_participant_page in chat_thread_participants.by_page(): for chat_thread_participant in chat_thread_participant_page: print("ChatParticipant: ", chat_thread_participant) - if chat_thread_participant.identifier.properties['id'] == user1.properties['id']: + if chat_thread_participant.identifier.properties["id"] == user1.properties["id"]: print("Found Fred!") chat_thread_client.remove_participant(chat_thread_participant.identifier) print("Fred has been removed from the thread...") break # Option 2: Directly remove Wilma Flinstone - unique_identifier = user2.properties['id'] # in real scenario the identifier would need to be retrieved from elsewhere + unique_identifier = user2.properties[ + "id" + ] # in real scenario the identifier would need to be retrieved from elsewhere chat_thread_client.remove_participant(CommunicationUserIdentifier(unique_identifier)) print("Wilma has been removed from the thread...") # [END remove_participant] @@ -386,7 +379,8 @@ def clean_up(self): self.identity_client.delete_user(self.user) self.identity_client.delete_user(self.new_user) -if __name__ == '__main__': + +if __name__ == "__main__": sample = ChatThreadClientSamples() sample.create_chat_thread_client() sample.update_topic() diff --git a/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample_async.py b/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample_async.py index 94cdb1fba83a..cee02eb226e3 100644 --- a/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample_async.py +++ b/sdk/communication/azure-communication-chat/samples/chat_thread_client_sample_async.py @@ -58,16 +58,13 @@ async def create_chat_thread_client_async(self): from datetime import datetime from azure.communication.chat.aio import ChatClient, CommunicationTokenCredential from azure.communication.chat import ChatParticipant, CommunicationUserIdentifier + # set `endpoint` to an existing ACS endpoint chat_client = ChatClient(endpoint, CommunicationTokenCredential(token)) async with chat_client: topic = "test topic" - participants = [ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] create_chat_thread_result = await chat_client.create_chat_thread(topic, thread_participants=participants) chat_thread_client = chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) # [END create_chat_thread_client] @@ -90,11 +87,14 @@ async def get_chat_thread_properties_async(self): async with chat_thread_client: chat_thread_properties = chat_thread_client.get_properties() - print('Expected Thread Id: ', thread_id, ' Actual Value: ', chat_thread_properties.id) - # [END get_thread] - print("get_chat_thread_properties_async succeeded, thread id: " + chat_thread.id - + ", thread topic: " + chat_thread.topic) - + print("Expected Thread Id: ", thread_id, " Actual Value: ", chat_thread_properties.id) + # [END get_thread] + print( + "get_chat_thread_properties_async succeeded, thread id: " + + chat_thread.id + + ", thread topic: " + + chat_thread.topic + ) async def update_topic_async(self): thread_id = self._thread_id @@ -126,28 +126,32 @@ async def send_message_async(self): # [START send_message] from azure.communication.chat import ChatMessageType + async with chat_client: chat_thread_client = chat_client.get_chat_thread_client(thread_id=thread_id) async with chat_thread_client: # Scenario 1: Send message without specifying chat_message_type send_message_result = await chat_thread_client.send_message( - "Hello! My name is Fred Flinstone", - sender_display_name="Fred Flinstone", - metadata={"tags": "tags"}) + "Hello! My name is Fred Flinstone", sender_display_name="Fred Flinstone", metadata={"tags": "tags"} + ) send_message_result_id = send_message_result.id # Scenario 2: Send message specifying chat_message_type send_message_result_w_type = await chat_thread_client.send_message( "Hello! My name is Wilma Flinstone", sender_display_name="Wilma Flinstone", - chat_message_type=ChatMessageType.TEXT) # equivalent to setting chat_message_type='text' + chat_message_type=ChatMessageType.TEXT, + ) # equivalent to setting chat_message_type='text' send_message_result_w_type_id = send_message_result_w_type.id # Verify message content chat_message_1 = await chat_thread_client.get_message(send_message_result_id) print("First Message:", chat_message_1.content.message, chat_message_1.metadata) - print("Second Message:", (await chat_thread_client.get_message(send_message_result_w_type_id)).content.message) - # [END send_message] + print( + "Second Message:", + (await chat_thread_client.get_message(send_message_result_w_type_id)).content.message, + ) + # [END send_message] self._message_id = send_message_result_id print("send_message succeeded, message id:", self._message_id) print("send_message succeeded with type specified, message id:", send_message_result_w_type_id) @@ -176,6 +180,7 @@ async def list_messages_async(self): # [START list_messages] from datetime import datetime, timedelta + async with chat_client: # set `thread_id` to an existing thread id chat_thread_client = chat_client.get_chat_thread_client(thread_id=thread_id) @@ -281,7 +286,6 @@ async def list_participants_async(self): # [END list_participants] print("list_participants_async succeeded") - async def add_participants_w_check_async(self): thread_id = self._thread_id chat_client = self._chat_client @@ -300,10 +304,10 @@ def decide_to_retry(error): async with chat_thread_client: from azure.communication.chat import ChatParticipant from datetime import datetime + new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=datetime.utcnow()) + identifier=self.new_user, display_name="name", share_history_time=datetime.utcnow() + ) thread_participants = [new_participant] result = await chat_thread_client.add_participants(thread_participants) @@ -335,14 +339,12 @@ async def remove_participant_async(self): async with chat_thread_client: # add user1 and user2 to chat thread participant1 = ChatParticipant( - identifier=user1, - display_name='Fred Flinstone', - share_history_time=datetime.utcnow()) + identifier=user1, display_name="Fred Flinstone", share_history_time=datetime.utcnow() + ) participant2 = ChatParticipant( - identifier=user2, - display_name='Wilma Flinstone', - share_history_time=datetime.utcnow()) + identifier=user2, display_name="Wilma Flinstone", share_history_time=datetime.utcnow() + ) thread_participants = [participant1, participant2] await chat_thread_client.add_participants(thread_participants) @@ -353,14 +355,16 @@ async def remove_participant_async(self): async for chat_thread_participant_page in chat_thread_participants.by_page(): async for chat_thread_participant in chat_thread_participant_page: print("ChatParticipant: ", chat_thread_participant) - if chat_thread_participant.identifier.properties['id'] == user1.properties['id']: + if chat_thread_participant.identifier.properties["id"] == user1.properties["id"]: print("Found Fred!") await chat_thread_client.remove_participant(chat_thread_participant.identifier) print("Fred has been removed from the thread...") break # Option 2: Directly remove Wilma Flinstone - unique_identifier = user2.properties['id'] # in real scenario the identifier would need to be retrieved from elsewhere + unique_identifier = user2.properties[ + "id" + ] # in real scenario the identifier would need to be retrieved from elsewhere await chat_thread_client.remove_participant(CommunicationUserIdentifier(unique_identifier)) print("Wilma has been removed from the thread...") # [END remove_participant] @@ -405,5 +409,6 @@ async def main(): await sample.send_typing_notification_async() sample.clean_up() -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/communication/azure-communication-chat/samples/user_credential_sample.py b/sdk/communication/azure-communication-chat/samples/user_credential_sample.py index 055fd9e4d96a..4dc5c699e1a0 100644 --- a/sdk/communication/azure-communication-chat/samples/user_credential_sample.py +++ b/sdk/communication/azure-communication-chat/samples/user_credential_sample.py @@ -23,8 +23,9 @@ from azure.communication.chat import CommunicationTokenCredential from azure.communication.identity import CommunicationIdentityClient + class CommunicationTokenCredentialSamples(object): - + connection_string = os.environ.get("COMMUNICATION_SAMPLES_CONNECTION_STRING", None) if not connection_string: raise ValueError("Set COMMUNICATION_SAMPLES_CONNECTION_STRING env before running this sample.") @@ -35,7 +36,7 @@ class CommunicationTokenCredentialSamples(object): token = token_response.token def create_credential_with_static_token(self): - # For short-lived clients, refreshing the token upon expiry is not necessary + # For short-lived clients, refreshing the token upon expiry is not necessary # and `CommunicationTokenCredential` may be instantiated with a static token. with CommunicationTokenCredential(self.token) as credential: token_response = credential.get_token() @@ -45,26 +46,27 @@ def create_credential_with_refreshing_callback(self): # Alternatively, for long-lived clients, you can create a `CommunicationTokenCredential` with a callback to renew tokens if expired. # Here we assume that we have a function `fetch_token_from_server` that makes a network request to retrieve a token string for a user. # It's necessary that the `fetch_token_from_server` function returns a valid token (with an expiration date set in the future) at all times. - fetch_token_from_server = lambda: None - with CommunicationTokenCredential( - self.token, token_refresher=fetch_token_from_server) as credential: + fetch_token_from_server = lambda: None + with CommunicationTokenCredential(self.token, token_refresher=fetch_token_from_server) as credential: token_response = credential.get_token() print("Token issued with value: " + token_response.token) def create_credential_with_proactive_refreshing_callback(self): # Optionally, you can enable proactive token refreshing where a fresh token will be acquired as soon as the # previous token approaches expiry. Using this method, your requests are less likely to be blocked to acquire a fresh token - fetch_token_from_server = lambda: None + fetch_token_from_server = lambda: None with CommunicationTokenCredential( - self.token, token_refresher=fetch_token_from_server, proactive_refresh=True) as credential: + self.token, token_refresher=fetch_token_from_server, proactive_refresh=True + ) as credential: token_response = credential.get_token() print("Token issued with value: " + token_response.token) - + def clean_up(self): print("cleaning up: deleting created user.") self.identity_client.delete_user(self.user) - -if __name__ == '__main__': + + +if __name__ == "__main__": sample = CommunicationTokenCredentialSamples() sample.create_credential_with_static_token() sample.create_credential_with_refreshing_callback() diff --git a/sdk/communication/azure-communication-chat/samples/user_credential_sample_async.py b/sdk/communication/azure-communication-chat/samples/user_credential_sample_async.py index 60791cee875c..95da45db5aec 100644 --- a/sdk/communication/azure-communication-chat/samples/user_credential_sample_async.py +++ b/sdk/communication/azure-communication-chat/samples/user_credential_sample_async.py @@ -24,8 +24,9 @@ from azure.communication.chat.aio import CommunicationTokenCredential from azure.communication.identity import CommunicationIdentityClient + class CommunicationTokenCredentialSamples(object): - + connection_string = os.environ.get("COMMUNICATION_SAMPLES_CONNECTION_STRING", None) if not connection_string: raise ValueError("Set COMMUNICATION_SAMPLES_CONNECTION_STRING env before running this sample.") @@ -36,7 +37,7 @@ class CommunicationTokenCredentialSamples(object): token = token_response.token async def create_credential_with_static_token(self): - # For short-lived clients, refreshing the token upon expiry is not necessary + # For short-lived clients, refreshing the token upon expiry is not necessary # and `CommunicationTokenCredential` may be instantiated with a static token. async with CommunicationTokenCredential(self.token) as credential: token_response = await credential.get_token() @@ -46,25 +47,26 @@ async def create_credential_with_refreshing_callback(self): # Alternatively, for long-lived clients, you can create a `CommunicationTokenCredential` with a callback to renew tokens if expired. # Here we assume that we have a function `fetch_token_from_server` that makes a network request to retrieve a token string for a user. # It's necessary that the `fetch_token_from_server` function returns a valid token (with an expiration date set in the future) at all times. - fetch_token_from_server = lambda: None - async with CommunicationTokenCredential( - self.token, token_refresher=fetch_token_from_server) as credential: + fetch_token_from_server = lambda: None + async with CommunicationTokenCredential(self.token, token_refresher=fetch_token_from_server) as credential: token_response = await credential.get_token() print("Token issued with value: " + token_response.token) async def create_credential_with_proactive_refreshing_callback(self): # Optionally, you can enable proactive token refreshing where a fresh token will be acquired as soon as the # previous token approaches expiry. Using this method, your requests are less likely to be blocked to acquire a fresh token - fetch_token_from_server = lambda: None + fetch_token_from_server = lambda: None async with CommunicationTokenCredential( - self.token, token_refresher=fetch_token_from_server, proactive_refresh=True) as credential: + self.token, token_refresher=fetch_token_from_server, proactive_refresh=True + ) as credential: token_response = await credential.get_token() print("Token issued with value: " + token_response.token) - + def clean_up(self): print("cleaning up: deleting created user.") self.identity_client.delete_user(self.user) - + + async def main(): sample = CommunicationTokenCredentialSamples() await sample.create_credential_with_static_token() @@ -72,5 +74,6 @@ async def main(): await sample.create_credential_with_proactive_refreshing_callback() sample.clean_up() -if __name__ == '__main__': + +if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/communication/azure-communication-chat/setup.py b/sdk/communication/azure-communication-chat/setup.py index 977faf887492..f493d261c27f 100644 --- a/sdk/communication/azure-communication-chat/setup.py +++ b/sdk/communication/azure-communication-chat/setup.py @@ -14,58 +14,59 @@ PACKAGE_PPRINT_NAME = "Communication Chat" # a-b-c => a/b/c -package_folder_path = PACKAGE_NAME.replace('-', '/') +package_folder_path = PACKAGE_NAME.replace("-", "/") # a-b-c => a.b.c -namespace_name = PACKAGE_NAME.replace('-', '.') +namespace_name = PACKAGE_NAME.replace("-", ".") # Version extraction inspired from 'requests' -with open(os.path.join(package_folder_path, '_version.py'), 'r') as fd: - version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', - fd.read(), re.MULTILINE).group(1) +with open(os.path.join(package_folder_path, "_version.py"), "r") as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) if not version: - raise RuntimeError('Cannot find version information') + raise RuntimeError("Cannot find version information") -with open('README.md', encoding='utf-8') as f: +with open("README.md", encoding="utf-8") as f: long_description = f.read() setup( name=PACKAGE_NAME, version=version, - description='Microsoft Azure {} Client Library for Python'.format(PACKAGE_PPRINT_NAME), + description="Microsoft Azure {} Client Library for Python".format(PACKAGE_PPRINT_NAME), long_description=long_description, - long_description_content_type='text/markdown', - license='MIT License', - author='Microsoft Corporation', - author_email='azpysdkhelp@microsoft.com', - url='https://github.com/Azure/azure-sdk-for-python', + long_description_content_type="text/markdown", + license="MIT License", + author="Microsoft Corporation", + author_email="azpysdkhelp@microsoft.com", + url="https://github.com/Azure/azure-sdk-for-python", keywords="azure, azure sdk", classifiers=[ "Development Status :: 5 - Production/Stable", - 'Programming Language :: Python', + "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'License :: OSI Approved :: MIT License', + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "License :: OSI Approved :: MIT License", ], zip_safe=False, - packages=find_packages(exclude=[ - 'tests', - # Exclude packages that will be covered by PEP420 or nspkg - 'azure', - 'azure.communication' - ]), + packages=find_packages( + exclude=[ + "tests", + # Exclude packages that will be covered by PEP420 or nspkg + "azure", + "azure.communication", + ] + ), python_requires=">=3.8", include_package_data=True, package_data={ - 'pytyped': ['py.typed'], + "pytyped": ["py.typed"], }, install_requires=[ "isodate>=0.6.1", "azure-core>=1.29.5", "typing-extensions>=4.3.0", - ] + ], ) diff --git a/sdk/communication/azure-communication-chat/tests/_shared/utils.py b/sdk/communication/azure-communication-chat/tests/_shared/utils.py index 955346bee1a6..69a0d2586209 100644 --- a/sdk/communication/azure-communication-chat/tests/_shared/utils.py +++ b/sdk/communication/azure-communication-chat/tests/_shared/utils.py @@ -20,7 +20,7 @@ def create_token_credential(): from .fake_token_credential import FakeTokenCredential return FakeTokenCredential() - + return get_credential() @@ -32,7 +32,7 @@ def async_create_token_credential(): from .async_fake_token_credential import AsyncFakeTokenCredential return AsyncFakeTokenCredential() - + return get_credential(is_async=True) diff --git a/sdk/communication/azure-communication-chat/tests/chat_e2e_helper.py b/sdk/communication/azure-communication-chat/tests/chat_e2e_helper.py index b2872acbbd86..3f4318cb93c7 100644 --- a/sdk/communication/azure-communication-chat/tests/chat_e2e_helper.py +++ b/sdk/communication/azure-communication-chat/tests/chat_e2e_helper.py @@ -11,8 +11,9 @@ def get_connection_str(): if not is_live(): return "endpoint=https://sanitized.communication.azure.com/;accesskey=fake===" - return os.getenv('COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING') or \ - os.getenv('COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING') + return os.getenv("COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING") or os.getenv( + "COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING" + ) # class ChatURIReplacer(RecordingProcessor): diff --git a/sdk/communication/azure-communication-chat/tests/conftest.py b/sdk/communication/azure-communication-chat/tests/conftest.py index e1e359b15288..be32de3276cd 100644 --- a/sdk/communication/azure-communication-chat/tests/conftest.py +++ b/sdk/communication/azure-communication-chat/tests/conftest.py @@ -27,6 +27,7 @@ from devtools_testutils import add_body_key_sanitizer + @pytest.fixture(scope="session", autouse=True) def add_sanitizers(test_proxy): # Two sanitizers for chatMessageId because it can be either top-level or nested in bodies diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_client.py b/sdk/communication/azure-communication-chat/tests/test_chat_client.py index 0d1d1d73f101..e69aaed7472f 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_client.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_client.py @@ -9,13 +9,8 @@ from azure.core.exceptions import HttpResponseError from azure.core.credentials import AccessToken from datetime import datetime, timezone -from azure.communication.chat import ( - ChatClient, - ChatParticipant -) -from azure.communication.chat._shared.models import( - CommunicationUserIdentifier -) +from azure.communication.chat import ChatClient, ChatParticipant +from azure.communication.chat._shared.models import CommunicationUserIdentifier from unittest_helpers import mock_response from datetime import datetime @@ -23,16 +18,20 @@ from unittest.mock import Mock, patch + def _convert_datetime_to_utc_int(input): return int(calendar.timegm(input.utctimetuple())) + class TestChatClient(unittest.TestCase): @classmethod - @patch('azure.communication.identity._shared.user_credential.CommunicationTokenCredential') + @patch("azure.communication.identity._shared.user_credential.CommunicationTokenCredential") def setUpClass(cls, credential): - credential.get_token = Mock(return_value=AccessToken( - "some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc)) - )) + credential.get_token = Mock( + return_value=AccessToken( + "some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc)) + ) + ) TestChatClient.credential = credential def test_create_chat_thread(self): @@ -41,122 +40,124 @@ def test_create_chat_thread(self): raised = False def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "chatThread": { - "id": thread_id, - "topic": "test topic", - "createdOn": "2020-12-03T21:09:17Z", - "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" - } - }) - + return mock_response( + status_code=201, + json_payload={ + "chatThread": { + "id": thread_id, + "topic": "test topic", + "createdOn": "2020-12-03T21:09:17Z", + "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041", + } + }, + ) + chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) - topic="test topic" + topic = "test topic" user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] try: create_chat_thread_result = chat_client.create_chat_thread(topic, thread_participants=participants) except: raised = True raise - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert create_chat_thread_result.chat_thread.id == thread_id def test_create_chat_thread_w_repeatability_request_id(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" chat_thread_client = None raised = False - idempotency_token="b66d6031-fdcc-41df-8306-e524c9f226b8" + idempotency_token = "b66d6031-fdcc-41df-8306-e524c9f226b8" def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "chatThread": { - "id": thread_id, - "topic": "test topic", - "createdOn": "2020-12-03T21:09:17Z", - "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" - } - }) + return mock_response( + status_code=201, + json_payload={ + "chatThread": { + "id": thread_id, + "topic": "test topic", + "createdOn": "2020-12-03T21:09:17Z", + "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041", + } + }, + ) chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) topic = "test topic" user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - participants = [ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] try: - create_chat_thread_result = chat_client.create_chat_thread(topic=topic, - thread_participants=participants, - idempotency_token=idempotency_token) + create_chat_thread_result = chat_client.create_chat_thread( + topic=topic, thread_participants=participants, idempotency_token=idempotency_token + ) except: raised = True raise - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert create_chat_thread_result.chat_thread.id == thread_id def test_create_chat_thread_raises_error(self): def mock_send(*_, **__): return mock_response(status_code=400, json_payload={"msg": "some error"}) + chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) - topic="test topic", + topic = ("test topic",) user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - thread_participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] - - self.assertRaises(HttpResponseError, chat_client.create_chat_thread, topic=topic, thread_participants=thread_participants) - + thread_participants = [ + ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow()) + ] + + self.assertRaises( + HttpResponseError, chat_client.create_chat_thread, topic=topic, thread_participants=thread_participants + ) + def test_create_chat_thread_with_invalid_participant_raises_error(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" + def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "chatThread": { - "id": thread_id, - "topic": "Lunch", - "createdOn": "2020-06-06T05:55:41.6460000Z", - "createdByCommunicationIdentifier": { - "rawId": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10a", - "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10a" - } - } - }, - "invalidParticipants": [ - { - "target": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10c", - "code": "403", - "message": "Permissions check failed" + return mock_response( + status_code=201, + json_payload={ + "chatThread": { + "id": thread_id, + "topic": "Lunch", + "createdOn": "2020-06-06T05:55:41.6460000Z", + "createdByCommunicationIdentifier": { + "rawId": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10a", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10a" + }, + }, }, - { - "target": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10d", - "code": "404", - "message": "Not found" - } - ] - }) + "invalidParticipants": [ + { + "target": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10c", + "code": "403", + "message": "Permissions check failed", + }, + { + "target": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10d", + "code": "404", + "message": "Not found", + }, + ], + }, + ) + chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) - topic="test topic", + topic = ("test topic",) user = CommunicationUserIdentifier("57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - thread_participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] - + thread_participants = [ + ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow()) + ] + create_chat_thread_result = chat_client.create_chat_thread(topic, thread_participants=thread_participants) assert create_chat_thread_result.errors is not None assert len(create_chat_thread_result.errors) is 2 @@ -167,6 +168,7 @@ def test_delete_chat_thread(self): def mock_send(*_, **__): return mock_response(status_code=204) + chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) try: @@ -174,7 +176,7 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_list_chat_threads(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -182,6 +184,7 @@ def test_list_chat_threads(self): def mock_send(*_, **__): return mock_response(status_code=200, json_payload={"value": [{"id": thread_id}]}) + chat_client = ChatClient("https://endpoint", TestChatClient.credential, transport=Mock(send=mock_send)) chat_threads = None @@ -190,7 +193,7 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for chat_thread_item_page in chat_threads.by_page(): l = list(chat_thread_item_page) assert len(l) == 1 @@ -203,5 +206,6 @@ def test_get_thread_client(self): assert chat_thread_client.thread_id == thread_id -if __name__ == '__main__': - unittest.main() \ No newline at end of file + +if __name__ == "__main__": + unittest.main() diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_client_async.py b/sdk/communication/azure-communication-chat/tests/test_chat_client_async.py index 782e113874c4..bdef7744cd22 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_client_async.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_client_async.py @@ -4,14 +4,10 @@ # license information. # ------------------------------------------------------------------------- from azure.core.credentials import AccessToken -from azure.communication.chat.aio import ( - ChatClient -) +from azure.communication.chat.aio import ChatClient from azure.communication.chat import ChatParticipant -from azure.communication.chat._shared.models import( - CommunicationUserIdentifier -) +from azure.communication.chat._shared.models import CommunicationUserIdentifier from unittest_helpers import mock_response from azure.core.exceptions import HttpResponseError from datetime import datetime, timezone @@ -22,6 +18,7 @@ import time import calendar + def _convert_datetime_to_utc_int(input): return int(calendar.timegm(input.utctimetuple())) @@ -29,6 +26,7 @@ def _convert_datetime_to_utc_int(input): async def mock_get_token(*_, **__): return AccessToken("some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc))) + credential = Mock(spec_set=["get_token"], get_token=mock_get_token) @@ -37,68 +35,66 @@ async def test_create_chat_thread(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" async def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "chatThread": { - "id": thread_id, - "topic": "test topic", - "createdOn": "2020-12-03T21:09:17Z", - "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" - } - }) + return mock_response( + status_code=201, + json_payload={ + "chatThread": { + "id": thread_id, + "topic": "test topic", + "createdOn": "2020-12-03T21:09:17Z", + "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041", + } + }, + ) chat_client = ChatClient("https://endpoint", credential, transport=Mock(send=mock_send)) - topic="test topic" + topic = "test topic" user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] create_chat_thread_result = await chat_client.create_chat_thread(topic, thread_participants=participants) assert create_chat_thread_result.chat_thread.id == thread_id + @pytest.mark.asyncio async def test_create_chat_thread_w_repeatability_request_id(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" idempotency_token = "b66d6031-fdcc-41df-8306-e524c9f226b8" + async def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "chatThread": { - "id": thread_id, - "topic": "test topic", - "createdOn": "2020-12-03T21:09:17Z", - "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" - } - }) + return mock_response( + status_code=201, + json_payload={ + "chatThread": { + "id": thread_id, + "topic": "test topic", + "createdOn": "2020-12-03T21:09:17Z", + "createdBy": "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041", + } + }, + ) chat_client = ChatClient("https://endpoint", credential, transport=Mock(send=mock_send)) - topic="test topic" + topic = "test topic" user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] - create_chat_thread_result = await chat_client.create_chat_thread(topic=topic, - thread_participants=participants, - idempotency_token=idempotency_token) + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] + create_chat_thread_result = await chat_client.create_chat_thread( + topic=topic, thread_participants=participants, idempotency_token=idempotency_token + ) assert create_chat_thread_result.chat_thread.id == thread_id + @pytest.mark.asyncio async def test_create_chat_thread_raises_error(): async def mock_send(*_, **__): return mock_response(status_code=400, json_payload={"msg": "some error"}) + chat_client = ChatClient("https://endpoint", credential, transport=Mock(send=mock_send)) - topic="test topic", + topic = ("test topic",) user = CommunicationUserIdentifier("8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041") - participants=[ChatParticipant( - identifier=user, - display_name='name', - share_history_time=datetime.utcnow() - )] + participants = [ChatParticipant(identifier=user, display_name="name", share_history_time=datetime.utcnow())] raised = False try: @@ -108,6 +104,7 @@ async def mock_send(*_, **__): assert raised == True + @pytest.mark.asyncio async def test_delete_chat_thread(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -115,6 +112,7 @@ async def test_delete_chat_thread(): async def mock_send(*_, **__): return mock_response(status_code=204) + chat_client = ChatClient("https://endpoint", credential, transport=Mock(send=mock_send)) raised = False @@ -125,6 +123,7 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_list_chat_threads(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -132,6 +131,7 @@ async def test_list_chat_threads(): async def mock_send(*_, **__): return mock_response(status_code=200, json_payload={"value": [{"id": thread_id}]}) + chat_client = ChatClient("https://endpoint", credential, transport=Mock(send=mock_send)) chat_threads = None diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e.py b/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e.py index 8516e2cf48b5..f342d07f5cb1 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e.py @@ -10,11 +10,7 @@ from uuid import uuid4 from azure.communication.identity import CommunicationIdentityClient -from azure.communication.chat import ( - ChatClient, - CommunicationTokenCredential, - ChatParticipant -) +from azure.communication.chat import ChatClient, CommunicationTokenCredential, ChatParticipant from azure.communication.chat._shared.utils import parse_connection_str from chat_e2e_helper import get_connection_str from _shared.utils import get_http_logging_policy @@ -35,9 +31,7 @@ def setup_method(self): # create ChatClient self.chat_client = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token), - http_logging_policy=get_http_logging_policy() + self.endpoint, CommunicationTokenCredential(self.token), http_logging_policy=get_http_logging_policy() ) def teardown_method(self): @@ -51,14 +45,12 @@ def _create_thread(self, idempotency_token=None): topic = "test topic" share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) - participants = [ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - )] - create_chat_thread_result = self.chat_client.create_chat_thread(topic, - thread_participants=participants, - idempotency_token=idempotency_token) + participants = [ + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time) + ] + create_chat_thread_result = self.chat_client.create_chat_thread( + topic, thread_participants=participants, idempotency_token=idempotency_token + ) self.thread_id = create_chat_thread_result.chat_thread.id @pytest.mark.live_test_only @@ -71,9 +63,7 @@ def test_access_token_validation(self): # create ChatClient chat_client = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token), - http_logging_policy=get_http_logging_policy() + self.endpoint, CommunicationTokenCredential(self.token), http_logging_policy=get_http_logging_policy() ) raised = False try: @@ -91,7 +81,7 @@ def test_access_token_validation(self): for chat_thread_info in chat_threads_info_page: print("ChatThreadInfo: ", chat_thread_info) except: - raised = True + raised = True assert raised is False diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e_async.py b/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e_async.py index 0aaa0725087f..c7bef5fba380 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e_async.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_client_e2e_async.py @@ -11,13 +11,8 @@ from uuid import uuid4 from azure.communication.identity import CommunicationIdentityClient -from azure.communication.chat.aio import ( - ChatClient, - CommunicationTokenCredential -) -from azure.communication.chat import ( - ChatParticipant -) +from azure.communication.chat.aio import ChatClient, CommunicationTokenCredential +from azure.communication.chat import ChatParticipant from azure.communication.chat._shared.utils import parse_connection_str from chat_e2e_helper import get_connection_str from _shared.utils import get_http_logging_policy @@ -38,9 +33,7 @@ def setup_method(self): # create ChatClient self.chat_client = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token), - http_logging_policy=get_http_logging_policy() + self.endpoint, CommunicationTokenCredential(self.token), http_logging_policy=get_http_logging_policy() ) def teardown_method(self): @@ -53,16 +46,14 @@ async def _create_thread(self, idempotency_token=None): topic = "test topic" share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) - participants = [ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - )] - create_chat_thread_result = await self.chat_client.create_chat_thread(topic, - thread_participants=participants, - idempotency_token=idempotency_token) + participants = [ + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time) + ] + create_chat_thread_result = await self.chat_client.create_chat_thread( + topic, thread_participants=participants, idempotency_token=idempotency_token + ) self.thread_id = create_chat_thread_result.chat_thread.id - + @pytest.mark.live_test_only @pytest.mark.asyncio @recorded_by_proxy_async @@ -90,7 +81,7 @@ async def test_create_chat_thread_w_no_participants_async(self): # delete created users and chat threads if not self.is_playback(): await self.chat_client.delete_chat_thread(create_chat_thread_result.chat_thread.id) - + @pytest.mark.live_test_only @pytest.mark.asyncio @recorded_by_proxy_async @@ -107,7 +98,6 @@ async def test_create_chat_thread_w_repeatability_request_id_async(self): await self._create_thread(idempotency_token=idempotency_token) assert thread_id == self.thread_id - # delete created users and chat threads if not self.is_playback(): await self.chat_client.delete_chat_thread(self.thread_id) diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client.py b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client.py index c97bda3154fe..42fefe70409b 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client.py @@ -10,28 +10,26 @@ from datetime import datetime, timezone from azure.core.credentials import AccessToken from azure.core.exceptions import HttpResponseError -from azure.communication.chat import ( - ChatThreadClient, - ChatParticipant, - ChatMessageType -) -from azure.communication.chat._shared.models import( - CommunicationUserIdentifier -) +from azure.communication.chat import ChatThreadClient, ChatParticipant, ChatMessageType +from azure.communication.chat._shared.models import CommunicationUserIdentifier from unittest_helpers import mock_response from unittest.mock import Mock, patch + def _convert_datetime_to_utc_int(input): return int(calendar.timegm(input.utctimetuple())) + class TestChatThreadClient(unittest.TestCase): @classmethod - @patch('azure.communication.identity._shared.user_credential.CommunicationTokenCredential') + @patch("azure.communication.identity._shared.user_credential.CommunicationTokenCredential") def setUpClass(cls, credential): - credential.get_token = Mock(return_value=AccessToken( - "some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc)) - )) + credential.get_token = Mock( + return_value=AccessToken( + "some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc)) + ) + ) TestChatThreadClient.credential = credential def test_update_topic(self): @@ -40,7 +38,10 @@ def test_update_topic(self): def mock_send(*_, **__): return mock_response(status_code=204) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) topic = "update topic" try: @@ -48,36 +49,38 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_send_message(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False def mock_send(*_, **__): return mock_response(status_code=201, json_payload={"id": message_id}) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) create_message_result = None try: - content='hello world' - sender_display_name='sender name' - metadata={ "tags": "tag" } + content = "hello world" + sender_display_name = "sender name" + metadata = {"tags": "tag"} create_message_result = chat_thread_client.send_message( - content=content, - sender_display_name=sender_display_name, - metadata=metadata) + content=content, sender_display_name=sender_display_name, metadata=metadata + ) create_message_result_id = create_message_result.id except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert create_message_result_id == message_id def test_send_message_w_type(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False message_str = "Hi I am Bob." @@ -86,131 +89,157 @@ def test_send_message_w_type(self): for chat_message_type in chat_message_types: def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "id": message_id, - "type": chat_message_type, - "sequenceId": "3", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b", - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiator": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + return mock_response( + status_code=201, + json_payload={ + "id": message_id, + "type": chat_message_type, + "sequenceId": "3", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b", + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiator": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b", + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderId": "8:acs:46849534-eb08-4ab7-bde7-c36928cd1547_00000007-e155-1f06-1db7-3a3a0d00004b", }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderId": "8:acs:46849534-eb08-4ab7-bde7-c36928cd1547_00000007-e155-1f06-1db7-3a3a0d00004b" - }) + ) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, - transport=Mock(send=mock_send)) + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: - content='hello world' - sender_display_name='sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = chat_thread_client.send_message( - content=content, - chat_message_type=chat_message_type, - sender_display_name=sender_display_name) + content=content, chat_message_type=chat_message_type, sender_display_name=sender_display_name + ) create_message_result_id = create_message_result.id except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert create_message_result_id == message_id def test_send_message_w_invalid_type_throws_error(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False message_str = "Hi I am Bob." # the payload is irrelevant - it'll fail before def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "id": message_id - }) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + return mock_response(status_code=201, json_payload={"id": message_id}) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) create_message_result = None - chat_message_types = [ChatMessageType.PARTICIPANT_ADDED, ChatMessageType.PARTICIPANT_REMOVED, - ChatMessageType.TOPIC_UPDATED, "participant_added", "participant_removed", "topic_updated", - "ChatMessageType.TEXT", "ChatMessageType.HTML", - "ChatMessageType.PARTICIPANT_ADDED", "ChatMessageType.PARTICIPANT_REMOVED", - "ChatMessageType.TOPIC_UPDATED"] + chat_message_types = [ + ChatMessageType.PARTICIPANT_ADDED, + ChatMessageType.PARTICIPANT_REMOVED, + ChatMessageType.TOPIC_UPDATED, + "participant_added", + "participant_removed", + "topic_updated", + "ChatMessageType.TEXT", + "ChatMessageType.HTML", + "ChatMessageType.PARTICIPANT_ADDED", + "ChatMessageType.PARTICIPANT_REMOVED", + "ChatMessageType.TOPIC_UPDATED", + ] for chat_message_type in chat_message_types: try: - content='hello world' - sender_display_name='sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = chat_thread_client.send_message( - content=content, - chat_message_type=chat_message_type, - sender_display_name=sender_display_name) + content=content, chat_message_type=chat_message_type, sender_display_name=sender_display_name + ) except: raised = True - self.assertTrue(raised, 'Expected is excpetion raised') - + self.assertTrue(raised, "Expected is excpetion raised") def test_get_message(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False message_str = "Hi I am Bob." def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "id": message_id, - "type": "text", - "sequenceId": "3", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "attachments": [ - { - "id": "id", - "attachmentType": "image", - "name": "name.png", - "url": "https://endpoint/threads/chatThreadId/images/imageId/views/original", - "previewUrl": "https://endpoint/threads/chatThreadId/images/imageId/views/preview", + return mock_response( + status_code=200, + json_payload={ + "id": message_id, + "type": "text", + "sequenceId": "3", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, }, - { - "id": "id", - "attachmentType": "file", - "name": "name.pdf", - "previewUrl": "https://contoso.sharepoint.com/teams/TeamName/DocumentLibrary/FileName", - } - ] + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z", - "metadata": { - "tags": "tag" - } - }) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + "attachments": [ + { + "id": "id", + "attachmentType": "image", + "name": "name.png", + "url": "https://endpoint/threads/chatThreadId/images/imageId/views/original", + "previewUrl": "https://endpoint/threads/chatThreadId/images/imageId/views/preview", + }, + { + "id": "id", + "attachmentType": "file", + "name": "name.pdf", + "previewUrl": "https://contoso.sharepoint.com/teams/TeamName/DocumentLibrary/FileName", + }, + ], + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", + "metadata": {"tags": "tag"}, + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) message = None try: @@ -218,7 +247,7 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert message.id == message_id assert message.content.message == message_str assert message.type == ChatMessageType.TEXT @@ -230,38 +259,60 @@ def mock_send(*_, **__): def test_list_messages(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" message_str = "Hi I am Bob." raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={"value": [{ - "id": message_id, - "type": "text", - "sequenceId": "3", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} - }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - }]}) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "id": message_id, + "type": "text", + "sequenceId": "3", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", + } + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) chat_messages = None try: @@ -269,7 +320,7 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for chat_message in chat_messages.by_page(): l = list(chat_message) assert len(l) == 1 @@ -278,88 +329,120 @@ def mock_send(*_, **__): def test_list_messages_with_start_time(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" raised = False - message_id = '1596823919339' + message_id = "1596823919339" message_str = "Hi I am Bob." def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "id": message_id, - "type": "text", - "sequenceId": "2", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "id": message_id, + "type": "text", + "sequenceId": "2", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - }, - { - "id": message_id, - "type": "text", - "sequenceId": "3", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} + { + "id": message_id, + "type": "text", + "sequenceId": "3", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - } - ]}) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) chat_messages = None try: - chat_messages = chat_thread_client.list_messages( - start_time=datetime(2020, 8, 17, 18, 0, 0) - ) + chat_messages = chat_thread_client.list_messages(start_time=datetime(2020, 8, 17, 18, 0, 0)) except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for chat_message in chat_messages.by_page(): l = list(chat_message) assert len(l) == 2 def test_update_message_content(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False def mock_send(*_, **__): return mock_response(status_code=204) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: content = "updated message content" @@ -367,60 +450,72 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_update_message_metadata(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False def mock_send(*_, **__): return mock_response(status_code=204) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: - metadata={ "tags": "tag" } + metadata = {"tags": "tag"} chat_thread_client.update_message(message_id, metadata=metadata) except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_delete_message(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False def mock_send(*_, **__): return mock_response(status_code=204) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: chat_thread_client.delete_message(message_id) except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_list_participants(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={"value": [ - { - "communicationIdentifier": { - "rawId": participant_id, - "communicationUser": { - "id": participant_id + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "communicationIdentifier": { + "rawId": participant_id, + "communicationUser": {"id": participant_id}, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", } - }, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ]}) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) chat_thread_participants = None try: @@ -428,11 +523,11 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for chat_thread_participant_page in chat_thread_participants.by_page(): l = list(chat_thread_participant_page) assert len(l) == 1 - l[0].identifier.properties['id'] = participant_id + l[0].identifier.properties["id"] = participant_id def test_list_participants_with_results_per_page(self): thread_id = "19:81181a8abbf54b5695f87a0042ddcba9@thread.v2" @@ -441,32 +536,33 @@ def test_list_participants_with_results_per_page(self): raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "communicationIdentifier": { - "rawId": participant_id_1, - "communicationUser": { - "id": participant_id_1 - } + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "communicationIdentifier": { + "rawId": participant_id_1, + "communicationUser": {"id": participant_id_1}, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", }, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - }, - { - "communicationIdentifier": { - "rawId": participant_id_2, - "communicationUser": { - "id": participant_id_2 - } + { + "communicationIdentifier": { + "rawId": participant_id_2, + "communicationUser": {"id": participant_id_2}, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", }, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ]}) + ] + }, + ) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, - transport=Mock(send=mock_send)) + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) chat_thread_participants = None try: @@ -474,25 +570,28 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for chat_thread_participant_page in chat_thread_participants.by_page(): l = list(chat_thread_participant_page) assert len(l) == 2 - def test_add_participants(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - new_participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + new_participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False def mock_send(*_, **__): return mock_response(status_code=201) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) new_participant = ChatParticipant( - identifier=CommunicationUserIdentifier(new_participant_id), - display_name='name', - share_history_time=datetime.utcnow()) + identifier=CommunicationUserIdentifier(new_participant_id), + display_name="name", + share_history_time=datetime.utcnow(), + ) participants = [new_participant] try: @@ -500,32 +599,34 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") self.assertTrue(len(result) == 0) def test_add_participants_w_failed_participants_returns_nonempty_list(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - new_participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + new_participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False error_message = "some error message" def mock_send(*_, **__): - return mock_response(status_code=201,json_payload={ - "invalidParticipants": [ - { - "code": "string", - "message": error_message, - "target": new_participant_id, - "details": [] - } - ] - }) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + return mock_response( + status_code=201, + json_payload={ + "invalidParticipants": [ + {"code": "string", "message": error_message, "target": new_participant_id, "details": []} + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) new_participant = ChatParticipant( - identifier=CommunicationUserIdentifier(new_participant_id), - display_name='name', - share_history_time=datetime.utcnow()) + identifier=CommunicationUserIdentifier(new_participant_id), + display_name="name", + share_history_time=datetime.utcnow(), + ) participants = [new_participant] try: @@ -533,33 +634,35 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") self.assertTrue(len(result) == 1) failed_participant = result[0][0] communication_error = result[0][1] - self.assertEqual(new_participant.identifier.properties['id'], failed_participant.identifier.properties['id']) + self.assertEqual(new_participant.identifier.properties["id"], failed_participant.identifier.properties["id"]) self.assertEqual(new_participant.display_name, failed_participant.display_name) self.assertEqual(new_participant.share_history_time, failed_participant.share_history_time) self.assertEqual(error_message, communication_error.message) - def test_remove_participant(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False def mock_send(*_, **__): return mock_response(status_code=204) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: chat_thread_client.remove_participant(identifier=CommunicationUserIdentifier(participant_id)) except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_send_typing_notification(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -567,14 +670,17 @@ def test_send_typing_notification(self): def mock_send(*_, **__): return mock_response(status_code=200) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: chat_thread_client.send_typing_notification() except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_send_typing_notification_with_sender_display_name(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -582,51 +688,58 @@ def test_send_typing_notification_with_sender_display_name(self): def mock_send(*_, **__): return mock_response(status_code=200) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: chat_thread_client.send_typing_notification(sender_display_name="John") except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_send_read_receipt(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id="1596823919339" + message_id = "1596823919339" raised = False def mock_send(*_, **__): return mock_response(status_code=200) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) try: chat_thread_client.send_read_receipt(message_id) except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") def test_list_read_receipts(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id="1596823919339" + message_id = "1596823919339" raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "chatMessageId": message_id, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "chatMessageId": message_id, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, } - } - ] - }) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) read_receipts = None try: @@ -634,40 +747,37 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for read_receipt_page in read_receipts.by_page(): l = list(read_receipt_page) assert len(l) == 1 def test_list_read_receipts_with_results_per_page(self): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id_1="1596823919339" - message_id_2="1596823919340" + message_id_1 = "1596823919339" + message_id_2 = "1596823919340" raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "chatMessageId": message_id_1, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } - } - }, - { - "chatMessageId": message_id_2, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } - } - } - ]}) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "chatMessageId": message_id_1, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + { + "chatMessageId": message_id_2, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + ] + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) read_receipts = None try: @@ -675,7 +785,7 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") for read_receipt_page in read_receipts.by_page(): l = list(read_receipt_page) assert len(l) == 2 @@ -685,14 +795,20 @@ def test_get_properties(self): raised = False def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "id": thread_id, - "topic": "Lunch Chat thread", - "createdOn": "2020-10-30T10:50:50Z", - "deletedOn": "2020-10-30T10:50:50Z", - "createdByCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}} - }) - chat_thread_client = ChatThreadClient("https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send)) + return mock_response( + status_code=200, + json_payload={ + "id": thread_id, + "topic": "Lunch Chat thread", + "createdOn": "2020-10-30T10:50:50Z", + "deletedOn": "2020-10-30T10:50:50Z", + "createdByCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + ) + + chat_thread_client = ChatThreadClient( + "https://endpoint", TestChatThreadClient.credential, thread_id, transport=Mock(send=mock_send) + ) get_thread_result = None try: @@ -700,9 +816,9 @@ def mock_send(*_, **__): except: raised = True - self.assertFalse(raised, 'Expected is no excpetion raised') + self.assertFalse(raised, "Expected is no excpetion raised") assert get_thread_result.id == thread_id -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_async.py b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_async.py index 3deacc0c97bc..c724bcd5e493 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_async.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_async.py @@ -6,13 +6,8 @@ from azure.core.credentials import AccessToken from datetime import datetime, timezone from azure.communication.chat.aio import ChatThreadClient -from azure.communication.chat import ( - ChatParticipant, - ChatMessageType -) -from azure.communication.chat._shared.models import( - CommunicationUserIdentifier -) +from azure.communication.chat import ChatParticipant, ChatMessageType +from azure.communication.chat._shared.models import CommunicationUserIdentifier from unittest_helpers import mock_response from azure.core.exceptions import HttpResponseError @@ -22,6 +17,7 @@ import time import calendar + def _convert_datetime_to_utc_int(input): return int(calendar.timegm(input.utctimetuple())) @@ -29,6 +25,7 @@ def _convert_datetime_to_utc_int(input): async def mock_get_token(*_, **__): return AccessToken("some_token", _convert_datetime_to_utc_int(datetime.now().replace(tzinfo=timezone.utc))) + credential = Mock(spec_set=["get_token"], get_token=mock_get_token) @@ -39,6 +36,7 @@ async def test_update_topic(): async def mock_send(*_, **__): return mock_response(status_code=204) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) topic = "update topic" @@ -49,26 +47,27 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_send_message(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False async def mock_send(*_, **__): return mock_response(status_code=201, json_payload={"id": message_id}) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) create_message_result_id = None try: - content='hello world' - sender_display_name='sender name' - metadata={ "tags": "tag" } + content = "hello world" + sender_display_name = "sender name" + metadata = {"tags": "tag"} create_message_result = await chat_thread_client.send_message( - content, - sender_display_name=sender_display_name, - metadata=metadata) + content, sender_display_name=sender_display_name, metadata=metadata + ) create_message_result_id = create_message_result.id except: raised = True @@ -76,10 +75,11 @@ async def mock_send(*_, **__): assert raised == False assert create_message_result_id == message_id + @pytest.mark.asyncio async def test_send_message_w_type(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False message_str = "Hi I am Bob." @@ -90,7 +90,9 @@ async def test_send_message_w_type(): for chat_message_type in chat_message_types: async def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ + return mock_response( + status_code=201, + json_payload={ "id": message_id, "type": chat_message_type, "sequenceId": "3", @@ -102,26 +104,26 @@ async def mock_send(*_, **__): { "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b", "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" + "shareHistoryTime": "2020-10-30T10:50:50Z", } ], - "initiator": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + "initiator": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b", }, "senderDisplayName": "Bob", "createdOn": "2021-01-27T01:37:33Z", - "senderId": "8:acs:46849534-eb08-4ab7-bde7-c36928cd1547_00000007-e155-1f06-1db7-3a3a0d00004b" - }) + "senderId": "8:acs:46849534-eb08-4ab7-bde7-c36928cd1547_00000007-e155-1f06-1db7-3a3a0d00004b", + }, + ) chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: - content='hello world' - sender_display_name='sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = await chat_thread_client.send_message( - content, - chat_message_type=chat_message_type, - sender_display_name=sender_display_name) + content, chat_message_type=chat_message_type, sender_display_name=sender_display_name + ) create_message_result_id = create_message_result.id except: raised = True @@ -129,34 +131,43 @@ async def mock_send(*_, **__): assert raised == False assert create_message_result_id == message_id + @pytest.mark.asyncio async def test_send_message_w_invalid_type_throws_error(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False # the payload is irrelevant - it'll fail before async def mock_send(*_, **__): return mock_response(status_code=201, json_payload={"id": message_id}) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) create_message_result_id = None - chat_message_types = [ChatMessageType.PARTICIPANT_ADDED, ChatMessageType.PARTICIPANT_REMOVED, - ChatMessageType.TOPIC_UPDATED, "participant_added", "participant_removed", "topic_updated", - "ChatMessageType.TEXT", "ChatMessageType.HTML", - "ChatMessageType.PARTICIPANT_ADDED", "ChatMessageType.PARTICIPANT_REMOVED", - "ChatMessageType.TOPIC_UPDATED"] + chat_message_types = [ + ChatMessageType.PARTICIPANT_ADDED, + ChatMessageType.PARTICIPANT_REMOVED, + ChatMessageType.TOPIC_UPDATED, + "participant_added", + "participant_removed", + "topic_updated", + "ChatMessageType.TEXT", + "ChatMessageType.HTML", + "ChatMessageType.PARTICIPANT_ADDED", + "ChatMessageType.PARTICIPANT_REMOVED", + "ChatMessageType.TOPIC_UPDATED", + ] for chat_message_type in chat_message_types: try: - content='hello world' - sender_display_name='sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = await chat_thread_client.send_message( - content, - chat_message_type=chat_message_type, - sender_display_name=sender_display_name) + content, chat_message_type=chat_message_type, sender_display_name=sender_display_name + ) except: raised = True @@ -166,40 +177,54 @@ async def mock_send(*_, **__): @pytest.mark.asyncio async def test_get_message(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False message_str = "Hi I am Bob." async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "id": message_id, - "type": "text", - "sequenceId": "3", - "version": message_id, - "content": { - "message": message_str, - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} - }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z", - "metadata": { - "tags": "tag" + return mock_response( + status_code=200, + json_payload={ + "id": message_id, + "type": "text", + "sequenceId": "3", + "version": message_id, + "content": { + "message": message_str, + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", } - }) + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", + "metadata": {"tags": "tag"}, + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) message = None @@ -215,14 +240,19 @@ async def mock_send(*_, **__): assert message.metadata["tags"] == "tag" assert len(message.content.participants) > 0 + @pytest.mark.asyncio async def test_list_messages(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={"value": [{ + return mock_response( + status_code=200, + json_payload={ + "value": [ + { "id": message_id, "type": "text", "sequenceId": "3", @@ -232,22 +262,38 @@ async def mock_send(*_, **__): "topic": "Lunch Chat thread", "participants": [ { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" + "shareHistoryTime": "2020-10-30T10:50:50Z", } ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, }, "senderDisplayName": "Bob", "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - }]}) + "editedOn": "2021-01-27T01:37:33Z", + } + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) chat_messages = None @@ -272,67 +318,95 @@ async def test_list_messages_with_start_time(): raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "id": "message_id_1", - "type": "text", - "sequenceId": "3", - "version": "message_id_1", - "content": { - "message": "message_str", - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "id": "message_id_1", + "type": "text", + "sequenceId": "3", + "version": "message_id_1", + "content": { + "message": "message_str", + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - }, - { - "id": "message_id_2", - "type": "text", - "sequenceId": "3", - "version": "message_id_2", - "content": { - "message": "message_str", - "topic": "Lunch Chat thread", - "participants": [ - { - "communicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ], - "initiatorCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}} + { + "id": "message_id_2", + "type": "text", + "sequenceId": "3", + "version": "message_id_2", + "content": { + "message": "message_str", + "topic": "Lunch Chat thread", + "participants": [ + { + "communicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", + } + ], + "initiatorCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + }, + "senderDisplayName": "Bob", + "createdOn": "2021-01-27T01:37:33Z", + "senderCommunicationIdentifier": { + "rawId": "string", + "communicationUser": { + "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b" + }, + }, + "deletedOn": "2021-01-27T01:37:33Z", + "editedOn": "2021-01-27T01:37:33Z", }, - "senderDisplayName": "Bob", - "createdOn": "2021-01-27T01:37:33Z", - "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": { - "id": "8:acs:8540c0de-899f-5cce-acb5-3ec493af3800_0e59221d-0c1d-46ae-9544-c963ce56c10b"}}, - "deletedOn": "2021-01-27T01:37:33Z", - "editedOn": "2021-01-27T01:37:33Z" - }]}) + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) chat_messages = None try: - chat_messages = chat_thread_client.list_messages( - start_time=datetime(2020, 8, 17, 18, 0, 0) - ) + chat_messages = chat_thread_client.list_messages(start_time=datetime(2020, 8, 17, 18, 0, 0)) except: raised = True @@ -344,14 +418,16 @@ async def mock_send(*_, **__): assert len(items) == 2 + @pytest.mark.asyncio async def test_update_message_content(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False async def mock_send(*_, **__): return mock_response(status_code=204) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -362,32 +438,36 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_update_message_metadata(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False async def mock_send(*_, **__): return mock_response(status_code=204) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: - metadata={ "tags": "tag" } + metadata = {"tags": "tag"} await chat_thread_client.update_message(message_id, metadata=metadata) except: raised = True assert raised == False + @pytest.mark.asyncio async def test_delete_message(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id='1596823919339' + message_id = "1596823919339" raised = False async def mock_send(*_, **__): return mock_response(status_code=204) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -397,25 +477,30 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_list_participants(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={"value": [ - { - "communicationIdentifier": { - "rawId": participant_id, - "communicationUser": { - "id": participant_id + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "communicationIdentifier": { + "rawId": participant_id, + "communicationUser": {"id": participant_id}, + }, + "displayName": "Bob", + "shareHistoryTime": "2020-10-30T10:50:50Z", } - }, - "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ]}) + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) chat_thread_participants = None @@ -432,6 +517,7 @@ async def mock_send(*_, **__): assert len(items) == 1 + @pytest.mark.asyncio async def test_list_participants_with_results_per_page(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -440,29 +526,30 @@ async def test_list_participants_with_results_per_page(): raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ + return mock_response( + status_code=200, + json_payload={ "value": [ { "communicationIdentifier": { "rawId": participant_id_1, - "communicationUser": { - "id": participant_id_1 - } + "communicationUser": {"id": participant_id_1}, }, "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" + "shareHistoryTime": "2020-10-30T10:50:50Z", }, { "communicationIdentifier": { "rawId": participant_id_2, - "communicationUser": { - "id": participant_id_2 - } + "communicationUser": {"id": participant_id_2}, }, "displayName": "Bob", - "shareHistoryTime": "2020-10-30T10:50:50Z" - } - ]}) + "shareHistoryTime": "2020-10-30T10:50:50Z", + }, + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) chat_thread_participants = None @@ -483,17 +570,19 @@ async def mock_send(*_, **__): @pytest.mark.asyncio async def test_add_participants(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - new_participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + new_participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False async def mock_send(*_, **__): return mock_response(status_code=201) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) new_participant = ChatParticipant( - identifier=CommunicationUserIdentifier(new_participant_id), - display_name='name', - share_history_time=datetime.utcnow()) + identifier=CommunicationUserIdentifier(new_participant_id), + display_name="name", + share_history_time=datetime.utcnow(), + ) participants = [new_participant] try: @@ -503,30 +592,31 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_add_participants_w_failed_participants_returns_nonempty_list(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - new_participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + new_participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False error_message = "some error message" async def mock_send(*_, **__): - return mock_response(status_code=201, json_payload={ - "invalidParticipants": [ - { - "code": "string", - "message": error_message, - "target": new_participant_id, - "details": [] - } - ] - }) + return mock_response( + status_code=201, + json_payload={ + "invalidParticipants": [ + {"code": "string", "message": error_message, "target": new_participant_id, "details": []} + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) new_participant = ChatParticipant( - identifier=CommunicationUserIdentifier(new_participant_id), - display_name='name', - share_history_time=datetime.utcnow()) + identifier=CommunicationUserIdentifier(new_participant_id), + display_name="name", + share_history_time=datetime.utcnow(), + ) participants = [new_participant] try: @@ -540,19 +630,21 @@ async def mock_send(*_, **__): failed_participant = result[0][0] communication_error = result[0][1] - assert new_participant.identifier.properties['id'] == failed_participant.identifier.properties['id'] + assert new_participant.identifier.properties["id"] == failed_participant.identifier.properties["id"] assert new_participant.display_name == failed_participant.display_name assert new_participant.share_history_time == failed_participant.share_history_time assert error_message == communication_error.message + @pytest.mark.asyncio async def test_remove_participant(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - participant_id="8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" + participant_id = "8:acs:57b9bac9-df6c-4d39-a73b-26e944adf6ea_9b0110-08007f1041" raised = False async def mock_send(*_, **__): return mock_response(status_code=204) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -562,6 +654,7 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_send_typing_notification(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -569,6 +662,7 @@ async def test_send_typing_notification(): async def mock_send(*_, **__): return mock_response(status_code=200) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -578,6 +672,7 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_send_typing_notification_with_sender_display_name(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -585,6 +680,7 @@ async def test_send_typing_notification_with_sender_display_name(): async def mock_send(*_, **__): return mock_response(status_code=200) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -594,14 +690,16 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_send_read_receipt(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id="1596823919339" + message_id = "1596823919339" raised = False async def mock_send(*_, **__): return mock_response(status_code=200) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) try: @@ -611,24 +709,26 @@ async def mock_send(*_, **__): assert raised == False + @pytest.mark.asyncio async def test_list_read_receipts(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" - message_id="1596823919339" + message_id = "1596823919339" raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={"value": [ - { - "chatMessageId": message_id, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "chatMessageId": message_id, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, } - } - } - ]}) + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) read_receipts = None @@ -645,6 +745,7 @@ async def mock_send(*_, **__): assert len(items) == 1 + @pytest.mark.asyncio async def test_list_read_receipts_with_results_per_page(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -653,27 +754,22 @@ async def test_list_read_receipts_with_results_per_page(): raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "chatMessageId": message_id_1, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } - } - }, - { - "chatMessageId": message_id_2, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } - } - } - ]}) + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "chatMessageId": message_id_1, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + { + "chatMessageId": message_id_2, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) read_receipts = None @@ -690,6 +786,7 @@ async def mock_send(*_, **__): assert len(items) == 2 + @pytest.mark.asyncio async def test_list_read_receipts_with_results_per_page_and_skip(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" @@ -697,18 +794,18 @@ async def test_list_read_receipts_with_results_per_page_and_skip(): raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ - "value": [ - { - "chatMessageId": message_id_1, - "senderCommunicationIdentifier": { - "rawId": "string", - "communicationUser": { - "id": "string" - } + return mock_response( + status_code=200, + json_payload={ + "value": [ + { + "chatMessageId": message_id_1, + "senderCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, } - } - ]}) + ] + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) read_receipts = None @@ -725,19 +822,24 @@ async def mock_send(*_, **__): assert len(items) == 1 + @pytest.mark.asyncio async def test_get_properties(): thread_id = "19:bcaebfba0d314c2aa3e920d38fa3df08@thread.v2" raised = False async def mock_send(*_, **__): - return mock_response(status_code=200, json_payload={ + return mock_response( + status_code=200, + json_payload={ "id": thread_id, "topic": "Lunch Chat thread", "createdOn": "2020-10-30T10:50:50Z", "deletedOn": "2020-10-30T10:50:50Z", - "createdByCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}} - }) + "createdByCommunicationIdentifier": {"rawId": "string", "communicationUser": {"id": "string"}}, + }, + ) + chat_thread_client = ChatThreadClient("https://endpoint", credential, thread_id, transport=Mock(send=mock_send)) get_thread_result = None diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e.py b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e.py index d027c214d12f..be06be00e178 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e.py @@ -9,12 +9,7 @@ from devtools_testutils import AzureRecordedTestCase, is_live, recorded_by_proxy from azure.communication.identity import CommunicationIdentityClient -from azure.communication.chat import ( - ChatClient, - ChatParticipant, - ChatMessageType, - CommunicationTokenCredential -) +from azure.communication.chat import ChatClient, ChatParticipant, ChatMessageType, CommunicationTokenCredential from azure.communication.chat._shared.utils import parse_connection_str from chat_e2e_helper import get_connection_str @@ -41,14 +36,12 @@ def setup_method(self): # create ChatClient self.chat_client = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token), - http_logging_policy=get_http_logging_policy() + self.endpoint, CommunicationTokenCredential(self.token), http_logging_policy=get_http_logging_policy() ) self.chat_client_new_user = ChatClient( - self.endpoint, + self.endpoint, CommunicationTokenCredential(self.token_new_user), - http_logging_policy=get_http_logging_policy() + http_logging_policy=get_http_logging_policy(), ) def teardown_method(self): @@ -58,42 +51,26 @@ def teardown_method(self): self.identity_client.delete_user(self.user) self.identity_client.delete_user(self.new_user) - def _create_thread( - self, - **kwargs - ): + def _create_thread(self, **kwargs): # create chat thread, and ChatThreadClient topic = "test topic" share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) - participants = [ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - )] + participants = [ + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time) + ] create_chat_thread_result = self.chat_client.create_chat_thread(topic, thread_participants=participants) self.chat_thread_client = self.chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) self.thread_id = self.chat_thread_client.thread_id - def _create_thread_w_two_users( - self, - **kwargs - ): + def _create_thread_w_two_users(self, **kwargs): # create chat thread, and ChatThreadClient topic = "test topic" share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) participants = [ - ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - ), - ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time - ) + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time), + ChatParticipant(identifier=self.new_user, display_name="name", share_history_time=share_history_time), ] create_chat_thread_result = self.chat_client.create_chat_thread(topic, thread_participants=participants) self.chat_thread_client = self.chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) @@ -101,11 +78,9 @@ def _create_thread_w_two_users( def _send_message(self): # send a message - content = 'hello world' - sender_display_name = 'sender name' - create_message_result = self.chat_thread_client.send_message( - content, - sender_display_name=sender_display_name) + content = "hello world" + sender_display_name = "sender name" + create_message_result = self.chat_thread_client.send_message(content, sender_display_name=sender_display_name) message_id = create_message_result.id return message_id @@ -121,12 +96,10 @@ def test_update_topic(self): def test_send_message(self): self._create_thread() - content = 'hello world' - sender_display_name = 'sender name' + content = "hello world" + sender_display_name = "sender name" - create_message_result = self.chat_thread_client.send_message( - content, - sender_display_name=sender_display_name) + create_message_result = self.chat_thread_client.send_message(content, sender_display_name=sender_display_name) create_message_result_id = create_message_result.id assert create_message_result_id is not None @@ -139,7 +112,7 @@ def test_get_message(self): message = self.chat_thread_client.get_message(message_id) assert message.id == message_id assert message.type == ChatMessageType.TEXT - assert message.content.message == 'hello world' + assert message.content.message == "hello world" @pytest.mark.live_test_only @recorded_by_proxy @@ -179,9 +152,8 @@ def test_list_participants(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) self.chat_thread_client.add_participants([new_participant]) @@ -194,10 +166,9 @@ def test_list_participants(self): li = list(chat_thread_participant_page) assert len(li) <= 1 participant_count += len(li) - li[0].identifier.properties['id'] = self.user.properties['id'] + li[0].identifier.properties["id"] = self.user.properties["id"] assert participant_count == 1 - @pytest.mark.live_test_only @recorded_by_proxy def test_add_participants(self): @@ -206,9 +177,8 @@ def test_add_participants(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) participants = [new_participant] failed_participants = self.chat_thread_client.add_participants(participants) @@ -216,7 +186,6 @@ def test_add_participants(self): # no error occured while adding participants assert len(failed_participants) == 0 - @pytest.mark.live_test_only @recorded_by_proxy def test_remove_participant(self): @@ -226,9 +195,8 @@ def test_remove_participant(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) participants = [new_participant] self.chat_thread_client.add_participants(participants) @@ -258,7 +226,6 @@ def test_send_read_receipt(self): self.chat_thread_client.send_read_receipt(message_id) - def _wait_on_thread(self, chat_client, thread_id, message_id): # print("Read Receipts Sent: ", read_receipts_sent) chat_thread_client = chat_client.get_chat_thread_client(thread_id) @@ -276,7 +243,6 @@ def _wait_on_thread(self, chat_client, thread_id, message_id): time.sleep(2) raise Exception("Read receipts not updated in 20 seconds. Failing.") - @pytest.mark.live_test_only @recorded_by_proxy def test_list_read_receipts(self): @@ -295,14 +261,16 @@ def test_list_read_receipts(self): chat_thread_client_new_user = self.chat_client_new_user.get_chat_thread_client(self.thread_id) # second user sends 1 message message_result_new_user = chat_thread_client_new_user.send_message( - "content", - sender_display_name="sender_display_name") + "content", sender_display_name="sender_display_name" + ) message_id_new_user = message_result_new_user.id # send read receipt chat_thread_client_new_user.send_read_receipt(message_id_new_user) if self.is_live: - self._wait_on_thread(chat_client=self.chat_client_new_user, thread_id=self.thread_id, message_id=message_id_new_user) + self._wait_on_thread( + chat_client=self.chat_client_new_user, thread_id=self.thread_id, message_id=message_id_new_user + ) # list read receipts read_receipts = self.chat_thread_client.list_read_receipts(results_per_page=2, skip=0) diff --git a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e_async.py b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e_async.py index 2c81e9d654cd..f510003b9a3a 100644 --- a/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e_async.py +++ b/sdk/communication/azure-communication-chat/tests/test_chat_thread_client_e2e_async.py @@ -10,14 +10,8 @@ from devtools_testutils.aio import recorded_by_proxy_async from azure.communication.identity import CommunicationIdentityClient -from azure.communication.chat.aio import ( - ChatClient, - CommunicationTokenCredential -) -from azure.communication.chat import ( - ChatParticipant, - ChatMessageType -) +from azure.communication.chat.aio import ChatClient, CommunicationTokenCredential +from azure.communication.chat import ChatParticipant, ChatMessageType from azure.communication.chat._shared.utils import parse_connection_str from chat_e2e_helper import get_connection_str @@ -48,14 +42,12 @@ def setup_method(self): # create ChatClient self.chat_client = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token), - http_logging_policy=get_http_logging_policy() + self.endpoint, CommunicationTokenCredential(self.token), http_logging_policy=get_http_logging_policy() ) self.chat_client_new_user = ChatClient( - self.endpoint, - CommunicationTokenCredential(self.token_new_user), - http_logging_policy=get_http_logging_policy() + self.endpoint, + CommunicationTokenCredential(self.token_new_user), + http_logging_policy=get_http_logging_policy(), ) def teardown_method(self): @@ -69,11 +61,9 @@ async def _create_thread(self): topic = "test topic" share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) - participants = [ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - )] + participants = [ + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time) + ] create_chat_thread_result = await self.chat_client.create_chat_thread(topic, thread_participants=participants) self.chat_thread_client = self.chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) self.thread_id = self.chat_thread_client.thread_id @@ -84,29 +74,20 @@ async def _create_thread_w_two_users(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) participants = [ - ChatParticipant( - identifier=self.user, - display_name='name', - share_history_time=share_history_time - ), - ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time - ) + ChatParticipant(identifier=self.user, display_name="name", share_history_time=share_history_time), + ChatParticipant(identifier=self.new_user, display_name="name", share_history_time=share_history_time), ] create_chat_thread_result = await self.chat_client.create_chat_thread(topic, thread_participants=participants) self.chat_thread_client = self.chat_client.get_chat_thread_client(create_chat_thread_result.chat_thread.id) self.thread_id = self.chat_thread_client.thread_id - async def _send_message(self): # send a message - content = 'hello world' - sender_display_name = 'sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = await self.chat_thread_client.send_message( - content, - sender_display_name=sender_display_name) + content, sender_display_name=sender_display_name + ) message_id = create_message_result.id return message_id @@ -133,12 +114,12 @@ async def test_send_message(self): await self._create_thread() async with self.chat_thread_client: - content = 'hello world' - sender_display_name = 'sender name' + content = "hello world" + sender_display_name = "sender name" create_message_result = await self.chat_thread_client.send_message( - content, - sender_display_name=sender_display_name) + content, sender_display_name=sender_display_name + ) create_message_result_id = create_message_result.id assert create_message_result_id @@ -159,7 +140,7 @@ async def test_get_message(self): message = await self.chat_thread_client.get_message(message_id) assert message.id == message_id assert message.type == ChatMessageType.TEXT - assert message.content.message == 'hello world' + assert message.content.message == "hello world" # delete chat threads if not self.is_playback(): @@ -232,9 +213,8 @@ async def test_list_participants(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) await self.chat_thread_client.add_participants([new_participant]) @@ -261,9 +241,8 @@ async def test_add_participants(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) participants = [new_participant] failed_participants = await self.chat_thread_client.add_participants(participants) @@ -286,9 +265,8 @@ async def test_remove_participant(self): share_history_time = datetime.utcnow() share_history_time = share_history_time.replace(tzinfo=timezone.utc) new_participant = ChatParticipant( - identifier=self.new_user, - display_name='name', - share_history_time=share_history_time) + identifier=self.new_user, display_name="name", share_history_time=share_history_time + ) participants = [new_participant] await self.chat_thread_client.add_participants(participants) @@ -372,23 +350,25 @@ async def test_list_read_receipts(self): await self.chat_thread_client.send_read_receipt(message_id) if self.is_live: - await self._wait_on_thread(chat_client=self.chat_client, thread_id=self.thread_id, message_id=message_id) - - + await self._wait_on_thread( + chat_client=self.chat_client, thread_id=self.thread_id, message_id=message_id + ) # get chat thread client for second user chat_thread_client_new_user = self.chat_client_new_user.get_chat_thread_client(self.thread_id) # second user sends 1 message message_result_new_user = await chat_thread_client_new_user.send_message( - "content", - sender_display_name="sender_display_name") + "content", sender_display_name="sender_display_name" + ) message_id_new_user = message_result_new_user.id # send read receipt await chat_thread_client_new_user.send_read_receipt(message_id_new_user) if self.is_live: - await self._wait_on_thread(chat_client=self.chat_client_new_user, thread_id=self.thread_id, message_id=message_id_new_user) + await self._wait_on_thread( + chat_client=self.chat_client_new_user, thread_id=self.thread_id, message_id=message_id_new_user + ) # list read receipts read_receipts = self.chat_thread_client.list_read_receipts(results_per_page=2, skip=0) diff --git a/sdk/communication/azure-communication-chat/tests/test_communication_identifier_serializer.py b/sdk/communication/azure-communication-chat/tests/test_communication_identifier_serializer.py index a78fadf7c78f..77175c1a4f2d 100644 --- a/sdk/communication/azure-communication-chat/tests/test_communication_identifier_serializer.py +++ b/sdk/communication/azure-communication-chat/tests/test_communication_identifier_serializer.py @@ -5,63 +5,52 @@ # ------------------------------------------------------------------------- import unittest from azure.communication.chat._communication_identifier_serializer import serialize_identifier, deserialize_identifier -from azure.communication.chat._generated.models import( +from azure.communication.chat._generated.models import ( CommunicationIdentifierModel, MicrosoftTeamsUserIdentifierModel, CommunicationUserIdentifierModel, - PhoneNumberIdentifierModel + PhoneNumberIdentifierModel, ) -from azure.communication.chat._shared.models import( +from azure.communication.chat._shared.models import ( CommunicationUserIdentifier, CommunicationCloudEnvironment, UnknownIdentifier, PhoneNumberIdentifier, - MicrosoftTeamsUserIdentifier + MicrosoftTeamsUserIdentifier, ) + class CommunicationUserIdentifierSerializerTest(unittest.TestCase): def setUp(self): - self.testPhoneNumber="+12223334444" + self.testPhoneNumber = "+12223334444" self.testUserModel = CommunicationUserIdentifierModel(id="User Id") self.testPhoneNumberModel = PhoneNumberIdentifierModel(value=self.testPhoneNumber) - self.testTeamsUserModel = MicrosoftTeamsUserIdentifierModel(user_id="Microsoft Teams User Id", - is_anonymous=True, - cloud=CommunicationCloudEnvironment.PUBLIC) - + self.testTeamsUserModel = MicrosoftTeamsUserIdentifierModel( + user_id="Microsoft Teams User Id", is_anonymous=True, cloud=CommunicationCloudEnvironment.PUBLIC + ) def test_serialize_communication_user(self): - communication_identifier_model = serialize_identifier( - CommunicationUserIdentifier("an id") - ) + communication_identifier_model = serialize_identifier(CommunicationUserIdentifier("an id")) - assert communication_identifier_model['communication_user']['id'] is "an id" + assert communication_identifier_model["communication_user"]["id"] is "an id" def test_deserialize_communication_user(self): communication_identifier_actual = deserialize_identifier( - CommunicationIdentifierModel( - raw_id="an id", - communication_user=self.testUserModel - ) + CommunicationIdentifierModel(raw_id="an id", communication_user=self.testUserModel) ) communication_identifier_expected = CommunicationUserIdentifier("an id") assert isinstance(communication_identifier_actual, CommunicationUserIdentifier) - assert communication_identifier_actual.properties['id'] == communication_identifier_expected.properties['id'] + assert communication_identifier_actual.properties["id"] == communication_identifier_expected.properties["id"] def test_serialize_unknown_identifier(self): - unknown_identifier_model = serialize_identifier( - UnknownIdentifier("an id") - ) + unknown_identifier_model = serialize_identifier(UnknownIdentifier("an id")) - assert unknown_identifier_model['raw_id'] is "an id" + assert unknown_identifier_model["raw_id"] is "an id" def test_deserialize_unknown_identifier(self): - unknown_identifier_actual = deserialize_identifier( - CommunicationIdentifierModel( - raw_id="an id" - ) - ) + unknown_identifier_actual = deserialize_identifier(CommunicationIdentifierModel(raw_id="an id")) unknown_identifier_expected = UnknownIdentifier("an id") @@ -69,66 +58,59 @@ def test_deserialize_unknown_identifier(self): assert unknown_identifier_actual.raw_id == unknown_identifier_expected.raw_id def test_serialize_phone_number(self): - phone_number_identifier_model = serialize_identifier( - PhoneNumberIdentifier("phonenumber") - ) + phone_number_identifier_model = serialize_identifier(PhoneNumberIdentifier("phonenumber")) - assert phone_number_identifier_model['phone_number']['value'] is "phonenumber" + assert phone_number_identifier_model["phone_number"]["value"] is "phonenumber" def test_deserialize_phone_number(self): phone_number_identifier_actual = deserialize_identifier( - CommunicationIdentifierModel( - raw_id="someid", - phone_number=self.testPhoneNumberModel - ) + CommunicationIdentifierModel(raw_id="someid", phone_number=self.testPhoneNumberModel) ) phone_number_identifier_expected = PhoneNumberIdentifier(self.testPhoneNumber, raw_id="someid") assert isinstance(phone_number_identifier_actual, PhoneNumberIdentifier) - assert phone_number_identifier_actual.properties['value'] == phone_number_identifier_expected.properties['value'] + assert ( + phone_number_identifier_actual.properties["value"] == phone_number_identifier_expected.properties["value"] + ) assert phone_number_identifier_actual.raw_id == phone_number_identifier_expected.raw_id def test_serialize_teams_user(self): teams_user_identifier_model = serialize_identifier( - MicrosoftTeamsUserIdentifier( - user_id="teamsid", - cloud=CommunicationCloudEnvironment.PUBLIC, - raw_id="someid" - ) + MicrosoftTeamsUserIdentifier(user_id="teamsid", cloud=CommunicationCloudEnvironment.PUBLIC, raw_id="someid") ) - assert teams_user_identifier_model['microsoft_teams_user']['user_id'] is "teamsid" - assert teams_user_identifier_model['microsoft_teams_user']['cloud'] is CommunicationCloudEnvironment.PUBLIC - assert teams_user_identifier_model['raw_id'] is "someid" + assert teams_user_identifier_model["microsoft_teams_user"]["user_id"] is "teamsid" + assert teams_user_identifier_model["microsoft_teams_user"]["cloud"] is CommunicationCloudEnvironment.PUBLIC + assert teams_user_identifier_model["raw_id"] is "someid" def test_deserialize_teams_user(self): teams_user_identifier_actual = deserialize_identifier( - CommunicationIdentifierModel( - raw_id="someid", - microsoft_teams_user=self.testTeamsUserModel - ) + CommunicationIdentifierModel(raw_id="someid", microsoft_teams_user=self.testTeamsUserModel) ) teams_user_identifier_expected = MicrosoftTeamsUserIdentifier( raw_id="someid", user_id="Microsoft Teams User Id", cloud=CommunicationCloudEnvironment.PUBLIC, - is_anonymous=True + is_anonymous=True, ) assert isinstance(teams_user_identifier_actual, MicrosoftTeamsUserIdentifier) assert teams_user_identifier_actual.raw_id == teams_user_identifier_expected.raw_id - assert teams_user_identifier_actual.properties['user_id'] == teams_user_identifier_expected.properties['user_id'] - assert teams_user_identifier_actual.properties['is_anonymous'] == teams_user_identifier_expected.properties['is_anonymous'] - assert teams_user_identifier_actual.properties['cloud'] == teams_user_identifier_expected.properties['cloud'] + assert ( + teams_user_identifier_actual.properties["user_id"] == teams_user_identifier_expected.properties["user_id"] + ) + assert ( + teams_user_identifier_actual.properties["is_anonymous"] + == teams_user_identifier_expected.properties["is_anonymous"] + ) + assert teams_user_identifier_actual.properties["cloud"] == teams_user_identifier_expected.properties["cloud"] def test_serialize_foreign_throws(self): foreign_obj = "Foreign object" - self.assertRaises( - TypeError, - lambda : serialize_identifier(foreign_obj) - ) + self.assertRaises(TypeError, lambda: serialize_identifier(foreign_obj)) + if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/sdk/communication/azure-communication-chat/tests/unittest_helpers.py b/sdk/communication/azure-communication-chat/tests/unittest_helpers.py index 45142b807611..3bc29f4ede4b 100644 --- a/sdk/communication/azure-communication-chat/tests/unittest_helpers.py +++ b/sdk/communication/azure-communication-chat/tests/unittest_helpers.py @@ -18,4 +18,4 @@ def mock_response(status_code=200, headers=None, json_payload=None): response.text = lambda encoding=None: "" response.headers["content-type"] = "text/plain" response.content_type = "text/plain" - return response \ No newline at end of file + return response diff --git a/sdk/communication/azure-communication-email/azure/communication/email/__init__.py b/sdk/communication/azure-communication-email/azure/communication/email/__init__.py index b6ecdc17c2cb..6916c6bfc57c 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/__init__.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/__init__.py @@ -6,4 +6,4 @@ from ._email_client import EmailClient -__all__ = ['EmailClient'] +__all__ = ["EmailClient"] diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_email_client.py b/sdk/communication/azure-communication-email/azure/communication/email/_email_client.py index 65e5a10d1f3e..c54ed6c368c2 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_email_client.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_email_client.py @@ -37,17 +37,13 @@ class EmailClient(object): Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ - def __init__( - self, - endpoint: str, - credential: Union[TokenCredential, AzureKeyCredential], - **kwargs - ) -> None: + + def __init__(self, endpoint: str, credential: Union[TokenCredential, AzureKeyCredential], **kwargs) -> None: try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Account URL must be a string.") # pylint: disable=raise-missing-from + raise ValueError("Account URL must be a string.") # pylint: disable=raise-missing-from if endpoint.endswith("/"): endpoint = endpoint[:-1] @@ -57,18 +53,11 @@ def __init__( authentication_policy = get_authentication_policy(endpoint, credential) self._generated_client = AzureCommunicationEmailService( - endpoint, - authentication_policy=authentication_policy, - sdk_moniker=SDK_MONIKER, - **kwargs + endpoint, authentication_policy=authentication_policy, sdk_moniker=SDK_MONIKER, **kwargs ) @classmethod - def from_connection_string( - cls, - conn_str: str, - **kwargs - ) -> 'EmailClient': + def from_connection_string(cls, conn_str: str, **kwargs) -> "EmailClient": """Create EmailClient from a Connection String. :param str conn_str: @@ -81,11 +70,7 @@ def from_connection_string( return cls(endpoint, AzureKeyCredential(access_key), **kwargs) @distributed_trace - def begin_send( - self, - message: Union[JSON, IO], - **kwargs: Any - ) -> LROPoller[JSON]: + def begin_send(self, message: Union[JSON, IO], **kwargs: Any) -> LROPoller[JSON]: # cSpell:disable """Queues an email message to be sent to one or more recipients. diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/auth_policy_utils.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/auth_policy_utils.py index d3bc1bfda04f..a771dd2fd42f 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/auth_policy_utils.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/auth_policy_utils.py @@ -43,9 +43,7 @@ def get_authentication_policy( return AsyncBearerTokenCredentialPolicy( credential, "https://communication.azure.com//.default" # type: ignore ) - return BearerTokenCredentialPolicy( - credential, "https://communication.azure.com//.default" # type: ignore - ) + return BearerTokenCredentialPolicy(credential, "https://communication.azure.com//.default") # type: ignore if isinstance(credential, (AzureKeyCredential, str)): return HMACCredentialsPolicy(endpoint, credential, decode_url=decode_url) diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/models.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/models.py index 7b646472045c..43875e1197e5 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/models.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/models.py @@ -14,8 +14,11 @@ class DeprecatedEnumMeta(CaseInsensitiveEnumMeta): def __getattribute__(cls, item): if item.upper() == "MICROSOFT_BOT": - warnings.warn("MICROSOFT_BOT is deprecated and has been replaced by \ - MICROSOFT_TEAMS_APP identifier.", DeprecationWarning) + warnings.warn( + "MICROSOFT_BOT is deprecated and has been replaced by \ + MICROSOFT_TEAMS_APP identifier.", + DeprecationWarning, + ) item = "MICROSOFT_TEAMS_APP" return super().__getattribute__(item) @@ -47,14 +50,17 @@ class CommunicationCloudEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta @runtime_checkable class CommunicationIdentifier(Protocol): """Communication Identifier.""" + @property def raw_id(self) -> str: """The raw ID of the identifier.""" ... + @property def kind(self) -> CommunicationIdentifierKind: """The type of identifier.""" ... + @property def properties(self) -> Mapping[str, Any]: """The properties of the identifier.""" @@ -83,12 +89,14 @@ def properties(self) -> Mapping[str, Any]: class CommunicationUserProperties(TypedDict): """Dictionary of properties for a CommunicationUserIdentifier.""" + id: str """ID of the Communication user as returned from Azure Communication Identity.""" class CommunicationUserIdentifier: """Represents a user in Azure Communication Service.""" + kind: Literal[CommunicationIdentifierKind.COMMUNICATION_USER] = CommunicationIdentifierKind.COMMUNICATION_USER """The type of identifier.""" properties: CommunicationUserProperties @@ -116,12 +124,14 @@ def __eq__(self, other): class PhoneNumberProperties(TypedDict): """Dictionary of properties for a PhoneNumberIdentifier.""" + value: str """The phone number in E.164 format.""" class PhoneNumberIdentifier: """Represents a phone number.""" + kind: Literal[CommunicationIdentifierKind.PHONE_NUMBER] = CommunicationIdentifierKind.PHONE_NUMBER """The type of identifier.""" properties: PhoneNumberProperties @@ -165,6 +175,7 @@ class UnknownIdentifier: It is not advisable to rely on the `kind` property with a value `unknown`, as it could become a new or existing distinct type in the future. """ + kind: Literal[CommunicationIdentifierKind.UNKNOWN] = CommunicationIdentifierKind.UNKNOWN """The type of identifier.""" properties: Mapping[str, Any] @@ -188,6 +199,7 @@ def __eq__(self, other): class MicrosoftTeamsUserProperties(TypedDict): """Dictionary of properties for a MicrosoftTeamsUserIdentifier.""" + 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 @@ -198,6 +210,7 @@ class MicrosoftTeamsUserProperties(TypedDict): class MicrosoftTeamsUserIdentifier: """Represents an identifier for a Microsoft Teams user.""" + kind: Literal[CommunicationIdentifierKind.MICROSOFT_TEAMS_USER] = CommunicationIdentifierKind.MICROSOFT_TEAMS_USER """The type of identifier.""" properties: MicrosoftTeamsUserProperties @@ -246,6 +259,7 @@ def _format_raw_id(self, properties: MicrosoftTeamsUserProperties) -> str: class MicrosoftTeamsAppProperties(TypedDict): """Dictionary of properties for a MicrosoftTeamsAppIdentifier.""" + app_id: str """The id of the Microsoft Teams application.""" cloud: Union[CommunicationCloudEnvironment, str] @@ -254,6 +268,7 @@ class MicrosoftTeamsAppProperties(TypedDict): class _botbackcompatdict(dict): """Backwards compatible properties.""" + def __getitem__(self, __key: Any) -> Any: try: return super().__getitem__(__key) @@ -267,6 +282,7 @@ def __getitem__(self, __key: Any) -> Any: class MicrosoftTeamsAppIdentifier: """Represents an identifier for a Microsoft Teams application.""" + kind: Literal[CommunicationIdentifierKind.MICROSOFT_TEAMS_APP] = CommunicationIdentifierKind.MICROSOFT_TEAMS_APP """The type of identifier.""" properties: MicrosoftTeamsAppProperties @@ -282,10 +298,13 @@ def __init__(self, app_id: str, **kwargs: Any) -> None: :keyword str raw_id: The raw ID of the identifier. If not specified, this value will be constructed from the other properties. """ - self.properties = cast(MicrosoftTeamsAppProperties, _botbackcompatdict( - app_id=app_id, - cloud=kwargs.get("cloud") or CommunicationCloudEnvironment.PUBLIC, - )) + self.properties = cast( + MicrosoftTeamsAppProperties, + _botbackcompatdict( + app_id=app_id, + cloud=kwargs.get("cloud") or CommunicationCloudEnvironment.PUBLIC, + ), + ) raw_id: Optional[str] = kwargs.get("raw_id") self.raw_id = raw_id if raw_id is not None else self._format_raw_id(self.properties) @@ -323,7 +342,7 @@ def __init__(self, bot_id, **kwargs): """ warnings.warn( "The MicrosoftBotIdentifier is deprecated and has been replaced by MicrosoftTeamsAppIdentifier.", - DeprecationWarning + DeprecationWarning, ) super().__init__(bot_id, **kwargs) @@ -339,9 +358,7 @@ def identifier_from_raw_id(raw_id: str) -> CommunicationIdentifier: # pylint: d :rtype: CommunicationIdentifier """ if raw_id.startswith(PHONE_NUMBER_PREFIX): - return PhoneNumberIdentifier( - value=raw_id[len(PHONE_NUMBER_PREFIX) :], raw_id=raw_id - ) + return PhoneNumberIdentifier(value=raw_id[len(PHONE_NUMBER_PREFIX) :], raw_id=raw_id) segments = raw_id.split(":", maxsplit=2) if len(segments) < 3: @@ -350,9 +367,7 @@ def identifier_from_raw_id(raw_id: str) -> CommunicationIdentifier: # pylint: d prefix = f"{segments[0]}:{segments[1]}:" suffix = segments[2] if prefix == TEAMS_USER_ANONYMOUS_PREFIX: - return MicrosoftTeamsUserIdentifier( - user_id=suffix, is_anonymous=True, raw_id=raw_id - ) + return MicrosoftTeamsUserIdentifier(user_id=suffix, is_anonymous=True, raw_id=raw_id) if prefix == TEAMS_USER_PUBLIC_CLOUD_PREFIX: return MicrosoftTeamsUserIdentifier( user_id=suffix, diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/policy.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/policy.py index 2fd2e7426c73..79aa48136fd3 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/policy.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/policy.py @@ -50,9 +50,7 @@ def _compute_hmac( else: decoded_secret = base64.b64decode(self._access_key) - digest = hmac.new( - decoded_secret, value.encode("utf-8"), hashlib.sha256 - ).digest() + digest = hmac.new(decoded_secret, value.encode("utf-8"), hashlib.sha256).digest() return base64.b64encode(digest).decode("utf-8") @@ -101,22 +99,10 @@ def _sign_request(self, request): utc_now = get_current_utc_time() if request.http_request.body is None: request.http_request.body = "" - content_digest = hashlib.sha256( - (request.http_request.body.encode("utf-8")) - ).digest() + content_digest = hashlib.sha256((request.http_request.body.encode("utf-8"))).digest() content_hash = base64.b64encode(content_digest).decode("utf-8") - string_to_sign = ( - verb - + "\n" - + query_url - + "\n" - + utc_now - + ";" - + self._host - + ";" - + content_hash - ) + string_to_sign = verb + "\n" + query_url + "\n" + utc_now + ";" + self._host + ";" + content_hash signature = self._compute_hmac(string_to_sign) @@ -124,10 +110,7 @@ def _sign_request(self, request): "x-ms-date": utc_now, "x-ms-content-sha256": content_hash, "x-ms-return-client-request-id": "true", - "Authorization": "HMAC-SHA256 SignedHeaders=" - + signed_headers - + "&Signature=" - + signature, + "Authorization": "HMAC-SHA256 SignedHeaders=" + signed_headers + "&Signature=" + signature, } request.http_request.headers.update(signature_header) diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential.py index c7c150052918..54603e7b32ce 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential.py @@ -38,9 +38,7 @@ def __init__(self, token: str, **kwargs: Any): self._token_refresher = kwargs.pop("token_refresher", None) self._proactive_refresh = kwargs.pop("proactive_refresh", False) if self._proactive_refresh and self._token_refresher is None: - raise ValueError( - "When 'proactive_refresh' is True, 'token_refresher' must not be None." - ) + raise ValueError("When 'proactive_refresh' is True, 'token_refresher' must not be None.") self._timer = None self._lock = Condition(Lock()) self._some_thread_refreshing = False @@ -54,9 +52,7 @@ def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument :rtype: ~azure.core.credentials.AccessToken """ if self._proactive_refresh and self._is_closed.is_set(): - raise RuntimeError( - "An instance of CommunicationTokenCredential cannot be reused once it has been closed." - ) + raise RuntimeError("An instance of CommunicationTokenCredential cannot be reused once it has been closed.") if not self._token_refresher or not self._is_token_expiring_soon(self._token): return self._token @@ -80,9 +76,7 @@ def _update_token_and_reschedule(self): try: new_token = self._token_refresher() if not self._is_token_valid(new_token): - raise ValueError( - "The token returned from the token_refresher is expired." - ) + raise ValueError("The token returned from the token_refresher is expired.") with self._lock: self._token = new_token self._some_thread_refreshing = False @@ -109,12 +103,7 @@ def _schedule_refresh(self): timespan = token_ttl // 2 else: # Schedule the next refresh for when it gets in to the soon-to-expire window. - timespan = ( - token_ttl - - timedelta( - minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES - ).total_seconds() - ) + timespan = token_ttl - timedelta(minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES).total_seconds() if timespan <= TIMEOUT_MAX: self._timer = Timer(timespan, self._update_token_and_reschedule) self._timer.daemon = True diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential_async.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential_async.py index dcd934aba464..15ad17da1a8c 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential_async.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/user_credential_async.py @@ -40,9 +40,7 @@ def __init__(self, token: str, **kwargs: Any): self._token_refresher = kwargs.pop("token_refresher", None) self._proactive_refresh = kwargs.pop("proactive_refresh", False) if self._proactive_refresh and self._token_refresher is None: - raise ValueError( - "When 'proactive_refresh' is True, 'token_refresher' must not be None." - ) + raise ValueError("When 'proactive_refresh' is True, 'token_refresher' must not be None.") self._timer = None self._async_mutex = Lock() if sys.version_info[:3] == (3, 10, 0): @@ -60,9 +58,7 @@ async def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument :rtype: ~azure.core.credentials.AccessToken """ if self._proactive_refresh and self._is_closed.is_set(): - raise RuntimeError( - "An instance of CommunicationTokenCredential cannot be reused once it has been closed." - ) + raise RuntimeError("An instance of CommunicationTokenCredential cannot be reused once it has been closed.") if not self._token_refresher or not self._is_token_expiring_soon(self._token): return self._token @@ -86,9 +82,7 @@ async def _update_token_and_reschedule(self): try: new_token = await self._token_refresher() if not self._is_token_valid(new_token): - raise ValueError( - "The token returned from the token_refresher is expired." - ) + raise ValueError("The token returned from the token_refresher is expired.") async with self._lock: self._token = new_token self._some_thread_refreshing = False @@ -115,12 +109,7 @@ def _schedule_refresh(self): timespan = token_ttl // 2 else: # Schedule the next refresh for when it gets in to the soon-to-expire window. - timespan = ( - token_ttl - - timedelta( - minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES - ).total_seconds() - ) + timespan = token_ttl - timedelta(minutes=self._DEFAULT_AUTOREFRESH_INTERVAL_MINUTES).total_seconds() self._timer = AsyncTimer(timespan, self._update_token_and_reschedule) self._timer.start() diff --git a/sdk/communication/azure-communication-email/azure/communication/email/_shared/utils.py b/sdk/communication/azure-communication-email/azure/communication/email/_shared/utils.py index 47da8a283e5f..8576c31ddc56 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/_shared/utils.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/_shared/utils.py @@ -87,9 +87,7 @@ def create_access_token(token): payload = json.loads(padded_base64_payload) return AccessToken( token, - _convert_datetime_to_utc_int( - datetime.fromtimestamp(payload["exp"], TZ_UTC) - ), + _convert_datetime_to_utc_int(datetime.fromtimestamp(payload["exp"], TZ_UTC)), ) except ValueError as val_error: raise ValueError(token_parse_err_msg) from val_error diff --git a/sdk/communication/azure-communication-email/azure/communication/email/aio/__init__.py b/sdk/communication/azure-communication-email/azure/communication/email/aio/__init__.py index aa02483033ff..a74f3c131fb1 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/aio/__init__.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/aio/__init__.py @@ -1,5 +1,5 @@ from ._email_client_async import EmailClient __all__ = [ - 'EmailClient', + "EmailClient", ] diff --git a/sdk/communication/azure-communication-email/azure/communication/email/aio/_email_client_async.py b/sdk/communication/azure-communication-email/azure/communication/email/aio/_email_client_async.py index 90fcddb4fb4a..5e287c1840b4 100644 --- a/sdk/communication/azure-communication-email/azure/communication/email/aio/_email_client_async.py +++ b/sdk/communication/azure-communication-email/azure/communication/email/aio/_email_client_async.py @@ -22,7 +22,8 @@ from typing import MutableMapping # type: ignore # pylint: disable=ungrouped-imports JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object -class EmailClient(object): # pylint: disable=client-accepts-api-version-keyword + +class EmailClient(object): # pylint: disable=client-accepts-api-version-keyword """A client to interact with the AzureCommunicationService Email gateway asynchronously. This client provides operations to send an email and monitor its status. @@ -36,17 +37,13 @@ class EmailClient(object): # pylint: disable=client-accepts-api-version-keyword Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ - def __init__( - self, - endpoint: str, - credential: Union[AsyncTokenCredential, AzureKeyCredential], - **kwargs - ) -> None: + + def __init__(self, endpoint: str, credential: Union[AsyncTokenCredential, AzureKeyCredential], **kwargs) -> None: try: - if not endpoint.lower().startswith('http'): + if not endpoint.lower().startswith("http"): endpoint = "https://" + endpoint except AttributeError: - raise ValueError("Account URL must be a string.") # pylint: disable=raise-missing-from + raise ValueError("Account URL must be a string.") # pylint: disable=raise-missing-from if endpoint.endswith("/"): endpoint = endpoint[:-1] @@ -56,18 +53,11 @@ def __init__( authentication_policy = get_authentication_policy(endpoint, credential, decode_url=True, is_async=True) self._generated_client = AzureCommunicationEmailService( - endpoint, - authentication_policy=authentication_policy, - sdk_moniker=SDK_MONIKER, - **kwargs + endpoint, authentication_policy=authentication_policy, sdk_moniker=SDK_MONIKER, **kwargs ) @classmethod - def from_connection_string( - cls, - conn_str: str, - **kwargs - ) -> 'EmailClient': + def from_connection_string(cls, conn_str: str, **kwargs) -> "EmailClient": """Create EmailClient from a Connection String. :param str conn_str: @@ -80,11 +70,7 @@ def from_connection_string( return cls(endpoint, AzureKeyCredential(access_key), **kwargs) @distributed_trace_async - async def begin_send( - self, - message: Union[JSON, IO], - **kwargs: Any - ) -> AsyncLROPoller[JSON]: + async def begin_send(self, message: Union[JSON, IO], **kwargs: Any) -> AsyncLROPoller[JSON]: # cSpell:disable """Queues an email message to be sent to one or more recipients. diff --git a/sdk/communication/azure-communication-email/samples/send_email_to_multiple_recipients_sample.py b/sdk/communication/azure-communication-email/samples/send_email_to_multiple_recipients_sample.py index 4009aaf0f805..283063d82ecc 100644 --- a/sdk/communication/azure-communication-email/samples/send_email_to_multiple_recipients_sample.py +++ b/sdk/communication/azure-communication-email/samples/send_email_to_multiple_recipients_sample.py @@ -27,6 +27,7 @@ sys.path.append("..") + class EmailMultipleRecipientSample(object): connection_string = os.getenv("COMMUNICATION_CONNECTION_STRING_EMAIL") @@ -43,34 +44,35 @@ def send_email_to_multiple_recipients(self): "content": { "subject": "This is the subject", "plainText": "This is the body", - "html": "html>