Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 | :mod:`smtplib` --- SMTP protocol client |
| 2 | ======================================= |
| 3 | |
| 4 | .. module:: smtplib |
| 5 | :synopsis: SMTP protocol client (requires sockets). |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 6 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 7 | .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com> |
| 8 | |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 9 | **Source code:** :source:`Lib/smtplib.py` |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 10 | |
| 11 | .. index:: |
| 12 | pair: SMTP; protocol |
| 13 | single: Simple Mail Transfer Protocol |
| 14 | |
Raymond Hettinger | 469271d | 2011-01-27 20:38:46 +0000 | [diff] [blame] | 15 | -------------- |
| 16 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 17 | The :mod:`smtplib` module defines an SMTP client session object that can be used |
| 18 | to send mail to any Internet machine with an SMTP or ESMTP listener daemon. For |
| 19 | details of SMTP and ESMTP operation, consult :rfc:`821` (Simple Mail Transfer |
| 20 | Protocol) and :rfc:`1869` (SMTP Service Extensions). |
| 21 | |
| 22 | |
Senthil Kumaran | 3d23fd6 | 2011-07-30 10:56:50 +0800 | [diff] [blame] | 23 | .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 24 | |
Martin Panter | 7462b649 | 2015-11-02 03:37:02 +0000 | [diff] [blame] | 25 | An :class:`SMTP` instance encapsulates an SMTP connection. It has methods |
Alexandre Vassalotti | 5f8ced2 | 2008-05-16 00:03:33 +0000 | [diff] [blame] | 26 | that support a full repertoire of SMTP and ESMTP operations. If the optional |
R David Murray | 021362d | 2013-06-23 16:05:44 -0400 | [diff] [blame] | 27 | host and port parameters are given, the SMTP :meth:`connect` method is |
| 28 | called with those parameters during initialization. If specified, |
| 29 | *local_hostname* is used as the FQDN of the local host in the HELO/EHLO |
| 30 | command. Otherwise, the local hostname is found using |
| 31 | :func:`socket.getfqdn`. If the :meth:`connect` call returns anything other |
| 32 | than a success code, an :exc:`SMTPConnectError` is raised. The optional |
| 33 | *timeout* parameter specifies a timeout in seconds for blocking operations |
| 34 | like the connection attempt (if not specified, the global default timeout |
R David Murray | 6ceca4e | 2014-06-09 16:41:06 -0400 | [diff] [blame] | 35 | setting will be used). If the timeout expires, :exc:`socket.timeout` is |
Martin Panter | c04fb56 | 2016-02-10 05:44:01 +0000 | [diff] [blame] | 36 | raised. The optional source_address parameter allows binding |
R David Murray | 021362d | 2013-06-23 16:05:44 -0400 | [diff] [blame] | 37 | to some specific source address in a machine with multiple network |
| 38 | interfaces, and/or to some specific source TCP port. It takes a 2-tuple |
| 39 | (host, port), for the socket to bind to as its source address before |
| 40 | connecting. If omitted (or if host or port are ``''`` and/or 0 respectively) |
| 41 | the OS default behavior will be used. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 42 | |
| 43 | For normal use, you should only require the initialization/connect, |
takey | ba57963 | 2018-11-24 01:53:24 +0900 | [diff] [blame] | 44 | :meth:`sendmail`, and :meth:`SMTP.quit` methods. |
Jesus Cea | c73f863 | 2012-12-26 16:47:03 +0100 | [diff] [blame] | 45 | An example is included below. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 46 | |
Barry Warsaw | 1f5c958 | 2011-03-15 15:04:44 -0400 | [diff] [blame] | 47 | The :class:`SMTP` class supports the :keyword:`with` statement. When used |
| 48 | like this, the SMTP ``QUIT`` command is issued automatically when the |
Serhiy Storchaka | 2b57c43 | 2018-12-19 08:09:46 +0200 | [diff] [blame] | 49 | :keyword:`!with` statement exits. E.g.:: |
Barry Warsaw | 1f5c958 | 2011-03-15 15:04:44 -0400 | [diff] [blame] | 50 | |
| 51 | >>> from smtplib import SMTP |
| 52 | >>> with SMTP("domain.org") as smtp: |
| 53 | ... smtp.noop() |
| 54 | ... |
| 55 | (250, b'Ok') |
| 56 | >>> |
| 57 | |
Steve Dower | 44f91c3 | 2019-06-27 10:47:59 -0700 | [diff] [blame] | 58 | .. audit-event:: smtplib.send self,data smtplib.SMTP |
| 59 | |
| 60 | All commands will raise an :ref:`auditing event <auditing>` |
| 61 | ``smtplib.SMTP.send`` with arguments ``self`` and ``data``, |
| 62 | where ``data`` is the bytes about to be sent to the remote host. |
Steve Dower | 60419a7 | 2019-06-24 08:42:54 -0700 | [diff] [blame] | 63 | |
Antoine Pitrou | 45456a0 | 2011-04-26 18:53:42 +0200 | [diff] [blame] | 64 | .. versionchanged:: 3.3 |
Barry Warsaw | 1f5c958 | 2011-03-15 15:04:44 -0400 | [diff] [blame] | 65 | Support for the :keyword:`with` statement was added. |
| 66 | |
Senthil Kumaran | b351a48 | 2011-07-31 09:14:17 +0800 | [diff] [blame] | 67 | .. versionchanged:: 3.3 |
| 68 | source_address argument was added. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 69 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 70 | .. versionadded:: 3.5 |
| 71 | The SMTPUTF8 extension (:rfc:`6531`) is now supported. |
| 72 | |
Dong-hee Na | 62e3973 | 2020-01-14 16:49:59 +0900 | [diff] [blame] | 73 | .. versionchanged:: 3.9 |
| 74 | If the *timeout* parameter is set to be zero, it will raise a |
| 75 | :class:`ValueError` to prevent the creation of a non-blocking socket |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 76 | |
R David Murray | 36beb66 | 2013-06-23 15:47:50 -0400 | [diff] [blame] | 77 | .. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, \ |
| 78 | certfile=None [, timeout], context=None, \ |
| 79 | source_address=None) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 80 | |
Martin Panter | 7462b649 | 2015-11-02 03:37:02 +0000 | [diff] [blame] | 81 | An :class:`SMTP_SSL` instance behaves exactly the same as instances of |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 82 | :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is |
Alexandre Vassalotti | 5f8ced2 | 2008-05-16 00:03:33 +0000 | [diff] [blame] | 83 | required from the beginning of the connection and using :meth:`starttls` is |
| 84 | not appropriate. If *host* is not specified, the local host is used. If |
R David Murray | 36beb66 | 2013-06-23 15:47:50 -0400 | [diff] [blame] | 85 | *port* is zero, the standard SMTP-over-SSL port (465) is used. The optional |
Antoine Pitrou | c5e075f | 2014-03-22 18:19:11 +0100 | [diff] [blame] | 86 | arguments *local_hostname*, *timeout* and *source_address* have the same |
| 87 | meaning as they do in the :class:`SMTP` class. *context*, also optional, |
Martin Panter | c04fb56 | 2016-02-10 05:44:01 +0000 | [diff] [blame] | 88 | can contain a :class:`~ssl.SSLContext` and allows configuring various |
Antoine Pitrou | c5e075f | 2014-03-22 18:19:11 +0100 | [diff] [blame] | 89 | aspects of the secure connection. Please read :ref:`ssl-security` for |
| 90 | best practices. |
| 91 | |
| 92 | *keyfile* and *certfile* are a legacy alternative to *context*, and can |
| 93 | point to a PEM formatted private key and certificate chain file for the |
| 94 | SSL connection. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 95 | |
Antoine Pitrou | e065020 | 2011-05-18 18:03:09 +0200 | [diff] [blame] | 96 | .. versionchanged:: 3.3 |
| 97 | *context* was added. |
| 98 | |
Senthil Kumaran | b351a48 | 2011-07-31 09:14:17 +0800 | [diff] [blame] | 99 | .. versionchanged:: 3.3 |
| 100 | source_address argument was added. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 101 | |
Christian Heimes | a5768f7 | 2013-12-02 20:44:17 +0100 | [diff] [blame] | 102 | .. versionchanged:: 3.4 |
| 103 | The class now supports hostname check with |
Antoine Pitrou | c5e075f | 2014-03-22 18:19:11 +0100 | [diff] [blame] | 104 | :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see |
| 105 | :data:`ssl.HAS_SNI`). |
Senthil Kumaran | 3d23fd6 | 2011-07-30 10:56:50 +0800 | [diff] [blame] | 106 | |
Christian Heimes | d048637 | 2016-09-10 23:23:33 +0200 | [diff] [blame] | 107 | .. deprecated:: 3.6 |
| 108 | |
| 109 | *keyfile* and *certfile* are deprecated in favor of *context*. |
| 110 | Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let |
| 111 | :func:`ssl.create_default_context` select the system's trusted CA |
| 112 | certificates for you. |
| 113 | |
Dong-hee Na | 62e3973 | 2020-01-14 16:49:59 +0900 | [diff] [blame] | 114 | .. versionchanged:: 3.9 |
| 115 | If the *timeout* parameter is set to be zero, it will raise a |
| 116 | :class:`ValueError` to prevent the creation of a non-blocking socket |
Christian Heimes | d048637 | 2016-09-10 23:23:33 +0200 | [diff] [blame] | 117 | |
Dong-hee Na | 65a5ce2 | 2020-01-15 06:42:09 +0900 | [diff] [blame] | 118 | .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, |
| 119 | source_address=None[, timeout]) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 120 | |
| 121 | The LMTP protocol, which is very similar to ESMTP, is heavily based on the |
Senthil Kumaran | 3d23fd6 | 2011-07-30 10:56:50 +0800 | [diff] [blame] | 122 | standard SMTP client. It's common to use Unix sockets for LMTP, so our |
| 123 | :meth:`connect` method must support that as well as a regular host:port |
Senthil Kumaran | b351a48 | 2011-07-31 09:14:17 +0800 | [diff] [blame] | 124 | server. The optional arguments local_hostname and source_address have the |
R David Murray | 021362d | 2013-06-23 16:05:44 -0400 | [diff] [blame] | 125 | same meaning as they do in the :class:`SMTP` class. To specify a Unix |
| 126 | socket, you must use an absolute path for *host*, starting with a '/'. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 127 | |
R David Murray | 021362d | 2013-06-23 16:05:44 -0400 | [diff] [blame] | 128 | Authentication is supported, using the regular SMTP mechanism. When using a |
| 129 | Unix socket, LMTP generally don't support or require any authentication, but |
| 130 | your mileage might vary. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 131 | |
Dong-hee Na | 65a5ce2 | 2020-01-15 06:42:09 +0900 | [diff] [blame] | 132 | .. versionchanged:: 3.9 |
| 133 | The optional *timeout* parameter was added. |
| 134 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 135 | |
| 136 | A nice selection of exceptions is defined as well: |
| 137 | |
| 138 | |
| 139 | .. exception:: SMTPException |
| 140 | |
R David Murray | 8a34596 | 2013-04-14 06:46:35 -0400 | [diff] [blame] | 141 | Subclass of :exc:`OSError` that is the base exception class for all |
Ned Deily | 7cf5e61 | 2013-08-13 01:15:14 -0700 | [diff] [blame] | 142 | the other exceptions provided by this module. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 143 | |
Larry Hastings | 3732ed2 | 2014-03-15 21:13:56 -0700 | [diff] [blame] | 144 | .. versionchanged:: 3.4 |
| 145 | SMTPException became subclass of :exc:`OSError` |
| 146 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 147 | |
| 148 | .. exception:: SMTPServerDisconnected |
| 149 | |
| 150 | This exception is raised when the server unexpectedly disconnects, or when an |
| 151 | attempt is made to use the :class:`SMTP` instance before connecting it to a |
| 152 | server. |
| 153 | |
| 154 | |
| 155 | .. exception:: SMTPResponseException |
| 156 | |
| 157 | Base class for all exceptions that include an SMTP error code. These exceptions |
| 158 | are generated in some instances when the SMTP server returns an error code. The |
| 159 | error code is stored in the :attr:`smtp_code` attribute of the error, and the |
| 160 | :attr:`smtp_error` attribute is set to the error message. |
| 161 | |
| 162 | |
| 163 | .. exception:: SMTPSenderRefused |
| 164 | |
| 165 | Sender address refused. In addition to the attributes set by on all |
| 166 | :exc:`SMTPResponseException` exceptions, this sets 'sender' to the string that |
| 167 | the SMTP server refused. |
| 168 | |
| 169 | |
| 170 | .. exception:: SMTPRecipientsRefused |
| 171 | |
| 172 | All recipient addresses refused. The errors for each recipient are accessible |
| 173 | through the attribute :attr:`recipients`, which is a dictionary of exactly the |
| 174 | same sort as :meth:`SMTP.sendmail` returns. |
| 175 | |
| 176 | |
| 177 | .. exception:: SMTPDataError |
| 178 | |
| 179 | The SMTP server refused to accept the message data. |
| 180 | |
| 181 | |
| 182 | .. exception:: SMTPConnectError |
| 183 | |
| 184 | Error occurred during establishment of a connection with the server. |
| 185 | |
| 186 | |
| 187 | .. exception:: SMTPHeloError |
| 188 | |
| 189 | The server refused our ``HELO`` message. |
| 190 | |
| 191 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 192 | .. exception:: SMTPNotSupportedError |
| 193 | |
| 194 | The command or option attempted is not supported by the server. |
| 195 | |
| 196 | .. versionadded:: 3.5 |
| 197 | |
| 198 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 199 | .. exception:: SMTPAuthenticationError |
| 200 | |
| 201 | SMTP authentication went wrong. Most probably the server didn't accept the |
| 202 | username/password combination provided. |
| 203 | |
| 204 | |
| 205 | .. seealso:: |
| 206 | |
| 207 | :rfc:`821` - Simple Mail Transfer Protocol |
| 208 | Protocol definition for SMTP. This document covers the model, operating |
| 209 | procedure, and protocol details for SMTP. |
| 210 | |
| 211 | :rfc:`1869` - SMTP Service Extensions |
| 212 | Definition of the ESMTP extensions for SMTP. This describes a framework for |
| 213 | extending SMTP with new commands, supporting dynamic discovery of the commands |
| 214 | provided by the server, and defines a few additional commands. |
| 215 | |
| 216 | |
| 217 | .. _smtp-objects: |
| 218 | |
| 219 | SMTP Objects |
| 220 | ------------ |
| 221 | |
| 222 | An :class:`SMTP` instance has the following methods: |
| 223 | |
| 224 | |
| 225 | .. method:: SMTP.set_debuglevel(level) |
| 226 | |
R David Murray | 2e6ad42 | 2015-04-16 17:24:52 -0400 | [diff] [blame] | 227 | Set the debug output level. A value of 1 or ``True`` for *level* results in |
| 228 | debug messages for connection and for all messages sent to and received from |
| 229 | the server. A value of 2 for *level* results in these messages being |
| 230 | timestamped. |
| 231 | |
| 232 | .. versionchanged:: 3.5 Added debuglevel 2. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 233 | |
| 234 | |
Georg Brandl | 1824415 | 2009-09-02 20:34:52 +0000 | [diff] [blame] | 235 | .. method:: SMTP.docmd(cmd, args='') |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 236 | |
Georg Brandl | 1824415 | 2009-09-02 20:34:52 +0000 | [diff] [blame] | 237 | Send a command *cmd* to the server. The optional argument *args* is simply |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 238 | concatenated to the command, separated by a space. |
| 239 | |
| 240 | This returns a 2-tuple composed of a numeric response code and the actual |
| 241 | response line (multiline responses are joined into one long line.) |
| 242 | |
| 243 | In normal operation it should not be necessary to call this method explicitly. |
| 244 | It is used to implement other methods and may be useful for testing private |
| 245 | extensions. |
| 246 | |
| 247 | If the connection to the server is lost while waiting for the reply, |
| 248 | :exc:`SMTPServerDisconnected` will be raised. |
| 249 | |
| 250 | |
R David Murray | 14ee3cf | 2013-04-13 14:40:33 -0400 | [diff] [blame] | 251 | .. method:: SMTP.connect(host='localhost', port=0) |
| 252 | |
| 253 | Connect to a host on a given port. The defaults are to connect to the local |
| 254 | host at the standard SMTP port (25). If the hostname ends with a colon (``':'``) |
| 255 | followed by a number, that suffix will be stripped off and the number |
| 256 | interpreted as the port number to use. This method is automatically invoked by |
| 257 | the constructor if a host is specified during instantiation. Returns a |
| 258 | 2-tuple of the response code and message sent by the server in its |
| 259 | connection response. |
| 260 | |
Steve Dower | 44f91c3 | 2019-06-27 10:47:59 -0700 | [diff] [blame] | 261 | .. audit-event:: smtplib.connect self,host,port smtplib.SMTP.connect |
Steve Dower | 60419a7 | 2019-06-24 08:42:54 -0700 | [diff] [blame] | 262 | |
R David Murray | 14ee3cf | 2013-04-13 14:40:33 -0400 | [diff] [blame] | 263 | |
Georg Brandl | 1824415 | 2009-09-02 20:34:52 +0000 | [diff] [blame] | 264 | .. method:: SMTP.helo(name='') |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 265 | |
| 266 | Identify yourself to the SMTP server using ``HELO``. The hostname argument |
| 267 | defaults to the fully qualified domain name of the local host. |
Benjamin Peterson | ae5360b | 2008-09-08 23:05:23 +0000 | [diff] [blame] | 268 | The message returned by the server is stored as the :attr:`helo_resp` attribute |
| 269 | of the object. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 270 | |
| 271 | In normal operation it should not be necessary to call this method explicitly. |
| 272 | It will be implicitly called by the :meth:`sendmail` when necessary. |
| 273 | |
| 274 | |
Georg Brandl | 1824415 | 2009-09-02 20:34:52 +0000 | [diff] [blame] | 275 | .. method:: SMTP.ehlo(name='') |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 276 | |
| 277 | Identify yourself to an ESMTP server using ``EHLO``. The hostname argument |
| 278 | defaults to the fully qualified domain name of the local host. Examine the |
Georg Brandl | 48310cd | 2009-01-03 21:18:54 +0000 | [diff] [blame] | 279 | response for ESMTP option and store them for use by :meth:`has_extn`. |
| 280 | Also sets several informational attributes: the message returned by |
| 281 | the server is stored as the :attr:`ehlo_resp` attribute, :attr:`does_esmtp` |
Benjamin Peterson | ae5360b | 2008-09-08 23:05:23 +0000 | [diff] [blame] | 282 | is set to true or false depending on whether the server supports ESMTP, and |
| 283 | :attr:`esmtp_features` will be a dictionary containing the names of the |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 284 | SMTP service extensions this server supports, and their parameters (if any). |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 285 | |
| 286 | Unless you wish to use :meth:`has_extn` before sending mail, it should not be |
| 287 | necessary to call this method explicitly. It will be implicitly called by |
| 288 | :meth:`sendmail` when necessary. |
| 289 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 290 | .. method:: SMTP.ehlo_or_helo_if_needed() |
| 291 | |
Ville Skyttä | da12063 | 2018-08-13 06:39:19 +0300 | [diff] [blame] | 292 | This method calls :meth:`ehlo` and/or :meth:`helo` if there has been no |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 293 | previous ``EHLO`` or ``HELO`` command this session. It tries ESMTP ``EHLO`` |
| 294 | first. |
| 295 | |
Georg Brandl | 1f01deb | 2009-01-03 22:47:39 +0000 | [diff] [blame] | 296 | :exc:`SMTPHeloError` |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 297 | The server didn't reply properly to the ``HELO`` greeting. |
| 298 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 299 | .. method:: SMTP.has_extn(name) |
| 300 | |
| 301 | Return :const:`True` if *name* is in the set of SMTP service extensions returned |
| 302 | by the server, :const:`False` otherwise. Case is ignored. |
| 303 | |
| 304 | |
| 305 | .. method:: SMTP.verify(address) |
| 306 | |
| 307 | Check the validity of an address on this server using SMTP ``VRFY``. Returns a |
| 308 | tuple consisting of code 250 and a full :rfc:`822` address (including human |
| 309 | name) if the user address is valid. Otherwise returns an SMTP error code of 400 |
| 310 | or greater and an error string. |
| 311 | |
| 312 | .. note:: |
| 313 | |
| 314 | Many sites disable SMTP ``VRFY`` in order to foil spammers. |
| 315 | |
| 316 | |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 317 | .. method:: SMTP.login(user, password, *, initial_response_ok=True) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 318 | |
| 319 | Log in on an SMTP server that requires authentication. The arguments are the |
| 320 | username and the password to authenticate with. If there has been no previous |
| 321 | ``EHLO`` or ``HELO`` command this session, this method tries ESMTP ``EHLO`` |
| 322 | first. This method will return normally if the authentication was successful, or |
| 323 | may raise the following exceptions: |
| 324 | |
| 325 | :exc:`SMTPHeloError` |
| 326 | The server didn't reply properly to the ``HELO`` greeting. |
| 327 | |
| 328 | :exc:`SMTPAuthenticationError` |
| 329 | The server didn't accept the username/password combination. |
| 330 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 331 | :exc:`SMTPNotSupportedError` |
| 332 | The ``AUTH`` command is not supported by the server. |
| 333 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 334 | :exc:`SMTPException` |
| 335 | No suitable authentication method was found. |
| 336 | |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 337 | Each of the authentication methods supported by :mod:`smtplib` are tried in |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 338 | turn if they are advertised as supported by the server. See :meth:`auth` |
| 339 | for a list of supported authentication methods. *initial_response_ok* is |
| 340 | passed through to :meth:`auth`. |
| 341 | |
| 342 | Optional keyword argument *initial_response_ok* specifies whether, for |
| 343 | authentication methods that support it, an "initial response" as specified |
| 344 | in :rfc:`4954` can be sent along with the ``AUTH`` command, rather than |
| 345 | requiring a challenge/response. |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 346 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 347 | .. versionchanged:: 3.5 |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 348 | :exc:`SMTPNotSupportedError` may be raised, and the |
| 349 | *initial_response_ok* parameter was added. |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 350 | |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 351 | |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 352 | .. method:: SMTP.auth(mechanism, authobject, *, initial_response_ok=True) |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 353 | |
| 354 | Issue an ``SMTP`` ``AUTH`` command for the specified authentication |
| 355 | *mechanism*, and handle the challenge response via *authobject*. |
| 356 | |
| 357 | *mechanism* specifies which authentication mechanism is to |
| 358 | be used as argument to the ``AUTH`` command; the valid values are |
| 359 | those listed in the ``auth`` element of :attr:`esmtp_features`. |
| 360 | |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 361 | *authobject* must be a callable object taking an optional single argument: |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 362 | |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 363 | data = authobject(challenge=None) |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 364 | |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 365 | If optional keyword argument *initial_response_ok* is true, |
| 366 | ``authobject()`` will be called first with no argument. It can return the |
Sebastian Rittau | 78deb7f | 2018-09-10 19:29:43 +0200 | [diff] [blame] | 367 | :rfc:`4954` "initial response" ASCII ``str`` which will be encoded and sent with |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 368 | the ``AUTH`` command as below. If the ``authobject()`` does not support an |
| 369 | initial response (e.g. because it requires a challenge), it should return |
Serhiy Storchaka | ecf41da | 2016-10-19 16:29:26 +0300 | [diff] [blame] | 370 | ``None`` when called with ``challenge=None``. If *initial_response_ok* is |
| 371 | false, then ``authobject()`` will not be called first with ``None``. |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 372 | |
Serhiy Storchaka | ecf41da | 2016-10-19 16:29:26 +0300 | [diff] [blame] | 373 | If the initial response check returns ``None``, or if *initial_response_ok* is |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 374 | false, ``authobject()`` will be called to process the server's challenge |
| 375 | response; the *challenge* argument it is passed will be a ``bytes``. It |
Sebastian Rittau | 78deb7f | 2018-09-10 19:29:43 +0200 | [diff] [blame] | 376 | should return ASCII ``str`` *data* that will be base64 encoded and sent to the |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 377 | server. |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 378 | |
| 379 | The ``SMTP`` class provides ``authobjects`` for the ``CRAM-MD5``, ``PLAIN``, |
| 380 | and ``LOGIN`` mechanisms; they are named ``SMTP.auth_cram_md5``, |
| 381 | ``SMTP.auth_plain``, and ``SMTP.auth_login`` respectively. They all require |
| 382 | that the ``user`` and ``password`` properties of the ``SMTP`` instance are |
| 383 | set to appropriate values. |
| 384 | |
| 385 | User code does not normally need to call ``auth`` directly, but can instead |
Barry Warsaw | c5ea754 | 2015-07-09 10:39:55 -0400 | [diff] [blame] | 386 | call the :meth:`login` method, which will try each of the above mechanisms |
| 387 | in turn, in the order listed. ``auth`` is exposed to facilitate the |
| 388 | implementation of authentication methods not (or not yet) supported |
| 389 | directly by :mod:`smtplib`. |
R David Murray | 76e13c1 | 2014-07-03 14:47:46 -0400 | [diff] [blame] | 390 | |
| 391 | .. versionadded:: 3.5 |
| 392 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 393 | |
Antoine Pitrou | e065020 | 2011-05-18 18:03:09 +0200 | [diff] [blame] | 394 | .. method:: SMTP.starttls(keyfile=None, certfile=None, context=None) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 395 | |
| 396 | Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP |
| 397 | commands that follow will be encrypted. You should then call :meth:`ehlo` |
| 398 | again. |
| 399 | |
Ville Skyttä | da12063 | 2018-08-13 06:39:19 +0300 | [diff] [blame] | 400 | If *keyfile* and *certfile* are provided, they are used to create an |
| 401 | :class:`ssl.SSLContext`. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 402 | |
Ville Skyttä | da12063 | 2018-08-13 06:39:19 +0300 | [diff] [blame] | 403 | Optional *context* parameter is an :class:`ssl.SSLContext` object; This is |
Serhiy Storchaka | ecf41da | 2016-10-19 16:29:26 +0300 | [diff] [blame] | 404 | an alternative to using a keyfile and a certfile and if specified both |
| 405 | *keyfile* and *certfile* should be ``None``. |
Antoine Pitrou | e065020 | 2011-05-18 18:03:09 +0200 | [diff] [blame] | 406 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 407 | If there has been no previous ``EHLO`` or ``HELO`` command this session, |
| 408 | this method tries ESMTP ``EHLO`` first. |
| 409 | |
Ville Skyttä | da12063 | 2018-08-13 06:39:19 +0300 | [diff] [blame] | 410 | .. deprecated:: 3.6 |
| 411 | |
| 412 | *keyfile* and *certfile* are deprecated in favor of *context*. |
| 413 | Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let |
| 414 | :func:`ssl.create_default_context` select the system's trusted CA |
| 415 | certificates for you. |
| 416 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 417 | :exc:`SMTPHeloError` |
| 418 | The server didn't reply properly to the ``HELO`` greeting. |
| 419 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 420 | :exc:`SMTPNotSupportedError` |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 421 | The server does not support the STARTTLS extension. |
| 422 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 423 | :exc:`RuntimeError` |
Ezio Melotti | 0639d5a | 2009-12-19 23:26:38 +0000 | [diff] [blame] | 424 | SSL/TLS support is not available to your Python interpreter. |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 425 | |
Antoine Pitrou | e065020 | 2011-05-18 18:03:09 +0200 | [diff] [blame] | 426 | .. versionchanged:: 3.3 |
| 427 | *context* was added. |
| 428 | |
Christian Heimes | a5768f7 | 2013-12-02 20:44:17 +0100 | [diff] [blame] | 429 | .. versionchanged:: 3.4 |
| 430 | The method now supports hostname check with |
| 431 | :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see |
| 432 | :data:`~ssl.HAS_SNI`). |
| 433 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 434 | .. versionchanged:: 3.5 |
| 435 | The error raised for lack of STARTTLS support is now the |
| 436 | :exc:`SMTPNotSupportedError` subclass instead of the base |
| 437 | :exc:`SMTPException`. |
| 438 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 439 | |
Pablo Aguiar | d5fbe9b | 2018-09-08 00:04:48 +0200 | [diff] [blame] | 440 | .. method:: SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=()) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 441 | |
| 442 | Send mail. The required arguments are an :rfc:`822` from-address string, a list |
| 443 | of :rfc:`822` to-address strings (a bare string will be treated as a list with 1 |
| 444 | address), and a message string. The caller may pass a list of ESMTP options |
| 445 | (such as ``8bitmime``) to be used in ``MAIL FROM`` commands as *mail_options*. |
| 446 | ESMTP options (such as ``DSN`` commands) that should be used with all ``RCPT`` |
| 447 | commands can be passed as *rcpt_options*. (If you need to use different ESMTP |
| 448 | options to different recipients you have to use the low-level methods such as |
| 449 | :meth:`mail`, :meth:`rcpt` and :meth:`data` to send the message.) |
| 450 | |
| 451 | .. note:: |
| 452 | |
| 453 | The *from_addr* and *to_addrs* parameters are used to construct the message |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 454 | envelope used by the transport agents. ``sendmail`` does not modify the |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 455 | message headers in any way. |
| 456 | |
Benjamin Peterson | a6c4a10 | 2011-12-30 23:08:09 -0600 | [diff] [blame] | 457 | *msg* may be a string containing characters in the ASCII range, or a byte |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 458 | string. A string is encoded to bytes using the ascii codec, and lone ``\r`` |
Benjamin Peterson | a6c4a10 | 2011-12-30 23:08:09 -0600 | [diff] [blame] | 459 | and ``\n`` characters are converted to ``\r\n`` characters. A byte string is |
| 460 | not modified. |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 461 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 462 | If there has been no previous ``EHLO`` or ``HELO`` command this session, this |
| 463 | method tries ESMTP ``EHLO`` first. If the server does ESMTP, message size and |
| 464 | each of the specified options will be passed to it (if the option is in the |
| 465 | feature set the server advertises). If ``EHLO`` fails, ``HELO`` will be tried |
| 466 | and ESMTP options suppressed. |
| 467 | |
| 468 | This method will return normally if the mail is accepted for at least one |
Georg Brandl | 7cb1319 | 2010-08-03 12:06:29 +0000 | [diff] [blame] | 469 | recipient. Otherwise it will raise an exception. That is, if this method does |
| 470 | not raise an exception, then someone should get your mail. If this method does |
| 471 | not raise an exception, it returns a dictionary, with one entry for each |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 472 | recipient that was refused. Each entry contains a tuple of the SMTP error code |
| 473 | and the accompanying error message sent by the server. |
| 474 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 475 | If ``SMTPUTF8`` is included in *mail_options*, and the server supports it, |
Raymond Hettinger | 624e222 | 2016-08-30 13:25:06 -0700 | [diff] [blame] | 476 | *from_addr* and *to_addrs* may contain non-ASCII characters. |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 477 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 478 | This method may raise the following exceptions: |
| 479 | |
| 480 | :exc:`SMTPRecipientsRefused` |
| 481 | All recipients were refused. Nobody got the mail. The :attr:`recipients` |
| 482 | attribute of the exception object is a dictionary with information about the |
| 483 | refused recipients (like the one returned when at least one recipient was |
| 484 | accepted). |
| 485 | |
| 486 | :exc:`SMTPHeloError` |
| 487 | The server didn't reply properly to the ``HELO`` greeting. |
| 488 | |
| 489 | :exc:`SMTPSenderRefused` |
| 490 | The server didn't accept the *from_addr*. |
| 491 | |
| 492 | :exc:`SMTPDataError` |
| 493 | The server replied with an unexpected error code (other than a refusal of a |
| 494 | recipient). |
| 495 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 496 | :exc:`SMTPNotSupportedError` |
| 497 | ``SMTPUTF8`` was given in the *mail_options* but is not supported by the |
| 498 | server. |
| 499 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 500 | Unless otherwise noted, the connection will be open even after an exception is |
| 501 | raised. |
| 502 | |
Georg Brandl | 61063cc | 2012-06-24 22:48:30 +0200 | [diff] [blame] | 503 | .. versionchanged:: 3.2 |
| 504 | *msg* may be a byte string. |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 505 | |
R David Murray | cee7cf6 | 2015-05-16 13:58:14 -0400 | [diff] [blame] | 506 | .. versionchanged:: 3.5 |
| 507 | ``SMTPUTF8`` support added, and :exc:`SMTPNotSupportedError` may be |
| 508 | raised if ``SMTPUTF8`` is specified but the server does not support it. |
| 509 | |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 510 | |
R David Murray | ac4e5ab | 2011-07-02 21:03:19 -0400 | [diff] [blame] | 511 | .. method:: SMTP.send_message(msg, from_addr=None, to_addrs=None, \ |
Pablo Aguiar | d5fbe9b | 2018-09-08 00:04:48 +0200 | [diff] [blame] | 512 | mail_options=(), rcpt_options=()) |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 513 | |
| 514 | This is a convenience method for calling :meth:`sendmail` with the message |
| 515 | represented by an :class:`email.message.Message` object. The arguments have |
| 516 | the same meaning as for :meth:`sendmail`, except that *msg* is a ``Message`` |
| 517 | object. |
| 518 | |
R David Murray | ac4e5ab | 2011-07-02 21:03:19 -0400 | [diff] [blame] | 519 | If *from_addr* is ``None`` or *to_addrs* is ``None``, ``send_message`` fills |
| 520 | those arguments with addresses extracted from the headers of *msg* as |
R David Murray | 8308444 | 2015-05-17 19:27:22 -0400 | [diff] [blame] | 521 | specified in :rfc:`5322`\: *from_addr* is set to the :mailheader:`Sender` |
R David Murray | ac4e5ab | 2011-07-02 21:03:19 -0400 | [diff] [blame] | 522 | field if it is present, and otherwise to the :mailheader:`From` field. |
Raymond Hettinger | 624e222 | 2016-08-30 13:25:06 -0700 | [diff] [blame] | 523 | *to_addrs* combines the values (if any) of the :mailheader:`To`, |
R David Murray | ac4e5ab | 2011-07-02 21:03:19 -0400 | [diff] [blame] | 524 | :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one |
| 525 | set of :mailheader:`Resent-*` headers appear in the message, the regular |
| 526 | headers are ignored and the :mailheader:`Resent-*` headers are used instead. |
| 527 | If the message contains more than one set of :mailheader:`Resent-*` headers, |
| 528 | a :exc:`ValueError` is raised, since there is no way to unambiguously detect |
| 529 | the most recent set of :mailheader:`Resent-` headers. |
| 530 | |
| 531 | ``send_message`` serializes *msg* using |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 532 | :class:`~email.generator.BytesGenerator` with ``\r\n`` as the *linesep*, and |
R David Murray | ac4e5ab | 2011-07-02 21:03:19 -0400 | [diff] [blame] | 533 | calls :meth:`sendmail` to transmit the resulting message. Regardless of the |
| 534 | values of *from_addr* and *to_addrs*, ``send_message`` does not transmit any |
| 535 | :mailheader:`Bcc` or :mailheader:`Resent-Bcc` headers that may appear |
R David Murray | 8308444 | 2015-05-17 19:27:22 -0400 | [diff] [blame] | 536 | in *msg*. If any of the addresses in *from_addr* and *to_addrs* contain |
| 537 | non-ASCII characters and the server does not advertise ``SMTPUTF8`` support, |
| 538 | an :exc:`SMTPNotSupported` error is raised. Otherwise the ``Message`` is |
| 539 | serialized with a clone of its :mod:`~email.policy` with the |
| 540 | :attr:`~email.policy.EmailPolicy.utf8` attribute set to ``True``, and |
| 541 | ``SMTPUTF8`` and ``BODY=8BITMIME`` are added to *mail_options*. |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 542 | |
| 543 | .. versionadded:: 3.2 |
| 544 | |
R David Murray | 8308444 | 2015-05-17 19:27:22 -0400 | [diff] [blame] | 545 | .. versionadded:: 3.5 |
| 546 | Support for internationalized addresses (``SMTPUTF8``). |
| 547 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 548 | |
| 549 | .. method:: SMTP.quit() |
| 550 | |
Christian Heimes | ba4af49 | 2008-03-28 00:55:15 +0000 | [diff] [blame] | 551 | Terminate the SMTP session and close the connection. Return the result of |
| 552 | the SMTP ``QUIT`` command. |
| 553 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 554 | |
| 555 | Low-level methods corresponding to the standard SMTP/ESMTP commands ``HELP``, |
| 556 | ``RSET``, ``NOOP``, ``MAIL``, ``RCPT``, and ``DATA`` are also supported. |
| 557 | Normally these do not need to be called directly, so they are not documented |
| 558 | here. For details, consult the module code. |
| 559 | |
| 560 | |
| 561 | .. _smtp-example: |
| 562 | |
| 563 | SMTP Example |
| 564 | ------------ |
| 565 | |
| 566 | This example prompts the user for addresses needed in the message envelope ('To' |
| 567 | and 'From' addresses), and the message to be delivered. Note that the headers |
| 568 | to be included with the message must be included in the message as entered; this |
| 569 | example doesn't do any processing of the :rfc:`822` headers. In particular, the |
| 570 | 'To' and 'From' addresses must be included in the message headers explicitly. :: |
| 571 | |
| 572 | import smtplib |
| 573 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 574 | def prompt(prompt): |
Georg Brandl | 8d5c392 | 2007-12-02 22:48:17 +0000 | [diff] [blame] | 575 | return input(prompt).strip() |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 576 | |
| 577 | fromaddr = prompt("From: ") |
| 578 | toaddrs = prompt("To: ").split() |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 579 | print("Enter message, end with ^D (Unix) or ^Z (Windows):") |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 580 | |
| 581 | # Add the From: and To: headers at the start! |
| 582 | msg = ("From: %s\r\nTo: %s\r\n\r\n" |
| 583 | % (fromaddr, ", ".join(toaddrs))) |
Collin Winter | 4633448 | 2007-09-10 00:49:57 +0000 | [diff] [blame] | 584 | while True: |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 585 | try: |
Georg Brandl | 8d5c392 | 2007-12-02 22:48:17 +0000 | [diff] [blame] | 586 | line = input() |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 587 | except EOFError: |
| 588 | break |
| 589 | if not line: |
| 590 | break |
| 591 | msg = msg + line |
| 592 | |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 593 | print("Message length is", len(msg)) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 594 | |
| 595 | server = smtplib.SMTP('localhost') |
| 596 | server.set_debuglevel(1) |
| 597 | server.sendmail(fromaddr, toaddrs, msg) |
| 598 | server.quit() |
| 599 | |
Benjamin Peterson | fa0d703 | 2009-06-01 22:42:33 +0000 | [diff] [blame] | 600 | .. note:: |
| 601 | |
| 602 | In general, you will want to use the :mod:`email` package's features to |
R. David Murray | 7dff9e0 | 2010-11-08 17:15:13 +0000 | [diff] [blame] | 603 | construct an email message, which you can then send |
| 604 | via :meth:`~smtplib.SMTP.send_message`; see :ref:`email-examples`. |