exchangelib.items.base API documentation

# Module `exchangelib.items.base`

## Classes

`class BaseItem (**kwargs)`
  Expand source code

      class BaseItem(RegisterMixIn, metaclass=EWSMeta):
          """Base class for all other classes that implement EWS items."""

          ID_ELEMENT_CLS = ItemId
          _id = IdElementField(field_uri="item:ItemId", value_cls=ID_ELEMENT_CLS)

          __slots__ = "account", "folder"

          def __init__(self, **kwargs):
              """Pick out optional 'account' and 'folder' kwargs, and pass the rest to the parent class.

              :param kwargs:
                  'account' is optional but allows calling 'send()' and 'delete()'
                  'folder' is optional but allows calling 'save()'. If 'folder' has an account, and 'account' is not set,
                      we use folder.account.
              """
              from ..account import Account
              from ..folders import BaseFolder

              self.account = kwargs.pop("account", None)
              if self.account is not None and not isinstance(self.account, Account):
                  raise InvalidTypeError("account", self.account, Account)
              self.folder = kwargs.pop("folder", None)
              if self.folder is not None:
                  if not isinstance(self.folder, BaseFolder):
                      raise InvalidTypeError("folder", self.folder, BaseFolder)
                  if self.folder.account is not None:
                      if self.account is not None:
                          # Make sure the account from kwargs matches the folder account
                          if self.account != self.folder.account:
                              raise ValueError("'account' does not match 'folder.account'")
                      self.account = self.folder.account
              super().__init__(**kwargs)

          @classmethod
          def from_xml(cls, elem, account):
              item = super().from_xml(elem=elem, account=account)
              item.account = account
              return item

  Base class for all other classes that implement EWS items.

  Pick out optional 'account' and 'folder' kwargs, and pass the rest to the parent class.

  :param kwargs: 'account' is optional but allows calling 'send()' and 'delete()' 'folder' is optional but allows calling 'save()'. If 'folder' has an account, and 'account' is not set, we use folder.account.

  ### Ancestors

  - RegisterMixIn
  - IdChangeKeyMixIn
  - EWSElement

  ### Subclasses

  - BulkCreateResult
  - BaseMeetingReplyItem
  - Item

  ### Static methods

  `def from_xml(elem, account)`

  ### Instance variables

  `var account`
    Expand source code

        class BaseItem(RegisterMixIn, metaclass=EWSMeta):
            """Base class for all other classes that implement EWS items."""

            ID_ELEMENT_CLS = ItemId
            _id = IdElementField(field_uri="item:ItemId", value_cls=ID_ELEMENT_CLS)

            __slots__ = "account", "folder"

            def __init__(self, **kwargs):
                """Pick out optional 'account' and 'folder' kwargs, and pass the rest to the parent class.

                :param kwargs:
                    'account' is optional but allows calling 'send()' and 'delete()'
                    'folder' is optional but allows calling 'save()'. If 'folder' has an account, and 'account' is not set,
                        we use folder.account.
                """
                from ..account import Account
                from ..folders import BaseFolder

                self.account = kwargs.pop("account", None)
                if self.account is not None and not isinstance(self.account, Account):
                    raise InvalidTypeError("account", self.account, Account)
                self.folder = kwargs.pop("folder", None)
                if self.folder is not None:
                    if not isinstance(self.folder, BaseFolder):
                        raise InvalidTypeError("folder", self.folder, BaseFolder)
                    if self.folder.account is not None:
                        if self.account is not None:
                            # Make sure the account from kwargs matches the folder account
                            if self.account != self.folder.account:
                                raise ValueError("'account' does not match 'folder.account'")
                        self.account = self.folder.account
                super().__init__(**kwargs)

            @classmethod
            def from_xml(cls, elem, account):
                item = super().from_xml(elem=elem, account=account)
                item.account = account
                return item

  `var folder`
    Expand source code

        class BaseItem(RegisterMixIn, metaclass=EWSMeta):
            """Base class for all other classes that implement EWS items."""

            ID_ELEMENT_CLS = ItemId
            _id = IdElementField(field_uri="item:ItemId", value_cls=ID_ELEMENT_CLS)

            __slots__ = "account", "folder"

            def __init__(self, **kwargs):
                """Pick out optional 'account' and 'folder' kwargs, and pass the rest to the parent class.

                :param kwargs:
                    'account' is optional but allows calling 'send()' and 'delete()'
                    'folder' is optional but allows calling 'save()'. If 'folder' has an account, and 'account' is not set,
                        we use folder.account.
                """
                from ..account import Account
                from ..folders import BaseFolder

                self.account = kwargs.pop("account", None)
                if self.account is not None and not isinstance(self.account, Account):
                    raise InvalidTypeError("account", self.account, Account)
                self.folder = kwargs.pop("folder", None)
                if self.folder is not None:
                    if not isinstance(self.folder, BaseFolder):
                        raise InvalidTypeError("folder", self.folder, BaseFolder)
                    if self.folder.account is not None:
                        if self.account is not None:
                            # Make sure the account from kwargs matches the folder account
                            if self.account != self.folder.account:
                                raise ValueError("'account' does not match 'folder.account'")
                        self.account = self.folder.account
                super().__init__(**kwargs)

            @classmethod
            def from_xml(cls, elem, account):
                item = super().from_xml(elem=elem, account=account)
                item.account = account
                return item

  ### Inherited members

  - `RegisterMixIn`:
    - `ELEMENT_NAME`
    - `FIELDS`
    - `ID_ELEMENT_CLS`
    - `INSERT_AFTER_FIELD`
    - `NAMESPACE`
    - `add_field`
    - `deregister`
    - `register`
    - `remove_field`
    - `supported_fields`
    - `validate_field`
`class BaseReplyItem (**kwargs)`
  Expand source code

      class BaseReplyItem(EWSElement, metaclass=EWSMeta):
          """Base class for reply/forward elements that share the same fields."""

          subject = CharField(field_uri="Subject")
          body = BodyField(field_uri="Body")  # Accepts and returns Body or HTMLBody instances
          to_recipients = MailboxListField(field_uri="ToRecipients")
          cc_recipients = MailboxListField(field_uri="CcRecipients")
          bcc_recipients = MailboxListField(field_uri="BccRecipients")
          is_read_receipt_requested = BooleanField(field_uri="IsReadReceiptRequested")
          is_delivery_receipt_requested = BooleanField(field_uri="IsDeliveryReceiptRequested")
          author = MailboxField(field_uri="From")
          reference_item_id = EWSElementField(value_cls=ReferenceItemId)
          new_body = BodyField(field_uri="NewBodyContent")  # Accepts and returns Body or HTMLBody instances
          received_by = MailboxField(field_uri="ReceivedBy", supported_from=EXCHANGE_2007_SP1)
          received_representing = MailboxField(field_uri="ReceivedRepresenting", supported_from=EXCHANGE_2007_SP1)

          __slots__ = ("account",)

          def __init__(self, **kwargs):
              # 'account' is optional but allows calling 'send()' and 'save()'
              from ..account import Account

              self.account = kwargs.pop("account", None)
              if self.account is not None and not isinstance(self.account, Account):
                  raise InvalidTypeError("account", self.account, Account)
              super().__init__(**kwargs)

          @require_account
          def send(self, save_copy=True, copy_to_folder=None):
              from ..services import CreateItem

              if copy_to_folder and not save_copy:
                  raise AttributeError("'save_copy' must be True when 'copy_to_folder' is set")
              message_disposition = SEND_AND_SAVE_COPY if save_copy else SEND_ONLY
              return CreateItem(account=self.account).get(
                  items=[self],
                  folder=copy_to_folder,
                  message_disposition=message_disposition,
                  send_meeting_invitations=SEND_TO_NONE,
              )

          @require_account
          def save(self, folder):
              """Save the item for later modification. You may want to use account.drafts as the folder.

              :param folder:
              :return:
              """
              from ..services import CreateItem

              return CreateItem(account=self.account).get(
                  items=[self],
                  folder=folder,
                  message_disposition=SAVE_ONLY,
                  send_meeting_invitations=SEND_TO_NONE,
              )

  Base class for reply/forward elements that share the same fields.

  ### Ancestors

  - EWSElement

  ### Subclasses

  - CancelCalendarItem
  - ForwardItem
  - ReplyAllToItem
  - ReplyToItem

  ### Instance variables

  `var account`
    Expand source code

        class BaseReplyItem(EWSElement, metaclass=EWSMeta):
            """Base class for reply/forward elements that share the same fields."""

            subject = CharField(field_uri="Subject")
            body = BodyField(field_uri="Body")  # Accepts and returns Body or HTMLBody instances
            to_recipients = MailboxListField(field_uri="ToRecipients")
            cc_recipients = MailboxListField(field_uri="CcRecipients")
            bcc_recipients = MailboxListField(field_uri="BccRecipients")
            is_read_receipt_requested = BooleanField(field_uri="IsReadReceiptRequested")
            is_delivery_receipt_requested = BooleanField(field_uri="IsDeliveryReceiptRequested")
            author = MailboxField(field_uri="From")
            reference_item_id = EWSElementField(value_cls=ReferenceItemId)
            new_body = BodyField(field_uri="NewBodyContent")  # Accepts and returns Body or HTMLBody instances
            received_by = MailboxField(field_uri="ReceivedBy", supported_from=EXCHANGE_2007_SP1)
            received_representing = MailboxField(field_uri="ReceivedRepresenting", supported_from=EXCHANGE_2007_SP1)

            __slots__ = ("account",)

            def __init__(self, **kwargs):
                # 'account' is optional but allows calling 'send()' and 'save()'
                from ..account import Account

                self.account = kwargs.pop("account", None)
                if self.account is not None and not isinstance(self.account, Account):
                    raise InvalidTypeError("account", self.account, Account)
                super().__init__(**kwargs)

            @require_account
            def send(self, save_copy=True, copy_to_folder=None):
                from ..services import CreateItem

                if copy_to_folder and not save_copy:
                    raise AttributeError("'save_copy' must be True when 'copy_to_folder' is set")
                message_disposition = SEND_AND_SAVE_COPY if save_copy else SEND_ONLY
                return CreateItem(account=self.account).get(
                    items=[self],
                    folder=copy_to_folder,
                    message_disposition=message_disposition,
                    send_meeting_invitations=SEND_TO_NONE,
                )

            @require_account
            def save(self, folder):
                """Save the item for later modification. You may want to use account.drafts as the folder.

                :param folder:
                :return:
                """
                from ..services import CreateItem

                return CreateItem(account=self.account).get(
                    items=[self],
                    folder=folder,
                    message_disposition=SAVE_ONLY,
                    send_meeting_invitations=SEND_TO_NONE,
                )

  `var author`

    The type of the None singleton.

  `var bcc_recipients`

    The type of the None singleton.

  `var body`

    The type of the None singleton.

  `var cc_recipients`

    The type of the None singleton.

  `var is_delivery_receipt_requested`

    The type of the None singleton.

  `var is_read_receipt_requested`

    The type of the None singleton.

  `var new_body`

    The type of the None singleton.

  `var received_by`

    The type of the None singleton.

  `var received_representing`

    The type of the None singleton.

  `var reference_item_id`

    The type of the None singleton.

  `var subject`

    The type of the None singleton.

  `var to_recipients`

    The type of the None singleton.

  ### Methods

  `def save(self, folder)`
    Expand source code

        @require_account
        def save(self, folder):
            """Save the item for later modification. You may want to use account.drafts as the folder.

            :param folder:
            :return:
            """
            from ..services import CreateItem

            return CreateItem(account=self.account).get(
                items=[self],
                folder=folder,
                message_disposition=SAVE_ONLY,
                send_meeting_invitations=SEND_TO_NONE,
            )

    Save the item for later modification. You may want to use account.drafts as the folder.

    :param folder: :return:

  `def send(self, save_copy=True, copy_to_folder=None)`
    Expand source code

        @require_account
        def send(self, save_copy=True, copy_to_folder=None):
            from ..services import CreateItem

            if copy_to_folder and not save_copy:
                raise AttributeError("'save_copy' must be True when 'copy_to_folder' is set")
            message_disposition = SEND_AND_SAVE_COPY if save_copy else SEND_ONLY
            return CreateItem(account=self.account).get(
                items=[self],
                folder=copy_to_folder,
                message_disposition=message_disposition,
                send_meeting_invitations=SEND_TO_NONE,
            )

  ### Inherited members

  - `EWSElement`:
    - `ELEMENT_NAME`
    - `FIELDS`
    - `NAMESPACE`
    - `add_field`
    - `remove_field`
    - `supported_fields`
    - `validate_field`
`class BulkCreateResult (**kwargs)`
  Expand source code

      class BulkCreateResult(BaseItem):
          """A dummy class to store return values from a CreateItem service call."""

          attachments = AttachmentField(field_uri="item:Attachments")  # ItemAttachment or FileAttachment

          def __init__(self, **kwargs):
              super().__init__(**kwargs)
              if self.attachments is None:
                  self.attachments = []

  A dummy class to store return values from a CreateItem service call.

  Pick out optional 'account' and 'folder' kwargs, and pass the rest to the parent class.

  :param kwargs: 'account' is optional but allows calling 'send()' and 'delete()' 'folder' is optional but allows calling 'save()'. If 'folder' has an account, and 'account' is not set, we use folder.account.

  ### Ancestors

  - BaseItem
  - RegisterMixIn
  - IdChangeKeyMixIn
  - EWSElement

  ### Instance variables

  `var attachments`

    The type of the None singleton.

  ### Inherited members

  - `BaseItem`:
    - `ELEMENT_NAME`
    - `FIELDS`
    - `ID_ELEMENT_CLS`
    - `INSERT_AFTER_FIELD`
    - `NAMESPACE`
    - `add_field`
    - `deregister`
    - `register`
    - `remove_field`
    - `supported_fields`
    - `validate_field`
`class RegisterMixIn (**kwargs)`
  Expand source code

      class RegisterMixIn(IdChangeKeyMixIn, metaclass=EWSMeta):
          """Base class for classes that can change their list of supported fields dynamically."""

          # This class implements dynamic fields on an element class, so we need to include __dict__ in __slots__
          __slots__ = ("__dict__",)

          INSERT_AFTER_FIELD = None

          @classmethod
          def register(cls, attr_name, attr_cls):
              """Register a custom extended property in this item class so they can be accessed just like any other attribute

              :param attr_name:
              :param attr_cls:
              :return:
              """
              if not cls.INSERT_AFTER_FIELD:
                  raise ValueError(f"Class {cls} is missing INSERT_AFTER_FIELD value")
              try:
                  cls.get_field_by_fieldname(attr_name)
              except InvalidField:
                  pass
              else:
                  raise ValueError(f"'attr_name' {attr_name!r} is already registered")
              if not issubclass(attr_cls, ExtendedProperty):
                  raise TypeError(f"'attr_cls' {attr_cls!r} must be a subclass of type {ExtendedProperty}")
              # Check if class attributes are properly defined
              attr_cls.validate_cls()
              # ExtendedProperty is not a real field, but a placeholder in the fields list. See
              #   https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/item
              #
              # Find the correct index for the new extended property, and insert.
              if attr_cls.is_array_type():
                  field = ExtendedPropertyListField(attr_name, value_cls=attr_cls)
              else:
                  field = ExtendedPropertyField(attr_name, value_cls=attr_cls)
              cls.add_field(field, insert_after=cls.INSERT_AFTER_FIELD)

          @classmethod
          def deregister(cls, attr_name):
              """De-register an extended property that has been registered with register().

              :param attr_name:
              :return:
              """
              try:
                  field = cls.get_field_by_fieldname(attr_name)
              except InvalidField:
                  raise ValueError(f"{attr_name!r} is not registered")
              if not isinstance(field, ExtendedPropertyField):
                  raise ValueError(f"{attr_name} is not registered as an ExtendedProperty")
              cls.remove_field(field)

  Base class for classes that can change their list of supported fields dynamically.

  ### Ancestors

  - IdChangeKeyMixIn
  - EWSElement

  ### Subclasses

  - BaseFolder
  - BaseItem

  ### Class variables

  `var INSERT_AFTER_FIELD`

    The type of the None singleton.

  ### Static methods

  `def deregister(attr_name)`

    De-register an extended property that has been registered with register().

    :param attr_name: :return:

  `def register(attr_name, attr_cls)`

    Register a custom extended property in this item class so they can be accessed just like any other attribute

    :param attr_name: :param attr_cls: :return:

  ### Inherited members

  - `IdChangeKeyMixIn`:
    - `ELEMENT_NAME`
    - `FIELDS`
    - `ID_ELEMENT_CLS`
    - `NAMESPACE`
    - `add_field`
    - `remove_field`
    - `supported_fields`
    - `validate_field`