Plain is headed towards 1.0! Subscribe for development updates →

 1"""Base email backend class."""
 2
 3from __future__ import annotations
 4
 5from abc import ABC, abstractmethod
 6from typing import TYPE_CHECKING, Any
 7
 8if TYPE_CHECKING:
 9    from types import TracebackType
10
11    from ..message import EmailMessage
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 __init__(self, fail_silently: bool = False, **kwargs: Any) -> None:
29        self.fail_silently = fail_silently
30
31    def open(self) -> bool | None:
32        """
33        Open a network connection.
34
35        This method can be overwritten by backend implementations to
36        open a network connection.
37
38        It's up to the backend implementation to track the status of
39        a network connection if it's needed by the backend.
40
41        This method can be called by applications to force a single
42        network connection to be used when sending mails. See the
43        send_messages() method of the SMTP backend for a reference
44        implementation.
45
46        The default implementation does nothing.
47        """
48        pass
49
50    def close(self) -> None:
51        """Close a network connection."""
52        pass
53
54    def __enter__(self) -> BaseEmailBackend:
55        try:
56            self.open()
57        except Exception:
58            self.close()
59            raise
60        return self
61
62    def __exit__(
63        self,
64        exc_type: type[BaseException] | None,
65        exc_value: BaseException | None,
66        traceback: TracebackType | None,
67    ) -> None:
68        self.close()
69
70    @abstractmethod
71    def send_messages(self, email_messages: list[EmailMessage]) -> int:
72        """
73        Send one or more EmailMessage objects and return the number of email
74        messages sent.
75        """
76        ...