Skip to content

Commit

Permalink
Communication chat - paginated results for participants and readrecei…
Browse files Browse the repository at this point in the history
…pts (#15682)

* Failed participant check + single member add
* Add failed participant check in response header for create_thread method
* New convention method add_participant(thread_participant: ChatThreadParticipant) - sync and async

* Add empty line at the end of files

* Enable pagination for list participants

* Enable pagination for read receipts

* conflicts resolved after merge with upstream

* update README.md

* e2e test fix

* bkp commit

* updated e2e tests

* adding test recording

Co-authored-by: Leo Li <jixli@microsoft.com>
  • Loading branch information
sarkar-rajarshi and Leo Li authored Jan 25, 2021
1 parent 1e5e65e commit db42686
Show file tree
Hide file tree
Showing 45 changed files with 4,304 additions and 2,109 deletions.
4 changes: 2 additions & 2 deletions sdk/communication/azure-communication-chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ Use `list_participants` to retrieve the participants of the thread.
An iterator of `[ChatThreadParticipant]` is the response returned from listing participants

```python
chat_thread_participants = chat_thread_client.list_participants()
chat_thread_participants = chat_thread_client.list_participants(results_per_page=5, skip=5)
for chat_thread_participant in chat_thread_participants:
print(chat_thread_participant)
```
Expand Down Expand Up @@ -352,7 +352,7 @@ chat_thread_client.send_read_receipt(message_id)
An iterator of `[ChatMessageReadReceipt]` is the response returned from listing read receipts

```python
read_receipts = chat_thread_client.list_read_receipts()
read_receipts = chat_thread_client.list_read_receipts(results_per_page=5, skip=5)
for read_receipt in read_receipts:
print(read_receipt)
print(read_receipt.sender)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ def list_read_receipts(
# type: (...) -> ItemPaged[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.
:keyword int skip: Skips chat message read receipts up to a specified position in response.
:keyword callable cls: A custom type or function that will be passed the direct response
:return: ItemPaged[:class:`~azure.communication.chat.ChatMessageReadReceipt`]
:rtype: ~azure.core.paging.ItemPaged
Expand All @@ -201,8 +203,13 @@ def list_read_receipts(
:dedent: 8
:caption: Listing read receipts.
"""
results_per_page = kwargs.pop("results_per_page", None)
skip = kwargs.pop("skip", None)

return self._client.chat_thread.list_chat_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)

Expand Down Expand Up @@ -337,7 +344,7 @@ def list_messages(

a = self._client.chat_thread.list_chat_messages(
self._thread_id,
maxpagesize=results_per_page,
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)
Expand Down Expand Up @@ -423,6 +430,8 @@ def list_participants(
# type: (...) -> ItemPaged[ChatThreadParticipant]
"""Gets the participants of a thread.
:keyword int results_per_page: The maximum number of participants to be returned per page.
:keyword int skip: Skips participants up to a specified position in response.
:keyword callable cls: A custom type or function that will be passed the direct response
:return: ItemPaged[:class:`~azure.communication.chat.ChatThreadParticipant`]
:rtype: ~azure.core.paging.ItemPaged
Expand All @@ -438,8 +447,13 @@ def list_participants(
:caption: Listing participants of chat thread.
"""

results_per_page = kwargs.pop("results_per_page", None)
skip = kwargs.pop("skip", None)

return self._client.chat_thread.list_chat_participants(
self._thread_id,
max_page_size=results_per_page,
skip=skip,
cls=lambda objs: [ChatThreadParticipant._from_generated(x) for x in objs], # pylint:disable=protected-access
**kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, client, config, serializer, deserializer) -> None:
def list_chat_read_receipts(
self,
chat_thread_id: str,
maxpagesize: Optional[int] = None,
max_page_size: Optional[int] = None,
skip: Optional[int] = None,
**kwargs
) -> AsyncIterable["_models.ChatMessageReadReceiptsCollection"]:
Expand All @@ -54,8 +54,8 @@ def list_chat_read_receipts(
:param chat_thread_id: Thread id to get the chat message read receipts for.
:type chat_thread_id: str
:param maxpagesize: The maximum number of chat message read receipts to be returned per page.
:type maxpagesize: int
:param max_page_size: The maximum number of chat message read receipts to be returned per page.
:type max_page_size: int
:param skip: Skips chat message read receipts up to a specified position in response.
:type skip: int
:keyword callable cls: A custom type or function that will be passed the direct response
Expand Down Expand Up @@ -91,8 +91,8 @@ def prepare_request(next_link=None):
url = self._client.format_url(url, **path_format_arguments)
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if maxpagesize is not None:
query_parameters['$maxpagesize'] = self._serialize.query("maxpagesize", maxpagesize, 'int')
if max_page_size is not None:
query_parameters['maxPageSize'] = self._serialize.query("max_page_size", max_page_size, 'int')
if skip is not None:
query_parameters['skip'] = self._serialize.query("skip", skip, 'int')
query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
Expand Down Expand Up @@ -190,7 +190,7 @@ async def send_chat_read_receipt(
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
response = pipeline_response.http_response

if response.status_code not in [201]:
if response.status_code not in [200]:
map_error(status_code=response.status_code, response=response, error_map=error_map)
raise HttpResponseError(response=response)

Expand Down Expand Up @@ -271,7 +271,7 @@ async def send_chat_message(
def list_chat_messages(
self,
chat_thread_id: str,
maxpagesize: Optional[int] = None,
max_page_size: Optional[int] = None,
start_time: Optional[datetime.datetime] = None,
**kwargs
) -> AsyncIterable["_models.ChatMessagesCollection"]:
Expand All @@ -281,8 +281,8 @@ def list_chat_messages(
:param chat_thread_id: The thread id of the message.
:type chat_thread_id: str
:param maxpagesize: The maximum number of messages to be returned per page.
:type maxpagesize: int
:param max_page_size: The maximum number of messages to be returned per page.
:type max_page_size: int
:param start_time: The earliest point in time to get messages up to. The timestamp should be in
RFC3339 format: ``yyyy-MM-ddTHH:mm:ssZ``.
:type start_time: ~datetime.datetime
Expand Down Expand Up @@ -319,8 +319,8 @@ def prepare_request(next_link=None):
url = self._client.format_url(url, **path_format_arguments)
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if maxpagesize is not None:
query_parameters['$maxpagesize'] = self._serialize.query("maxpagesize", maxpagesize, 'int')
if max_page_size is not None:
query_parameters['maxPageSize'] = self._serialize.query("max_page_size", max_page_size, 'int')
if start_time is not None:
query_parameters['startTime'] = self._serialize.query("start_time", start_time, 'iso-8601')
query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
Expand Down Expand Up @@ -619,7 +619,7 @@ async def send_typing_notification(
def list_chat_participants(
self,
chat_thread_id: str,
maxpagesize: Optional[int] = None,
max_page_size: Optional[int] = None,
skip: Optional[int] = None,
**kwargs
) -> AsyncIterable["_models.ChatParticipantsCollection"]:
Expand All @@ -629,8 +629,8 @@ def list_chat_participants(
:param chat_thread_id: Thread id to get participants for.
:type chat_thread_id: str
:param maxpagesize: The maximum number of participants to be returned per page.
:type maxpagesize: int
:param max_page_size: The maximum number of participants to be returned per page.
:type max_page_size: int
:param skip: Skips participants up to a specified position in response.
:type skip: int
:keyword callable cls: A custom type or function that will be passed the direct response
Expand Down Expand Up @@ -666,8 +666,8 @@ def prepare_request(next_link=None):
url = self._client.format_url(url, **path_format_arguments)
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if maxpagesize is not None:
query_parameters['$maxpagesize'] = self._serialize.query("maxpagesize", maxpagesize, 'int')
if max_page_size is not None:
query_parameters['maxPageSize'] = self._serialize.query("max_page_size", max_page_size, 'int')
if skip is not None:
query_parameters['skip'] = self._serialize.query("skip", skip, 'int')
query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
Expand Down Expand Up @@ -708,26 +708,26 @@ async def get_next(next_link=None):
)
list_chat_participants.metadata = {'url': '/chat/threads/{chatThreadId}/participants'} # type: ignore

async def add_chat_participants(
async def remove_chat_participant(
self,
chat_thread_id: str,
add_chat_participants_request: "_models.AddChatParticipantsRequest",
chat_participant_id: str,
**kwargs
) -> "_models.AddChatParticipantsResult":
"""Adds thread participants to a thread. If participants already exist, no change occurs.
) -> None:
"""Remove a participant from a thread.
Adds thread participants to a thread. If participants already exist, no change occurs.
Remove a participant from a thread.
:param chat_thread_id: Id of the thread to add participants to.
:param chat_thread_id: Thread id to remove the participant from.
:type chat_thread_id: str
:param add_chat_participants_request: Thread participants to be added to the thread.
:type add_chat_participants_request: ~azure.communication.chat.models.AddChatParticipantsRequest
:param chat_participant_id: Id of the thread participant to remove from the thread.
:type chat_participant_id: str
:keyword callable cls: A custom type or function that will be passed the direct response
:return: AddChatParticipantsResult, or the result of cls(response)
:rtype: ~azure.communication.chat.models.AddChatParticipantsResult
:return: None, or the result of cls(response)
:rtype: None
:raises: ~azure.core.exceptions.HttpResponseError
"""
cls = kwargs.pop('cls', None) # type: ClsType["_models.AddChatParticipantsResult"]
cls = kwargs.pop('cls', None) # type: ClsType[None]
error_map = {
404: ResourceNotFoundError,
409: ResourceExistsError,
Expand All @@ -738,14 +738,14 @@ async def add_chat_participants(
}
error_map.update(kwargs.pop('error_map', {}))
api_version = "2020-11-01-preview3"
content_type = kwargs.pop("content_type", "application/json")
accept = "application/json"

# Construct URL
url = self.add_chat_participants.metadata['url'] # type: ignore
url = self.remove_chat_participant.metadata['url'] # type: ignore
path_format_arguments = {
'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
'chatThreadId': self._serialize.url("chat_thread_id", chat_thread_id, 'str'),
'chatParticipantId': self._serialize.url("chat_participant_id", chat_participant_id, 'str'),
}
url = self._client.format_url(url, **path_format_arguments)

Expand All @@ -755,48 +755,41 @@ async def add_chat_participants(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

body_content_kwargs = {} # type: Dict[str, Any]
body_content = self._serialize.body(add_chat_participants_request, 'AddChatParticipantsRequest')
body_content_kwargs['content'] = body_content
request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
request = self._client.delete(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
response = pipeline_response.http_response

if response.status_code not in [201]:
if response.status_code not in [204]:
map_error(status_code=response.status_code, response=response, error_map=error_map)
raise HttpResponseError(response=response)

deserialized = self._deserialize('AddChatParticipantsResult', pipeline_response)

if cls:
return cls(pipeline_response, deserialized, {})
return cls(pipeline_response, None, {})

return deserialized
add_chat_participants.metadata = {'url': '/chat/threads/{chatThreadId}/participants'} # type: ignore
remove_chat_participant.metadata = {'url': '/chat/threads/{chatThreadId}/participants/{chatParticipantId}'} # type: ignore

async def remove_chat_participant(
async def add_chat_participants(
self,
chat_thread_id: str,
chat_participant_id: str,
add_chat_participants_request: "_models.AddChatParticipantsRequest",
**kwargs
) -> None:
"""Remove a participant from a thread.
) -> "_models.AddChatParticipantsResult":
"""Adds thread participants to a thread. If participants already exist, no change occurs.
Remove a participant from a thread.
Adds thread participants to a thread. If participants already exist, no change occurs.
:param chat_thread_id: Thread id to remove the participant from.
:param chat_thread_id: Id of the thread to add participants to.
:type chat_thread_id: str
:param chat_participant_id: Id of the thread participant to remove from the thread.
:type chat_participant_id: str
:param add_chat_participants_request: Thread participants to be added to the thread.
:type add_chat_participants_request: ~azure.communication.chat.models.AddChatParticipantsRequest
:keyword callable cls: A custom type or function that will be passed the direct response
:return: None, or the result of cls(response)
:rtype: None
:return: AddChatParticipantsResult, or the result of cls(response)
:rtype: ~azure.communication.chat.models.AddChatParticipantsResult
:raises: ~azure.core.exceptions.HttpResponseError
"""
cls = kwargs.pop('cls', None) # type: ClsType[None]
cls = kwargs.pop('cls', None) # type: ClsType["_models.AddChatParticipantsResult"]
error_map = {
404: ResourceNotFoundError,
409: ResourceExistsError,
Expand All @@ -807,14 +800,14 @@ async def remove_chat_participant(
}
error_map.update(kwargs.pop('error_map', {}))
api_version = "2020-11-01-preview3"
content_type = kwargs.pop("content_type", "application/json")
accept = "application/json"

# Construct URL
url = self.remove_chat_participant.metadata['url'] # type: ignore
url = self.add_chat_participants.metadata['url'] # type: ignore
path_format_arguments = {
'endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True),
'chatThreadId': self._serialize.url("chat_thread_id", chat_thread_id, 'str'),
'chatParticipantId': self._serialize.url("chat_participant_id", chat_participant_id, 'str'),
}
url = self._client.format_url(url, **path_format_arguments)

Expand All @@ -824,20 +817,27 @@ async def remove_chat_participant(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.delete(url, query_parameters, header_parameters)
body_content_kwargs = {} # type: Dict[str, Any]
body_content = self._serialize.body(add_chat_participants_request, 'AddChatParticipantsRequest')
body_content_kwargs['content'] = body_content
request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
response = pipeline_response.http_response

if response.status_code not in [204]:
if response.status_code not in [201]:
map_error(status_code=response.status_code, response=response, error_map=error_map)
raise HttpResponseError(response=response)

deserialized = self._deserialize('AddChatParticipantsResult', pipeline_response)

if cls:
return cls(pipeline_response, None, {})
return cls(pipeline_response, deserialized, {})

remove_chat_participant.metadata = {'url': '/chat/threads/{chatThreadId}/participants/{chatParticipantId}'} # type: ignore
return deserialized
add_chat_participants.metadata = {'url': '/chat/threads/{chatThreadId}/participants/:add'} # type: ignore

async def update_chat_thread(
self,
Expand Down
Loading

0 comments on commit db42686

Please sign in to comment.