v0.166.0
 1"""Base email backend class."""
 2
 3from abc import ABC, abstractmethod
 4from typing import TYPE_CHECKING, Self
 5
 6if TYPE_CHECKING:
 7    from types import TracebackType
 8
 9    from ..message import EmailMessage
10
11__all__ = ["BaseEmailBackend"]
12
13
14class BaseEmailBackend(ABC):
15    """
16    Base class for email backend implementations.
17
18    Subclasses must at least overwrite send_messages().
19
20    open() and close() can be called indirectly by using a backend object as a
21    context manager:
22
23       with backend as connection:
24           # do something with connection
25           pass
26    """
27
28    def open(self) -> bool:
29        """
30        Open a network connection.
31
32        This method can be overwritten by backend implementations to
33        open a network connection.
34
35        It's up to the backend implementation to track the status of
36        a network connection if it's needed by the backend.
37
38        This method can be called by applications to force a single
39        network connection to be used when sending mails. See the
40        send_messages() method of the SMTP backend for a reference
41        implementation.
42
43        The default implementation does nothing.
44        """
45        return False
46
47    def close(self) -> None:
48        """Close a network connection."""
49
50    def __enter__(self) -> Self:
51        try:
52            self.open()
53        except Exception:
54            self.close()
55            raise
56        return self
57
58    def __exit__(
59        self,
60        exc_type: type[BaseException] | None,
61        exc_value: BaseException | None,
62        traceback: TracebackType | None,
63    ) -> None:
64        self.close()
65
66    @abstractmethod
67    def send_messages(self, email_messages: list[EmailMessage]) -> int:
68        """
69        Send one or more EmailMessage objects and return the number of email
70        messages sent.
71        """
72        ...