exchangelib.services.find_people API documentation

# Module `exchangelib.services.find_people`

Expand source code

    import logging
    from collections import OrderedDict

    from .common import EWSAccountService, create_shape_element
    from ..util import create_element, set_xml_value, MNS
    from ..version import EXCHANGE_2013

    log = logging.getLogger(__name__)

    class FindPeople(EWSAccountService):
        """MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation"""

        SERVICE_NAME = 'FindPeople'
        element_container_name = '{%s}People' % MNS
        supported_from = EXCHANGE_2013
        supports_paging = True

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # A hack to communicate parsing args to _elems_to_objs()
            self.additional_fields = None
            self.shape = None

        def call(self, folder, additional_fields, restriction, order_fields, shape, query_string, depth, max_items, offset):
            """Find items in an account.

            :param folder: the Folder object to query
            :param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
            :param restriction: a Restriction object for
            :param order_fields: the fields to sort the results by
            :param shape: The set of attributes to return
            :param query_string: a QueryString object
            :param depth: How deep in the folder structure to search for items
            :param max_items: the max number of items to return
            :param offset: the offset relative to the first item in the item collection. Usually 0.

            :return: XML elements for the matching items
            """
            self.additional_fields = additional_fields
            self.shape = shape
            return self._elems_to_objs(self._paged_call(
                payload_func=self.get_payload,
                max_items=max_items,
                folders=[folder],  # We can only query one folder, so there will only be one element in response
                **dict(
                    additional_fields=additional_fields,
                    restriction=restriction,
                    order_fields=order_fields,
                    query_string=query_string,
                    shape=shape,
                    depth=depth,
                    page_size=self.chunk_size,
                    offset=offset,
                )
            ))

        def _elems_to_objs(self, elems):
            from ..items import Persona, ID_ONLY
            for elem in elems:
                if isinstance(elem, Exception):
                    yield elem
                    continue
                if self.shape == ID_ONLY and self.additional_fields is None:
                    yield Persona.id_from_xml(elem)
                    continue
                yield Persona.from_xml(elem, account=self.account)

        def get_payload(self, folders, additional_fields, restriction, order_fields, query_string, shape, depth, page_size,
                        offset=0):
            folders = list(folders)
            if len(folders) != 1:
                raise ValueError('%r can only query one folder' % self.SERVICE_NAME)
            folder = folders[0]
            findpeople = create_element('m:%s' % self.SERVICE_NAME, attrs=dict(Traversal=depth))
            personashape = create_shape_element(
                tag='m:PersonaShape', shape=shape, additional_fields=additional_fields, version=self.account.version
            )
            findpeople.append(personashape)
            view_type = create_element(
                'm:IndexedPageItemView',
                attrs=OrderedDict([
                    ('MaxEntriesReturned', str(page_size)),
                    ('Offset', str(offset)),
                    ('BasePoint', 'Beginning'),
                ])
            )
            findpeople.append(view_type)
            if restriction:
                findpeople.append(restriction.to_xml(version=self.account.version))
            if order_fields:
                findpeople.append(set_xml_value(
                    create_element('m:SortOrder'),
                    order_fields,
                    version=self.account.version
                ))
            findpeople.append(set_xml_value(
                create_element('m:ParentFolderId'),
                folder,
                version=self.account.version
            ))
            if query_string:
                findpeople.append(query_string.to_xml(version=self.account.version))
            return findpeople

        @staticmethod
        def _get_paging_values(elem):
            """Find paging values. The paging element from FindPeople is different from other paging containers."""
            item_count = int(elem.find('{%s}TotalNumberOfPeopleInView' % MNS).text)
            first_matching = int(elem.find('{%s}FirstMatchingRowIndex' % MNS).text)
            first_loaded = int(elem.find('{%s}FirstLoadedRowIndex' % MNS).text)
            log.debug('Got page with total items %s, first matching %s, first loaded %s ', item_count, first_matching,
                      first_loaded)
            next_offset = None  # GetPersona does not support fetching more pages
            return item_count, next_offset

## Classes

`class FindPeople (*args, **kwargs)`

  MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation

  Expand source code

      class FindPeople(EWSAccountService):
          """MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation"""

          SERVICE_NAME = 'FindPeople'
          element_container_name = '{%s}People' % MNS
          supported_from = EXCHANGE_2013
          supports_paging = True

          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              # A hack to communicate parsing args to _elems_to_objs()
              self.additional_fields = None
              self.shape = None

          def call(self, folder, additional_fields, restriction, order_fields, shape, query_string, depth, max_items, offset):
              """Find items in an account.

              :param folder: the Folder object to query
              :param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
              :param restriction: a Restriction object for
              :param order_fields: the fields to sort the results by
              :param shape: The set of attributes to return
              :param query_string: a QueryString object
              :param depth: How deep in the folder structure to search for items
              :param max_items: the max number of items to return
              :param offset: the offset relative to the first item in the item collection. Usually 0.

              :return: XML elements for the matching items
              """
              self.additional_fields = additional_fields
              self.shape = shape
              return self._elems_to_objs(self._paged_call(
                  payload_func=self.get_payload,
                  max_items=max_items,
                  folders=[folder],  # We can only query one folder, so there will only be one element in response
                  **dict(
                      additional_fields=additional_fields,
                      restriction=restriction,
                      order_fields=order_fields,
                      query_string=query_string,
                      shape=shape,
                      depth=depth,
                      page_size=self.chunk_size,
                      offset=offset,
                  )
              ))

          def _elems_to_objs(self, elems):
              from ..items import Persona, ID_ONLY
              for elem in elems:
                  if isinstance(elem, Exception):
                      yield elem
                      continue
                  if self.shape == ID_ONLY and self.additional_fields is None:
                      yield Persona.id_from_xml(elem)
                      continue
                  yield Persona.from_xml(elem, account=self.account)

          def get_payload(self, folders, additional_fields, restriction, order_fields, query_string, shape, depth, page_size,
                          offset=0):
              folders = list(folders)
              if len(folders) != 1:
                  raise ValueError('%r can only query one folder' % self.SERVICE_NAME)
              folder = folders[0]
              findpeople = create_element('m:%s' % self.SERVICE_NAME, attrs=dict(Traversal=depth))
              personashape = create_shape_element(
                  tag='m:PersonaShape', shape=shape, additional_fields=additional_fields, version=self.account.version
              )
              findpeople.append(personashape)
              view_type = create_element(
                  'm:IndexedPageItemView',
                  attrs=OrderedDict([
                      ('MaxEntriesReturned', str(page_size)),
                      ('Offset', str(offset)),
                      ('BasePoint', 'Beginning'),
                  ])
              )
              findpeople.append(view_type)
              if restriction:
                  findpeople.append(restriction.to_xml(version=self.account.version))
              if order_fields:
                  findpeople.append(set_xml_value(
                      create_element('m:SortOrder'),
                      order_fields,
                      version=self.account.version
                  ))
              findpeople.append(set_xml_value(
                  create_element('m:ParentFolderId'),
                  folder,
                  version=self.account.version
              ))
              if query_string:
                  findpeople.append(query_string.to_xml(version=self.account.version))
              return findpeople

          @staticmethod
          def _get_paging_values(elem):
              """Find paging values. The paging element from FindPeople is different from other paging containers."""
              item_count = int(elem.find('{%s}TotalNumberOfPeopleInView' % MNS).text)
              first_matching = int(elem.find('{%s}FirstMatchingRowIndex' % MNS).text)
              first_loaded = int(elem.find('{%s}FirstLoadedRowIndex' % MNS).text)
              log.debug('Got page with total items %s, first matching %s, first loaded %s ', item_count, first_matching,
                        first_loaded)
              next_offset = None  # GetPersona does not support fetching more pages
              return item_count, next_offset

  ### Ancestors

  - EWSAccountService
  - EWSService

  ### Class variables

  `var SERVICE_NAME`
  `var element_container_name`
  `var supported_from`
  `var supports_paging`

  ### Methods

  `def call(self, folder, additional_fields, restriction, order_fields, shape, query_string, depth, max_items, offset)`

    Find items in an account.

    :param folder: the Folder object to query :param additional_fields: the extra fields that should be returned with the item, as FieldPath objects :param restriction: a Restriction object for :param order_fields: the fields to sort the results by :param shape: The set of attributes to return :param query_string: a QueryString object :param depth: How deep in the folder structure to search for items :param max_items: the max number of items to return :param offset: the offset relative to the first item in the item collection. Usually 0.

    :return: XML elements for the matching items

    Expand source code

        def call(self, folder, additional_fields, restriction, order_fields, shape, query_string, depth, max_items, offset):
            """Find items in an account.

            :param folder: the Folder object to query
            :param additional_fields: the extra fields that should be returned with the item, as FieldPath objects
            :param restriction: a Restriction object for
            :param order_fields: the fields to sort the results by
            :param shape: The set of attributes to return
            :param query_string: a QueryString object
            :param depth: How deep in the folder structure to search for items
            :param max_items: the max number of items to return
            :param offset: the offset relative to the first item in the item collection. Usually 0.

            :return: XML elements for the matching items
            """
            self.additional_fields = additional_fields
            self.shape = shape
            return self._elems_to_objs(self._paged_call(
                payload_func=self.get_payload,
                max_items=max_items,
                folders=[folder],  # We can only query one folder, so there will only be one element in response
                **dict(
                    additional_fields=additional_fields,
                    restriction=restriction,
                    order_fields=order_fields,
                    query_string=query_string,
                    shape=shape,
                    depth=depth,
                    page_size=self.chunk_size,
                    offset=offset,
                )
            ))

  `def get_payload(self, folders, additional_fields, restriction, order_fields, query_string, shape, depth, page_size, offset=0)`
    Expand source code

        def get_payload(self, folders, additional_fields, restriction, order_fields, query_string, shape, depth, page_size,
                        offset=0):
            folders = list(folders)
            if len(folders) != 1:
                raise ValueError('%r can only query one folder' % self.SERVICE_NAME)
            folder = folders[0]
            findpeople = create_element('m:%s' % self.SERVICE_NAME, attrs=dict(Traversal=depth))
            personashape = create_shape_element(
                tag='m:PersonaShape', shape=shape, additional_fields=additional_fields, version=self.account.version
            )
            findpeople.append(personashape)
            view_type = create_element(
                'm:IndexedPageItemView',
                attrs=OrderedDict([
                    ('MaxEntriesReturned', str(page_size)),
                    ('Offset', str(offset)),
                    ('BasePoint', 'Beginning'),
                ])
            )
            findpeople.append(view_type)
            if restriction:
                findpeople.append(restriction.to_xml(version=self.account.version))
            if order_fields:
                findpeople.append(set_xml_value(
                    create_element('m:SortOrder'),
                    order_fields,
                    version=self.account.version
                ))
            findpeople.append(set_xml_value(
                create_element('m:ParentFolderId'),
                folder,
                version=self.account.version
            ))
            if query_string:
                findpeople.append(query_string.to_xml(version=self.account.version))
            return findpeople

  ### Inherited members

  - `EWSAccountService`:
    - `NO_VALID_SERVER_VERSIONS`
    - `WARNINGS_TO_CATCH_IN_RESPONSE`
    - `get`
    - `parse`