Skip to content

Envoi d'e-mails en Python

Le Simple Mail Transfer Protocol (SMTP) est le protocole Internet standard pour l’envoi de courrier électronique (e-mail). Le module smtplib intégré de Python offre des fonctionnalités côté client pour se connecter à un serveur SMTP et envoyer des e-mails.

Pour construire des messages e-mail de manière robuste (gestion des en-têtes, des différents types de contenu, des pièces jointes), le module standard email.message est fortement recommandé plutôt que le formatage manuel de chaînes de caractères.

Vous créez un objet de session client SMTP en utilisant smtplib.SMTP ou smtplib.SMTP_SSL (pour les serveurs nécessitant une connexion SSL dès le début). Il est crucial d’utiliser des connexions chiffrées (SSL/TLS) chaque fois que possible.

import smtplib
# Option 1 : Se connecter au port SMTP standard, puis passer au TLS
# smtp_server = smtplib.SMTP(host, port)
# smtp_server.starttls() # Sécurise la connexion
# Option 2 : Se connecter directement en utilisant SSL
# smtp_server = smtplib.SMTP_SSL(host, port)
# Exemple pour Gmail (nécessite un mot de passe d'application si la 2FA est activée)
# host = 'smtp.gmail.com'
# port = 465 # Pour SSL
# smtp_server = smtplib.SMTP_SSL(host, port)
# Exemple pour un serveur de débogage local (pas de chiffrement)
# python -m smtpd -c DebuggingServer -n localhost:1025
# smtp_server = smtplib.SMTP('localhost', 1025)

Paramètres pour SMTP() / SMTP_SSL() :

Après la connexion, vous devez généralement vous authentifier :

# smtp_server.login(sender_email, password)

Remarque sur la sécurité : Évitez de coder en dur les identifiants directement dans votre script. Utilisez des variables d’environnement, des fichiers de configuration ou des outils sécurisés de gestion des secrets.

Utilisez la classe email.message.EmailMessage pour construire la structure de l’e-mail.

import smtplib
import os
from email.message import EmailMessage
# --- Configuration (Charger de manière sécurisée, par ex. depuis les variables d'environnement) ---
SMTP_HOST = 'smtp.example.com' # À remplacer par votre hôte SMTP
SMTP_PORT = 587 # À remplacer par votre port SMTP (TLS)
SENDER_EMAIL = 'your_email@example.com' # À remplacer
SENDER_PASSWORD = os.environ.get('EMAIL_PASSWORD') # Exemple : Obtenir d'une variable d'environnement
RECEIVER_EMAIL = 'recipient@example.com' # À remplacer
# --------------------------------------------------------------------
if not SENDER_PASSWORD:
print("Error: Email password not set in environment variable EMAIL_PASSWORD")
exit()
# Créer l'objet message e-mail
msg = EmailMessage()
msg['Subject'] = 'Test Email from Python'
msg['From'] = SENDER_EMAIL
msg['To'] = RECEIVER_EMAIL
msg.set_content('This is a plain text email sent using Python.')
try:
# Connecter, se connecter (login) et envoyer
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
server.starttls() # Sécuriser la connexion (si le port 587 est utilisé)
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.send_message(msg)
print("E-mail envoyé avec succès !")
except smtplib.SMTPAuthenticationError:
print("Échec de l'authentification. Vérifiez l'e-mail/le mot de passe ou les paramètres de mot de passe spécifique à l'application.")
except smtplib.SMTPException as e:
print(f"Une erreur SMTP s'est produite : {e}")
except Exception as e:
print(f"Une erreur s'est produite : {e}")

Étapes clés :

Pour envoyer du contenu HTML, utilisez msg.add_alternative().

import smtplib
import os
from email.message import EmailMessage
# --- Configuration (comme précédemment) ---
SMTP_HOST = 'smtp.example.com'
SMTP_PORT = 587
SENDER_EMAIL = 'your_email@example.com'
SENDER_PASSWORD = os.environ.get('EMAIL_PASSWORD')
RECEIVER_EMAIL = 'recipient@example.com'
# ----------------------------------
if not SENDER_PASSWORD:
print("Error: Email password not set.")
exit()
msg = EmailMessage()
msg['Subject'] = 'HTML Email Test from Python'
msg['From'] = SENDER_EMAIL
msg['To'] = RECEIVER_EMAIL
# Définir le contenu en texte brut (solution de repli pour les clients ne supportant pas le HTML)
msg.set_content('This is the plain text version.')
# Ajouter une alternative HTML
html_content = """
<html>
<body>
<p>This is an **HTML** email message.</p>
<h1>Headline</h1>
<p>Sent using Python's `smtplib` and `email.message` modules.</p>
</body>
</html>
"""
msg.add_alternative(html_content, subtype='html')
try:
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
server.starttls()
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.send_message(msg)
print("E-mail HTML envoyé avec succès !")
except Exception as e:
print(f"Une erreur s'est produite : {e}")

add_alternative() ajoute une représentation différente du même contenu. Les clients de messagerie afficheront généralement le format le plus riche qu’ils prennent en charge (HTML dans ce cas). Fournir une version de repli en texte brut est une bonne pratique.

Envoi d’e-mails avec des pièces jointes

Section titled “Envoi d’e-mails avec des pièces jointes”

Utilisez msg.add_attachment() pour inclure des fichiers.

import smtplib
import os
from email.message import EmailMessage
import mimetypes # Pour deviner le type de fichier
# --- Configuration (comme précédemment) ---
SMTP_HOST = 'smtp.example.com'
SMTP_PORT = 587
SENDER_EMAIL = 'your_email@example.com'
SENDER_PASSWORD = os.environ.get('EMAIL_PASSWORD')
RECEIVER_EMAIL = 'recipient@example.com'
# ----------------------------------
if not SENDER_PASSWORD:
print("Error: Email password not set.")
exit()
ATTACHMENT_PATH = 'files/document.pdf' # À remplacer par le chemin de votre fichier
if not os.path.exists(ATTACHMENT_PATH):
print(f"Error: Attachment file not found at {ATTACHMENT_PATH}")
exit()
msg = EmailMessage()
msg['Subject'] = 'Email with Attachment from Python'
msg['From'] = SENDER_EMAIL
msg['To'] = RECEIVER_EMAIL
msg.set_content('Please find the attached document.')
# --- Ajouter une pièce jointe ---
# Deviner le type MIME
mime_type, _ = mimetypes.guess_type(ATTACHMENT_PATH)
if mime_type is None:
# Par défaut, binaire générique si le type ne peut pas être deviné
mime_type = 'application/octet-stream'
maintype, subtype = mime_type.split('/', 1)
with open(ATTACHMENT_PATH, 'rb') as fp:
msg.add_attachment(fp.read(),
maintype=maintype,
subtype=subtype,
filename=os.path.basename(ATTACHMENT_PATH))
# ---------------------
try:
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
server.starttls()
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.send_message(msg)
print("E-mail avec pièce jointe envoyé avec succès !")
except Exception as e:
print(f"Une erreur s'est produite : {e}")

Étapes clés pour les pièces jointes :