async def search_all_users( self, query: UserSearchQuery, local: bool = False, chunk_size: int = 50, max_number: int = None) -> AsyncGenerator[UserV2, None]: """Search for users by first name, last name, display name, and email; optionally, filter results by company, title, location, marketCoverage, responsibility, function, or instrument. Same as :func:`~search_users` but returns an asynchronous generator which performs the paginated calls with the correct skip and limit values. See: `Search Users <https://developers.symphony.com/restapi/v20.10/reference#search-users>`_ :param query: Searching query containing complex information like title, location, company... :param local: If true then a local DB search will be performed and only local pod users will be returned. If absent or false then a directory search will be performed and users from other pods who are visible to the calling user will also be returned. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call :param max_number: the total maximum number of elements to retrieve :return: an asynchronous generator of users """ async def search_users_one_page(skip: int, limit: int): results = await self.search_users(query, local, skip, limit) return results.users if results else None return offset_based_pagination(search_users_one_page, chunk_size, max_number)
async def list_all_user_details( self, chunk_size: int = 50, max_number: int = None) -> AsyncGenerator[V2UserDetail, None]: """Retrieve all users in the company (pod). Same as :func:`~list_user_details` but returns an asynchronous generator which performs the paginated calls with the correct skip and limit values. See: 'List Users V2 <https://developers.symphony.com/restapi/reference#list-users-v2>'_ :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call :param max_number: the total maximum number of elements to retrieve :return: an asynchronous generator of user details """ return offset_based_pagination(self.list_user_details, chunk_size, max_number)
async def list_all_stream_members(self, stream_id: str, chunk_size: int = 50, max_number=None) \ -> AsyncGenerator[V2MemberInfo, None]: """List the current members of an existing stream. The stream can be of type IM, MIM, or ROOM. Wraps the `Stream Members <https://developers.symphony.com/restapi/reference#stream-members>`_ endpoint. :param stream_id: the ID of the stream. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call. :param max_number: the total maximum number of elements to retrieve. :return: an asynchronous generator of the stream members. """ async def list_stream_members_one_page(skip, limit): members = await self.list_stream_members(stream_id, skip, limit) return members.members.value if members.members else None return offset_based_pagination(list_stream_members_one_page, chunk_size, max_number)
async def list_all_subscribers(self, signal_id: str, chunk_size: int = 50, max_number: int = None) \ -> AsyncGenerator[ChannelSubscriber, None]: """Gets all the subscribers for the specified signal. See: 'Subscribers <https://developers.symphony.com/restapi/reference#subscribers>'_ :param signal_id: the Id of the signal. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call. :param max_number: the total maximum number of elements to retrieve. :return: an asynchronous generator returning all users subscribed to the signal. """ async def list_subscribers_one_page(skip, limit): result = await self.list_subscribers(signal_id, skip, limit) return result.data if result else None return offset_based_pagination(list_subscribers_one_page, chunk_size, max_number)
async def list_all_streams(self, stream_filter: StreamFilter, chunk_size: int = 50, max_number: int = None) \ -> AsyncGenerator[StreamAttributes, None]: """Returns an asynchronous of all the streams of which the requesting user is a member, sorted by creation date (ascending - oldest to newest). Wraps the `List User Streams <https://developers.symphony.com/restapi/reference#list-user-streams>`_ endpoint. :param stream_filter: the stream searching criteria. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call :param max_number: the total maximum number of elements to retrieve :return: an asynchronous generator of the streams matching the search filter. """ async def list_streams_one_page(skip, limit): result = await self.list_streams(stream_filter, skip, limit) return result.value if result else None return offset_based_pagination(list_streams_one_page, chunk_size, max_number)
async def list_all_streams_admin(self, stream_filter: V2AdminStreamFilter, chunk_size=50, max_number=None) \ -> AsyncGenerator[V2AdminStreamInfo, None]: """Retrieves all the streams across the enterprise. Wraps the `List Streams for Enterprise V2 <https://developers.symphony.com/restapi/reference#list-streams-for-enterprise-v2>`_ endpoint. :param stream_filter: the stream searching filter. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call. :param max_number: the total maximum number of elements to retrieve. :return: an asynchronous generator of streams matching the search criteria. """ async def list_streams_admin_one_page(skip, limit): result = await self.list_streams_admin(stream_filter, skip, limit) return result.streams.value if result.streams else None return offset_based_pagination(list_streams_admin_one_page, chunk_size, max_number)
async def list_all_signals( self, chunk_size: int = 50, max_number: int = None) -> AsyncGenerator[Signal, None]: """Lists all signals on behalf of the user. The response includes signals that the user has created and public signals to which they have subscribed. See: 'List signals <https://developers.symphony.com/restapi/reference#list-signals>'_ :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call :param max_number: the total maximum number of elements to retrieve :return: an asynchronous generator of found signals """ async def list_signals_one_page(skip, limit): result = await self.list_signals(skip, limit) return result.value if result else None return offset_based_pagination(list_signals_one_page, chunk_size, max_number)
async def search_all_rooms( self, query: V2RoomSearchCriteria, chunk_size: int = 50, max_number: int = None) -> AsyncGenerator[V3RoomDetail, None]: """Search for rooms according to the specified criteria. Wraps the `Search Rooms V3 <https://developers.symphony.com/restapi/reference#search-rooms-v3>`_ endpoint. :param query: the search criteria. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call. :param max_number: the total maximum number of elements to retrieve. :return: an asynchronous generator of the rooms matching the search criteria. """ async def search_rooms_one_page(skip, limit): result = await self.search_rooms(query, skip, limit) return result.rooms if result.rooms else None return offset_based_pagination(search_rooms_one_page, chunk_size, max_number)
async def list_all_user_details_by_filter( self, user_filter: UserFilter, chunk_size: int = 50, max_number: int = None) -> AsyncGenerator[V2UserDetail, None]: """Retrieve an asynchronous generator of users in the company (pod) by a filter. Same as :func:`~list_user_details_by_filter` but returns an generator which performs the paginated calls with the correct skip and limit values. See: `Find Users V1 <https://developers.symphony.com/restapi/reference#find-users>`_ :param user_filter: Filter using to filter users by. :param chunk_size: the maximum number of elements to retrieve in one underlying HTTP call :param max_number: the total maximum number of elements to retrieve :return: an asynchronous generator of user details """ async def list_user_details_one_page(skip, limit): return await self.list_user_details_by_filter( user_filter, skip, limit) return offset_based_pagination(list_user_details_one_page, chunk_size, max_number)
async def assert_generator_produces(func_responses, max_number, expected_output, expected_calls): mock_func = AsyncMock() mock_func.side_effect = func_responses assert [x async for x in offset_based_pagination(mock_func, CHUNK_SIZE, max_number)] == expected_output mock_func.assert_has_awaits(expected_calls)