Python - Как отправить электронное письмо с вложением, не загружая сразу весь файл в память?

Я хотел бы отправлять электронные письма с вложениями размером 10 МБ или более на VPS с небольшим объемом оперативной памяти; обычный способ отправить электронное письмо с вложениями в Python 3 (который я нашел) таков:

from email.message import EmailMessage
# import other needed stuff here omitted for simplicity
attachment = 'some_file.tar'
msg = EmailMessage()
# set from, to, subject here
# set maintype, subtype here
with open(attachment, 'rb') as fd:
    msg.add_attachment(fd.read(),  # this is the problem, the whole file is loaded
                       maintype=maintype,
                       subtype=subtype,
                       filename=attachment)
# smtp_serv is an instance of smtplib.SMTP
smtp_serv.send_message(msg)

При таком подходе весь файл загружается в память, а затем объект EmailMessage отправляется с помощью smtplib.SMTP.send_message, я ожидаю, что это способ предоставить add_attachment дескриптор файла (или итерируемый) вместо содержимого файла, который читается в ленивом подходе (например, построчно или по некоторому фиксированному количеству байтов), когда вложение отправляется на сервер, например:

with open('somefile') as fd:
    msg.add_attachment(fd, maintype=mt, subtype=st, filename=fn)
    smtp_serv.send_message(msg)

Есть ли способ сделать это (отправить вложение без загрузки всего файла сразу) с помощью стандартной библиотеки (электронная почта и smtplib)???? Я не могу найти подсказку в документации по Python.

Заранее спасибо.


person Asiel Diaz Benitez    schedule 16.11.2017    source источник
comment
Решение заключается в использовании ContentManager, ContentManager.set_content() — это способ любой данные помещаются в сообщение. Проблема в том, что стандартный ContentManager поддерживает только ограниченное количество типов данных. Поэтому нужно расширить его, если ему нужно больше   -  person user3159253    schedule 09.01.2018
comment
Вопрос в том, «вам действительно нужно помещать эти большие файлы во вложения?» Рассматривали ли вы возможные проблемы с ограничениями SMTP-серверов и возможные переполнения почтовых ящиков получателей сообщений?   -  person user3159253    schedule 10.01.2018
comment
Мне действительно нужно отправить эти файлы по электронной почте, ограничение сервера составляет 50 МБ для одного письма, и пространство почтового ящика не является проблемой, и электронные письма будут загружаться по мере их поступления, в любом случае я не думаю, что загрузка всего файла в память - хороший подход, и она замораживает мой VPS. Сейчас я слишком занят, чтобы проверять ContentManager, но я проверю его как можно скорее, если вы уверены, что это решение, отправьте ответ с примером кода, и я приму его, спасибо!   -  person Asiel Diaz Benitez    schedule 16.01.2018
comment
Можно ли использовать объект mmap вместо строки?   -  person Davis Herring    schedule 01.11.2018


Ответы (1)


Я рекомендую загружать вложения в корзину S3 или Google Storage, а затем указывать URL-адрес в электронном письме, чтобы получатель мог загрузить его. Большинство почтовых серверов ограничивают размер вложений, поэтому маловероятно, что они дойдут до большинства почтовых клиентов.

Вам не нужно использовать общедоступную корзину, вы можете запутать имена вложений и добавить «предварительно подписанный» URL-адрес — это работает только в течение ограниченного периода времени: https://docs.aws.amazon

person rotten    schedule 09.12.2019