RK
RK
Sep 9, 2018 · 3 min read

Я участвую в разработке одного проекта на работе. Мы разрабатываем прототипы Raspberry Pi и специальное программное обеспечение. Хоть и разработанное ПО работает блестяще, нам бы хотелось добавить немного дополнительных функций.

Используем Python!

Первое, что мне пришло в голову — это отправка e-mail. Я подумал, что это будет самый сложный фрагмент кода, который мне придётся написать. Если закончу с ним, остальная работа для меня будет довольно лёгкой. Ну или я так думал…

Первое, что я сделал — пошёл на Stack Overflow и нашёл ответ на свой вопрос.

Кажется, довольно просто.

Отправка e-mail

Добавив smtplib из стандартной библиотеки, вы можете отсылать письма очень легко. Мне пришлось посмотреть синтаксис определения функций и прочитать про код-стайл Python. Я всегда предпочитаю использовать имена функций, которые больше всего подходят для языка. Это привело меня к созданию следующей функции:

def send_mail(
sender,
receivers: List[str],
subject,
body,
username,
password,
server_address
):
"""Sends an email to the specified receivers using an Exchange server."""
message = MIMEMultipart()
message["From"] = sender
message["To"] = ",".join(receivers)
message["Subject"] = subject
message.attach(MIMEText(body))

server = smtplib.SMTP(server_address, 587)
server.starttls()
server.login(username, password)
server.sendmail(sender, receivers, message.as_string())
server.quit()

Поскольку я использую Exchange сервер, мне приходится инициализировать TLS. Не считая этого, всё довольно просто.

Запускаем скрипт в терминале

Я также хотел иметь возможность запуска скрипта в терминале. Это можно сделать, вызвав функцию после её определения. Когда интерпретатор Python будет проходить через файл, он выполнит её вызов.

Однако в Python хорошим тоном считается поместить вызов внутри аргумента __name__ == » __main__». Это делается для того, чтобы определить, запущен файл напрямую или импортирован другим файлом или модулем.

Когда интерпретатор Python запускает файл напрямую (например, в терминале), он устанавливает глобальную переменную __name__ в __main__.
Когда файл импортируется другим файлом или модулем, __name__ будет установлено как имя файла или модуля.

Поместив выполняемый код внутри if __name__ == » __main__», мы убеждаемся, что код запускается только тогда, когда файл используется напрямую, а не импортируется в другую часть кода.

Анализ входных данных

Я хотел бы указать параметры для функции send_mail, передав их при запуске файла в терминале. Оказывается, у Python тоже есть библиотека для этого!
Импортируя argparse, у меня появляется возможность определить параметры, добавить типовые подсказки и справочные тексты. argparse автоматически добавляет ключ -h, который показывает все возможные параметры и справочные тексты.

Чтобы было поинтереснее, я добавил функцию, которая может использовать файл с текстом, вместо обычного ввода текста. Скрипт получает текст из файла и использует его как контент письма.

if __name__ == " __main__":  
parser = argparse.ArgumentParser(description="Sends an email to the specified receivers using the Sykehuspartner Exchange server.")
parser.add_argument("sender", type=str, help="Sender's email address.")
parser.add_argument("receivers", type=str, help="Comma-seperated list of email addresses.")
parser.add_argument("subject", type=str, help="Subject of the email.")
parser.add_argument("body", type=str, help="Body text of the email. Can be plain text or a file path when -f is passed.")
parser.add_argument("username", type=str, help="The username to authenticate with on mail server.")
parser.add_argument("password", type=str, help="The password to authenticate with on mail server.")
parser.add_argument("server", type=str, help="The address of the mail server.")
parser.add_argument("-f", "--file", action="store_true", help="Specifies that the body argument contains a file path instead of plain text")
args = parser.parse_args()

if args.file:
with open(args.body) as file:
args.body = file.read()

send_mail(args.sender, args.receivers.split(","), args.subject, args.body, args.username, args.password, args.server)

Перевод статьи Jon Stødle: Sending an email with Python

RK

Written by

RK

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade