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('smtp.toto.fr', 587) # 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()

Commentaires

Bonjour, je débute sur python j'ai testé votre code qui marche très bien, sauf que je ne peux pas utiliser les accents dans mon message (j'ai l'impression que le message utilise le code ascii et non de l'unicode mais comme je débute...).
Est ce que vous auriez une solution ?
Dans tout les cas merci pour votre partage sur votre site.
Bonne journée

Tout dépend de la version de Python utilisée

Si c'est la version 3, en théorie, il ne doit pas y avoir de problème

Si c'est la version 2, effectivement il peut y avoir des soucis au niveau de l'encodage des caractères

Je ne pense pas à le mettre systématiquement dans mes exemples mais il est très fortement recommandé d'indiquer au début de chaque script l'encodage grâce à la ligne suivante

# -*- coding: UTF-8 -*-

Ensuite, ce site http://sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/ explique très clairement toutes les subtilités de l'encodage

Je pense que ça devrait t'aider à résoudre ton problème

Bonjour,
J'ai utilisé le premier code de votre page qui fonctionne très bien tout seul. Or j'ai besoin d'envoyer plusieurs mail à la suite, donc ai voulu en faire une méthode. L'envoie s'effectue, en effet, mais je reçois un mail vide (pas de subject ni de message ...)
Pensez vous à une solution ?

Envoyez moi la méthode que vous avez faite.
Je verrais peut-être d'où vient le problème.
Vous pouvez utiliser le formulaire de contact pour me l'envoyer.

Bonjour

Quand je run le programme, j'ai une erreur 503 et je ne comprend pas ce que c'est...
je vous envoie l'erreur:
(503, b'5.5.1 Error: send HELO/EHLO first', 'TOTO ')
voila. Bien sûr j'ai remplacé l'adresse e-mail par la mienne...
merci d'avance

Quand je vois l'erreur, j'ai l'impression que tu n'exécutes pas la commande

server.helo()

ou que tu l'exécutes au mauvais endroit.

L'erreur renvoyée indique bien d'envoyer la commande HELO/EHLO en premier.

Il faut obligatoirement l'exécuter tout de suite après la connexion au serveur SMTP

Bonjour,

Lorsque je teste votre code je reçois un msg d'erreur connect: to ('smtp.office365.com', 25) et ensuite l'erreur 10013 "An attempt was made to access a socket in a way forbidden by its access permissions.

Pourriez-vous m'éclairer SVP?

Bien à vous.

Bonjour,

Je ne sais pas si vous souhaitez utiliser le smtp d'office365 pour envoyer des mails à l'extérieur du domaine ou pour une adresse interne au domaine.

Pour utiliser le smtp d'office365 pour l'envoi de mails à des domaines externes il est nécessaire de s'authentifier en TLS sur le port 587.

Pour utiliser le smtp d'office365 pour l'envoi de mails à des adresses internes, je sais que les serveurs office365 sont très restrictifs pour éviter le spam au maximum.

Bonsoir,
Je trouve vraiment super votre page. Mais j'ai petit souci dans mon code ci-dessous. Il s’exécute mais je ne vois aucun mail envoyé. pouvez m'aider svp?

import smtplib
email_user='ouattaraarthur0@gmail.com'
email_send='ouattaraarthur0@gmail.com'
password='xxxxxxxxx'

server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()

server.login(email_user,password)

message='Hi bro, comment tu vas?'
server.send_mail=(email_user,email_send,message)
server.quit

import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login('xxx@gmail.com', 'xxx')
fromaddr = 'foo <xxx@gmail.com>'
toaddrs = ['xxx@xxx.fr']
sujet = "Test"
message = u"""\
Message test
"""
msg = """\
From: %s\r\n\
To: %s\r\n\
Subject: %s\r\n\
\r\n\
%s
""" % (fromaddr, ", ".join(toaddrs), sujet, message)
try:
    server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPException as e:
    print(e)
server.quit()

Bonjour,
Grand merci pour vos scripts qui font gagner un temps précieux.
Comment customiser le premier des scripts pour permettre l'envoi d'une pièce attaché ?
Merci bien

J'ai ajouté un exemple en fin d'article.
Bonne continuation.

Bonjour j'essaye désespérément d'envoyer un mail avec PJ via Python.
Je souhaite l'envoyer via Outlook sur une adresse Outlook.
Cependant j'ai testé vos scripts et aucun ne fonctionne.
J'utilise WinPython l'erreur vient-elle de là?
Pouvez-vous m'aider?

Bonjour,
Qu'entends tu par envoyer un mail via Outlook ?
Tous mes exemples utilisent un serveur smtp, obligatoire pour envoyer des mails.

En fait je souhaiterai envoyer un mail chaques semaines depuis une station de travail qui fonctionne en Linux vers un pc Linux aussi.
Les addresses émetteurs et récepteurs utiliseraint la messagerie Outlook.

J'ai ajouté ci-dessus un petit exemple fonctionnel qui utilise le serveur SMTP SMTP.office365.com.

En théorie, outlook utilise ce serveur smtp pour l'envoi des mails.

De mon coté ça fonctionne parfaitement bien.

Bon courage.

Merci pour votre aide, il semble que mon serpent soit capricieux.
Je vais essayer de voit d'où peut provenir le problème.
Je vous met à la suite les messages d'erreurs que j'ai eu avec le dernier script que vous avez posté.

Traceback (most recent call last):
File "C:\Users\joan burgalat\Desktop\test_mail.py", line 79, in
server = smtplib.SMTP('SMTP.office365.com', 587)
File "C:\Users\joan burgalat\Desktop\Winpython64-3.8.7.0\WPy64-3870\python-3.8.7.amd64\lib\smtplib.py", line 253, in __init__
(code, msg) = self.connect(host, port)
File "C:\Users\joan burgalat\Desktop\Winpython64-3.8.7.0\WPy64-3870\python-3.8.7.amd64\lib\smtplib.py", line 337, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Users\joan burgalat\Desktop\Winpython64-3.8.7.0\WPy64-3870\python-3.8.7.amd64\lib\smtplib.py", line 308, in _get_socket
return socket.create_connection((host, port), timeout,
File "C:\Users\joan burgalat\Desktop\Winpython64-3.8.7.0\WPy64-3870\python-3.8.7.amd64\lib\socket.py", line 808, in create_connection
raise err
File "C:\Users\joan burgalat\Desktop\Winpython64-3.8.7.0\WPy64-3870\python-3.8.7.amd64\lib\socket.py", line 796, in create_connection
sock.connect(sa)
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

je pense que c'est un problème d'accès réseau.

la machine sur laquelle est exécuté le script ne doit pas avoir accès à internet.

peut-être un proxy non configuré, ou un port fermé en sortie...

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.