smtplibSMTP协议客户端

源代码: Lib / smtplib.py


smtplib模块定义了一个可用于发送邮件的SMTP客户端会话对象到具有SMTPESMTP侦听器守护程序的任何Internet计算机。有关SMTP和ESMTP操作的详细信息,请参阅 RFC 821 (简单邮件传输协议)和 RFC 1869 (SMTP服务扩展).

class smtplib.SMTPhost=””, port=0, local_hostname=None, [timeout, ] source_address=None

SMTP实例封装了一个SMTP连接。它的方法支持完整的SMTP和ESMTP操作。如果给出了可选的主机和端口参数,则在初始化期间使用这些参数调用SMTP connect()方法。如果指定,则local_hostname用作HELO / EHLO命令中本地主机的FQDN。否则,使用socket.getfqdn()找到本地主机名。如果connect()调用返回除成功代码之外的任何内容,则会引发SMTPConnectError。可选timeout参数指定阻塞操作(如连接尝试)的超时(以秒为单位)(如果未指定,将使用全局默认超时设置)。如果超时到期,则socket.timeout israised。可选的source_address参数允许绑定到具有多个网络接口的机器中的某个特定源地址,和/或某个特定源TCP端口。它需要一个2元组(主机,端口),以便在连接之前将套接字绑定为其源地址。如果省略(或主机或端口分别为""和/或0),将使用OS默认行为.

对于正常使用,您应该只需要初始化/连接,sendmail()SMTP.quit()方法。下面有一个例子.

SMTP支持with语句。像这样使用时,QUIT语句退出时会自动发出SMTP with命令。例如:

>>> from smtplib import SMTP>>> with SMTP("domain.org") as smtp:...     smtp.noop()...(250, b"Ok")>>>

在版本3.3中更改:添加了对with语句的支持.

在版本3.3中更改:添加了source_address参数.

版本3.5:现在支持SMTPUTF8扩展名( RFC 6531

class smtplib.SMTP_SSL//(host=””, port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ] context=None, source_address=None

SMTP_SSL实例的行为与SMTP. SMTP_SSL的实例完全相同应该用于从连接开始需要SSL并且使用starttls()不合适的情况。如果未指定host,则使用本地主机。如果port为零,则使用标准的SMTP-over-SSL端口(465)。选项报告local_hostname, timeoutsource_addressSMTP类中的含义相同。context,也是可选的,可以包含SSLContext,并允许配置安全连接的各个方面。请阅读安全考虑最好的做法.

keyfilecertfilecontext的遗留替代品,可以指向PEM格式化用于SSL连接的私钥和证书链文件.

在版本3.3中更改:context已添加.

在版本3.3中更改:添加了source_address参数.

更改版本3.4:该类现在支持使用ssl.SSLContext.check_hostnameServer Name Indication进行主机名检查(参见ssl.HAS_SNI).

自版本3.6以来不推荐使用:keyfilecertfile不赞成使用context。请使用ssl.SSLContext.load_cert_chain()代替,或者让ssl.create_default_context()为你选择系统的可信任CA证书.

class smtplib.LMTP(host=””, port=LMTP_PORT, local_hostname=None, source_address=None)

LMTP协议,与ESMTP非常相似,严重依据标准SMTP客户端。对于LMTP使用Unix套接字是很常见的,所以我们的connect()方法必须支持它以及常规主机:portserver。可选参数local_hostname和source_address具有与SMTP类中相同的含义。要指定Unixsocket,必须使用host的绝对路径,以’/’开头.

使用常规SMTP机制支持身份验证。当使用unix套接字时,LMTP通常不支持或要求任何身份验证,但你的里程可能会有所不同.

也定义了很好的异常选择:

exception smtplib.SMTPException

的子类OSError这是该模块提供的所有其他异常的基本异常类.

版本3.4更改:SMTPException成为OSError

exception smtplib.SMTPServerDisconnected

服务器意外断开连接,或者在连接到服务器之前使用SMTP实例时,会引发此异常.

exception smtplib.SMTPResponseException

包含SMTP错误代码的所有异常的基类。当SMTP服务器返回错误代码时,会在某些情况下生成这些异常。错误代码存储在smtp_code错误的属性,并将smtp_error属性设置为错误消息.

exception smtplib.SMTPSenderRefused

拒绝了地址。除了所有SMTPResponseException例外,这会将’sender’设置为SMTP服务器拒绝的字符串.

exception smtplib.SMTPRecipientsRefused

所有收件人地址都被拒绝。每个收件人的错误都可以通过属性recipients,这是一个完全相同的字典SMTP.sendmail()返回

exception smtplib.SMTPDataError

SMTP服务器拒绝接受消息数据.

exception smtplib.SMTPConnectError

与服务器建立连接时发生错误.

exception smtplib.SMTPHeloError

服务器拒绝了我们的HELO消息

exception smtplib.SMTPNotSupportedError

服务器不支持所尝试的命令或选项.

3.5版本中的新功能

exception smtplib.SMTPAuthenticationError

SMTP身份验证出错了。很可能服务器不接受提供的用户名/密码组合.

参见

RFC 821 – 简单邮件传输协议
SMTP的协议定义。本文档介绍了SMTP的型号,操作步骤和协议详细信息.
RFC 1869 – SMTP服务扩展
SMTP的ESMTP扩展的定义。这描述了一个框架,它使用新命令来扩展SMTP,支持动态发现服务器提供的命令,并定义了一些额外的命令.

SMTP对象

SMTP实例有以下方法:

SMTP.set_debuglevellevel

设置调试输出级别。对于True,值为1或level导致连接的调试消息以及发送到服务器和从服务器接收的所有消息。level导致这些消息被加上时间戳

在版本3.5中更改:添加了debuglevel 2.

SMTP.docmd(cmd, args=””)

向服务器发送命令cmd。可选参数args简单地与命令相连,用空格分隔.

这将返回一个由数字响应代码和实际响应行组成的2元组(多行响应连接成一条长行。)

在正常操作中,没有必要显式调用此方法。它用于实现其他方法,可能对测试privateextensions有用.

如果在等待回复时丢失了与服务器的连接,则SMTPServerDisconnected将被抬起.

SMTP.connect (host=”localhost”, port=0 )

连接到给定端口上的主机。默认设置是连接到标准SMTP端口(25)的localhost。如果主机名以冒号结尾(":")后跟一个数字,该后缀将被剥离,并将该数字解释为要使用的端口号。如果在实例化期间指定了主机,则构造函数会自动调用此方法。返回服务器在其连接响应中发送的响应代码和消息的a2元组.

SMTP.heloname=””

使用HELO。hostname参数默认为本地主机的完全限定域名。服务器返回的消息存储为对象的helo_resp属性.

在正常操作中,没有必要明确地调用这个方法。必要时会被sendmail()隐式调用.

SMTP.ehlo (name=””)

使用EHLO。hostname参数默认为本地主机的完全限定域名。检查ESMTP选项的响应并将其存储以供has_extn()。还设置了几个信息属性:服务器返回的消息存储为ehlo_resp属性,does_esmtp设置为true或false,具体取决于服务器是否支持ESMTP,esmtp_features将是一个字典,其中包含此服务器支持的SMTP服务扩展名及其参数(如果有).

除非您想使用has_extn()在发送邮件之前,不必明确地调用此方法。它会被sendmail()必要时。

SMTP.ehlo_or_helo_if_needed

这个方法叫ehlo()和/或helo()如果有一个不太明显的EHLOHELO指挥本次会议。它尝试了ESMTP EHLO第一个

SMTPHeloError
服务器没有正确回复HELO问候
SMTP.has_extnname

返回True如果name在服务器返回的SMTP服务扩展集中,False除此以外。案件被忽略了

SMTP.verifyaddress

使用SMTP VRFY。返回包含代码250和完整 RFC 822 如果用户地址有效,则为地址(包括人名)。否则返回一个400或更大的SMTP错误代码和一个错误字符串.

注意

许多网站禁用SMTP VRFY为了欺骗垃圾邮件发送者.

SMTP.login (user, password, *, initial_response_ok=True

登录需要验证的SMTP服务器。参数是用于进行身份验证的用户名和密码。如果以前没有EHLOHELO命令此会话,此方法首先尝试ESMTP EHLO。如果验证成功,此方法将正常返回,或者可能引发以下异常:

SMTPHeloError
服务器没有正确回复HELOgreeting.
SMTPAuthenticationError
服务器不接受用户名/密码组合.
SMTPNotSupportedError
AUTH服务器不支持命令.
SMTPException
没有找到合适的身份验证方法.

如果它们被广告宣传为服务器支持,则smtplib支持的每种身份验证方法都会被尝试。见auth()获取支持的身份验证方法列表。initial_response_ok通过auth().

可选关键字参数initial_response_ok指定支持它的forauthentication方法, RFC 4954 中指定的“初始响应”是否可以与AUTH命令,而不是要求挑战/响应.

版本3.5改变:SMTPNotSupportedError可能会被提升,并且initial_response_ok参数被添加了

SMTP.authmechanism, authobject, *, initial_response_ok=True/)

发一个SMTP AUTH命令用于指定的验证mechanism,并通过authobject.

mechanism处理质询响应,指定哪个验证机制用作AUTH命令;auth esmtp_features.

authobject元素中列出的有效值必须是一个可调用的对象,它带有一个可选的单个参数:

data = authobject(challenge = None)

如果可选的关键字参数initial_response_ok为true,则authobject()将首先调用,不带参数。它可以返回 RFC 4954 “初始响应”ASCII str,它将被编码并与AUTH命令如下。如果authobject()不支持初始响应(例如因为它需要一个挑战),它应该在None调用时返回challenge=None。如果initial_response_ok是假的,那么authobject()不会先用None.

如果初始响应检查返回​​None, 或者如果 initial_response_ok是的,authobject()将被调用来处理服务器的challengeresponse;challenge它传递的参数将是bytes。它应该返回ASCII str data,它将被base64编码并发送到服务器.

SMTP class为authobjects提供CRAM-MD5, PLAIN,以及LOGIN机制;它们分别命名为SMTP.auth_cram_md5,SMTP.auth_plainSMTP.auth_login。它们都要求user实例的passwordSMTP属性设置为适当的值.

用户代码通常不需要直接调用auth,而是可以调用login()方法,它将按照列出的顺序依次尝试上述每个机制。auth暴露是为了方便实现身份验证方法而不是(或尚未)直接支持smtplib.

新版本3.5.

SMTP.starttls (keyfile=None, certfile=None, context=None)

将SMTP连接置于TLS(传输层安全性)模式。随后的所有SMTP命令都将加密。然后你应该拨打ehlo()again.

如果keyfilecertfile提供,它们用于创建ssl.SSLContext.

可选context参数是ssl.SSLContext对象;这是使用密钥文件和证书文件的替代方法,如果指定keyfilecertfile应该是None.

如果以前没有EHLOHELO命令这个会话,这个方法首先尝试ESMTP EHLO.

自版本3.6以后删除:keyfilecertfile不赞成使用context。请用 ssl.SSLContext.load_cert_chain()相反,或者让ssl.create_default_context()为您选择系统的可信任CA证书.

SMTPHeloError
服务器没有正确回复HELOgreeting.
SMTPNotSupportedError
服务器不支持STARTTLS扩展.
RuntimeError
您的Python解释器无法使用SSL / TLS支持.

在版本3.3中更改:context已添加.

在版本3.4中更改:该方法现在支持使用SSLContext.check_hostnameServer Name Indicator进行主机名检查(参见HAS_SNI).

在版本3.5中更改:引发的错误由于缺少STARTTLS支持现在是SMTPNotSupportedError子类而不是基础SMTPException.

SMTP.sendmailfrom_addr, to_addrs, msg, mail_options=(), rcpt_options=()

发送邮件。所需的参数是 RFC 822 from-address字符串, RFC 822 列表到地址字符串(一个简单的字符串将是被视为具有1address的列表)和消息字符串。调用者可以传递一个ESMTP选项列表(例如8bitmime)以在MAIL FROM命令中使用mail_options.ESMTP选项(例如DSN命令))应该与所有RCPT命令一起使用,可以作为rcpt_options传递。(如果需要对不同的收件人使用不同的ESMTPoptions,则必须使用低级方法,如mail(), rcpt()data()来发送邮件。)

注意

from_addrto_addrs参数用于构造传输代理使用的messageenvelope。sendmail不会以任何方式修改themessage标题.

msg可以是包含ASCII范围内的字符或字节串的字符串。使用ascii编解码器将字符串编码为字节,并将单独的\r\n字符转换为\r\n字符。字节串没有被修改.

如果以前没有EHLOHELO命令这个会话,这个方法首先尝试ESMTP EHLO。如果服务器执行ESMTP,则会将消息大小和指定选项的每个传递给它(如果该选项位于服务器通告的特征集中)。如果EHLO失败,HELO将被尝试并且ESMTP选项被抑制.

如果邮件被至少一个接收者接受,则此方法将正常返回。否则会引发异常。也就是说,如果此方法不会引发异常,那么有人应该收到您的邮件。如果此方法不引发异常,则返回一个字典,每个被拒绝的一个条目都有一个条目。每个条目都包含一个SMTP错误代码元组和服务器发送的随附错误消息.

如果SMTPUTF8包含在mail_options中,服务器支持它,from_addrto_addrs可能包含非ASCII字符.

此方法可能会引发以下异常:

SMTPRecipientsRefused
所有收件人都被拒绝了。没有人收到邮件。异常对象的recipients属性是一个字典,其中包含有关已注入的收件人的信息(如至少有一个收件人被收到时返回的那个).
SMTPHeloError
服务器没有正确回复HELO问候
SMTPSenderRefused
服务器不接受from_addr.
SMTPDataError
服务器回复了一个意外的错误代码(除了拒绝接受者).
SMTPNotSupportedError
SMTPUTF8mail_options中给出但服务器不支持.

除非另有说明,否则即使在异常情况下连接也会打开.

在版本3.2中更改:msg可能是一个字节串.

在版本3.5中更改:SMTPUTF8支持补充,和SMTPNotSupportedError如果指定了SMTPUTF8但是服务器不支持它可以进行评估.

SMTP.send_message (msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())

这是一个方便的方法来调用sendmail()email.message.Message宾语。这些论点与sendmail()的含义相同,除了msgMessageobject.

如果from_addrNoneto_addrsNone, send_message使用从msg在中指定RFC 5322 from_addr设置为Sender字段,如果它存在,否则到From领域。to_addrs结合To,CcBccmsg字段的值(如果有的话)。如果消息中只出现一对Resent-*标题,则忽略常规标题和Resent-*使用标题。如果消息包含多个Resent-*标题集,则会引发ValueError,因为无法明确地检测到最新的Resent-集合headers.

send_message序列化msg使用BytesGenerator\r\n作为linesep,并调用sendmail()来传输结果消息。无论from_addrto_addrs, send_message的值如何都不传送任何BccResent-Bcc可能出现在msg的标题。如果from_addrto_addrs中的任何地址包含非ASCII字符并且服务器没有通告SMTPUTF8支持,则会引发SMTPNotSupported错误。否则Messagepolicy的一个克隆进行序列化,utf8属性设置为True,并将SMTPUTF8BODY=8BITMIME添加到mail_options.

版本3.2中的新功能

//版本3.5:支持国际化地址(SMTPUTF8).

SMTP.quit()

终止SMTP会话并关闭连接。返回SMTP QUIT命令的结果

对应于标准SMTP / ESMTP命令的低级方法HELP,RSET, NOOP, MAIL, RCPTDATA也支持。通常这些不需要直接调用,因此它们没有在文档中记录。有关详细信息,请参阅模块代码.

SMTP示例

示例提示用户输入消息信封中所需的地址(“To”和“From”地址)以及要传递的消息。请注意,消息中包含的标题必须包含在输入的消息中;这个例子不对RFC 822 头。特别是,’To’和’From’地址必须明确地包含在邮件头中.

import smtplibdef prompt(prompt):    return input(prompt).strip()fromaddr = prompt("From: ")toaddrs  = prompt("To: ").split()print("Enter message, end with ^D (Unix) or ^Z (Windows):")# Add the From: and To: headers at the start!msg = ("From: %s\r\nTo: %s\r\n\r\n"       % (fromaddr, ", ".join(toaddrs)))while True:    try:        line = input()    except EOFError:        break    if not line:        break    msg = msg + lineprint("Message length is", len(msg))server = smtplib.SMTP("localhost")server.set_debuglevel(1)server.sendmail(fromaddr, toaddrs, msg)server.quit()

注意

一般来说,你会想要使用email包的功能包括一个电子邮件消息,然后您可以发送send_message();看电子邮件:例子.

评论被关闭。