def send_mail(from_addr, to_addr, file, host='localhost', port=25, timeout=60, retries=5, use_ssl=False, require_transport_security=None, require_authentication=None, username=None, password=None, helo_fallback=False): """ A utility function used to send email. :param from_addr: Sender email address. :param to_addr: Recipients email address. :param file: The full message, including headers. Any file-like or any object with a ``__str__`` can be used. :param host: Which SMTP server to use. :param port: Which port to connect to. :param use_ssl: Whether the server speaks SSL. :param require_transport_security: Whether to require transport security (TLS) before sending the email. Defaults to ``True`` if a username is specified. Defaults to ``False`` if using SSL due to `Twisted #3989 <http://twistedmatrix.com/trac/ticket/3989>`_. :param require_authentication: Whether to login before sending an email. Defaults to ``True`` if a username is specified, ``False`` otherwise. :param username: The username used when logging in. :param password: The password used when logging in. :param timeout: Number of seconds to wait before timing out a connection. If ``None``, perform no timeout checking. :param retries: Number of retries if we cannot connect to the server. :param helo_fallback: Whether to fallback to HELO if EHLO fails. """ if hasattr(file, 'as_string'): # this looks like a email.message.Message file = StringIO(file.as_string()) if not hasattr(file, 'read'): file = StringIO(str(file)) if require_transport_security is None: if use_ssl: require_transport_security = False else: require_transport_security = username is not None if require_authentication is None: require_authentication = username is not None context_factory = None if use_ssl or require_transport_security: # only import the ssl module if required from twisted.internet import ssl context_factory = ssl.ClientContextFactory() deferred = defer.Deferred() sender_factory = smtp.ESMTPSenderFactory( contextFactory = context_factory, deferred = deferred, timeout = timeout, fromEmail = from_addr, toEmail = to_addr, file = file, retries = retries, requireTransportSecurity = require_transport_security, requireAuthentication = require_authentication, username = username, password = password, heloFallback = helo_fallback, ) if use_ssl: reactor.connectSSL(host, port, sender_factory, context_factory) else: reactor.connectTCP(host, port, sender_factory) return deferred