email-examples.md
1> **Источник:** https://python-all.ru/3.0/library/email-examples.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`email`](https://python-all.ru/3.0/library/email.html#module-email): Примеры89Вот несколько примеров использования пакета [`email`](https://python-all.ru/3.0/library/email.html#module-email) для чтения, записи и отправки простых email-сообщений, а также более сложных MIME-сообщений.1011Сначала посмотрим, как создать и отправить простое текстовое сообщение:1213```python14# Импорт smtplib для функции отправки15import smtplib1617# Импортируются необходимые модули email.18from email.mime.text import MIMEText1920# Открыть обычный текстовый файл для чтения. В этом примере предполагается, что21# текстовый файл содержит только символы ASCII.22fp = open(textfile, 'rb')23# Создать сообщение text/plain24msg = MIMEText(fp.read())25fp.close()2627# me == адрес электронной почты отправителя28# you == адрес электронной почты получателя29msg['Subject'] = 'The contents of %s' % textfile30msg['From'] = me31msg['To'] = you3233# Отправить сообщение через собственный SMTP-сервер, но не включать34# заголовок конверта.35s = smtplib.SMTP()36s.connect()37s.sendmail(me, [you], msg.as_string())38s.close()39```4041Вот пример отправки MIME-сообщения, содержащего много семейных фотографий, которые могут находиться в каталоге:4243```python44# Импорт smtplib для функции отправки45import smtplib4647# Вот модули пакета email, которые нам понадобятся48from email.mime.image import MIMEImage49from email.mime.multipart import MIMEMultipart5051COMMASPACE = ', '5253# Создать контейнер (внешнее) email-сообщение.54msg = MIMEMultipart()55msg['Subject'] = 'Our family reunion'56# me == адрес электронной почты отправителя57# family = список адресов электронной почты всех получателей58msg['From'] = me59msg['To'] = COMMASPACE.join(family)60msg.preamble = 'Our family reunion'6162# Предположим, что все файлы изображений в формате PNG.63for file in pngfiles:64 # Открыть файлы в двоичном режиме. Пусть класс MIMEImage автоматически65 # определяет конкретный тип изображения.66 fp = open(file, 'rb')67 img = MIMEImage(fp.read())68 fp.close()69 msg.attach(img)7071# Отправляем email через собственный SMTP-сервер.72s = smtplib.SMTP()73s.connect()74s.sendmail(me, family, msg.as_string())75s.close()76```7778Вот пример отправки всего содержимого каталога в виде email- сообщения: [\[1\]](https://python-all.ru/3.0/library/email-examples.html#id3)7980```python81#!/usr/bin/env python8283"""Send the contents of a directory as a MIME message."""8485import os86import sys87import smtplib88# For guessing MIME type based on file name extension89import mimetypes9091from optparse import OptionParser9293from email import encoders94from email.message import Message95from email.mime.audio import MIMEAudio96from email.mime.base import MIMEBase97from email.mime.image import MIMEImage98from email.mime.multipart import MIMEMultipart99from email.mime.text import MIMEText100101COMMASPACE = ', '102103def main():104 parser = OptionParser(usage="""\105Send the contents of a directory as a MIME message.106107Usage: %prog [options]108109Unless the -o option is given, the email is sent by forwarding to your local110SMTP server, which then does the normal delivery process. Your local machine111must be running an SMTP server.112""")113 parser.add_option('-d', '--directory',114 type='string', action='store',115 help="""Mail the contents of the specified directory,116 otherwise use the current directory. Only the regular117 files in the directory are sent, and we don't recurse to118 subdirectories.""")119 parser.add_option('-o', '--output',120 type='string', action='store', metavar='FILE',121 help="""Print the composed message to FILE instead of122 sending the message to the SMTP server.""")123 parser.add_option('-s', '--sender',124 type='string', action='store', metavar='SENDER',125 help='The value of the From: header (required)')126 parser.add_option('-r', '--recipient',127 type='string', action='append', metavar='RECIPIENT',128 default=[], dest='recipients',129 help='A To: header value (at least one required)')130 opts, args = parser.parse_args()131 if not opts.sender or not opts.recipients:132 parser.print_help()133 sys.exit(1)134 directory = opts.directory135 if not directory:136 directory = '.'137 # Create the enclosing (outer) message138 outer = MIMEMultipart()139 outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)140 outer['To'] = COMMASPACE.join(opts.recipients)141 outer['From'] = opts.sender142 outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'143144 for filename in os.listdir(directory):145 path = os.path.join(directory, filename)146 if not os.path.isfile(path):147 continue148 # Guess the content type based on the file's extension. Encoding149 # will be ignored, although we should check for simple things like150 # gzip'd or compressed files.151 ctype, encoding = mimetypes.guess_type(path)152 if ctype is None or encoding is not None:153 # No guess could be made, or the file is encoded (compressed), so154 # use a generic bag-of-bits type.155 ctype = 'application/octet-stream'156 maintype, subtype = ctype.split('/', 1)157 if maintype == 'text':158 fp = open(path)159 # Note: we should handle calculating the charset160 msg = MIMEText(fp.read(), _subtype=subtype)161 fp.close()162 elif maintype == 'image':163 fp = open(path, 'rb')164 msg = MIMEImage(fp.read(), _subtype=subtype)165 fp.close()166 elif maintype == 'audio':167 fp = open(path, 'rb')168 msg = MIMEAudio(fp.read(), _subtype=subtype)169 fp.close()170 else:171 fp = open(path, 'rb')172 msg = MIMEBase(maintype, subtype)173 msg.set_payload(fp.read())174 fp.close()175 # Encode the payload using Base64176 encoders.encode_base64(msg)177 # Set the filename parameter178 msg.add_header('Content-Disposition', 'attachment', filename=filename)179 outer.attach(msg)180 # Now send or store the message181 composed = outer.as_string()182 if opts.output:183 fp = open(opts.output, 'w')184 fp.write(composed)185 fp.close()186 else:187 s = smtplib.SMTP()188 s.connect()189 s.sendmail(opts.sender, opts.recipients, composed)190 s.close()191192if __name__ == '__main__':193 main()194```195196Вот пример распаковки MIME-сообщения вроде показанного выше в каталог с файлами:197198```python199#!/usr/bin/env python200201"""Unpack a MIME message into a directory of files."""202203import os204import sys205import email206import errno207import mimetypes208209from optparse import OptionParser210211def main():212 parser = OptionParser(usage="""\213Unpack a MIME message into a directory of files.214215Usage: %prog [options] msgfile216""")217 parser.add_option('-d', '--directory',218 type='string', action='store',219 help="""Unpack the MIME message into the named220 directory, which will be created if it doesn't already221 exist.""")222 opts, args = parser.parse_args()223 if not opts.directory:224 parser.print_help()225 sys.exit(1)226227 try:228 msgfile = args[0]229 except IndexError:230 parser.print_help()231 sys.exit(1)232233 try:234 os.mkdir(opts.directory)235 except OSError as e:236 # Ignore directory exists error237 if e.errno != errno.EEXIST:238 raise239240 fp = open(msgfile)241 msg = email.message_from_file(fp)242 fp.close()243244 counter = 1245 for part in msg.walk():246 # multipart/* are just containers247 if part.get_content_maintype() == 'multipart':248 continue249 # Applications should really sanitize the given filename so that an250 # email message can't be used to overwrite important files251 filename = part.get_filename()252 if not filename:253 ext = mimetypes.guess_extension(part.get_content_type())254 if not ext:255 # Use a generic bag-of-bits extension256 ext = '.bin'257 filename = 'part-%03d%s' % (counter, ext)258 counter += 1259 fp = open(os.path.join(opts.directory, filename), 'wb')260 fp.write(part.get_payload(decode=True))261 fp.close()262263if __name__ == '__main__':264 main()265```266267Here’s an example of how to create an HTML message with an alternative plain text version: [\[2\]](https://python-all.ru/3.0/library/email-examples.html#id4)268269```python270#! /usr/bin/python271272import smtplib273274from email.mime.multipart import MIMEMultipart275from email.mime.text import MIMEText276277# me == мой адрес электронной почты.278# you == адрес электронной почты получателя.279me = "my@email.com"280you = "your@email.com"281282# Создать контейнер сообщения – правильный тип MIME – multipart/alternative.283msg = MIMEMultipart('alternative')284msg['Subject'] = "Link"285msg['From'] = me286msg['To'] = you287288# Создать тело сообщения (версии в виде простого текста и HTML).289text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"290html = """\291<html>292 <head></head>293 <body>294 <p>Hi!<br>295 How are you?<br>296 Here is the <a href="http://www.python.org">link</a> you wanted.297 </p>298 </body>299</html>300"""301302# Записать MIME-типы обеих частей – text/plain и text/html.303part1 = MIMEText(text, 'plain')304part2 = MIMEText(html, 'html')305306# Прикрепить части к контейнеру сообщения.307# Согласно RFC 2046, последняя часть многокомпонентного сообщения, в данном случае308# HTML-сообщение, является наилучшим и предпочтительным.309msg.attach(part1)310msg.attach(part2)311312# Отправка сообщения через локальный SMTP-сервер.313s = smtplib.SMTP('localhost')314# Функция sendmail принимает 3 аргумента: адрес отправителя, адрес получателя315# и сообщение для отправки – здесь оно отправляется в виде одной строки.316s.sendmail(me, you, msg.as_string())317s.close()318```319320Сноски321322| [\[1\]](https://python-all.ru/3.0/library/email-examples.html#id1) | Спасибо Matthew Dixon Cowles за оригинальную идею и примеры. |323| --- | --- |324325| [\[2\]](https://python-all.ru/3.0/library/email-examples.html#id2) | Автор: Martin Matejek. |326| --- | --- |327