Python: Envoyer un mail tout simplement

Envoi d'un mail via un serveur SMTP (sans authentification):

import smtplib
from email.utils import formatdate
server = smtplib.SMTP()
# server.set_debuglevel(1) # Décommenter pour activer le debug
server.connect('smtp.toto.fr')
# (220, 'toto ESMTP Postfix') # Réponse du serveur
server.helo()
# (250, 'toto\nPIPELINING\nSIZE 10240000\nVRFY\nETRN\nSTARTTLS\nENHANCEDSTATUSCODES\n8BITMIME\nDSN') # Réponse du serveur
fromaddr = 'TOTO <moi@toto.fr>'
toaddrs = ['lui@toto.fr', 'elle@toto.fr'] # On peut mettre autant d'adresses que l'on souhaite
sujet = "Un Mail avec Python"
message = u"""\
Velit morbi ultrices magna integer.
Metus netus nascetur amet cum viverra ve cum.
Curae fusce condimentum interdum felis sit risus.
Proin class condimentum praesent hendrer
it donec odio facilisi sit.
Etiam massa tempus scelerisque curae habitasse vestibulum arcu metus iaculis hac.
"""
msg = """\
From: %s\r\n\
To: %s\r\n\
Subject: %s\r\n\
Date: %s\r\n\
\r\n\
%s
""" % (fromaddr, ", ".join(toaddrs), sujet, formatdate(localtime=True), message)
try:
    server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPException as e:
    print(e)
# {} # Réponse du serveur
server.quit()
# (221, '2.0.0 Bye') # Réponse du serveur

Envoi d'un mail via un serveur SMTP en SSL (avec authentification):

import smtplib
from email.utils import formatdate
server = smtplib.SMTP_SSL() # On utilise SMTP_SSL() à la place de SMTP()
# server.set_debuglevel(1) # Décommenter pour activer le debug
server.connect('smtp.toto.fr')
# (220, 'toto ESMTP Postfix') # Réponse du serveur
server.ehlo() # ATTENTION, avec SSL, c'est la commande EHLO au lieu de HELO
#(250, 'toto\nPIPELINING\nSIZE 10240000\nVRFY\nETRN\nAUTH LOGIN PLAIN\nAUTH=LOGIN PLAIN\nENHANCEDSTATUSCODES\n8BITMIME\nDSN') # Réponse du serveur
server.login('user', 'pass') # On s'authentifie
# (235, '2.7.0 Authentication successful') # Réponse du serveur
fromaddr = 'TOTO <moi@toto.fr>'
toaddrs = ['lui@toto.fr', 'elle@toto.fr'] # On peut mettre autant d'adresses que l'on souhaite
sujet = "Un Mail avec Python"
message = u"""\
Velit morbi ultrices magna integer.
Metus netus nascetur amet cum viverra ve cum.
Curae fusce condimentum interdum felis sit risus.
Proin class condimentum praesent hendrer
it donec odio facilisi sit.
Etiam massa tempus scelerisque curae habitasse vestibulum arcu metus iaculis hac.
"""
msg = """\
From: %s\r\n\
To: %s\r\n\
Subject: %s\r\n\
Date: %s\r\n\
\r\n\
%s
""" % (fromaddr, ", ".join(toaddrs), sujet, formatdate(localtime=True), message)
try:
    server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPException as e:
    print(e)
# {} # Réponse du serveur
server.quit()
# (221, '2.0.0 Bye')

Envoi d'un mail via un serveur SMTP en SSL + TLS (avec authentification):

import smtplib
from email.utils import formatdate
server = smtplib.SMTP() # Avec TLS, on utilise SMTP()
# server.set_debuglevel(1) # Décommenter pour activer le debug
server.connect('smtp.toto.fr', 587) # On indique le port TLS
# (220, 'toto ESMTP Postfix') # Réponse du serveur
server.ehlo() # On utilise la commande EHLO
# (250, 'toto\nPIPELINING\nSIZE 10240000\nVRFY\nETRN\nSTARTTLS\nENHANCEDSTATUSCODES\n8BITMIME\nDSN') # Réponse du serveur
server.starttls() # On appelle la fonction STARTTLS
# (220, '2.0.0 Ready to start TLS') # Réponse du serveur
server.login('user', 'pass')
# (235, '2.7.0 Authentication successful') # Réponse du serveur
fromaddr = 'TOTO <moi@toto.fr>'
toaddrs = ['lui@toto.fr', 'elle@toto.fr'] # On peut mettre autant d'adresses que l'on souhaite
sujet = "Un Mail avec Python"
message = u"""\
Velit morbi ultrices magna integer.
Metus netus nascetur amet cum viverra ve cum.
Curae fusce condimentum interdum felis sit risus.
Proin class condimentum praesent hendrer
it donec odio facilisi sit.
Etiam massa tempus scelerisque curae habitasse vestibulum arcu metus iaculis hac.
"""
msg = """\
From: %s\r\n\
To: %s\r\n\
Subject: %s\r\n\
Date: %s\r\n\
\r\n\
%s
""" % (fromaddr, ", ".join(toaddrs), sujet, formatdate(localtime=True), message)
try:
    server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPException as e:
    print(e)
# {} # Réponse du serveur
server.quit()
# (221, '2.0.0 Bye')

infoEn cas d'erreur, lors de l'exécution de la commande server.sendmail(fromaddr, toaddrs, msg), le serveur répond en indiquant l'erreur rencontrée

{'elle@toto.fr': (450, '4.2.0 <elle@toto.fr>: Recipient address rejected: User unknown in relay recipient table')}

Et en HTML, c'est plus sympa

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate

server = smtplib.SMTP()
# server.set_debuglevel(1) # Décommenter pour activer le debug
server.connect('smtp.toto.fr')

server.helo()

fromaddr = 'TOTO <moi@toto.fr>'
toaddrs = ['lui@toto.fr', 'elle@toto.fr'] # On peut mettre autant d'adresses que l'on souhaite
sujet = "Un Mail avec Python"
html = u"""\
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div>
Velit morbi ultrices magna integer.
Metus netus nascetur amet cum viverra ve cum.
Curae fusce condimentum interdum felis sit risus.
Proin class condimentum praesent hendrer
it donec odio facilisi sit.
Etiam massa tempus scelerisque curae habitasse vestibulum arcu metus iaculis hac.
</div>
</body
</html>
"""

msg = MIMEMultipart('alternative')
msg['Subject'] = sujet
msg['From'] = fromaddr
msg['To'] = ','.join(toaddrs)
msg["Date"] = formatdate(localtime=True)

part = MIMEText(html, 'html')
msg.attach(part)

try:
    server.sendmail(fromaddr, toaddrs, msg.as_string())
except smtplib.SMTPException as e:
    print(e)

server.quit()

A la demande d'Alain, un exemple de script qui permet d'envoyer un mail avec une pièce jointe:
 

source:
https://docs.python.org/3/library/email.examples.html#email-examples
https://docs.python.org/3.8/library/mimetypes.html

from email.message import EmailMessage
from email.utils import formatdate
import mimetypes
from pathlib import Path
import smtplib
msg = EmailMessage()
msg['Subject'] = 'Un Mail avec Python'
msg['From'] = 'TOTO <moi@toto.fr>'
msg['To'] = ', '.join(['lui@toto.fr', 'elle@toto.fr'])
msg["Date"] = formatdate(localtime=True)
msg.set_content("""\
Salut!
Ci joint le fichier demandé.
""")
cfile = Path('myfile.txt')
ctype, encoding = mimetypes.guess_type(cfile)
if ctype is None or encoding is not None:
    ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
msg.add_attachment(cfile.read_bytes(), maintype=maintype, subtype=subtype, filename=cfile.name)
with smtplib.SMTP('smtp.toto.fr') as csmtp:
    csmtp.send_message(msg)

Python 3.9 - Envoi d'un mail via le SMTP office365 (outlook):

import smtplib
from email.utils import formatdate
server = smtplib.SMTP('SMTP.office365.com', 587)
server.connect('SMTP.office365.com', 587)
server.ehlo()
server.starttls()
server.login('julieraymond@example.org', 'Q7!7KgR3+5')
fromaddr = 'Antoine-Marcel Weber <julieraymond@example.org>'
toaddrs = ['renee88@example.org', 'etienneguyot@example.net']
sujet = "Reculer voile finir arrêter complètement lever."
message = u"""\
Extraordinaire longtemps taille musique. Discussion expérience français anglais fleur toujours.
Professeur dieu agir ouvrir escalier facile supposer. Action maintenir contenter bois. Même puis autre discours de mince veille quarante.
Fille retomber air accuser. Suivant dans bien sous oncle vent. Travail jour refuser nuit réel."""
msg = f"""\
From: {fromaddr}\r\n\
To: {", ".join(toaddrs)}\r\n\
Subject: {sujet}\r\n\
Date: {formatdate(localtime=True)}\r\n\
\r\n\
{message}"""
try:
    server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPException as e:
    print(e)
server.quit()